diff --git a/.github/ISSUE_TEMPLATE/Question.md b/.github/ISSUE_TEMPLATE/Question.md index a3f9a38394f3..3e71b8399611 100644 --- a/.github/ISSUE_TEMPLATE/Question.md +++ b/.github/ISSUE_TEMPLATE/Question.md @@ -11,5 +11,5 @@ so we recommend using our other community resources instead of asking here 👍. If you have a support request or question please submit them to one of these resources: -* [Terraform community resources](https://www.terraform.io/docs/extend/community/index.html) +* [HashiCorp Community Forums](https://discuss.hashicorp.com/c/terraform-providers) * [HashiCorp support](https://support.hashicorp.com) (Terraform Enterprise customers) diff --git a/.gitignore b/.gitignore index 6c6ffa9ab9d0..247ea4cb6fdc 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ examples/**/test.tf examples/**/test.tfvars examples/**/terraform examples/**/terraform.zip + +#never upload the build to git +terraform-provider-azurerm diff --git a/.golangci.yml b/.golangci.yml index 4e8d9293d05e..1455602e8204 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,3 +1,7 @@ +run: + deadline: 10m10s + modules-download-mode: vendor + issues: max-per-linter: 0 max-same-issues: 0 @@ -8,6 +12,7 @@ linters: - deadcode - errcheck - gofmt + - goimports - gosimple - govet - ineffassign @@ -26,6 +31,6 @@ linters: linters-settings: errcheck: ignore: github.com/hashicorp/terraform/helper/schema:ForceNew|Set,fmt:.*,io:Close - -run: - modules-download-mode: vendor \ No newline at end of file + misspell: + ignore-words: + - hdinsight \ No newline at end of file diff --git a/.hashibot.hcl b/.hashibot.hcl new file mode 100644 index 000000000000..ff3069ff6b3a --- /dev/null +++ b/.hashibot.hcl @@ -0,0 +1,26 @@ +queued_behavior "release_commenter" "releases" { + repo_prefix = "terraform-provider-" + + message = <<-EOF + This has been released in [version ${var.release_version} of the provider](${var.changelog_link}). Please see the [Terraform documentation on provider versioning](https://www.terraform.io/docs/configuration/providers.html#provider-versions) or reach out if you need any assistance upgrading. As an example: + ```hcl + provider "${var.project_name}" { + version = "~> ${var.release_version}" + } + # ... other configuration ... + ``` + EOF +} + +poll "closed_issue_locker" "locker" { + schedule = "0 50 14 * * *" + closed_for = "720h" # 30 days + max_issues = 500 + sleep_between_issues = "5s" + + message = <<-EOF + I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues. + + If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 hashibot-feedback@hashicorp.com. Thanks! + EOF +} diff --git a/.travis.yml b/.travis.yml index 1f7a4d34cf7c..167309d41898 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,28 +1,33 @@ -dist: trusty +dist: xenial sudo: required services: - docker language: go go: -- "1.11.x" - -install: -# This script is used by the Travis build to install a cookie for -# go.googlesource.com so rate limits are higher when using `go get` to fetch -# packages that live there. -# See: https://github.com/golang/go/issues/12933 -- bash scripts/gogetcookie.sh -- make tools - -script: -- make test -- make lint -- make website-test +- "1.12.x" branches: only: - - master + - master + +install: + # This script is used by the Travis build to install a cookie for + # go.googlesource.com so rate limits are higher when using `go get` to fetch + # packages that live there. + # See: https://github.com/golang/go/issues/12933 + - bash scripts/gogetcookie.sh + - make tools + matrix: fast_finish: true allow_failures: - - go: tip + - go: tip + include: + - name: "make lint" + script: GOGC=20 make lint + - name: "make test" + script: make test + - name: "make website-lint" + script: make website-lint + - name: "make website-test" + script: make website-test diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b781dfa0627..15686a435fed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,31 +1,484 @@ -## 1.24.0 (Unreleased) +## 1.34.0 (Unreleased) FEATURES: -* **New Data Source:** `azurerm_api_management_api` [GH-3010] -* **New Resource:** `azurerm_api_management_api` [GH-3010] -* **New Resource:** `azurerm_api_management_product_api` [GH-3066] +* **New Resource:** `azurerm_app_service_certificate` [GH-4192] +* **New Resource:** `azurerm_kusto_cluster` [GH-4129] +* **New Resource:** `azurerm_web_application_firewall_policy` [GH-4119] IMPROVEMENTS: -* Data Source: `azurerm_storage_account` - exposing the Hierarchical Namespace state [GH-3032] -* `azurerm_app_service` - support for migrating between App Service Plans [GH-3048] -* `azurerm_app_service` - support for additional types for the `scm_type` field in the `site_config` block [GH-3019] -* `azurerm_app_service_slot` - support for additional types for the `scm_type` field in the `site_config` block [GH-3019] -* `azurerm_batch_account` - now exports the `primary_access_key`, `secondary_access_key`, and `account_endpoint` properties [GH-3071] -* `azurerm_container_group` - support for attaching GPU's [GH-3053] -* `azurerm_function_app` - exporting `possible_outbound_ip_addresses` [GH-3043] -* `azurerm_eventhub_namespace` - increase maximum `capacity` to 100 [GH-3049] -* `azurerm_managed_disk` - support for managed disks up to 32TB [GH-3062] -* `azurerm_storage_account` - support for configuring the Hierarchical Namespace state [GH-3032] -* `azurerm_virtual_machine` - support for managed disks up to 32TB [GH-3062] -* `azurerm_virtual_machine_scale_set` - support for managed disks up to 32TB [GH-3062] +* dependencies: updating `github.com/Azure/azure-sdk-for-go` to `v32.5.0` [GH-4166] +* dependencies: updating `github.com/Azure/go-autorest` to `v0.9.0` [GH-4166] +* dependencies: updating `github.com/hashicorp/go-azure-helpers` to `v0.7.0` [GH-4166] +* dependencies: updating `github.com/terraform-providers/terraform-provider-azuread` to `v0.6.0` [GH-4166] +* Data Source: `azurerm_storage_account_sas` - adding an `ISO8601` validator to the `start` and `end` dates [GH-4064] +* `azurerm_api_management` - support for multiple `additional_location` blocks [GH-4175] +* `azurerm_application_gateway` - allowing `capacity` to be set to 32 [GH-4189] +* `azurerm_cosmosdb_sql_container` - the property `unique_key.paths` is now marked as ForceNew [GH-4163] +* `azurerm_kubernetes_cluster` - support for configuring the `kube_dashboard` within the `addon_profile` block [GH-4139] +* `azurerm_mariadb_server` - support for version `10.3` [GH-4170] +* `azurerm_storage_blob` - switching over to use the new Storage SDK [GH-4179] +* `azurerm_storage_share_directory` - support for upper-case characters in the `name` field [GH-4178] +* `azurerm_subnet` - support for the actions `Microsoft.Network/virtualNetworks/subnets/join/action` and `Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action` [GH-4137] +* `azurerm_virtual_machine` - support for `UltraSSD_LRS` managed disks [GH-3860] BUG FIXES: -* `azurerm_key_vault_certificate` - making `contents` and `password` within the `certificate` block sensitive [GH-3064] -* `monitor_metric_alert` - support for setting `aggregation` to `count` [GH-3047] -* `azurerm_virtual_network_gateway` - fixing a crash when `bgp_settings` had no elements [GH-3038] +* `azurerm_app_service_plan` and `azurerm_app_service_slot` crash fixes [GH-4184] +* `azurerm_container_group~ - make `storage_account_key` field in `volume` block sensitive [GH-4201] +* `azurerm_log_analytics_linked_service` - crash fix [GH-4142] +* `azurerm_log_analytics_workspace_linked_service` - crash fix [GH-4152] +* `azurerm_virtual_network_peering` - prevent nil object from being read [GH-4180] + +## 1.33.1 (August 27, 2019) + +* networking: reducing the number of locks to avoid deadlock when creating 3 or more subnets with Network Security Group/Route Table Associations ([#3673](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3673)) + +## 1.33.0 (August 22, 2019) + +FEATURES: + +* **New Data Source:** `azurerm_dev_test_virtual_network` ([#3746](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3746)) +* **New Resource:** `azurerm_cosmosdb_sql_container` ([#3871](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3871)) +* **New Resource:** `azurerm_container_registry_webhook` ([#4112](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4112)) +* **New Resource:** `azurerm_dev_test_lab_schedule` ([#3554](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3554)) +* **New Resource:** `azurerm_mariadb_virtual_network_rule` ([#4048](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4048)) +* **New Resource:** `azurerm_mariadb_configuration` ([#4060](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4060)) +* **New Resource:** `azurerm_private_dns_cname_record` ([#4028](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4028)) +* **New Resource:** `azurerm_recovery_services_fabric` ([#4003](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4003)) +* **New Resource:** `azurerm_recovery_services_protection_container` ([#4003](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4003)) +* **New Resource:** `azurerm_recovery_services_replication_policy` ([#4003](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4003)) +* **New Resource:** `azurerm_recovery_services_protection_container_mapping` ([#4003](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4003)) +* **New Resource:** `azurerm_recovery_network_mapping` ([#4003](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4003)) +* **New Resource:** `azurerm_recovery_replicated_vm` ([#4003](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4003)) +* **New Resource:** `azurerm_sql_failover_group` ([#3901](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3901)) +* **New Resource:** `azurerm_virtual_wan` ([#4089](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4089)) + +IMPROVEMENTS: + +* all resources: increasing the maximum number of tags from `15` to `50` ([#4071](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4071)) +* dependencies: upgrading `github.com/tombuildsstuff/giovanni` to `v0.3.2` ([#4122](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4122)) +* dependencies: upgrading the `authorization` SDK to `2018-09-01` ([#4063](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4063)) +* dependencies: upgrading `github.com/hashicorp/terraform` to `0.12.6` ([#4041](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4041)) +* internal: removing a duplicate Date/Time from the debug logs ([#4024](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4024)) +* Data Source `azurerm_dns_zone`: deprecating the `zone_type` field ([#4033](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4033)) +* `azurerm_app_service` - `filesystem` logging can now be set. ([#4025](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4025)) +* `azurerm_batch_pool` - Support for Container Registry configurations ([#4072](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4072)) +* `azurerm_container_group` - support for attaching to a (Private) Virtual Network ([#3716](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3716)) +* `azurerm_container_group` - `log_type` can now be an empty string ([#4013](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4013)) +* `azurerm_cognitive_account` - Adding 'QnAMaker' as Kind ([#4126](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4126)) +* `azurerm_dns_zone` - deprecating the `zone_type` field ([#4033](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4033)) +* `azurerm_function_app` - support for cors ([#3949](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3949)) +* `azurerm_function_app` - support for the `virtual_network_name` property ([#4078](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4078)) +* `azurerm_iot_dps` - add support for the `linked_hub` property ([#3922](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3922)) +* `azurerm_kubernetes_cluster` - support for the `enable_pod_security_policy` property ([#4098](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4098)) +* `azurerm_monitor_diagnostic_setting` - support for `log_analytics_destination_type` ([#3987](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3987)) +* `azurerm_role_assignment` - now supports management groups ([#4063](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4063)) +* `azurerm_storage_account` - requesting an access token using the ARM Authorizer ([#4099](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4099)) +* `azurerm_storage_account` - support for `BlockBlobStorage` ([#4131](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4131)) +* `azurerm_subnet` - support for the Service Endpoints `Microsoft.BareMetal/AzureVMware`, `Microsoft.BareMetal/CrayServers`, `Microsoft.Databricks/workspaces` and `Microsoft.Web/hostingEnvironments` ([#4115](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4115)) +* `azurerm_traffic_manager_profile` - support for the `interval_in_seconds`, `timeout_in_seconds`, and `tolerated_number_of_failures` properties ([#3473](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3473)) +* `azurerm_user_assigned_identity` - the `name` field can now be up to 128 characters ([#4094](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4094)) + +BUG FIXES: + +* `azurerm_app_service_plan` - workaround for missing error on 404 ([#3990](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3990)) +* `azurerm_batch_certificate` - the `thumbprint_algorithm` property is now case insensitive ([#3977](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3977)) +* `azurerm_notification_hub_authorization_rule - fixing an issue when creating multiple authorization rules at the same time ([#4087](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4087)) +* `azurerm_postgresql_server` - removal of unsupported version `10.2` ([#3915](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3915)) +* `azurerm_role_definition` - enture `role_definition_id` is correctly set if left empty during creation ([#3913](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3913)) +* `azurerm_storage_account` - making `default_action` within the `network_rules` block required ([#4037](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4037)) +* `azurerm_storage_account` - making the `network_rules` block computed ([#4037](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4037)) +* `azurerm_storage_queue` - switching to using SharedKey for authentication ([#4122](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4122)) +* `azurerm_storage_share` - allow up to 100TB for the `quota` property ([#4054](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4054)) +* `azurerm_storage_share_directory` - handling the share being eventually consistent ([#4122](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4122)) +* `azurerm_storage_share_directory` - allowing nested directories ([#4122](https://github.com/terraform-providers/terraform-provider-azurerm/issues/4122)) + +## 1.32.1 (July 31, 2019) + +BUG FIXES: + +* `azurerm_application_gateway` fix an index out of range crash ([#3966](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3966)) +* `azurerm_api_management_backend` - ensuring a nil `certificates` object is sent to the API instead of an empty one ([#3931](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3931)) +* `azurerm_api_managment_product` - additional validation for `approval_required` ([#3945](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3945)) +* `azurerm_network_ddos_protection_plan` - correctly decodes the resource ID on read/delete ([#3975](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3975)) +* `azurerm_dev_test_virtual_network` - generate subnet IDs in the correct format ([#3717](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3717)) +* `azurerm_iot_dps` fixed deletion issue when using a service principal ([#3973](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3973)) +* `azurerm_kubernetes_cluster` - the `load_balancer_sku` property is now case insensitive ([#3958](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3958)) +* `azurerm_postgresql_server` - add missing support for version `11.0` ([#3970](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3970)) +* `azurerm_storage_*` - prevent multiple panics when a storage account/resource group cannot be found ([#3986](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3986)) +* `azurerm_storage_account` - fix `enable_advanced_threat_protection` create/read for unsupported regions ([#3947](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3947)) +* `azurerm_storage_table` - now migrates older versions of the resource id to the new format ([#3932](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3932)) +* `azurerm_virtual_machine_scale_set` - the `ssh_keys` property of the `os_profile_linux_config` block now recognizes updates ([#3837](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3837)) +* `azurerm_virtual_machine_scale_set` - changes made to the `network_profile` property should now be correctly reflected during updates ([#3821](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3821)) + + +## 1.32.0 (July 24, 2019) + +FEATURES: + +* **New Data Source:** `azurerm_maps_account` ([#3698](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3698)) +* **New Data Source:** `azurerm_mssql_elasticpool` ([#3824](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3824)) +* **New Resource:** `azurerm_analysis_services_server` ([#3721](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3721)) +* **New Resource:** `azurerm_api_management_backend` ([#3676](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3676)) +* **New Resource:** `azurerm_batch_application` ([#3825](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3825)) +* **New Resource:** `azurerm_maps_account` ([#3698](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3698)) +* **New Resource:** `azurerm_private_dns_zone_a_record` ([#3849](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3849)) +* **New Resource:** `azurerm_storage_table_entity` ([#3831](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3831)) +* **New Resource:** `azurerm_storage_share_directory` ([#3802](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3802)) + +IMPROVEMENTS: + +* dependencies: upgrading to `v31.0.0` of `github.com/Azure/azure-sdk-for-go` ([#3786](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3786)) +* dependencies: upgrading to `v0.5.0` of `github.com/hashicorp/go-azure-helpers` ([#3850](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3850)) +* dependencies: upgrading the `containerservice` SDK to `2019-02-01` ([#3787](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3787)) +* dependencies: upgrading the `subscription` SDK to `2018-06-01` ([#3811](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3811)) +* authentication: showing a more helpful error when attempting to use the Azure CLI authentication when logged in as a Service Principal ([#3850](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3850)) +* Data Source `azurerm_function_app` - support for `auth_settings` ([#3893](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3893)) +* Data Source `azurerm_subscription` - support the `tenant_id` property ([#3811](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3811)) +* `azurerm_app_service` - support for backups ([#3804](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3804)) +* `azurerm_app_service` - support for storage mounts ([#3792](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3792)) +* `azurerm_app_service` - support for user assigned identities ([#3637](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3637)) +* `azurerm_app_service_slot` - support for `auth_settings` ([#3897](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3897)) +* `azurerm_app_service_slot` - support for user assigned identities ([#3637](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3637)) +* `azurerm_application_gateway` - Support for Managed Identities ([#3648](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3648)) +* `azurerm_batch_pool` - support for custom images with the `storage_image_reference` property ([#3530](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3530)) +* `azurerm_batch_account` - expose required properties for when `pool_allocation_mode` is `UserSubscription` ([#3535](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3535)) +* `azurerm_cognitive_account` - add support for `CustomVision.Training` and `CustomVision.Prediction` to the `kind` property ([#3817](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3817)) +* `azurerm_container_registry` - support for `network_rule_set` property ([#3194](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3194)) +* `azurerm_cosmosdb_account` - validate `max_interval_in_seconds` and `max_staleness_prefix` correctly when using more then 1 geo_location ([#3906](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3906)) +* `azurerm_function_app` - support for `auth_settings` ([#3893](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3893)) +* `azurerm_iothub` - support for the `file_upload` property ([#3735](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3735)) +* `azurerm_kubernetes_cluster` - support for auto scaling ([#3361](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3361)) +* `azurerm_kubernetes_cluster` - support for `custom_resource_group_name` ([#3785](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3785)) +* `azurerm_kubernetes_cluster` - support for the `node_taints` property ([#3787](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3787)) +* `azurerm_kubernetes_cluster` - support for the `windows_profile` property ([#3519](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3519)) +* `kubernetes_cluster` - support for specifying the `load_balancer_sku` property ([#3890](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3890)) +* `azurerm_recovery_services_protected_vm` - changing `backup_policy_id` no longer forces a new resource ([#3822](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3822)) +* `azurerm_security_center_contact` - the `phone` property is now optional ([#3761](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3761)) +* `azurerm_storage_account` - the `account_kind` property now supports `FileStorage` ([#3750](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3750)) +* `azurerm_storage_account` - support for the `enable_advanced_threat_protection` property ([#3782](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3782)) +* `azurerm_storage_account` - support for `queue_properties` ([#3859](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3859)) +* `azurerm_storage_blob` - making `metadata` a computed field ([#3842](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3842)) +* `azurerm_storage_container` - switching to use github.com/tombuildsstuff/giovanni ([#3857](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3857)) +* `azurerm_storage_container` - adding support for `metadata` ([#3857](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3857)) +* `azurerm_storage_container` - can now create containers with the name `$web` ([#3896](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3896)) +* `azurerm_storage_queue` - switching to use github.com/tombuildsstuff/giovanni ([#3832](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3832)) +* `azurerm_storage_share` - switching to use github.com/tombuildsstuff/giovanni ([#3828](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3828)) +* `azurerm_storage_share` - support for configuring ACL's ([#3830](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3830)) +* `azurerm_storage_share` - support for configuring MetaData ([#3830](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3830)) +* `azurerm_storage_table` - switching to use github.com/tombuildsstuff/giovanni ([#3834](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3834)) +* `azurerm_storage_table` - support for configuring ACL's ([#3847](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3847)) +* `azurerm_traffic_manager_endpoint` - supper for `custom_header` and `subnet` properties ([#3655](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3655)) +* `azurerm_virtual_machine` - switching over to use the github.com/tombuildsstuff/giovanni Storage SDK ([#3838](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3838)) +* `azurerm_virtual_machine` - looking up the data disks attached to the Virtual Machine when optionally deleting them upon deletion rather than parsing them from the config ([#3838](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3838)) +* `azurerm_virtual_machine_scale_set` - prevent `public_ip_address_configuration` from being lost during update ([#3767](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3767)) + +BUG FIXES: + +* `azurerm_image` - prevent crash when using `data_disk` ([#3797](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3797)) +* `azurerm_role_assignment` - now correctly uses `scope` when looking up the role definition by name ([#3768](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3768)) + +## 1.31.0 (June 28, 2019) + +FEATURES: + +* increase the default timeout to `3 hours` ([#3737](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3737)) +* **New Resource:** `azurerm_iot_dps` ([#3618](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3618)) +* **New Resource:** `azurerm_iot_dps_certificate` ([#3567](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3645)) +* **New Resource:** `azurerm_mariadb_firewall_rule` ([#3720](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3720)) +* **New Resource:** `azurerm_private_dns_zone` ([#3718](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3718)) +* **New Resource:** `azurerm_stream_analytics_output_mssql` ([#3567](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3567)) + +IMPROVEMENTS: + +* Data Source `azurerm_key_vault` - deprecated `sku` in favour of `sku_name` ([#3119](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3119)) +* `azurerm_app_service` - support for shipping the application logs to blob storage ([#3520](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3520)) +* `azurerm_app_service_plan` - prevent a panic during import ([#3657](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3657)) +* `azurerm_app_service_slot` - updating `identity` no longer forces a new resource ([#3702](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3702)) +* `azurerm_automation_account` - deprecated `sku` in favour of `sku_name` ([#3119](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3119)) +* `azurerm_key_vault` - deprecated `sku` in favour of `sku_name` ([#3119](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3119)) +* `azurerm_key_vault_key` - add support for Elliptic Curve based keys ([#1814](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1814)) +* `azurerm_traffic_manager_profile` - `ttl` can now be 1 second ([#3632](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3632)) +* `azurerm_eventgrid_event_subscription` - now retrieves the full URL for event webhooks ([#3630](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3630)) +* `azurerm_lb` - support for the `public_ip_prefix_id` property ([#3675](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3675)) +* `azurerm_mysql_server` - add validation to the `name` property ([#3695](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3695)) +* `azurerm_notification_hub_namespace` - deprecated `sku` in favour of `sku_name` ([#3119](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3119)) +* `azurerm_redis_firewall_rule` - no longer fails with multiple rules ([#3731](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3731)) +* `azurerm_relay_namespace` - deprecated `sku` in favour of `sku_name` ([#3119](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3119)) +* `azurerm_service_fabric_cluster` - `tenant_id`, `cluster_application_id`, and `client_application_id` are now updateable ([#3654](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3654)) +* `azurerm_service_fabric_cluster` - ability to set `certificate_common_names` ([#3652](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3652)) +* `azurerm_storage_account` - ability to set `default_action` oi the `network_rules` block ([#3255](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3255)) + +BUG FIXES: + +* `azurerm_cosmosdb_account` - will ignore `500` responses from `documentdb.DatabaseAccountsClient#CheckNameExists` requests to work around a broken API ([#3747](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3747)) + +## 1.30.1 (June 07, 2019) + +BUG FIXES: + +* Ensuring the authorization header is set for calls to the User Assigned Identity API's ([#3613](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3613)) + +## 1.30.0 (June 07, 2019) + +FEATURES: + +* **New Data Source:** `azurerm_redis_cache` ([#3481](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3481)) +* **New Data Source:** `azurerm_sql_server` ([#3513](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3513)) +* **New Data Source:** `azurerm_virtual_network_gateway_connection` ([#3571](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3571)) + +IMPROVEMENTS: + +* dependencies: upgrading to Go 1.12 ([#3525](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3525)) +* dependencies: upgrading the `storage` SDK to `2019-04-01` ([#3578](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3578)) +* Data Source `azurerm_app_service` - support windows containers ([#3566](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3566)) +* Data Source `azurerm_app_service_plan` - support windows containers ([#3566](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3566)) +* `azurerm_api_management` - rename `disable_triple_des_chipers` to `disable_triple_des_ciphers` ([#3539](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3539)) +* `azurerm_application_gateway` - support for the value `General` in the `rule_group_name` field within the `disabled_rule_group` block ([#3533](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3533)) +* `azurerm_app_service` - support for windows containers ([#3566](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3566)) +* `azurerm_app_service_plan` - support for the `maximum_elastic_worker_count` property ([#3547](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3547)) +* `azurerm_managed_disk` - support for the `create_option` of `Restore` ([#3598](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3598)) +* `azurerm_app_service_plan` - support for windows containers ([#3566](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3566)) + + +## 1.29.0 (May 25, 2019) + +FEATURES: + +* **New Resource:** `azurerm_application_insights_web_test` ([#3331](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3331)) + +IMPROVEMENTS: + +* dependencies: upgrading to `v0.12.0` of `github.com/hashicorp/terraform` ([#3417](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3417)) +* sdk: configuring the Correlation Request ID ([#3253](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3253)) +* `azurerm_application_gateway` - support for rewrite rules ([#3423](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3423)) +* `azurerm_application_gateway` - support for `ssl_policy` blocks and deprecating `disabled_ssl_protocols` ([#3360](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3360)) +* `azurerm_app_service` - support for configuring authentication settings ([#2831](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2831)) +* `azurerm_kubernetes_cluster` - updating the casing on the `SubnetName` field to match a change in the AKS API ([#3484](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3484)) +* `azurerm_kubernetes_cluster` - support for multiple agent pools ([#3491](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3491)) + +BUG FIXES: + +* Data Source `azurerm_virtual_network`: add `network_space` property to match resource while deprecating `network_spaces` ([#3494](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3494)) +* `azurerm_automation_module` - now polls to wait until the module's finished provisioning ([#3482](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3482)) +* `azurerm_api_management_api` - correct validation to allow empty and strings 400 characters long ([#3475](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3475)) +* `azurerm_dev_test_virtual_network` - correctly manages `subnets` on the initial creation ([#3501](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3501)) +* `azurerm_express_route_circuit` - no longer removes circuit subresources on update ([#3496](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3496)) +* `azurerm_role_assignment` - making the `role_definition_name` field case-insensitive ([#3499](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3499)) + +## 1.28.0 (May 17, 2019) + +FEATURES: + +* **New Data Source:** `azurerm_automation_variable_bool` ([#3310](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3310)) +* **New Data Source:** `azurerm_automation_variable_datetime` ([#3310](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3310)) +* **New Data Source:** `azurerm_automation_variable_int` ([#3310](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3310)) +* **New Data Source:** `azurerm_automation_variable_string` ([#3310](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3310)) +* **New Data Source:** `zurerm_kubernetes_service_versions` ([#3382](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3382)) +* **New Data Source:** `azurerm_user_assigned_identity` ([#3343](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3343)) +* **New Resource:** `azurerm_automation_variable_bool` ([#3310](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3310)) +* **New Resource:** `azurerm_automation_variable_datetime` ([#3310](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3310)) +* **New Resource:** `azurerm_automation_variable_int` ([#3310](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3310)) +* **New Resource:** `azurerm_automation_variable_string` ([#3310](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3310)) +* **New Resource:** `azurerm_api_management_api_operation_policy` ([#3374](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3374)) +* **New Resource:** `azurerm_api_management_api_policy` ([#3367](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3367)) +* **New Resource:** `azurerm_api_management_product_policy` ([#3325](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3325)) +* **New Resource:** `azurerm_api_management_schema` ([#3357](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3357)) +* **New Resource:** `azurerm_cosmosdb_table` ([#3442](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3442)) +* **New Resource:** `azurerm_cosmosdb_cassandra_keyspace` ([#3442](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3442)) +* **New Resource:** `azurerm_cosmosdb_mongo_collection` ([#3459](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3459)) +* **New Resource:** `azurerm_cosmosdb_mongo_database` ([#3442](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3442)) +* **New Resource:** `azurerm_cosmosdb_sql_database` ([#3442](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3442)) +* **New Resource:** `azurerm_firewall_nat_rule_collection` ([#3218](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3218)) +* **New Resource:** `azurerm_data_factory_linked_service_data_lake_storage_gen2` ([#3425](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3425)) +* **New Resource:** `azurerm_network_profile` ([#2636](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2636)) + +IMPROVEMENTS: + +* dependencies: updating `github.com/Azure/azure-sdk-for-go` to v29.0.0 ([#3335](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3335)) +* Data Source `azurerm_kubernetes_cluster` - exposing the `type` field within the `agent_pool_profile ` block ([#3424](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3424)) +* `azurerm_application_gateway` - support for the `autoscale_configuration` property ([#3353](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3353)) +* `azurerm_application_gateway` added validation to ensure `redirect_configuration_name` must not be set if either `backend_address_pool_name` or `backend_http_settings_name` is set ([#3340](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3340)) +* `azurerm_application_gateway` - support for `affinity_cookie_name` ([#3434](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3434)) +* `azurerm_application_gateway` - support for `disabled_rule_groups` ([#3394](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3394)) +* `azurerm_app_service_slot` - exporting the `site_credential` block ([#3444](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3444)) +* `azurerm_batch_pool` support for the `container_configuration` property ([#3311](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3311)) +* `azurerm_kubernetes_cluster` - support for the `api_server_authorized_ip_ranges` property ([#3262](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3262)) +* `azurerm_kubernetes_cluster` - support for setting `type` within the `agent_pool_profile` block (Agent Pools via Virtual Machine Scale Sets) ([#3424](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3424)) +* `azurerm_redis_cache` - support for disabling authentication ([#3389](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3389)) +* `azurerm_redis_cache` - make the `redis_configuration` block optional ([#3397](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3397)) +* `azurerm_sql_database` - support for the `read_scale` property ([#3377](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3377)) +* `azurerm_stream_analytics_job` - `tags` can now be set on the property ([#3329](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3329)) +* `azurerm_virtual_network_peering` - retrying provisioning the peering of the virtual network ([#3392](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3392)) +* `azurerm_virtual_machine_scale_set` - support for the `provision_after_extensions` property to chain multiple extensions togeather ([#2937](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2937)) + +BUG FIXES: + +* Data Source: `azurerm_api_management` - correctly returning the hostname `portal` and `proxy` values ([#3385](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3385)) +* `azurerm_application_gateway` - will no longer prevent `default_backend_address_pool_name` and `redirect_configuration_name` from being set at the same time ([#3286](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3286)) +* `azurerm_application_gateway` prevent a potential panic in backend and probe validation ([#3438](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3438)) +* `azurerm_eventhub` - decrease minimum `partition_count` to correct value of `1` ([#3439](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3439)) +* `azurerm_eventhub_namespace` - decrease maximum `maximum_throughput_units` to correct value of `20` ([#3440](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3440)) +* `azurerm_firewall` - ensuring that the value for `subnet_id` within the `ip_configuration` block has the name `AzureFirewallSubnet` ([#3406](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3406)) +* `azurerm_managed_disk` - can now actually create `UltraSSD_LRS` disks ([#3453](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3453)) +* `azurerm_redis_configuration` - correctly display http errors encoutered during creation ([#3397](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3397)) +* `azurerm_sql_database` - making the `collation` field case insensitive to work around a bug in the API ([#3137](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3137)) +* `azurerm_stream_analytics_output_eventhub` will now correctly set `format` for JSON output ([#3318](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3318)) +* `azurerm_app_service_plan` - supports `elastic` for the sku tier ([#3402](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3402)) +* `azurerm_application_gateway` - supports `disabled_rule_group` for waf configurations ([#3394](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3394)) +* `azurerm_application_gateway` - supports `exclusion` for waf configurations ([#3407](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3407)) +* `azurerm_application_gateway` - supports updating a `gateway_ip_configuration.x.subnet_id` ([#3437](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3437)) + +## 1.27.1 (April 26, 2019) + +BUG FIXES: + +* provider will now only register available resource providers ([#3313](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3313)) + +## 1.27.0 (April 26, 2019) + +NOTES: + +* This release includes a Terraform SDK upgrade with compatibility for Terraform v0.12. The provider remains backwards compatible with Terraform v0.11 and there should not be any significant behavioural changes. ([#2968](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2968)) + +## 1.26.0 (April 25, 2019) + +IMPROVEMENTS: + +* `azurerm_app_service` - support for Java 11 ([#3270](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3270)) +* `azurerm_app_service_slot` - support for Java 11 ([#3270](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3270)) +* `azurerm_container_group` - support for the `identity` block ([#3243](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3243)) + +BUG FIXES: + +* provider will work through proxies again ([#3301](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3301)) + +## 1.25.0 (April 17, 2019) + +FEATURES: + +* **New Data Source:** `azurerm_batch_certificate` ([#3097](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3097)) +* **New Data Source:** `azurerm_express_route_circuit` ([#3158](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3158)) +* **New Data Source:** `azurerm_firewall` ([#3235](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3235)) +* **New Data Source:** `azurerm_hdinsight_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Data Source:** `azurerm_stream_analytics_job` ([#3227](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3227)) +* **New Resource:** `azurerm_batch_certificate` ([#3097](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3097)) +* **New Resource:** `azurerm_data_factory` ([#3159](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3159)) +* **New Resource:** `azurerm_data_factory_dataset_mysql` ([#3267](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3267)) +* **New Resource:** `azurerm_data_factory_dataset_postgresql` ([#3267](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3267)) +* **New Resource:** `azurerm_data_factory_dataset_sql_server_table` ([#3236](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3236)) +* **New Resource:** `azurerm_data_factory_linked_service_sql_server` ([#3205](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3205)) +* **New Resource:** `azurerm_data_factory_linked_service_mysql` ([#3265](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3265)) +* **New Resource:** `azurerm_data_factory_linked_service_postgresql` ([#3266](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3266)) +* **New Resource:** `azurerm_data_factory_pipeline` ([#3244](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3244)) +* **New Resource:** `azurerm_hdinsight_kafka_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Resource:** `azurerm_hdinsight_kbase_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Resource:** `azurerm_hdinsight_hadoop_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Resource:** `azurerm_hdinsight_interactive_query_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Resource:** `azurerm_hdinsight_ml_services_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Resource:** `azurerm_hdinsight_rserver_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Resource:** `azurerm_hdinsight_spark_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Resource:** `azurerm_hdinsight_storm_cluster` ([#3196](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3196)) +* **New Resource:** `azurerm_iothub_shared_access_policy` ([#3009](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3009)) +* **New Resource:** `azurerm_public_ip_prefix` ([#3139](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3139)) +* **New Resource:** `azurerm_stream_analytics_job` ([#3227](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3227)) +* **New Resource:** `azurerm_stream_analytics_function_javascript_udf` ([#3249](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3249)) +* **New Resource:** `azurerm_stream_analytics_stream_input_blob` ([#3250](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3250)) +* **New Resource:** `azurerm_stream_analytics_stream_input_eventhub` ([#3250](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3250)) +* **New Resource:** `azurerm_stream_analytics_stream_input_iothub` ([#3250](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3250)) +* **New Resource:** `azurerm_stream_analytics_output_blob` ([#3250](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3250)) +* **New Resource:** `azurerm_stream_analytics_output_eventhub` ([#3250](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3250)) +* **New Resource:** `azurerm_stream_analytics_output_servicebus_queue` ([#3250](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3250)) + +IMPROVEMENTS: + + +* dependencies: updating `github.com/Azure/azure-sdk-for-go` to v26.7.0 ([#3126](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3126)) +* dependencies: updating `github.com/Azure/go-autorest` to v11.7.0 ([#3126](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3126)) +* dependencies: updating `github.com/hashicorp/terraform` to `44702fa6c163` ([#3181](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3181)) +* Data Source: `azurerm_batch_pool` - adding the `resource_file` block to the `start_task` block ([#3192](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3192)) +* Data Source: `azurerm_subnet` - exposing the `service_endpoint` field ([#3184](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3184)) +* `azurerm_batch_pool` - adding the `resource_file` block to the `start_task` block ([#3192](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3192)) +* `azurerm_container_group` - support for specifying `liveness_probe` and `readiness_probe` blocks ([#3118](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3118)) +* `azurerm_key_vault_access_policy` - support for setting `storage_permissions` ([#3153](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3153)) +* `azurerm_kubernetes_cluster` - `network_policy` now supports `azure` ([#3213](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3213)) +* `azurerm_iothub` - support for configuring `ip_filter_rule` ([#3173](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3173)) +* `azurerm_public_ip` - support for attaching a `azurerm_public_ip_prefix` ([#3139](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3139)) +* `azurerm_redis_cache` - support for setting `aof_backup_enabled`, `aof_storage_connection_string_0` and `aof_storage_connection_string_1` ([#3155](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3155)) +* `azurerm_storage_blob` - support for the `metadata` property ([#3206](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3206)) +* `azurerm_traffic_manager_profile` - support the `MultiValue` and `Weighted` values for the `traffic_routing_method` property ([#3207](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3207)) +* `azurerm_virtual_network_gateway` - support for the `VpnGw1AZ`, `VpnGw2AZ`, and `VpnGw3AZ` SKU's ([#3171](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3171)) + +BUG FIXES: + +* dependencies: downgrading the Security API to `2017-08-01-preview` to work around a breaking API change ([#3269](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3269)) +* `azurerm_app_service` - removing Computed from the `use_32_bit_worker_process` property in the `site_config` block ([#3219](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3219)) +* `azurerm_app_service_slot` - removing Computed from the `use_32_bit_worker_process` property in the `site_config` block ([#3219](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3219)) +* `azurerm_batch_account` - temporarily treating the Resource Group Name as case insensitive to work around an API bug ([#3260](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3260)) +* `azurerm_batch_pool` - temporarily treating the Resource Group Name as case insensitive to work around an API bug ([#3260](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3260)) +* `azurerm_app_service` - ensuring deleted App Services are detected correctly ([#3198](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3198)) +* `azurerm_function_app` - ensuring deleted Function Apps are detected correctly ([#3198](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3198)) +* `azurerm_virtual_machine` - adding validation for the `identity_ids` field ([#3183](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3183)) + +## 1.24.0 (April 03, 2019) + +UPGRADE NOTES: + +* `azurerm_kubernetes_cluster` - `ssh_key` is now limited to a single element to reflect what the API expects ([#3099](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3099)) + +FEATURES: + +* **New Data Source:** `azurerm_api_management_api` ([#3010](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3010)) +* **New Resource:** `azurerm_api_management_api` ([#3010](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3010)) +* **New Resource:** `azurerm_api_management_api_operation` ([#3121](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3121)) +* **New Resource:** `azurerm_api_management_api_version_set` ([#3073](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3073)) +* **New Resource:** `azurerm_api_management_authorization_server` ([#3123](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3123)) +* **New Resource:** `azurerm_api_management_certificate` ([#3141](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3141)) +* **New Resource:** `azurerm_api_management_logger` ([#2994](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2994)) +* **New Resource:** `azurerm_api_management_openid_connect_provider` ([#3143](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3143)) +* **New Resource:** `azurerm_api_management_product_api` ([#3066](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3066)) +* **New Resource:** `azurerm_api_management_subscription` ([#3103](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3103)) + +IMPROVEMENTS: + +* Data Source: `azurerm_app_service` - exporting the `cors` headers ([#2870](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2870)) +* Data Source: `azurerm_storage_account` - exposing the Hierarchical Namespace state ([#3032](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3032)) +* `azurerm_api_management` - support for `sign_in`, `sign_up` and `policy` blocks ([#3151](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3151)) +* `azurerm_app_service` - support for migrating between App Service Plans ([#3048](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3048)) +* `azurerm_app_service` - support for additional types for the `scm_type` field in the `site_config` block ([#3019](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3019)) +* `azurerm_app_service` - support for specifying `cors` headers ([#2870](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2870)) +* `azurerm_app_service_slot` - support for specifying `cors` headers ([#2870](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2870)) +* `azurerm_app_service_slot` - support for additional types for the `scm_type` field in the `site_config` block ([#3019](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3019)) +* `azurerm_application_gateway` - support for WAF configuration properties `request_body_check` and `max_request_body_size_kb` ([#3093](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3093)) +* `azurerm_application_gateway` - support for the `hostname` property ([#2990](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2990)) +* `azurerm_application_gateway` - support for redirect rules ([#2908](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2908)) +* `azurerm_application_gateway` - support for `zones` ([#3144](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3144)) +* `azurerm_batch_account` - now exports the `primary_access_key`, `secondary_access_key`, and `account_endpoint` properties ([#3071](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3071)) +* `azurerm_container_group` - support for attaching GPU's ([#3053](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3053)) +* `azurerm_eventhub` - support for the `skip_empty_archives` property ([#3074](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3074)) +* `azurerm_eventhub_namespace` - increase maximum `maximum_throughput_units` to 100 ([#3049](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3049)) +* `azurerm_function_app` - exporting `possible_outbound_ip_addresses` ([#3043](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3043)) +* `azurerm_iothub` - properties `batch_frequency_in_seconds`, `max_chunk_size_in_bytes`, `encoding`, `container_name`, `file_name_format` are now correctly diff'd depending on the type ([#2951](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2951)) +* `azurerm_image` - support for the `zone_resilient` property ([#3100](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3100)) +* `azurerm_kubernetes_cluster` - support for the `network_profile` property ([#2987](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2987)) +* `azurerm_key_vault` - support for the `storage_permissions` property ([#3081](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3081)) +* `azurerm_managed_disk` - support for managed disks up to 32TB ([#3062](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3062)) +* `azurerm_mssql_elasticpool` - support setting the `zone_redundant` property ([#3104](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3104)) +* `azurerm_redis_cache` - support for the `minimum_tls_version` property ([#3111](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3111)) +* `azurerm_storage_account` - support for configuring the Hierarchical Namespace state ([#3032](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3032)) +* `azurerm_storage_account` - exposing the DFS File Secondary and Web endpoints ([#3110](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3110)) +* `azurerm_virtual_machine` - support for managed disks up to 32TB ([#3062](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3062)) +* `azurerm_virtual_machine_scale_set` - support for managed disks up to 32TB ([#3062](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3062)) + +BUG FIXES: + +* `azurerm_application_gateway` - correctly populating backend addresses from both new and deprecated properties `fqdns`/`fqdn_list` ([#3085](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3085)) +* `azurerm_key_vault_certificate` - making `contents` and `password` within the `certificate` block sensitive ([#3064](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3064)) +* `monitor_metric_alert` - support for setting `aggregation` to `count` ([#3047](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3047)) +* `azurerm_virtual_network_gateway` - fixing a crash when `bgp_settings` had no elements ([#3038](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3038)) +* `azurerm_virtual_machine_scale_set` - support setting `zones` to an empty list ([#3142](https://github.com/terraform-providers/terraform-provider-azurerm/issues/3142)) ## 1.23.0 (March 08, 2019) @@ -322,7 +775,7 @@ IMPROVEMENTS: * dependencies: upgrading to v21.3.0 of `github.com/Azure/azure-sdk-for-go` ([#2163](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2163)) * refactoring: decoupling Resource Provider Registration to enable splitting out the authentication library ([#2197](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2197)) * sdk: upgrading to `2018-10-01` of the `containerinstance` sdk ([#2174](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2174)) -* `azurerm_automation_account` - exposing `dsc_server_endpoint`, `dsc_primary_access_key`, `dsc_secondary_access_key` properties [[#2166](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2166)] +* `azurerm_automation_account` - exposing `dsc_server_endpoint`, `dsc_primary_access_key`, `dsc_secondary_access_key` properties ([#2166](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2166)) * `azurerm_automation_account` - support for the `free` SKU ([#2166](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2166)) * `azurerm_client_config` - ensuring the `service_principal_application_id` and `service_principal_object_id` are always set ([#2120](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2120)) * `azurerm_cosmosdb_account` - support for the `enable_multiple_write_locations` property ([#2109](https://github.com/terraform-providers/terraform-provider-azurerm/issues/2109)) @@ -452,7 +905,7 @@ FEATURES: IMPROVEMENTS: * dependencies: upgrading to v20.1.0 of `github.com/Azure/azure-sdk-for-go` ([#1861](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1861)) -* dependencies: upgrading to v10.15.4 of `github.com/Azure/go-autorest` ([#1861](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1861)] [[#1909](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1909)) +* dependencies: upgrading to v10.15.4 of `github.com/Azure/go-autorest` ([#1861](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1861)) ([#1909](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1909)) * sdk: upgrading to version `2018-06-01` of the Compute API's ([#1861](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1861)) * `azurerm_automation_runbook` - support for specifying the content field ([#1696](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1696)) * `azurerm_app_service` - adding the `virtual_network_name` property ([#1896](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1896)) @@ -834,7 +1287,7 @@ IMPROVEMENTS: * `azurerm_cosmosdb_account` - `prefixes` can now be configured for locations ([#1055](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1055)) * `azurerm_function_app` - support for updating in-place ([#1125](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1125)) * `azurerm_key_vault` - adding cert permissions for `Purge` and `Recover` ([#1132](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1132)) -* `azurerm_key_vault` - polling to ensure the Key Vault is resolvable via DNS ([#1081](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1081)] [[#1164](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1164)) +* `azurerm_key_vault` - polling to ensure the Key Vault is resolvable via DNS ([#1081](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1081)) ([#1164](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1164)) * `azurerm_kubernetes_cluster` - only setting the Subnet ID when it's not an empty string ([#1158](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1158)) * `azurerm_kubernetes_cluster` - exposing the clusters credentials as `kube_config` ([#953](https://github.com/terraform-providers/terraform-provider-azurerm/issues/953)) * `azurerm_metric_alertrule` - filtering out tags prefixed with `$type` ([#1107](https://github.com/terraform-providers/terraform-provider-azurerm/issues/1107)) diff --git a/GNUmakefile b/GNUmakefile index 22b826ed1b59..f5d2c54034a3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -TEST?=$$(go list ./... |grep -v 'vendor') +TEST?=$$(go list ./... |grep -v 'vendor'|grep -v 'examples') WEBSITE_REPO=github.com/hashicorp/terraform-website PKG_NAME=azurerm @@ -9,37 +9,29 @@ GOFLAGS=-mod=vendor default: build +tools: + @echo "==> installing required tooling..." + @sh "$(CURDIR)/scripts/gogetcookie.sh" + GO111MODULE=off go get -u github.com/client9/misspell/cmd/misspell + GO111MODULE=off go get -u github.com/golangci/golangci-lint/cmd/golangci-lint + build: fmtcheck go install build-docker: mkdir -p bin - docker run --rm -v $$(pwd)/bin:/go/bin -v $$(pwd):/go/src/github.com/terraform-providers/terraform-provider-azurerm -w /go/src/github.com/terraform-providers/terraform-provider-azurerm -e GOOS golang:1.11 make build - -test-docker: - docker run --rm -v $$(pwd):/go/src/github.com/terraform-providers/terraform-provider-azurerm -w /go/src/github.com/terraform-providers/terraform-provider-azurerm golang:1.11 make test - -test: fmtcheck - go test -i $(TEST) || exit 1 - echo $(TEST) | \ - xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 - -testacc: fmtcheck - TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 180m -ldflags="-X=github.com/terraform-providers/terraform-provider-azurerm/version.ProviderVersion=acc" - -debugacc: fmtcheck - TF_ACC=1 dlv test $(TEST) --headless --listen=:2345 --api-version=2 -- -test.v $(TESTARGS) + docker run --rm -v $$(pwd)/bin:/go/bin -v $$(pwd):/go/src/github.com/terraform-providers/terraform-provider-azurerm -w /go/src/github.com/terraform-providers/terraform-provider-azurerm -e GOOS golang:1.12 make build fmt: @echo "==> Fixing source code with gofmt..." # This logic should match the search logic in scripts/gofmtcheck.sh - gofmt -s -w `find . -name '*.go' | grep -v vendor` + find . -name '*.go' | grep -v vendor | xargs gofmt -s -w # Currently required by tf-deploy compile fmtcheck: @sh "$(CURDIR)/scripts/gofmtcheck.sh" -goimport: +goimports: @echo "==> Fixing imports code with goimports..." goimports -w $(PKG_NAME)/ @@ -47,11 +39,13 @@ lint: @echo "==> Checking source code against linters..." golangci-lint run ./... -tools: - @echo "==> installing required tooling..." - @sh "$(CURDIR)/scripts/gogetcookie.sh" - GO111MODULE=off go get -u github.com/client9/misspell/cmd/misspell - GO111MODULE=off go get -u github.com/golangci/golangci-lint/cmd/golangci-lint +test-docker: + docker run --rm -v $$(pwd):/go/src/github.com/terraform-providers/terraform-provider-azurerm -w /go/src/github.com/terraform-providers/terraform-provider-azurerm golang:1.12 make test + +test: fmtcheck + go test -i $(TEST) || exit 1 + echo $(TEST) | \ + xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 test-compile: @if [ "$(TEST)" = "./..." ]; then \ @@ -61,6 +55,12 @@ test-compile: fi go test -c $(TEST) $(TESTARGS) +testacc: fmtcheck + TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 180m -ldflags="-X=github.com/terraform-providers/terraform-provider-azurerm/version.ProviderVersion=acc" + +debugacc: fmtcheck + TF_ACC=1 dlv test $(TEST) --headless --listen=:2345 --api-version=2 -- -test.v $(TESTARGS) + website: ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO))) echo "$(WEBSITE_REPO) not found in your GOPATH (necessary for layouts and assets), get-ting..." @@ -68,6 +68,10 @@ ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO))) endif @$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME) +website-lint: + @echo "==> Checking website against linters..." + @misspell -error -source=text -i hdinsight website/ + website-test: ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO))) echo "$(WEBSITE_REPO) not found in your GOPATH (necessary for layouts and assets), get-ting..." diff --git a/README.md b/README.md index 5019d020a501..8a1d0b11a8c1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ General Requirements ------------ - [Terraform](https://www.terraform.io/downloads.html) 0.10.x -- [Go](https://golang.org/doc/install) 1.11.x (to build the provider plugin) +- [Go](https://golang.org/doc/install) 1.12.x (to build the provider plugin) Windows Specific Requirements ----------------------------- @@ -74,7 +74,7 @@ Further [usage documentation is available on the Terraform website](https://www. Developing the Provider --------------------------- -If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (version 1.11+ is *required*). You'll also need to correctly setup a [GOPATH](http://golang.org/doc/code.html#GOPATH), as well as adding `$GOPATH/bin` to your `$PATH`. +If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (version 1.12+ is **required**). You'll also need to correctly setup a [GOPATH](http://golang.org/doc/code.html#GOPATH), as well as adding `$GOPATH/bin` to your `$PATH`. To compile the provider, run `make build`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory. @@ -106,6 +106,7 @@ The following Environment Variables must be set in your shell prior to running a - `ARM_ENVIRONMENT` - `ARM_TEST_LOCATION` - `ARM_TEST_LOCATION_ALT` +- `ARM_TEST_LOCATION_ALT2` **Note:** Acceptance tests create real resources in Azure which often cost money to run. diff --git a/azurerm/automation_variable.go b/azurerm/automation_variable.go new file mode 100644 index 000000000000..b53a77559de2 --- /dev/null +++ b/azurerm/automation_variable.go @@ -0,0 +1,301 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + "strconv" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func parseAzureAutomationVariableValue(resource string, input *string) (interface{}, error) { + if input == nil { + if resource != "azurerm_automation_variable_null" { + return nil, fmt.Errorf("Expected value \"nil\" to be %q, actual type is \"azurerm_automation_variable_null\"", resource) + } + return nil, nil + } + + var value interface{} + var err error + actualResource := "Unknown" + datePattern := regexp.MustCompile(`"\\/Date\((-?[0-9]+)\)\\/"`) + matches := datePattern.FindStringSubmatch(*input) + + if len(matches) == 2 && matches[0] == *input { + if ticks, err := strconv.ParseInt(matches[1], 10, 64); err == nil { + value = time.Unix(ticks/1000, ticks%1000*1000000).In(time.UTC) + actualResource = "azurerm_automation_variable_datetime" + } + } else if value, err = strconv.Unquote(*input); err == nil { + actualResource = "azurerm_automation_variable_string" + } else if value, err = strconv.ParseBool(*input); err == nil { + actualResource = "azurerm_automation_variable_bool" + } else if value, err = strconv.ParseInt(*input, 10, 32); err == nil { + value = int32(value.(int64)) + actualResource = "azurerm_automation_variable_int" + } + + if actualResource != resource { + return nil, fmt.Errorf("Expected value %q to be %q, actual type is %q", *input, resource, actualResource) + } + return value, nil +} + +func resourceAutomationVariableCommonSchema(attType schema.ValueType, validateFunc schema.SchemaValidateFunc) map[string]*schema.Schema { + return map[string]*schema.Schema{ + "resource_group_name": azure.SchemaResourceGroupName(), + + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "automation_account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "encrypted": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "value": { + Type: attType, + Optional: true, + ValidateFunc: validateFunc, + }, + } +} + +func datasourceAutomationVariableCommonSchema(attType schema.ValueType) map[string]*schema.Schema { + return map[string]*schema.Schema{ + "resource_group_name": azure.SchemaResourceGroupName(), + + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "automation_account_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "description": { + Type: schema.TypeString, + Computed: true, + }, + + "encrypted": { + Type: schema.TypeBool, + Computed: true, + }, + + "value": { + Type: attType, + Computed: true, + }, + } +} + +func resourceAutomationVariableCreateUpdate(d *schema.ResourceData, meta interface{}, varType string) error { + client := meta.(*ArmClient).automation.VariableClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + accountName := d.Get("automation_account_name").(string) + varTypeLower := strings.ToLower(varType) + + if features.ShouldResourcesBeImported() { + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Error checking for present of existing Automation %s Variable %q (Automation Account Name %q / Resource Group %q): %+v", varType, name, accountName, resourceGroup, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return tf.ImportAsExistsError(fmt.Sprintf("azurerm_automation_variable_%s", varTypeLower), *resp.ID) + } + } + + description := d.Get("description").(string) + encrypted := d.Get("encrypted").(bool) + value := "" + + if varTypeLower == "datetime" { + vTime, parseErr := time.Parse(time.RFC3339, d.Get("value").(string)) + if parseErr != nil { + return fmt.Errorf("Error invalid time format: %+v", parseErr) + } + value = fmt.Sprintf("\"\\/Date(%d)\\/\"", vTime.UnixNano()/1000000) + } else if varTypeLower == "bool" { + value = strconv.FormatBool(d.Get("value").(bool)) + } else if varTypeLower == "int" { + value = strconv.Itoa(d.Get("value").(int)) + } else if varTypeLower == "string" { + value = strconv.Quote(d.Get("value").(string)) + } + + parameters := automation.VariableCreateOrUpdateParameters{ + Name: utils.String(name), + VariableCreateOrUpdateProperties: &automation.VariableCreateOrUpdateProperties{ + Description: utils.String(description), + IsEncrypted: utils.Bool(encrypted), + }, + } + + if varTypeLower != "null" { + parameters.VariableCreateOrUpdateProperties.Value = utils.String(value) + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, accountName, name, parameters); err != nil { + return fmt.Errorf("Error creating Automation %s Variable %q (Automation Account Name %q / Resource Group %q): %+v", varType, name, accountName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + return fmt.Errorf("Error retrieving Automation %s Variable %q (Automation Account Name %q / Resource Group %q): %+v", varType, name, accountName, resourceGroup, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read Automation %s Variable %q (Automation Account Name %q / Resource Group %q) ID", varType, name, accountName, resourceGroup) + } + d.SetId(*resp.ID) + + return resourceAutomationVariableRead(d, meta, varType) +} + +func resourceAutomationVariableRead(d *schema.ResourceData, meta interface{}, varType string) error { + client := meta.(*ArmClient).automation.VariableClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + accountName := id.Path["automationAccounts"] + name := id.Path["variables"] + varTypeLower := strings.ToLower(varType) + + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Automation %s Variable %q does not exist - removing from state", varType, d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading Automation %s Variable %q (Automation Account Name %q / Resource Group %q): %+v", varType, name, accountName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("automation_account_name", accountName) + if properties := resp.VariableProperties; properties != nil { + d.Set("description", properties.Description) + d.Set("encrypted", properties.IsEncrypted) + if !d.Get("encrypted").(bool) { + value, err := parseAzureAutomationVariableValue(fmt.Sprintf("azurerm_automation_variable_%s", varTypeLower), properties.Value) + if err != nil { + return err + } + + if varTypeLower == "datetime" { + d.Set("value", value.(time.Time).Format("2006-01-02T15:04:05.999Z")) + } else if varTypeLower != "null" { + d.Set("value", value) + } + } + } + + return nil +} + +func datasourceAutomationVariableRead(d *schema.ResourceData, meta interface{}, varType string) error { + client := meta.(*ArmClient).automation.VariableClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + accountName := d.Get("automation_account_name").(string) + name := d.Get("name").(string) + varTypeLower := strings.ToLower(varType) + + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Automation %s Variable %q does not exist - removing from state", varType, d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading Automation %s Variable %q (Automation Account Name %q / Resource Group %q): %+v", varType, name, accountName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("automation_account_name", accountName) + if properties := resp.VariableProperties; properties != nil { + d.Set("description", properties.Description) + d.Set("encrypted", properties.IsEncrypted) + if !d.Get("encrypted").(bool) { + value, err := parseAzureAutomationVariableValue(fmt.Sprintf("azurerm_automation_variable_%s", varTypeLower), properties.Value) + if err != nil { + return err + } + + if varTypeLower == "datetime" { + d.Set("value", value.(time.Time).Format("2006-01-02T15:04:05.999Z")) + } else if varTypeLower != "null" { + d.Set("value", value) + } + } + } + + return nil +} + +func resourceAutomationVariableDelete(d *schema.ResourceData, meta interface{}, varType string) error { + client := meta.(*ArmClient).automation.VariableClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + accountName := id.Path["automationAccounts"] + name := id.Path["variables"] + + if _, err := client.Delete(ctx, resourceGroup, accountName, name); err != nil { + return fmt.Errorf("Error deleting Automation %s Variable %q (Automation Account Name %q / Resource Group %q): %+v", varType, name, accountName, resourceGroup, err) + } + + return nil +} diff --git a/azurerm/automation_variable_test.go b/azurerm/automation_variable_test.go new file mode 100644 index 000000000000..1b286b54df1c --- /dev/null +++ b/azurerm/automation_variable_test.go @@ -0,0 +1,132 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + "time" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestParseAzureRmAutomationVariableValue(t *testing.T) { + type ExpectFunc func(interface{}) bool + cases := []struct { + Name string + Resource string + IsNil bool + Value string + HasError bool + ExpectValue interface{} + Expect ExpectFunc + }{ + { + Name: "string variable", + Resource: "azurerm_automation_variable_string", + Value: "\"Test String\"", + HasError: false, + ExpectValue: "Test String", + Expect: func(v interface{}) bool { return v.(string) == "Test String" }, + }, + { + Name: "integer variable", + Resource: "azurerm_automation_variable_int", + Value: "135", + HasError: false, + ExpectValue: 135, + Expect: func(v interface{}) bool { return v.(int32) == 135 }, + }, + { + Name: "boolean variable", + Resource: "azurerm_automation_variable_bool", + Value: "true", + HasError: false, + ExpectValue: true, + Expect: func(v interface{}) bool { return v.(bool) == true }, + }, + { + Name: "datetime variable", + Resource: "azurerm_automation_variable_datetime", + Value: "\"\\/Date(1556142054074)\\/\"", + HasError: false, + ExpectValue: time.Date(2019, time.April, 24, 21, 40, 54, 74000000, time.UTC), + Expect: func(v interface{}) bool { + return v.(time.Time) == time.Date(2019, time.April, 24, 21, 40, 54, 74000000, time.UTC) + }, + }, + } + + for _, tc := range cases { + t.Run(tc.Name, func(t *testing.T) { + value := &tc.Value + if tc.IsNil { + value = nil + } + actual, err := parseAzureAutomationVariableValue(tc.Resource, value) + if tc.HasError && err == nil { + t.Fatalf("Expect parseAzureAutomationVariableValue to return error for resource %q and value %s", tc.Resource, tc.Value) + } + if !tc.HasError { + if err != nil { + t.Fatalf("Expect parseAzureAutomationVariableValue to return no error for resource %q and value %s, err: %+v", tc.Resource, tc.Value, err) + } else if !tc.Expect(actual) { + t.Fatalf("Expect parseAzureAutomationVariableValue to return %v instead of %v for resource %q and value %s", tc.ExpectValue, actual, tc.Resource, tc.Value) + } + } + }) + } +} + +func testCheckAzureRMAutomationVariableExists(resourceName string, varType string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Automation %s Variable not found: %s", varType, resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + accountName := rs.Primary.Attributes["automation_account_name"] + + client := testAccProvider.Meta().(*ArmClient).automation.VariableClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + if resp, err := client.Get(ctx, resourceGroup, accountName, name); err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Automation %s Variable %q (Automation Account Name %q / Resource Group %q) does not exist", varType, name, accountName, resourceGroup) + } + return fmt.Errorf("Bad: Get on automationVariableClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMAutomationVariableDestroy(s *terraform.State, varType string) error { + client := testAccProvider.Meta().(*ArmClient).automation.VariableClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resourceName := fmt.Sprintf("azurerm_automation_variable_%s", strings.ToLower(varType)) + + for _, rs := range s.RootModule().Resources { + if rs.Type != resourceName { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + accountName := rs.Primary.Attributes["automation_account_name"] + + if resp, err := client.Get(ctx, resourceGroup, accountName, name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Get on automationVariableClient: %+v", err) + } + } + + return nil + } + + return nil +} diff --git a/azurerm/common_hdinsight.go b/azurerm/common_hdinsight.go new file mode 100644 index 000000000000..149d1991b34a --- /dev/null +++ b/azurerm/common_hdinsight.go @@ -0,0 +1,178 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func hdinsightClusterUpdate(clusterKind string, readFunc schema.ReadFunc) schema.UpdateFunc { + return func(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + if d.HasChange("tags") { + t := d.Get("tags").(map[string]interface{}) + params := hdinsight.ClusterPatchParameters{ + Tags: tags.Expand(t), + } + if _, err := client.Update(ctx, resourceGroup, name, params); err != nil { + return fmt.Errorf("Error updating Tags for HDInsight %q Cluster %q (Resource Group %q): %+v", clusterKind, name, resourceGroup, err) + } + } + + if d.HasChange("roles") { + log.Printf("[DEBUG] Resizing the HDInsight %q Cluster", clusterKind) + rolesRaw := d.Get("roles").([]interface{}) + roles := rolesRaw[0].(map[string]interface{}) + headNodes := roles["worker_node"].([]interface{}) + headNode := headNodes[0].(map[string]interface{}) + targetInstanceCount := headNode["target_instance_count"].(int) + params := hdinsight.ClusterResizeParameters{ + TargetInstanceCount: utils.Int32(int32(targetInstanceCount)), + } + + future, err := client.Resize(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error resizing the HDInsight %q Cluster %q (Resource Group %q): %+v", clusterKind, name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for the HDInsight %q Cluster %q (Resource Group %q) to finish resizing: %+v", clusterKind, name, resourceGroup, err) + } + } + + return readFunc(d, meta) + } +} + +func hdinsightClusterDelete(clusterKind string) schema.DeleteFunc { + return func(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + future, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error deleting HDInsight %q Cluster %q (Resource Group %q): %+v", clusterKind, name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of HDInsight %q Cluster %q (Resource Group %q): %+v", clusterKind, name, resourceGroup, err) + } + + return nil + } +} + +type hdInsightRoleDefinition struct { + HeadNodeDef azure.HDInsightNodeDefinition + WorkerNodeDef azure.HDInsightNodeDefinition + ZookeeperNodeDef azure.HDInsightNodeDefinition + EdgeNodeDef *azure.HDInsightNodeDefinition +} + +func expandHDInsightRoles(input []interface{}, definition hdInsightRoleDefinition) (*[]hdinsight.Role, error) { + v := input[0].(map[string]interface{}) + + headNodeRaw := v["head_node"].([]interface{}) + headNode, err := azure.ExpandHDInsightNodeDefinition("headnode", headNodeRaw, definition.HeadNodeDef) + if err != nil { + return nil, fmt.Errorf("Error expanding `head_node`: %+v", err) + } + + workerNodeRaw := v["worker_node"].([]interface{}) + workerNode, err := azure.ExpandHDInsightNodeDefinition("workernode", workerNodeRaw, definition.WorkerNodeDef) + if err != nil { + return nil, fmt.Errorf("Error expanding `worker_node`: %+v", err) + } + + zookeeperNodeRaw := v["zookeeper_node"].([]interface{}) + zookeeperNode, err := azure.ExpandHDInsightNodeDefinition("zookeepernode", zookeeperNodeRaw, definition.ZookeeperNodeDef) + if err != nil { + return nil, fmt.Errorf("Error expanding `zookeeper_node`: %+v", err) + } + + roles := []hdinsight.Role{ + *headNode, + *workerNode, + *zookeeperNode, + } + + if definition.EdgeNodeDef != nil { + edgeNodeRaw := v["edge_node"].([]interface{}) + edgeNode, err := azure.ExpandHDInsightNodeDefinition("edgenode", edgeNodeRaw, *definition.EdgeNodeDef) + if err != nil { + return nil, fmt.Errorf("Error expanding `edge_node`: %+v", err) + } + roles = append(roles, *edgeNode) + } + + return &roles, nil +} + +func flattenHDInsightRoles(d *schema.ResourceData, input *hdinsight.ComputeProfile, definition hdInsightRoleDefinition) []interface{} { + if input == nil || input.Roles == nil { + return []interface{}{} + } + + var existingEdgeNodes, existingHeadNodes, existingWorkerNodes, existingZookeeperNodes []interface{} + + existingVs := d.Get("roles").([]interface{}) + if len(existingVs) > 0 { + existingV := existingVs[0].(map[string]interface{}) + + if definition.EdgeNodeDef != nil { + existingEdgeNodes = existingV["edge_node"].([]interface{}) + } + + existingHeadNodes = existingV["head_node"].([]interface{}) + existingWorkerNodes = existingV["worker_node"].([]interface{}) + existingZookeeperNodes = existingV["zookeeper_node"].([]interface{}) + } + + headNode := azure.FindHDInsightRole(input.Roles, "headnode") + headNodes := azure.FlattenHDInsightNodeDefinition(headNode, existingHeadNodes, definition.HeadNodeDef) + + workerNode := azure.FindHDInsightRole(input.Roles, "workernode") + workerNodes := azure.FlattenHDInsightNodeDefinition(workerNode, existingWorkerNodes, definition.WorkerNodeDef) + + zookeeperNode := azure.FindHDInsightRole(input.Roles, "zookeepernode") + zookeeperNodes := azure.FlattenHDInsightNodeDefinition(zookeeperNode, existingZookeeperNodes, definition.ZookeeperNodeDef) + + result := map[string]interface{}{ + "head_node": headNodes, + "worker_node": workerNodes, + "zookeeper_node": zookeeperNodes, + } + + if definition.EdgeNodeDef != nil { + edgeNode := azure.FindHDInsightRole(input.Roles, "edgenode") + edgeNodes := azure.FlattenHDInsightNodeDefinition(edgeNode, existingEdgeNodes, *definition.EdgeNodeDef) + result["edge_node"] = edgeNodes + } + + return []interface{}{ + result, + } +} diff --git a/azurerm/common_hdinsight_test.go b/azurerm/common_hdinsight_test.go new file mode 100644 index 000000000000..ea631b009ff9 --- /dev/null +++ b/azurerm/common_hdinsight_test.go @@ -0,0 +1,59 @@ +package azurerm + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func testCheckAzureRMHDInsightClusterDestroy(terraformResourceName string) func(s *terraform.State) error { + return func(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != terraformResourceName { + continue + } + + client := testAccProvider.Meta().(*ArmClient).hdinsight.ClustersClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + resp, err := client.Get(ctx, resourceGroup, name) + + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + } + + return nil + } +} + +func testCheckAzureRMHDInsightClusterExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + clusterName := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + client := testAccProvider.Meta().(*ArmClient).hdinsight.ClustersClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, clusterName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: HDInsight Cluster %q (Resource Group: %q) does not exist", clusterName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on hdinsightClustersClient: %+v", err) + } + + return nil + } +} diff --git a/azurerm/common_schema.go b/azurerm/common_schema.go deleted file mode 100644 index b219efd48367..000000000000 --- a/azurerm/common_schema.go +++ /dev/null @@ -1,66 +0,0 @@ -package azurerm - -// NOTE: methods in this file will be moved to `./helpers/azurerm` in time -// new methods should be added to this directory instead. -// This file exists to be able to consolidate files in the root - -import ( - "github.com/hashicorp/terraform/helper/schema" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" -) - -func locationSchema() *schema.Schema { - return azure.SchemaLocation() -} - -func locationSchemaOptional() *schema.Schema { - return azure.SchemaLocationOptional() -} - -func locationForDataSourceSchema() *schema.Schema { - return azure.SchemaLocationForDataSource() -} - -func deprecatedLocationSchema() *schema.Schema { - return azure.SchemaLocationDeprecated() -} - -func azureRMNormalizeLocation(location interface{}) string { - return azure.NormalizeLocation(location) -} - -func azureRMSuppressLocationDiff(k, old, new string, d *schema.ResourceData) bool { - return azure.SuppressLocationDiff(k, old, new, d) -} - -func resourceGroupNameSchema() *schema.Schema { - return azure.SchemaResourceGroupName() -} - -func resourceGroupNameDiffSuppressSchema() *schema.Schema { - return azure.SchemaResourceGroupNameDiffSuppress() -} - -func resourceGroupNameForDataSourceSchema() *schema.Schema { - return azure.SchemaResourceGroupNameForDataSource() -} - -func zonesSchema() *schema.Schema { - return azure.SchemaZones() -} - -func singleZonesSchema() *schema.Schema { - return azure.SchemaSingleZone() -} - -func zonesSchemaComputed() *schema.Schema { - return azure.SchemaZonesComputed() -} - -func expandZones(v []interface{}) *[]string { - return azure.ExpandZones(v) -} - -func azureRMHashLocation(location interface{}) int { - return azure.HashAzureLocation(location) -} diff --git a/azurerm/config.go b/azurerm/config.go index 139fdcb53533..bbb27240c424 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -3,80 +3,67 @@ package azurerm import ( "context" "fmt" - "log" - "os" - "strings" - "sync" "time" - resourcesprofile "github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources" - "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" - appinsights "github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights" - "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" - "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2017-09-01/batch" - "github.com/Azure/azure-sdk-for-go/services/cdn/mgmt/2017-10-12/cdn" - "github.com/Azure/azure-sdk-for-go/services/cognitiveservices/mgmt/2017-04-18/cognitiveservices" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" - "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" - "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry" - "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2018-03-31/containerservice" - "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" - "github.com/Azure/azure-sdk-for-go/services/databricks/mgmt/2018-04-01/databricks" - analyticsAccount "github.com/Azure/azure-sdk-for-go/services/datalake/analytics/mgmt/2016-11-01/account" - "github.com/Azure/azure-sdk-for-go/services/datalake/store/2016-11-01/filesystem" - storeAccount "github.com/Azure/azure-sdk-for-go/services/datalake/store/mgmt/2016-11-01/account" - "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" - "github.com/Azure/azure-sdk-for-go/services/eventhub/mgmt/2017-04-01/eventhub" - "github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac" - keyVault "github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault" - "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2018-02-14/keyvault" - "github.com/Azure/azure-sdk-for-go/services/logic/mgmt/2016-06-01/logic" - "github.com/Azure/azure-sdk-for-go/services/mediaservices/mgmt/2018-07-01/media" - "github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" - "github.com/Azure/azure-sdk-for-go/services/notificationhubs/mgmt/2017-04-01/notificationhubs" - "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql" - "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-01-01-preview/authorization" - "github.com/Azure/azure-sdk-for-go/services/preview/devspaces/mgmt/2018-06-01-preview/devspaces" - "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" - "github.com/Azure/azure-sdk-for-go/services/preview/eventgrid/mgmt/2018-09-15-preview/eventgrid" - "github.com/Azure/azure-sdk-for-go/services/preview/iothub/mgmt/2018-12-01-preview/devices" - "github.com/Azure/azure-sdk-for-go/services/preview/mariadb/mgmt/2018-06-01-preview/mariadb" - "github.com/Azure/azure-sdk-for-go/services/preview/monitor/mgmt/2018-03-01/insights" - "github.com/Azure/azure-sdk-for-go/services/preview/msi/mgmt/2015-08-31-preview/msi" - "github.com/Azure/azure-sdk-for-go/services/preview/operationalinsights/mgmt/2015-11-01-preview/operationalinsights" - "github.com/Azure/azure-sdk-for-go/services/preview/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement" - "github.com/Azure/azure-sdk-for-go/services/preview/resources/mgmt/2018-03-01-preview/managementgroups" - "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" - "github.com/Azure/azure-sdk-for-go/services/preview/signalr/mgmt/2018-03-01-preview/signalr" - "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" - MsSql "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2017-10-01-preview/sql" - "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2016-06-01/recoveryservices" - "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2017-07-01/backup" - "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" - "github.com/Azure/azure-sdk-for-go/services/relay/mgmt/2017-04-01/relay" - "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions" - "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-09-01/locks" - "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/policy" - "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources" - "github.com/Azure/azure-sdk-for-go/services/scheduler/mgmt/2016-03-01/scheduler" - "github.com/Azure/azure-sdk-for-go/services/search/mgmt/2015-08-19/search" - "github.com/Azure/azure-sdk-for-go/services/servicebus/mgmt/2017-04-01/servicebus" - "github.com/Azure/azure-sdk-for-go/services/servicefabric/mgmt/2018-02-01/servicefabric" - "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-02-01/storage" - "github.com/Azure/azure-sdk-for-go/services/trafficmanager/mgmt/2017-05-01/trafficmanager" - "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" - - mainStorage "github.com/Azure/azure-sdk-for-go/storage" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/adal" - az "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/azure" "github.com/hashicorp/go-azure-helpers/authentication" - "github.com/hashicorp/go-uuid" - "github.com/hashicorp/terraform/httpclient" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" - "github.com/terraform-providers/terraform-provider-azurerm/version" + "github.com/hashicorp/go-azure-helpers/sender" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/analysisservices" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/apimanagement" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/applicationinsights" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/authorization" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/automation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/batch" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cdn" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cognitive" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/containers" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cosmos" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/databricks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/datafactory" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/datalake" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/devspace" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/devtestlabs" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/dns" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/eventgrid" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/eventhub" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/graph" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/hdinsight" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/iothub" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/kusto" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/loganalytics" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/logic" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/managementgroup" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/maps" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mariadb" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/media" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/monitor" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/msi" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mssql" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/network" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/notificationhub" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/policy" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/postgres" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/privatedns" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/recoveryservices" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/redis" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/relay" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/scheduler" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/search" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/securitycenter" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/servicebus" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/servicefabric" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/signalr" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/sql" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/streamanalytics" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/subscription" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/trafficmanager" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/web" ) // ArmClient contains the handles to all the specific Azure Resource Manager @@ -87,316 +74,72 @@ type ArmClient struct { subscriptionId string partnerId string usingServicePrincipal bool - environment az.Environment + environment azure.Environment skipProviderRegistration bool StopContext context.Context - cosmosDBClient documentdb.DatabaseAccountsClient - - automationAccountClient automation.AccountClient - automationAgentRegistrationInfoClient automation.AgentRegistrationInformationClient - automationCredentialClient automation.CredentialClient - automationDscConfigurationClient automation.DscConfigurationClient - automationDscNodeConfigurationClient automation.DscNodeConfigurationClient - automationModuleClient automation.ModuleClient - automationRunbookClient automation.RunbookClient - automationRunbookDraftClient automation.RunbookDraftClient - automationScheduleClient automation.ScheduleClient - - dnsClient dns.RecordSetsClient - zonesClient dns.ZonesClient - - containerRegistryClient containerregistry.RegistriesClient - containerRegistryReplicationsClient containerregistry.ReplicationsClient - containerServicesClient containerservice.ContainerServicesClient - kubernetesClustersClient containerservice.ManagedClustersClient - containerGroupsClient containerinstance.ContainerGroupsClient - - eventGridDomainsClient eventgrid.DomainsClient - eventGridEventSubscriptionsClient eventgrid.EventSubscriptionsClient - eventGridTopicsClient eventgrid.TopicsClient - eventHubClient eventhub.EventHubsClient - eventHubConsumerGroupClient eventhub.ConsumerGroupsClient - eventHubNamespacesClient eventhub.NamespacesClient - - solutionsClient operationsmanagement.SolutionsClient - - redisClient redis.Client - redisFirewallClient redis.FirewallRulesClient - redisPatchSchedulesClient redis.PatchSchedulesClient - - // API Management - apiManagementApiClient apimanagement.APIClient - apiManagementGroupClient apimanagement.GroupClient - apiManagementGroupUsersClient apimanagement.GroupUserClient - apiManagementProductsClient apimanagement.ProductClient - apiManagementProductApisClient apimanagement.ProductAPIClient - apiManagementProductGroupsClient apimanagement.ProductGroupClient - apiManagementPropertyClient apimanagement.PropertyClient - apiManagementServiceClient apimanagement.ServiceClient - apiManagementUsersClient apimanagement.UserClient - - // Application Insights - appInsightsClient appinsights.ComponentsClient - appInsightsAPIKeyClient appinsights.APIKeysClient - - // Authentication - roleAssignmentsClient authorization.RoleAssignmentsClient - roleDefinitionsClient authorization.RoleDefinitionsClient - applicationsClient graphrbac.ApplicationsClient - servicePrincipalsClient graphrbac.ServicePrincipalsClient - - // Autoscale Settings - autoscaleSettingsClient insights.AutoscaleSettingsClient - - // Batch - batchAccountClient batch.AccountClient - batchPoolClient batch.PoolClient - - // CDN - cdnCustomDomainsClient cdn.CustomDomainsClient - cdnEndpointsClient cdn.EndpointsClient - cdnProfilesClient cdn.ProfilesClient - - // Cognitive Services - cognitiveAccountsClient cognitiveservices.AccountsClient - - // Compute - availSetClient compute.AvailabilitySetsClient - diskClient compute.DisksClient - imageClient compute.ImagesClient - galleriesClient compute.GalleriesClient - galleryImagesClient compute.GalleryImagesClient - galleryImageVersionsClient compute.GalleryImageVersionsClient - snapshotsClient compute.SnapshotsClient - usageOpsClient compute.UsageClient - vmExtensionImageClient compute.VirtualMachineExtensionImagesClient - vmExtensionClient compute.VirtualMachineExtensionsClient - vmScaleSetClient compute.VirtualMachineScaleSetsClient - vmImageClient compute.VirtualMachineImagesClient - vmClient compute.VirtualMachinesClient - - // Devices - iothubResourceClient devices.IotHubResourceClient - - // DevTestLabs - devTestLabsClient dtl.LabsClient - devTestPoliciesClient dtl.PoliciesClient - devTestVirtualMachinesClient dtl.VirtualMachinesClient - devTestVirtualNetworksClient dtl.VirtualNetworksClient - - // DevSpace - devSpaceControllerClient devspaces.ControllersClient - - // Databases - mariadbDatabasesClient mariadb.DatabasesClient - mariadbServersClient mariadb.ServersClient - mysqlConfigurationsClient mysql.ConfigurationsClient - mysqlDatabasesClient mysql.DatabasesClient - mysqlFirewallRulesClient mysql.FirewallRulesClient - mysqlServersClient mysql.ServersClient - mysqlVirtualNetworkRulesClient mysql.VirtualNetworkRulesClient - postgresqlConfigurationsClient postgresql.ConfigurationsClient - postgresqlDatabasesClient postgresql.DatabasesClient - postgresqlFirewallRulesClient postgresql.FirewallRulesClient - postgresqlServersClient postgresql.ServersClient - postgresqlVirtualNetworkRulesClient postgresql.VirtualNetworkRulesClient - sqlDatabasesClient sql.DatabasesClient - sqlDatabaseThreatDetectionPoliciesClient sql.DatabaseThreatDetectionPoliciesClient - sqlElasticPoolsClient sql.ElasticPoolsClient - // Client for the new 2017-10-01-preview SQL API which implements vCore, DTU, and Azure data standards - msSqlElasticPoolsClient MsSql.ElasticPoolsClient - sqlFirewallRulesClient sql.FirewallRulesClient - sqlServersClient sql.ServersClient - sqlServerAzureADAdministratorsClient sql.ServerAzureADAdministratorsClient - sqlVirtualNetworkRulesClient sql.VirtualNetworkRulesClient - - // Data Lake Store - dataLakeStoreAccountClient storeAccount.AccountsClient - dataLakeStoreFirewallRulesClient storeAccount.FirewallRulesClient - dataLakeStoreFilesClient filesystem.Client - - // Data Lake Analytics - dataLakeAnalyticsAccountClient analyticsAccount.AccountsClient - dataLakeAnalyticsFirewallRulesClient analyticsAccount.FirewallRulesClient - - // Databricks - databricksWorkspacesClient databricks.WorkspacesClient - - // KeyVault - keyVaultClient keyvault.VaultsClient - keyVaultManagementClient keyVault.BaseClient - - // Log Analytics - linkedServicesClient operationalinsights.LinkedServicesClient - workspacesClient operationalinsights.WorkspacesClient - - // Logic - logicWorkflowsClient logic.WorkflowsClient - - // Management Groups - managementGroupsClient managementgroups.Client - managementGroupsSubscriptionClient managementgroups.SubscriptionsClient - - // Media - mediaServicesClient media.MediaservicesClient - - // Monitor - monitorActionGroupsClient insights.ActionGroupsClient - monitorActivityLogAlertsClient insights.ActivityLogAlertsClient - monitorAlertRulesClient insights.AlertRulesClient - monitorDiagnosticSettingsClient insights.DiagnosticSettingsClient - monitorDiagnosticSettingsCategoryClient insights.DiagnosticSettingsCategoryClient - monitorLogProfilesClient insights.LogProfilesClient - monitorMetricAlertsClient insights.MetricAlertsClient - - // MSI - userAssignedIdentitiesClient msi.UserAssignedIdentitiesClient - - // Networking - applicationGatewayClient network.ApplicationGatewaysClient - applicationSecurityGroupsClient network.ApplicationSecurityGroupsClient - azureFirewallsClient network.AzureFirewallsClient - connectionMonitorsClient network.ConnectionMonitorsClient - ddosProtectionPlanClient network.DdosProtectionPlansClient - expressRouteAuthsClient network.ExpressRouteCircuitAuthorizationsClient - expressRouteCircuitClient network.ExpressRouteCircuitsClient - expressRoutePeeringsClient network.ExpressRouteCircuitPeeringsClient - ifaceClient network.InterfacesClient - loadBalancerClient network.LoadBalancersClient - localNetConnClient network.LocalNetworkGatewaysClient - packetCapturesClient network.PacketCapturesClient - publicIPClient network.PublicIPAddressesClient - routesClient network.RoutesClient - routeTablesClient network.RouteTablesClient - secGroupClient network.SecurityGroupsClient - secRuleClient network.SecurityRulesClient - subnetClient network.SubnetsClient - vnetGatewayConnectionsClient network.VirtualNetworkGatewayConnectionsClient - vnetGatewayClient network.VirtualNetworkGatewaysClient - vnetClient network.VirtualNetworksClient - vnetPeeringsClient network.VirtualNetworkPeeringsClient - watcherClient network.WatchersClient - - // Notification Hubs - notificationHubsClient notificationhubs.Client - notificationNamespacesClient notificationhubs.NamespacesClient - - // Recovery Services - recoveryServicesVaultsClient recoveryservices.VaultsClient - recoveryServicesProtectedItemsClient backup.ProtectedItemsGroupClient - recoveryServicesProtectionPoliciesClient backup.ProtectionPoliciesClient - - // Relay - relayNamespacesClient relay.NamespacesClient - - // Resources - managementLocksClient locks.ManagementLocksClient - deploymentsClient resources.DeploymentsClient - providersClient resourcesprofile.ProvidersClient - resourcesClient resources.Client - resourceGroupsClient resources.GroupsClient - subscriptionsClient subscriptions.Client - - // Scheduler - schedulerJobCollectionsClient scheduler.JobCollectionsClient //nolint: megacheck - - schedulerJobsClient scheduler.JobsClient //nolint: megacheck - - // Search - searchServicesClient search.ServicesClient - searchAdminKeysClient search.AdminKeysClient - - // Security Centre - securityCenterPricingClient security.PricingsClient - securityCenterContactsClient security.ContactsClient - securityCenterWorkspaceClient security.WorkspaceSettingsClient - - // ServiceBus - serviceBusQueuesClient servicebus.QueuesClient - serviceBusNamespacesClient servicebus.NamespacesClient - serviceBusTopicsClient servicebus.TopicsClient - serviceBusSubscriptionsClient servicebus.SubscriptionsClient - serviceBusSubscriptionRulesClient servicebus.RulesClient - - // Service Fabric - serviceFabricClustersClient servicefabric.ClustersClient - - // SignalR - signalRClient signalr.Client - - // Storage - storageServiceClient storage.AccountsClient - storageUsageClient storage.UsageClient - - // Traffic Manager - trafficManagerGeographialHierarchiesClient trafficmanager.GeographicHierarchiesClient - trafficManagerProfilesClient trafficmanager.ProfilesClient - trafficManagerEndpointsClient trafficmanager.EndpointsClient - - // Web - appServicePlansClient web.AppServicePlansClient - appServicesClient web.AppsClient - - // Policy - policyAssignmentsClient policy.AssignmentsClient - policyDefinitionsClient policy.DefinitionsClient - policySetDefinitionsClient policy.SetDefinitionsClient -} - -var ( - msClientRequestIDOnce sync.Once - msClientRequestID string -) - -// clientRequestID generates a UUID to pass through `x-ms-client-request-id` header. -func clientRequestID() string { - msClientRequestIDOnce.Do(func() { - var err error - msClientRequestID, err = uuid.GenerateUUID() - - if err != nil { - log.Printf("[WARN] Fail to generate uuid for msClientRequestID: %+v", err) - } - }) - - log.Printf("[DEBUG] AzureRM Client Request Id: %s", msClientRequestID) - return msClientRequestID -} - -func (c *ArmClient) configureClient(client *autorest.Client, auth autorest.Authorizer) { - setUserAgent(client, c.partnerId) - client.Authorizer = auth - //client.RequestInspector = azure.WithClientID(clientRequestID()) - client.Sender = azure.BuildSender() - client.SkipResourceProviderRegistration = c.skipProviderRegistration - client.PollingDuration = 60 * time.Minute -} - -func setUserAgent(client *autorest.Client, partnerID string) { - // TODO: This is the SDK version not the CLI version, once we are on 0.12, should revisit - tfUserAgent := httpclient.UserAgentString() - - pv := version.ProviderVersion - providerUserAgent := fmt.Sprintf("%s terraform-provider-azurerm/%s", tfUserAgent, pv) - client.UserAgent = strings.TrimSpace(fmt.Sprintf("%s %s", client.UserAgent, providerUserAgent)) - - // append the CloudShell version to the user agent if it exists - if azureAgent := os.Getenv("AZURE_HTTP_USER_AGENT"); azureAgent != "" { - client.UserAgent = fmt.Sprintf("%s %s", client.UserAgent, azureAgent) - } - - if partnerID != "" { - client.UserAgent = fmt.Sprintf("%s pid-%s", client.UserAgent, partnerID) - } - - log.Printf("[DEBUG] AzureRM Client User Agent: %s\n", client.UserAgent) + // Services + analysisservices *analysisservices.Client + apiManagement *apimanagement.Client + appInsights *applicationinsights.Client + automation *automation.Client + authorization *authorization.Client + batch *batch.Client + cdn *cdn.Client + cognitive *cognitive.Client + compute *compute.Client + containers *containers.Client + cosmos *cosmos.Client + databricks *databricks.Client + dataFactory *datafactory.Client + datalake *datalake.Client + devSpace *devspace.Client + devTestLabs *devtestlabs.Client + dns *dns.Client + privateDns *privatedns.Client + eventGrid *eventgrid.Client + eventhub *eventhub.Client + graph *graph.Client + hdinsight *hdinsight.Client + iothub *iothub.Client + keyvault *keyvault.Client + kusto *kusto.Client + logAnalytics *loganalytics.Client + logic *logic.Client + managementGroups *managementgroup.Client + maps *maps.Client + mariadb *mariadb.Client + media *media.Client + monitor *monitor.Client + mysql *mysql.Client + msi *msi.Client + mssql *mssql.Client + network *network.Client + notificationHubs *notificationhub.Client + policy *policy.Client + postgres *postgres.Client + recoveryServices *recoveryservices.Client + redis *redis.Client + relay *relay.Client + resource *resource.Client + scheduler *scheduler.Client + search *search.Client + securityCenter *securitycenter.Client + servicebus *servicebus.Client + serviceFabric *servicefabric.Client + signalr *signalr.Client + storage *storage.Client + streamanalytics *streamanalytics.Client + subscription *subscription.Client + sql *sql.Client + trafficManager *trafficmanager.Client + web *web.Client } // getArmClient is a helper method which returns a fully instantiated // *ArmClient based on the Config's current settings. -func getArmClient(c *authentication.Config, skipProviderRegistration bool, partnerId string) (*ArmClient, error) { +func getArmClient(c *authentication.Config, skipProviderRegistration bool, partnerId string, disableCorrelationRequestID bool) (*ArmClient, error) { env, err := authentication.DetermineEnvironment(c.Environment) if err != nil { return nil, err @@ -413,7 +156,7 @@ func getArmClient(c *authentication.Config, skipProviderRegistration bool, partn skipProviderRegistration: skipProviderRegistration, } - oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, c.TenantID) + oauthConfig, err := c.BuildOAuthConfig(env.ActiveDirectoryEndpoint) if err != nil { return nil, err } @@ -423,974 +166,99 @@ func getArmClient(c *authentication.Config, skipProviderRegistration bool, partn return nil, fmt.Errorf("Unable to configure OAuthConfig for tenant %s", c.TenantID) } + sender := sender.BuildSender("AzureRM") + // Resource Manager endpoints endpoint := env.ResourceManagerEndpoint - auth, err := c.GetAuthorizationToken(oauthConfig, env.TokenAudience) + auth, err := c.GetAuthorizationToken(sender, oauthConfig, env.TokenAudience) if err != nil { return nil, err } // Graph Endpoints graphEndpoint := env.GraphEndpoint - graphAuth, err := c.GetAuthorizationToken(oauthConfig, graphEndpoint) + graphAuth, err := c.GetAuthorizationToken(sender, oauthConfig, graphEndpoint) if err != nil { return nil, err } - // Key Vault Endpoints - sender := azure.BuildSender() - keyVaultAuth := autorest.NewBearerAuthorizerCallback(sender, func(tenantID, resource string) (*autorest.BearerAuthorizer, error) { - keyVaultSpt, err := c.GetAuthorizationToken(oauthConfig, resource) - if err != nil { - return nil, err - } - - return keyVaultSpt, nil - }) - - client.registerApiManagementServiceClients(endpoint, c.SubscriptionID, auth) - client.registerAppInsightsClients(endpoint, c.SubscriptionID, auth) - client.registerAutomationClients(endpoint, c.SubscriptionID, auth) - client.registerAuthentication(endpoint, graphEndpoint, c.SubscriptionID, c.TenantID, auth, graphAuth) - client.registerBatchClients(endpoint, c.SubscriptionID, auth) - client.registerCDNClients(endpoint, c.SubscriptionID, auth) - client.registerCognitiveServiceClients(endpoint, c.SubscriptionID, auth) - client.registerComputeClients(endpoint, c.SubscriptionID, auth) - client.registerContainerInstanceClients(endpoint, c.SubscriptionID, auth) - client.registerContainerRegistryClients(endpoint, c.SubscriptionID, auth) - client.registerContainerServicesClients(endpoint, c.SubscriptionID, auth) - client.registerCosmosDBClients(endpoint, c.SubscriptionID, auth) - client.registerDatabricksClients(endpoint, c.SubscriptionID, auth) - client.registerDatabases(endpoint, c.SubscriptionID, auth, sender) - client.registerDataLakeStoreClients(endpoint, c.SubscriptionID, auth) - client.registerDeviceClients(endpoint, c.SubscriptionID, auth) - client.registerDevSpaceClients(endpoint, c.SubscriptionID, auth) - client.registerDevTestClients(endpoint, c.SubscriptionID, auth) - client.registerDNSClients(endpoint, c.SubscriptionID, auth) - client.registerEventGridClients(endpoint, c.SubscriptionID, auth) - client.registerEventHubClients(endpoint, c.SubscriptionID, auth) - client.registerKeyVaultClients(endpoint, c.SubscriptionID, auth, keyVaultAuth) - client.registerLogicClients(endpoint, c.SubscriptionID, auth) - client.registerMediaServiceClients(endpoint, c.SubscriptionID, auth) - client.registerMonitorClients(endpoint, c.SubscriptionID, auth) - client.registerNetworkingClients(endpoint, c.SubscriptionID, auth) - client.registerNotificationHubsClient(endpoint, c.SubscriptionID, auth) - client.registerOperationalInsightsClients(endpoint, c.SubscriptionID, auth) - client.registerRecoveryServiceClients(endpoint, c.SubscriptionID, auth) - client.registerPolicyClients(endpoint, c.SubscriptionID, auth) - client.registerManagementGroupClients(endpoint, auth) - client.registerRedisClients(endpoint, c.SubscriptionID, auth) - client.registerRelayClients(endpoint, c.SubscriptionID, auth) - client.registerResourcesClients(endpoint, c.SubscriptionID, auth) - client.registerSearchClients(endpoint, c.SubscriptionID, auth) - client.registerSecurityCenterClients(endpoint, c.SubscriptionID, auth) - client.registerServiceBusClients(endpoint, c.SubscriptionID, auth) - client.registerServiceFabricClients(endpoint, c.SubscriptionID, auth) - client.registerSchedulerClients(endpoint, c.SubscriptionID, auth) - client.registerSignalRClients(endpoint, c.SubscriptionID, auth) - client.registerStorageClients(endpoint, c.SubscriptionID, auth) - client.registerTrafficManagerClients(endpoint, c.SubscriptionID, auth) - client.registerWebClients(endpoint, c.SubscriptionID, auth) - - return &client, nil -} - -func (c *ArmClient) registerApiManagementServiceClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - apisClient := apimanagement.NewAPIClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&apisClient.Client, auth) - c.apiManagementApiClient = apisClient - - groupsClient := apimanagement.NewGroupClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&groupsClient.Client, auth) - c.apiManagementGroupClient = groupsClient - - groupUsersClient := apimanagement.NewGroupUserClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&groupUsersClient.Client, auth) - c.apiManagementGroupUsersClient = groupUsersClient - - serviceClient := apimanagement.NewServiceClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&serviceClient.Client, auth) - c.apiManagementServiceClient = serviceClient - - productsClient := apimanagement.NewProductClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&productsClient.Client, auth) - c.apiManagementProductsClient = productsClient - - productApisClient := apimanagement.NewProductAPIClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&productApisClient.Client, auth) - c.apiManagementProductApisClient = productApisClient - - productGroupsClient := apimanagement.NewProductGroupClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&productGroupsClient.Client, auth) - c.apiManagementProductGroupsClient = productGroupsClient - - propertiesClient := apimanagement.NewPropertyClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&propertiesClient.Client, auth) - c.apiManagementPropertyClient = propertiesClient - - usersClient := apimanagement.NewUserClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&usersClient.Client, auth) - c.apiManagementUsersClient = usersClient -} - -func (c *ArmClient) registerAppInsightsClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - ai := appinsights.NewComponentsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&ai.Client, auth) - c.appInsightsClient = ai - - aiak := appinsights.NewAPIKeysClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&aiak.Client, auth) - c.appInsightsAPIKeyClient = aiak -} - -func (c *ArmClient) registerAutomationClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - accountClient := automation.NewAccountClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&accountClient.Client, auth) - c.automationAccountClient = accountClient - - agentRegistrationInfoClient := automation.NewAgentRegistrationInformationClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&agentRegistrationInfoClient.Client, auth) - c.automationAgentRegistrationInfoClient = agentRegistrationInfoClient - - credentialClient := automation.NewCredentialClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&credentialClient.Client, auth) - c.automationCredentialClient = credentialClient - - dscConfigurationClient := automation.NewDscConfigurationClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&dscConfigurationClient.Client, auth) - c.automationDscConfigurationClient = dscConfigurationClient - - dscNodeConfigurationClient := automation.NewDscNodeConfigurationClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&dscNodeConfigurationClient.Client, auth) - c.automationDscNodeConfigurationClient = dscNodeConfigurationClient - - moduleClient := automation.NewModuleClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&moduleClient.Client, auth) - c.automationModuleClient = moduleClient - - runbookClient := automation.NewRunbookClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&runbookClient.Client, auth) - c.automationRunbookClient = runbookClient - - scheduleClient := automation.NewScheduleClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&scheduleClient.Client, auth) - c.automationScheduleClient = scheduleClient - - runbookDraftClient := automation.NewRunbookDraftClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&runbookDraftClient.Client, auth) - c.automationRunbookDraftClient = runbookDraftClient -} - -func (c *ArmClient) registerAuthentication(endpoint, graphEndpoint, subscriptionId, tenantId string, auth, graphAuth autorest.Authorizer) { - assignmentsClient := authorization.NewRoleAssignmentsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&assignmentsClient.Client, auth) - c.roleAssignmentsClient = assignmentsClient - - definitionsClient := authorization.NewRoleDefinitionsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&definitionsClient.Client, auth) - c.roleDefinitionsClient = definitionsClient - - applicationsClient := graphrbac.NewApplicationsClientWithBaseURI(graphEndpoint, tenantId) - c.configureClient(&applicationsClient.Client, graphAuth) - c.applicationsClient = applicationsClient - - servicePrincipalsClient := graphrbac.NewServicePrincipalsClientWithBaseURI(graphEndpoint, tenantId) - c.configureClient(&servicePrincipalsClient.Client, graphAuth) - c.servicePrincipalsClient = servicePrincipalsClient -} - -func (c *ArmClient) registerBatchClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - batchAccount := batch.NewAccountClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&batchAccount.Client, auth) - c.batchAccountClient = batchAccount - - batchPool := batch.NewPoolClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&batchPool.Client, auth) - c.batchPoolClient = batchPool -} - -func (c *ArmClient) registerCDNClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - customDomainsClient := cdn.NewCustomDomainsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&customDomainsClient.Client, auth) - c.cdnCustomDomainsClient = customDomainsClient - - endpointsClient := cdn.NewEndpointsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&endpointsClient.Client, auth) - c.cdnEndpointsClient = endpointsClient - - profilesClient := cdn.NewProfilesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&profilesClient.Client, auth) - c.cdnProfilesClient = profilesClient -} - -func (c *ArmClient) registerCognitiveServiceClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - accountsClient := cognitiveservices.NewAccountsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&accountsClient.Client, auth) - c.cognitiveAccountsClient = accountsClient -} - -func (c *ArmClient) registerCosmosDBClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - cdb := documentdb.NewDatabaseAccountsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&cdb.Client, auth) - c.cosmosDBClient = cdb -} - -func (c *ArmClient) registerMediaServiceClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - mediaServicesClient := media.NewMediaservicesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mediaServicesClient.Client, auth) - c.mediaServicesClient = mediaServicesClient -} - -func (c *ArmClient) registerComputeClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - availabilitySetsClient := compute.NewAvailabilitySetsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&availabilitySetsClient.Client, auth) - c.availSetClient = availabilitySetsClient - - diskClient := compute.NewDisksClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&diskClient.Client, auth) - c.diskClient = diskClient - - imagesClient := compute.NewImagesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&imagesClient.Client, auth) - c.imageClient = imagesClient - - snapshotsClient := compute.NewSnapshotsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&snapshotsClient.Client, auth) - c.snapshotsClient = snapshotsClient - - usageClient := compute.NewUsageClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&usageClient.Client, auth) - c.usageOpsClient = usageClient - - extensionImagesClient := compute.NewVirtualMachineExtensionImagesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&extensionImagesClient.Client, auth) - c.vmExtensionImageClient = extensionImagesClient - - extensionsClient := compute.NewVirtualMachineExtensionsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&extensionsClient.Client, auth) - c.vmExtensionClient = extensionsClient - - virtualMachineImagesClient := compute.NewVirtualMachineImagesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&virtualMachineImagesClient.Client, auth) - c.vmImageClient = virtualMachineImagesClient - - scaleSetsClient := compute.NewVirtualMachineScaleSetsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&scaleSetsClient.Client, auth) - c.vmScaleSetClient = scaleSetsClient - - virtualMachinesClient := compute.NewVirtualMachinesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&virtualMachinesClient.Client, auth) - c.vmClient = virtualMachinesClient - - galleriesClient := compute.NewGalleriesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&galleriesClient.Client, auth) - c.galleriesClient = galleriesClient - - galleryImagesClient := compute.NewGalleryImagesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&galleryImagesClient.Client, auth) - c.galleryImagesClient = galleryImagesClient - - galleryImageVersionsClient := compute.NewGalleryImageVersionsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&galleryImageVersionsClient.Client, auth) - c.galleryImageVersionsClient = galleryImageVersionsClient -} - -func (c *ArmClient) registerContainerInstanceClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - cgc := containerinstance.NewContainerGroupsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&cgc.Client, auth) - c.containerGroupsClient = cgc -} - -func (c *ArmClient) registerContainerRegistryClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - crc := containerregistry.NewRegistriesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&crc.Client, auth) - c.containerRegistryClient = crc - - // container registry replicalication client - crrc := containerregistry.NewReplicationsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&crrc.Client, auth) - c.containerRegistryReplicationsClient = crrc -} - -func (c *ArmClient) registerContainerServicesClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - // ACS - containerServicesClient := containerservice.NewContainerServicesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&containerServicesClient.Client, auth) - c.containerServicesClient = containerServicesClient - - // AKS - kubernetesClustersClient := containerservice.NewManagedClustersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&kubernetesClustersClient.Client, auth) - c.kubernetesClustersClient = kubernetesClustersClient -} - -func (c *ArmClient) registerDatabricksClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - databricksWorkspacesClient := databricks.NewWorkspacesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&databricksWorkspacesClient.Client, auth) - c.databricksWorkspacesClient = databricksWorkspacesClient -} - -func (c *ArmClient) registerDatabases(endpoint, subscriptionId string, auth autorest.Authorizer, sender autorest.Sender) { - mariadbDBClient := mariadb.NewDatabasesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mariadbDBClient.Client, auth) - c.mariadbDatabasesClient = mariadbDBClient - - mariadbServersClient := mariadb.NewServersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mariadbServersClient.Client, auth) - c.mariadbServersClient = mariadbServersClient - - // MySQL - mysqlConfigClient := mysql.NewConfigurationsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mysqlConfigClient.Client, auth) - c.mysqlConfigurationsClient = mysqlConfigClient - - mysqlDBClient := mysql.NewDatabasesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mysqlDBClient.Client, auth) - c.mysqlDatabasesClient = mysqlDBClient - - mysqlFWClient := mysql.NewFirewallRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mysqlFWClient.Client, auth) - c.mysqlFirewallRulesClient = mysqlFWClient - - mysqlServersClient := mysql.NewServersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mysqlServersClient.Client, auth) - c.mysqlServersClient = mysqlServersClient - - mysqlVirtualNetworkRulesClient := mysql.NewVirtualNetworkRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mysqlVirtualNetworkRulesClient.Client, auth) - c.mysqlVirtualNetworkRulesClient = mysqlVirtualNetworkRulesClient - - // PostgreSQL - postgresqlConfigClient := postgresql.NewConfigurationsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&postgresqlConfigClient.Client, auth) - c.postgresqlConfigurationsClient = postgresqlConfigClient - - postgresqlDBClient := postgresql.NewDatabasesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&postgresqlDBClient.Client, auth) - c.postgresqlDatabasesClient = postgresqlDBClient - - postgresqlFWClient := postgresql.NewFirewallRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&postgresqlFWClient.Client, auth) - c.postgresqlFirewallRulesClient = postgresqlFWClient - - postgresqlSrvClient := postgresql.NewServersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&postgresqlSrvClient.Client, auth) - c.postgresqlServersClient = postgresqlSrvClient - - postgresqlVNRClient := postgresql.NewVirtualNetworkRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&postgresqlVNRClient.Client, auth) - c.postgresqlVirtualNetworkRulesClient = postgresqlVNRClient - - // SQL Azure - sqlDBClient := sql.NewDatabasesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&sqlDBClient.Client, auth) - c.sqlDatabasesClient = sqlDBClient - - sqlDTDPClient := sql.NewDatabaseThreatDetectionPoliciesClientWithBaseURI(endpoint, subscriptionId) - setUserAgent(&sqlDTDPClient.Client, "") - sqlDTDPClient.Authorizer = auth - sqlDTDPClient.Sender = sender - sqlDTDPClient.SkipResourceProviderRegistration = c.skipProviderRegistration - c.sqlDatabaseThreatDetectionPoliciesClient = sqlDTDPClient - - sqlFWClient := sql.NewFirewallRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&sqlFWClient.Client, auth) - c.sqlFirewallRulesClient = sqlFWClient - - sqlEPClient := sql.NewElasticPoolsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&sqlEPClient.Client, auth) - c.sqlElasticPoolsClient = sqlEPClient - - MsSqlEPClient := MsSql.NewElasticPoolsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&MsSqlEPClient.Client, auth) - c.msSqlElasticPoolsClient = MsSqlEPClient - - sqlSrvClient := sql.NewServersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&sqlSrvClient.Client, auth) - c.sqlServersClient = sqlSrvClient - - sqlADClient := sql.NewServerAzureADAdministratorsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&sqlADClient.Client, auth) - c.sqlServerAzureADAdministratorsClient = sqlADClient - - sqlVNRClient := sql.NewVirtualNetworkRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&sqlVNRClient.Client, auth) - c.sqlVirtualNetworkRulesClient = sqlVNRClient -} - -func (c *ArmClient) registerDataLakeStoreClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - storeAccountClient := storeAccount.NewAccountsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&storeAccountClient.Client, auth) - c.dataLakeStoreAccountClient = storeAccountClient - - storeFirewallRulesClient := storeAccount.NewFirewallRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&storeFirewallRulesClient.Client, auth) - c.dataLakeStoreFirewallRulesClient = storeFirewallRulesClient - - analyticsAccountClient := analyticsAccount.NewAccountsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&analyticsAccountClient.Client, auth) - c.dataLakeAnalyticsAccountClient = analyticsAccountClient - - filesClient := filesystem.NewClient() - c.configureClient(&filesClient.Client, auth) - c.dataLakeStoreFilesClient = filesClient - - analyticsFirewallRulesClient := analyticsAccount.NewFirewallRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&analyticsFirewallRulesClient.Client, auth) - c.dataLakeAnalyticsFirewallRulesClient = analyticsFirewallRulesClient -} - -func (c *ArmClient) registerDeviceClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - iotClient := devices.NewIotHubResourceClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&iotClient.Client, auth) - c.iothubResourceClient = iotClient -} - -func (c *ArmClient) registerDevTestClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - labsClient := dtl.NewLabsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&labsClient.Client, auth) - c.devTestLabsClient = labsClient - - devTestPoliciesClient := dtl.NewPoliciesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&devTestPoliciesClient.Client, auth) - c.devTestPoliciesClient = devTestPoliciesClient + // Storage Endpoints + storageAuth := c.BearerAuthorizerCallback(sender, oauthConfig) - devTestVirtualMachinesClient := dtl.NewVirtualMachinesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&devTestVirtualMachinesClient.Client, auth) - c.devTestVirtualMachinesClient = devTestVirtualMachinesClient - - devTestVirtualNetworksClient := dtl.NewVirtualNetworksClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&devTestVirtualNetworksClient.Client, auth) - c.devTestVirtualNetworksClient = devTestVirtualNetworksClient -} - -func (c *ArmClient) registerDevSpaceClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - controllersClient := devspaces.NewControllersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&controllersClient.Client, auth) - c.devSpaceControllerClient = controllersClient -} - -func (c *ArmClient) registerDNSClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - dn := dns.NewRecordSetsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&dn.Client, auth) - c.dnsClient = dn - - zo := dns.NewZonesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&zo.Client, auth) - c.zonesClient = zo -} - -func (c *ArmClient) registerEventGridClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - egtc := eventgrid.NewTopicsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&egtc.Client, auth) - c.eventGridTopicsClient = egtc - - egdc := eventgrid.NewDomainsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&egdc.Client, auth) - c.eventGridDomainsClient = egdc - - egesc := eventgrid.NewEventSubscriptionsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&egesc.Client, auth) - c.eventGridEventSubscriptionsClient = egesc -} - -func (c *ArmClient) registerEventHubClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - ehc := eventhub.NewEventHubsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&ehc.Client, auth) - c.eventHubClient = ehc - - chcgc := eventhub.NewConsumerGroupsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&chcgc.Client, auth) - c.eventHubConsumerGroupClient = chcgc - - ehnc := eventhub.NewNamespacesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&ehnc.Client, auth) - c.eventHubNamespacesClient = ehnc -} - -func (c *ArmClient) registerKeyVaultClients(endpoint, subscriptionId string, auth autorest.Authorizer, keyVaultAuth autorest.Authorizer) { - keyVaultClient := keyvault.NewVaultsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&keyVaultClient.Client, auth) - c.keyVaultClient = keyVaultClient - - keyVaultManagementClient := keyVault.New() - c.configureClient(&keyVaultManagementClient.Client, keyVaultAuth) - c.keyVaultManagementClient = keyVaultManagementClient -} - -func (c *ArmClient) registerLogicClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - workflowsClient := logic.NewWorkflowsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&workflowsClient.Client, auth) - c.logicWorkflowsClient = workflowsClient -} - -func (c *ArmClient) registerMonitorClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - agc := insights.NewActionGroupsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&agc.Client, auth) - c.monitorActionGroupsClient = agc - - alac := insights.NewActivityLogAlertsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&alac.Client, auth) - c.monitorActivityLogAlertsClient = alac - - arc := insights.NewAlertRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&arc.Client, auth) - c.monitorAlertRulesClient = arc - - monitorLogProfilesClient := insights.NewLogProfilesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&monitorLogProfilesClient.Client, auth) - c.monitorLogProfilesClient = monitorLogProfilesClient - - mac := insights.NewMetricAlertsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&mac.Client, auth) - c.monitorMetricAlertsClient = mac - - autoscaleSettingsClient := insights.NewAutoscaleSettingsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&autoscaleSettingsClient.Client, auth) - c.autoscaleSettingsClient = autoscaleSettingsClient - - monitoringInsightsClient := insights.NewDiagnosticSettingsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&monitoringInsightsClient.Client, auth) - c.monitorDiagnosticSettingsClient = monitoringInsightsClient - - monitoringCategorySettingsClient := insights.NewDiagnosticSettingsCategoryClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&monitoringCategorySettingsClient.Client, auth) - c.monitorDiagnosticSettingsCategoryClient = monitoringCategorySettingsClient -} - -func (c *ArmClient) registerNetworkingClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - applicationGatewaysClient := network.NewApplicationGatewaysClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&applicationGatewaysClient.Client, auth) - c.applicationGatewayClient = applicationGatewaysClient - - appSecurityGroupsClient := network.NewApplicationSecurityGroupsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&appSecurityGroupsClient.Client, auth) - c.applicationSecurityGroupsClient = appSecurityGroupsClient - - azureFirewallsClient := network.NewAzureFirewallsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&azureFirewallsClient.Client, auth) - c.azureFirewallsClient = azureFirewallsClient - - connectionMonitorsClient := network.NewConnectionMonitorsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&connectionMonitorsClient.Client, auth) - c.connectionMonitorsClient = connectionMonitorsClient - - ddosProtectionPlanClient := network.NewDdosProtectionPlansClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&ddosProtectionPlanClient.Client, auth) - c.ddosProtectionPlanClient = ddosProtectionPlanClient - - expressRouteAuthsClient := network.NewExpressRouteCircuitAuthorizationsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&expressRouteAuthsClient.Client, auth) - c.expressRouteAuthsClient = expressRouteAuthsClient - - expressRouteCircuitsClient := network.NewExpressRouteCircuitsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&expressRouteCircuitsClient.Client, auth) - c.expressRouteCircuitClient = expressRouteCircuitsClient - - expressRoutePeeringsClient := network.NewExpressRouteCircuitPeeringsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&expressRoutePeeringsClient.Client, auth) - c.expressRoutePeeringsClient = expressRoutePeeringsClient - - interfacesClient := network.NewInterfacesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&interfacesClient.Client, auth) - c.ifaceClient = interfacesClient - - loadBalancersClient := network.NewLoadBalancersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&loadBalancersClient.Client, auth) - c.loadBalancerClient = loadBalancersClient - - localNetworkGatewaysClient := network.NewLocalNetworkGatewaysClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&localNetworkGatewaysClient.Client, auth) - c.localNetConnClient = localNetworkGatewaysClient - - gatewaysClient := network.NewVirtualNetworkGatewaysClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&gatewaysClient.Client, auth) - c.vnetGatewayClient = gatewaysClient - - gatewayConnectionsClient := network.NewVirtualNetworkGatewayConnectionsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&gatewayConnectionsClient.Client, auth) - c.vnetGatewayConnectionsClient = gatewayConnectionsClient - - networksClient := network.NewVirtualNetworksClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&networksClient.Client, auth) - c.vnetClient = networksClient - - packetCapturesClient := network.NewPacketCapturesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&packetCapturesClient.Client, auth) - c.packetCapturesClient = packetCapturesClient - - peeringsClient := network.NewVirtualNetworkPeeringsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&peeringsClient.Client, auth) - c.vnetPeeringsClient = peeringsClient - - publicIPAddressesClient := network.NewPublicIPAddressesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&publicIPAddressesClient.Client, auth) - c.publicIPClient = publicIPAddressesClient - - routesClient := network.NewRoutesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&routesClient.Client, auth) - c.routesClient = routesClient - - routeTablesClient := network.NewRouteTablesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&routeTablesClient.Client, auth) - c.routeTablesClient = routeTablesClient - - securityGroupsClient := network.NewSecurityGroupsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&securityGroupsClient.Client, auth) - c.secGroupClient = securityGroupsClient - - securityRulesClient := network.NewSecurityRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&securityRulesClient.Client, auth) - c.secRuleClient = securityRulesClient - - subnetsClient := network.NewSubnetsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&subnetsClient.Client, auth) - c.subnetClient = subnetsClient - - userAssignedIdentitiesClient := msi.NewUserAssignedIdentitiesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&userAssignedIdentitiesClient.Client, auth) - c.userAssignedIdentitiesClient = userAssignedIdentitiesClient - - watchersClient := network.NewWatchersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&watchersClient.Client, auth) - c.watcherClient = watchersClient -} - -func (c *ArmClient) registerNotificationHubsClient(endpoint, subscriptionId string, auth autorest.Authorizer) { - namespacesClient := notificationhubs.NewNamespacesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&namespacesClient.Client, auth) - c.notificationNamespacesClient = namespacesClient - - notificationHubsClient := notificationhubs.NewClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(¬ificationHubsClient.Client, auth) - c.notificationHubsClient = notificationHubsClient -} - -func (c *ArmClient) registerOperationalInsightsClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - opwc := operationalinsights.NewWorkspacesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&opwc.Client, auth) - c.workspacesClient = opwc - - solutionsClient := operationsmanagement.NewSolutionsClientWithBaseURI(endpoint, subscriptionId, "Microsoft.OperationsManagement", "solutions", "testing") - c.configureClient(&solutionsClient.Client, auth) - c.solutionsClient = solutionsClient - - lsClient := operationalinsights.NewLinkedServicesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&lsClient.Client, auth) - c.linkedServicesClient = lsClient -} - -func (c *ArmClient) registerRecoveryServiceClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - vaultsClient := recoveryservices.NewVaultsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&vaultsClient.Client, auth) - c.recoveryServicesVaultsClient = vaultsClient - - protectedItemsClient := backup.NewProtectedItemsGroupClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&protectedItemsClient.Client, auth) - c.recoveryServicesProtectedItemsClient = protectedItemsClient - - protectionPoliciesClient := backup.NewProtectionPoliciesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&protectionPoliciesClient.Client, auth) - c.recoveryServicesProtectionPoliciesClient = protectionPoliciesClient -} - -func (c *ArmClient) registerRedisClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - redisClient := redis.NewClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&redisClient.Client, auth) - c.redisClient = redisClient - - firewallRuleClient := redis.NewFirewallRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&firewallRuleClient.Client, auth) - c.redisFirewallClient = firewallRuleClient - - patchSchedulesClient := redis.NewPatchSchedulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&patchSchedulesClient.Client, auth) - c.redisPatchSchedulesClient = patchSchedulesClient -} - -func (c *ArmClient) registerRelayClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - relayNamespacesClient := relay.NewNamespacesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&relayNamespacesClient.Client, auth) - c.relayNamespacesClient = relayNamespacesClient -} - -func (c *ArmClient) registerResourcesClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - locksClient := locks.NewManagementLocksClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&locksClient.Client, auth) - c.managementLocksClient = locksClient - - deploymentsClient := resources.NewDeploymentsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&deploymentsClient.Client, auth) - c.deploymentsClient = deploymentsClient - - resourcesClient := resources.NewClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&resourcesClient.Client, auth) - c.resourcesClient = resourcesClient - - resourceGroupsClient := resources.NewGroupsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&resourceGroupsClient.Client, auth) - c.resourceGroupsClient = resourceGroupsClient - - subscriptionsClient := subscriptions.NewClientWithBaseURI(endpoint) - c.configureClient(&subscriptionsClient.Client, auth) - c.subscriptionsClient = subscriptionsClient - - // this has to come from the Profile since this is shared with Stack - providersClient := resourcesprofile.NewProvidersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&providersClient.Client, auth) - c.providersClient = providersClient -} - -func (c *ArmClient) registerSchedulerClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - jobCollectionsClient := scheduler.NewJobCollectionsClientWithBaseURI(endpoint, subscriptionId) //nolint: megacheck - c.configureClient(&jobCollectionsClient.Client, auth) - c.schedulerJobCollectionsClient = jobCollectionsClient - - jobsClient := scheduler.NewJobsClientWithBaseURI(endpoint, subscriptionId) //nolint: megacheck - c.configureClient(&jobsClient.Client, auth) - c.schedulerJobsClient = jobsClient -} - -func (c *ArmClient) registerSearchClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - searchClient := search.NewServicesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&searchClient.Client, auth) - c.searchServicesClient = searchClient - - searchAdminKeysClient := search.NewAdminKeysClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&searchAdminKeysClient.Client, auth) - c.searchAdminKeysClient = searchAdminKeysClient -} - -func (c *ArmClient) registerSecurityCenterClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - ascLocation := "Global" - - securityCenterPricingClient := security.NewPricingsClientWithBaseURI(endpoint, subscriptionId, ascLocation) - c.configureClient(&securityCenterPricingClient.Client, auth) - c.securityCenterPricingClient = securityCenterPricingClient - - securityCenterContactsClient := security.NewContactsClientWithBaseURI(endpoint, subscriptionId, ascLocation) - c.configureClient(&securityCenterContactsClient.Client, auth) - c.securityCenterContactsClient = securityCenterContactsClient - - securityCenterWorkspaceClient := security.NewWorkspaceSettingsClientWithBaseURI(endpoint, subscriptionId, ascLocation) - c.configureClient(&securityCenterWorkspaceClient.Client, auth) - c.securityCenterWorkspaceClient = securityCenterWorkspaceClient -} - -func (c *ArmClient) registerServiceBusClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - queuesClient := servicebus.NewQueuesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&queuesClient.Client, auth) - c.serviceBusQueuesClient = queuesClient - - namespacesClient := servicebus.NewNamespacesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&namespacesClient.Client, auth) - c.serviceBusNamespacesClient = namespacesClient - - topicsClient := servicebus.NewTopicsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&topicsClient.Client, auth) - c.serviceBusTopicsClient = topicsClient - - subscriptionsClient := servicebus.NewSubscriptionsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&subscriptionsClient.Client, auth) - c.serviceBusSubscriptionsClient = subscriptionsClient - - subscriptionRulesClient := servicebus.NewRulesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&subscriptionRulesClient.Client, auth) - c.serviceBusSubscriptionRulesClient = subscriptionRulesClient -} - -func (c *ArmClient) registerServiceFabricClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - clustersClient := servicefabric.NewClustersClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&clustersClient.Client, auth) - c.serviceFabricClustersClient = clustersClient -} - -func (c *ArmClient) registerSignalRClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - sc := signalr.NewClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&sc.Client, auth) - c.signalRClient = sc -} - -func (c *ArmClient) registerStorageClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - accountsClient := storage.NewAccountsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&accountsClient.Client, auth) - c.storageServiceClient = accountsClient - - usageClient := storage.NewUsageClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&usageClient.Client, auth) - c.storageUsageClient = usageClient -} - -func (c *ArmClient) registerTrafficManagerClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - endpointsClient := trafficmanager.NewEndpointsClientWithBaseURI(endpoint, c.subscriptionId) - c.configureClient(&endpointsClient.Client, auth) - c.trafficManagerEndpointsClient = endpointsClient - - geographicalHierarchiesClient := trafficmanager.NewGeographicHierarchiesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&geographicalHierarchiesClient.Client, auth) - c.trafficManagerGeographialHierarchiesClient = geographicalHierarchiesClient - - profilesClient := trafficmanager.NewProfilesClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&profilesClient.Client, auth) - c.trafficManagerProfilesClient = profilesClient -} - -func (c *ArmClient) registerWebClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - appServicePlansClient := web.NewAppServicePlansClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&appServicePlansClient.Client, auth) - c.appServicePlansClient = appServicePlansClient - - appsClient := web.NewAppsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&appsClient.Client, auth) - c.appServicesClient = appsClient -} - -func (c *ArmClient) registerPolicyClients(endpoint, subscriptionId string, auth autorest.Authorizer) { - policyAssignmentsClient := policy.NewAssignmentsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&policyAssignmentsClient.Client, auth) - c.policyAssignmentsClient = policyAssignmentsClient - - policyDefinitionsClient := policy.NewDefinitionsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&policyDefinitionsClient.Client, auth) - c.policyDefinitionsClient = policyDefinitionsClient - - policySetDefinitionsClient := policy.NewSetDefinitionsClientWithBaseURI(endpoint, subscriptionId) - c.configureClient(&policySetDefinitionsClient.Client, auth) - c.policySetDefinitionsClient = policySetDefinitionsClient -} - -func (c *ArmClient) registerManagementGroupClients(endpoint string, auth autorest.Authorizer) { - managementGroupsClient := managementgroups.NewClientWithBaseURI(endpoint) - c.configureClient(&managementGroupsClient.Client, auth) - c.managementGroupsClient = managementGroupsClient - - managementGroupsSubscriptionClient := managementgroups.NewSubscriptionsClientWithBaseURI(endpoint) - c.configureClient(&managementGroupsSubscriptionClient.Client, auth) - c.managementGroupsSubscriptionClient = managementGroupsSubscriptionClient -} - -var ( - storageKeyCacheMu sync.RWMutex - storageKeyCache = make(map[string]string) -) - -func (c *ArmClient) getKeyForStorageAccount(ctx context.Context, resourceGroupName, storageAccountName string) (string, bool, error) { - cacheIndex := resourceGroupName + "/" + storageAccountName - storageKeyCacheMu.RLock() - key, ok := storageKeyCache[cacheIndex] - storageKeyCacheMu.RUnlock() - - if ok { - return key, true, nil - } - - storageKeyCacheMu.Lock() - defer storageKeyCacheMu.Unlock() - key, ok = storageKeyCache[cacheIndex] - if !ok { - accountKeys, err := c.storageServiceClient.ListKeys(ctx, resourceGroupName, storageAccountName) - if utils.ResponseWasNotFound(accountKeys.Response) { - return "", false, nil - } - if err != nil { - // We assume this is a transient error rather than a 404 (which is caught above), so assume the - // storeAccount still exists. - return "", true, fmt.Errorf("Error retrieving keys for storage storeAccount %q: %s", storageAccountName, err) - } - - if accountKeys.Keys == nil { - return "", false, fmt.Errorf("Nil key returned for storage storeAccount %q", storageAccountName) - } - - keys := *accountKeys.Keys - if len(keys) <= 0 { - return "", false, fmt.Errorf("No keys returned for storage storeAccount %q", storageAccountName) - } - - keyPtr := keys[0].Value - if keyPtr == nil { - return "", false, fmt.Errorf("The first key returned is nil for storage storeAccount %q", storageAccountName) - } - - key = *keyPtr - storageKeyCache[cacheIndex] = key - } - - return key, true, nil -} - -func (c *ArmClient) getBlobStorageClientForStorageAccount(ctx context.Context, resourceGroupName, storageAccountName string) (*mainStorage.BlobStorageClient, bool, error) { - key, accountExists, err := c.getKeyForStorageAccount(ctx, resourceGroupName, storageAccountName) - if err != nil { - return nil, accountExists, err - } - if !accountExists { - return nil, false, nil - } - - storageClient, err := mainStorage.NewClient(storageAccountName, key, c.environment.StorageEndpointSuffix, - mainStorage.DefaultAPIVersion, true) - if err != nil { - return nil, true, fmt.Errorf("Error creating storage client for storage storeAccount %q: %s", storageAccountName, err) - } - - blobClient := storageClient.GetBlobService() - return &blobClient, true, nil -} - -func (c *ArmClient) getFileServiceClientForStorageAccount(ctx context.Context, resourceGroupName, storageAccountName string) (*mainStorage.FileServiceClient, bool, error) { - key, accountExists, err := c.getKeyForStorageAccount(ctx, resourceGroupName, storageAccountName) - if err != nil { - return nil, accountExists, err - } - if !accountExists { - return nil, false, nil - } - - storageClient, err := mainStorage.NewClient(storageAccountName, key, c.environment.StorageEndpointSuffix, - mainStorage.DefaultAPIVersion, true) - if err != nil { - return nil, true, fmt.Errorf("Error creating storage client for storage storeAccount %q: %s", storageAccountName, err) - } - - fileClient := storageClient.GetFileService() - return &fileClient, true, nil -} - -func (c *ArmClient) getTableServiceClientForStorageAccount(ctx context.Context, resourceGroupName, storageAccountName string) (*mainStorage.TableServiceClient, bool, error) { - key, accountExists, err := c.getKeyForStorageAccount(ctx, resourceGroupName, storageAccountName) - if err != nil { - return nil, accountExists, err - } - if !accountExists { - return nil, false, nil - } - - storageClient, err := mainStorage.NewClient(storageAccountName, key, c.environment.StorageEndpointSuffix, - mainStorage.DefaultAPIVersion, true) - if err != nil { - return nil, true, fmt.Errorf("Error creating storage client for storage storeAccount %q: %s", storageAccountName, err) - } - - tableClient := storageClient.GetTableService() - return &tableClient, true, nil -} - -func (c *ArmClient) getQueueServiceClientForStorageAccount(ctx context.Context, resourceGroupName, storageAccountName string) (*mainStorage.QueueServiceClient, bool, error) { - key, accountExists, err := c.getKeyForStorageAccount(ctx, resourceGroupName, storageAccountName) - if err != nil { - return nil, accountExists, err - } - if !accountExists { - return nil, false, nil + // Key Vault Endpoints + keyVaultAuth := c.BearerAuthorizerCallback(sender, oauthConfig) + + o := &common.ClientOptions{ + SubscriptionId: c.SubscriptionID, + TenantID: c.TenantID, + PartnerId: partnerId, + GraphAuthorizer: graphAuth, + GraphEndpoint: graphEndpoint, + KeyVaultAuthorizer: keyVaultAuth, + ResourceManagerAuthorizer: auth, + ResourceManagerEndpoint: endpoint, + StorageAuthorizer: storageAuth, + PollingDuration: 180 * time.Minute, + SkipProviderReg: skipProviderRegistration, + DisableCorrelationRequestID: disableCorrelationRequestID, + Environment: *env, } - storageClient, err := mainStorage.NewClient(storageAccountName, key, c.environment.StorageEndpointSuffix, - mainStorage.DefaultAPIVersion, true) - if err != nil { - return nil, true, fmt.Errorf("Error creating storage client for storage storeAccount %q: %s", storageAccountName, err) - } + client.analysisservices = analysisservices.BuildClient(o) + client.apiManagement = apimanagement.BuildClient(o) + client.appInsights = applicationinsights.BuildClient(o) + client.automation = automation.BuildClient(o) + client.authorization = authorization.BuildClient(o) + client.batch = batch.BuildClient(o) + client.cdn = cdn.BuildClient(o) + client.cognitive = cognitive.BuildClient(o) + client.compute = compute.BuildClient(o) + client.containers = containers.BuildClient(o) + client.cosmos = cosmos.BuildClient(o) + client.databricks = databricks.BuildClient(o) + client.dataFactory = datafactory.BuildClient(o) + client.datalake = datalake.BuildClient(o) + client.devSpace = devspace.BuildClient(o) + client.devTestLabs = devtestlabs.BuildClient(o) + client.dns = dns.BuildClient(o) + client.eventGrid = eventgrid.BuildClient(o) + client.eventhub = eventhub.BuildClient(o) + client.graph = graph.BuildClient(o) + client.hdinsight = hdinsight.BuildClient(o) + client.iothub = iothub.BuildClient(o) + client.keyvault = keyvault.BuildClient(o) + client.kusto = kusto.BuildClient(o) + client.logic = logic.BuildClient(o) + client.logAnalytics = loganalytics.BuildClient(o) + client.maps = maps.BuildClient(o) + client.mariadb = mariadb.BuildClient(o) + client.media = media.BuildClient(o) + client.monitor = monitor.BuildClient(o) + client.mssql = mssql.BuildClient(o) + client.msi = msi.BuildClient(o) + client.mysql = mysql.BuildClient(o) + client.managementGroups = managementgroup.BuildClient(o) + client.network = network.BuildClient(o) + client.notificationHubs = notificationhub.BuildClient(o) + client.policy = policy.BuildClient(o) + client.postgres = postgres.BuildClient(o) + client.privateDns = privatedns.BuildClient(o) + client.recoveryServices = recoveryservices.BuildClient(o) + client.redis = redis.BuildClient(o) + client.relay = relay.BuildClient(o) + client.resource = resource.BuildClient(o) + client.search = search.BuildClient(o) + client.securityCenter = securitycenter.BuildClient(o) + client.servicebus = servicebus.BuildClient(o) + client.serviceFabric = servicefabric.BuildClient(o) + client.scheduler = scheduler.BuildClient(o) + client.signalr = signalr.BuildClient(o) + client.streamanalytics = streamanalytics.BuildClient(o) + client.storage = storage.BuildClient(o) + client.subscription = subscription.BuildClient(o) + client.sql = sql.BuildClient(o) + client.trafficManager = trafficmanager.BuildClient(o) + client.web = web.BuildClient(o) - queueClient := storageClient.GetQueueService() - return &queueClient, true, nil + return &client, nil } diff --git a/azurerm/config_test.go b/azurerm/config_test.go deleted file mode 100644 index 83d7d86dd7a0..000000000000 --- a/azurerm/config_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package azurerm - -import "testing" - -func TestClientRequestID(t *testing.T) { - first := clientRequestID() - - if first == "" { - t.Fatal("no client request ID generated") - } - - second := clientRequestID() - if first != second { - t.Fatal("subsequent request ID not the same as the first") - } -} diff --git a/azurerm/data_factory.go b/azurerm/data_factory.go new file mode 100644 index 000000000000..c6bd3b394f04 --- /dev/null +++ b/azurerm/data_factory.go @@ -0,0 +1,192 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + "sort" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" +) + +func validateAzureRMDataFactoryLinkedServiceDatasetName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + if regexp.MustCompile(`^[-.+?/<>*%&:\\]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf("any of '-' '.', '+', '?', '/', '<', '>', '*', '%%', '&', ':', '\\', are not allowed in %q: %q", k, value)) + } + + return warnings, errors +} + +func expandDataFactoryLinkedServiceIntegrationRuntime(integrationRuntimeName string) *datafactory.IntegrationRuntimeReference { + typeString := "IntegrationRuntimeReference" + + return &datafactory.IntegrationRuntimeReference{ + ReferenceName: &integrationRuntimeName, + Type: &typeString, + } +} + +// Because the password isn't returned from the api in the connection string, we'll check all +// but the password string and return true if they match. +func azureRmDataFactoryLinkedServiceConnectionStringDiff(_, old string, new string, _ *schema.ResourceData) bool { + oldSplit := strings.Split(strings.ToLower(old), ";") + newSplit := strings.Split(strings.ToLower(new), ";") + + sort.Strings(oldSplit) + sort.Strings(newSplit) + + // We need to remove the password from the new string since it isn't returned from the api + for i, v := range newSplit { + if strings.HasPrefix(v, "password") { + newSplit = append(newSplit[:i], newSplit[i+1:]...) + } + } + + if len(oldSplit) != len(newSplit) { + return false + } + + // We'll error out if we find any differences between the old and the new connection strings + for i := range oldSplit { + if !strings.EqualFold(oldSplit[i], newSplit[i]) { + return false + } + } + + return true +} + +func expandDataFactoryParameters(input map[string]interface{}) map[string]*datafactory.ParameterSpecification { + output := make(map[string]*datafactory.ParameterSpecification) + + for k, v := range input { + output[k] = &datafactory.ParameterSpecification{ + Type: datafactory.ParameterTypeString, + DefaultValue: v.(string), + } + } + + return output +} + +func flattenDataFactoryParameters(input map[string]*datafactory.ParameterSpecification) map[string]interface{} { + output := make(map[string]interface{}) + + for k, v := range input { + if v != nil { + // we only support string parameters at this time + val, ok := v.DefaultValue.(string) + if !ok { + log.Printf("[DEBUG] Skipping parameter %q since it's not a string", k) + } + + output[k] = val + } + } + + return output +} + +func flattenDataFactoryAnnotations(input *[]interface{}) []string { + annotations := make([]string, 0) + if input == nil { + return annotations + } + + for _, annotation := range *input { + val, ok := annotation.(string) + if !ok { + log.Printf("[DEBUG] Skipping annotation %q since it's not a string", val) + } + annotations = append(annotations, val) + } + return annotations +} + +func expandDataFactoryVariables(input map[string]interface{}) map[string]*datafactory.VariableSpecification { + output := make(map[string]*datafactory.VariableSpecification) + + for k, v := range input { + output[k] = &datafactory.VariableSpecification{ + Type: datafactory.VariableTypeString, + DefaultValue: v.(string), + } + } + + return output +} + +func flattenDataFactoryVariables(input map[string]*datafactory.VariableSpecification) map[string]interface{} { + output := make(map[string]interface{}) + + for k, v := range input { + if v != nil { + // we only support string parameters at this time + val, ok := v.DefaultValue.(string) + if !ok { + log.Printf("[DEBUG] Skipping variable %q since it's not a string", k) + } + + output[k] = val + } + } + + return output +} + +// DatasetColumn describes the attributes needed to specify a structure column for a dataset +type DatasetColumn struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Type string `json:"type,omitempty"` +} + +func expandDataFactoryDatasetStructure(input []interface{}) interface{} { + columns := make([]DatasetColumn, 0) + for _, column := range input { + attrs := column.(map[string]interface{}) + + datasetColumn := DatasetColumn{ + Name: attrs["name"].(string), + } + if attrs["description"] != nil { + datasetColumn.Description = attrs["description"].(string) + } + if attrs["type"] != nil { + datasetColumn.Type = attrs["type"].(string) + } + columns = append(columns, datasetColumn) + } + return columns +} + +func flattenDataFactoryStructureColumns(input interface{}) []interface{} { + output := make([]interface{}, 0) + + columns, ok := input.([]interface{}) + if !ok { + return columns + } + + for _, v := range columns { + column, ok := v.(map[string]interface{}) + if !ok { + continue + } + result := make(map[string]interface{}) + if column["name"] != nil { + result["name"] = column["name"] + } + if column["type"] != nil { + result["type"] = column["type"] + } + if column["description"] != nil { + result["description"] = column["description"] + } + output = append(output, result) + } + return output +} diff --git a/azurerm/data_factory_test.go b/azurerm/data_factory_test.go new file mode 100644 index 000000000000..1424fe672118 --- /dev/null +++ b/azurerm/data_factory_test.go @@ -0,0 +1,40 @@ +package azurerm + +import "testing" + +func TestAzureRmDataFactoryLinkedServiceConnectionStringDiff(t *testing.T) { + cases := []struct { + Old string + New string + NoDiff bool + }{ + { + Old: "", + New: "", + NoDiff: true, + }, + { + Old: "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test", + New: "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test", + NoDiff: true, + }, + { + Old: "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test", + New: "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test", + NoDiff: true, + }, + { + Old: "Integrated Security=False;Data Source=test2;Initial Catalog=test;User ID=test", + New: "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test", + NoDiff: false, + }, + } + + for _, tc := range cases { + noDiff := azureRmDataFactoryLinkedServiceConnectionStringDiff("", tc.Old, tc.New, nil) + + if noDiff != tc.NoDiff { + t.Fatalf("Expected azureRmDataFactoryLinkedServiceConnectionStringDiff to be '%t' for '%s' '%s' - got '%t'", tc.NoDiff, tc.Old, tc.New, noDiff) + } + } +} diff --git a/azurerm/data_source_api_management.go b/azurerm/data_source_api_management.go index c17e8e367071..cdd88df1e527 100644 --- a/azurerm/data_source_api_management.go +++ b/azurerm/data_source_api_management.go @@ -7,6 +7,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -17,9 +18,9 @@ func dataSourceApiManagementService() *schema.Resource { Schema: map[string]*schema.Schema{ "name": azure.SchemaApiManagementDataSourceName(), - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "public_ip_addresses": { Type: schema.TypeList, @@ -91,7 +92,7 @@ func dataSourceApiManagementService() *schema.Resource { Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "gateway_regional_url": { Type: schema.TypeString, @@ -146,13 +147,13 @@ func dataSourceApiManagementService() *schema.Resource { }, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceApiManagementRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementServiceClient + client := meta.(*ArmClient).apiManagement.ServiceClient name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) @@ -174,7 +175,7 @@ func dataSourceApiManagementRead(d *schema.ResourceData, meta interface{}) error d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.ServiceProperties; props != nil { @@ -202,9 +203,7 @@ func dataSourceApiManagementRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error setting `sku`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func flattenDataSourceApiManagementHostnameConfigurations(input *[]apimanagement.HostnameConfiguration) []interface{} { @@ -255,8 +254,8 @@ func flattenDataSourceApiManagementHostnameConfigurations(input *[]apimanagement return []interface{}{ map[string]interface{}{ "management": managementResults, - "portal": proxyResults, - "proxy": portalResults, + "portal": portalResults, + "proxy": proxyResults, "scm": scmResults, }, } @@ -272,7 +271,7 @@ func flattenDataSourceApiManagementAdditionalLocations(input *[]apimanagement.Ad output := make(map[string]interface{}) if prop.Location != nil { - output["location"] = azureRMNormalizeLocation(*prop.Location) + output["location"] = azure.NormalizeLocation(*prop.Location) } if prop.PublicIPAddresses != nil { diff --git a/azurerm/data_source_api_management_api.go b/azurerm/data_source_api_management_api.go index 22697e8fd255..eb8bc8309d05 100644 --- a/azurerm/data_source_api_management_api.go +++ b/azurerm/data_source_api_management_api.go @@ -23,7 +23,7 @@ func dataSourceApiManagementApi() *schema.Resource { "api_management_name": azure.SchemaApiManagementDataSourceName(), - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "revision": { Type: schema.TypeString, @@ -106,7 +106,7 @@ func dataSourceApiManagementApi() *schema.Resource { func dataSourceApiManagementApiRead(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).apiManagementApiClient + client := meta.(*ArmClient).apiManagement.ApiClient resourceGroup := d.Get("resource_group_name").(string) serviceName := d.Get("api_management_name").(string) diff --git a/azurerm/data_source_api_management_api_test.go b/azurerm/data_source_api_management_api_test.go index c139e058108a..f23d9c10cbc7 100644 --- a/azurerm/data_source_api_management_api_test.go +++ b/azurerm/data_source_api_management_api_test.go @@ -4,13 +4,13 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" ) func TestAccDataSourceAzureRMApiManagementApi_basic(t *testing.T) { dataSourceName := "data.azurerm_api_management_api.test" - rInt := acctest.RandInt() + rInt := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -35,7 +35,7 @@ func TestAccDataSourceAzureRMApiManagementApi_basic(t *testing.T) { func TestAccDataSourceAzureRMApiManagementApi_complete(t *testing.T) { dataSourceName := "data.azurerm_api_management_api.test" - rInt := acctest.RandInt() + rInt := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ diff --git a/azurerm/data_source_api_management_group.go b/azurerm/data_source_api_management_group.go index 9c296b389d27..d5a7e13f9328 100644 --- a/azurerm/data_source_api_management_group.go +++ b/azurerm/data_source_api_management_group.go @@ -16,7 +16,7 @@ func dataSourceApiManagementGroup() *schema.Resource { Schema: map[string]*schema.Schema{ "name": azure.SchemaApiManagementChildDataSourceName(), - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "api_management_name": azure.SchemaApiManagementDataSourceName(), @@ -44,7 +44,7 @@ func dataSourceApiManagementGroup() *schema.Resource { } func dataSourceApiManagementGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementGroupClient + client := meta.(*ArmClient).apiManagement.GroupClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) diff --git a/azurerm/data_source_api_management_product.go b/azurerm/data_source_api_management_product.go index 6cde7a277d94..c5cf74872da2 100644 --- a/azurerm/data_source_api_management_product.go +++ b/azurerm/data_source_api_management_product.go @@ -18,7 +18,7 @@ func dataSourceApiManagementProduct() *schema.Resource { "api_management_name": azure.SchemaApiManagementDataSourceName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "display_name": { Type: schema.TypeString, @@ -58,7 +58,7 @@ func dataSourceApiManagementProduct() *schema.Resource { } } func dataSourceApiManagementProductRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductsClient + client := meta.(*ArmClient).apiManagement.ProductsClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) diff --git a/azurerm/data_source_api_management_product_test.go b/azurerm/data_source_api_management_product_test.go index 17293d2d300d..6a81fe584235 100644 --- a/azurerm/data_source_api_management_product_test.go +++ b/azurerm/data_source_api_management_product_test.go @@ -54,7 +54,6 @@ resource "azurerm_api_management" "test" { resource_group_name = "${azurerm_resource_group.test.name}" } - resource "azurerm_api_management_product" "test" { product_id = "test-product" api_management_name = "${azurerm_api_management.test.name}" @@ -62,6 +61,7 @@ resource "azurerm_api_management_product" "test" { display_name = "Test Product" subscription_required = true approval_required = true + subscriptions_limit = 2 published = true description = "This is an example description" terms = "These are some example terms and conditions" diff --git a/azurerm/data_source_api_management_user.go b/azurerm/data_source_api_management_user.go index 350844ff2d65..be5263ec9a8e 100644 --- a/azurerm/data_source_api_management_user.go +++ b/azurerm/data_source_api_management_user.go @@ -17,7 +17,7 @@ func dataSourceArmApiManagementUser() *schema.Resource { "api_management_name": azure.SchemaApiManagementDataSourceName(), - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "first_name": { Type: schema.TypeString, @@ -48,7 +48,7 @@ func dataSourceArmApiManagementUser() *schema.Resource { } func dataSourceArmApiManagementUserRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementUsersClient + client := meta.(*ArmClient).apiManagement.UsersClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) diff --git a/azurerm/data_source_api_management_user_test.go b/azurerm/data_source_api_management_user_test.go index e757346ccf9c..288ce1e3f9f7 100644 --- a/azurerm/data_source_api_management_user_test.go +++ b/azurerm/data_source_api_management_user_test.go @@ -53,16 +53,15 @@ resource "azurerm_api_management" "test" { resource_group_name = "${azurerm_resource_group.test.name}" } - resource "azurerm_api_management_user" "test" { - user_id = "test-user" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance" - last_name = "Test" - email = "azure-acctest%d@example.com" - state = "active" - note = "Used for testing in dimension C-137." + user_id = "test-user" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test" + email = "azure-acctest%d@example.com" + state = "active" + note = "Used for testing in dimension C-137." } data "azurerm_api_management_user" "test" { diff --git a/azurerm/data_source_app_service.go b/azurerm/data_source_app_service.go index 445306507990..1a07b7e48834 100644 --- a/azurerm/data_source_app_service.go +++ b/azurerm/data_source_app_service.go @@ -5,6 +5,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -19,16 +20,16 @@ func dataSourceArmAppService() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "app_service_plan_id": { Type: schema.TypeString, Computed: true, }, - "site_config": azure.SchemaAppServiceSiteConfig(), + "site_config": azure.SchemaAppServiceDataSourceSiteConfig(), "client_affinity_enabled": { Type: schema.TypeBool, @@ -77,7 +78,7 @@ func dataSourceArmAppService() *schema.Resource { }, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), "site_credential": { Type: schema.TypeList, @@ -132,7 +133,7 @@ func dataSourceArmAppService() *schema.Resource { } } func dataSourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient resourceGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) @@ -174,7 +175,7 @@ func dataSourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error if err != nil { return err } - siteCredResp, err := siteCredFuture.Result(client) + siteCredResp, err := siteCredFuture.Result(*client) if err != nil { return fmt.Errorf("Error making Read request on AzureRM App Service Site Credential %q: %+v", name, err) } @@ -184,7 +185,7 @@ func dataSourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.SiteProperties; props != nil { @@ -220,7 +221,5 @@ func dataSourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error return err } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_app_service_plan.go b/azurerm/data_source_app_service_plan.go index 2e6a3846823f..817f5442eb73 100644 --- a/azurerm/data_source_app_service_plan.go +++ b/azurerm/data_source_app_service_plan.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -17,9 +19,9 @@ func dataSourceAppServicePlan() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "kind": { Type: schema.TypeString, @@ -73,13 +75,23 @@ func dataSourceAppServicePlan() *schema.Resource { Computed: true, }, - "tags": tagsForDataSourceSchema(), + "maximum_elastic_worker_count": { + Type: schema.TypeInt, + Computed: true, + }, + + "is_xenon": { + Type: schema.TypeBool, + Computed: true, + }, + + "tags": tags.SchemaDataSource(), }, } } func dataSourceAppServicePlanRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicePlansClient + client := meta.(*ArmClient).web.AppServicePlansClient name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) @@ -101,7 +113,7 @@ func dataSourceAppServicePlanRead(d *schema.ResourceData, meta interface{}) erro d.Set("kind", resp.Kind) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.AppServicePlanProperties; props != nil { @@ -112,13 +124,17 @@ func dataSourceAppServicePlanRead(d *schema.ResourceData, meta interface{}) erro if props.MaximumNumberOfWorkers != nil { d.Set("maximum_number_of_workers", int(*props.MaximumNumberOfWorkers)) } + + if props.MaximumElasticWorkerCount != nil { + d.Set("maximum_elastic_worker_count", int(*props.MaximumElasticWorkerCount)) + } + + d.Set("is_xenon", props.IsXenon) } if err := d.Set("sku", flattenAppServicePlanSku(resp.Sku)); err != nil { return fmt.Errorf("Error setting `sku`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_app_service_plan_test.go b/azurerm/data_source_app_service_plan_test.go index 150ba6e05823..bd68b5878999 100644 --- a/azurerm/data_source_app_service_plan_test.go +++ b/azurerm/data_source_app_service_plan_test.go @@ -61,6 +61,52 @@ func TestAccDataSourceAzureRMAppServicePlan_complete(t *testing.T) { }) } +func TestAccDataSourceAzureRMAppServicePlan_premiumSKU(t *testing.T) { + dataSourceName := "data.azurerm_app_service_plan.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAppServicePlan_premiumSKU(rInt, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "elastic"), + resource.TestCheckResourceAttr(dataSourceName, "sku.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "sku.0.tier", "ElasticPremium"), + resource.TestCheckResourceAttr(dataSourceName, "sku.0.size", "EP1"), + resource.TestCheckResourceAttr(dataSourceName, "maximum_elastic_worker_count", "20"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMAppServicePlan_basicWindowsContainer(t *testing.T) { + dataSourceName := "data.azurerm_app_service_plan.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAppServicePlan_basicWindowsContainer(rInt, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "xenon"), + resource.TestCheckResourceAttr(dataSourceName, "sku.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "sku.0.tier", "PremiumContainer"), + resource.TestCheckResourceAttr(dataSourceName, "sku.0.size", "PC2"), + resource.TestCheckResourceAttr(dataSourceName, "is_xenon", "true"), + ), + }, + }, + }) +} + func testAccDataSourceAppServicePlan_basic(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -119,3 +165,65 @@ data "azurerm_app_service_plan" "test" { } `, rInt, location, rInt) } + +func testAccDataSourceAppServicePlan_premiumSKU(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + kind = "elastic" + maximum_elastic_worker_count = 20 + + sku { + tier = "ElasticPremium" + size = "EP1" + } + + properties { + per_site_scaling = true + } + + tags = { + environment = "Test" + } +} + +data "azurerm_app_service_plan" "test" { + name = "${azurerm_app_service_plan.test.name}" + resource_group_name = "${azurerm_app_service_plan.test.resource_group_name}" +} +`, rInt, location, rInt) +} + +func testAccDataSourceAppServicePlan_basicWindowsContainer(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + is_xenon = true + kind = "xenon" + + sku { + tier = "PremiumContainer" + size = "PC2" + } +} + +data "azurerm_app_service_plan" "test" { + name = "${azurerm_app_service_plan.test.name}" + resource_group_name = "${azurerm_app_service_plan.test.resource_group_name}" +} +`, rInt, location, rInt) +} diff --git a/azurerm/data_source_app_service_test.go b/azurerm/data_source_app_service_test.go index c0d9c875f9e5..e937096deaed 100644 --- a/azurerm/data_source_app_service_test.go +++ b/azurerm/data_source_app_service_test.go @@ -189,6 +189,26 @@ func TestAccDataSourceAzureRMAppService_minTls(t *testing.T) { }) } +func TestAccDataSourceAzureRMAppService_basicWindowsContainer(t *testing.T) { + dataSourceName := "data.azurerm_app_service.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAppService_basicWindowsContainer(rInt, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "site_config.0.windows_fx_version", "DOCKER|mcr.microsoft.com/azure-app-service/samples/aspnethelloworld:latest"), + resource.TestCheckResourceAttr(dataSourceName, "app_settings.DOCKER_REGISTRY_SERVER_URL", "https://mcr.microsoft.com"), + ), + }, + }, + }) +} + func testAccDataSourceAppService_basic(rInt int, location string) string { config := testAccAzureRMAppService_basic(rInt, location) return fmt.Sprintf(` @@ -296,3 +316,15 @@ data "azurerm_app_service" "test" { } `, config) } + +func testAccDataSourceAppService_basicWindowsContainer(rInt int, location string) string { + config := testAccAzureRMAppService_basicWindowsContainer(rInt, location) + return fmt.Sprintf(` +%s + +data "azurerm_app_service" "test" { + name = "${azurerm_app_service.test.name}" + resource_group_name = "${azurerm_app_service.test.resource_group_name}" +} +`, config) +} diff --git a/azurerm/data_source_application_insights.go b/azurerm/data_source_application_insights.go index b6cc24266773..f5d35a48d1e9 100644 --- a/azurerm/data_source_application_insights.go +++ b/azurerm/data_source_application_insights.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -12,7 +14,7 @@ func dataSourceArmApplicationInsights() *schema.Resource { return &schema.Resource{ Read: dataSourceArmApplicationInsightsRead, Schema: map[string]*schema.Schema{ - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "name": { Type: schema.TypeString, @@ -49,7 +51,7 @@ func dataSourceArmApplicationInsights() *schema.Resource { } func dataSourceArmApplicationInsightsRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appInsightsClient + client := meta.(*ArmClient).appInsights.ComponentsClient ctx := meta.(*ArmClient).StopContext resGroup := d.Get("resource_group_name").(string) @@ -69,7 +71,5 @@ func dataSourceArmApplicationInsightsRead(d *schema.ResourceData, meta interface d.Set("location", resp.Location) d.Set("app_id", resp.AppID) d.Set("application_type", resp.ApplicationType) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_application_insights_test.go b/azurerm/data_source_application_insights_test.go index feac4cfebdd0..cd84ade5d72a 100644 --- a/azurerm/data_source_application_insights_test.go +++ b/azurerm/data_source_application_insights_test.go @@ -36,19 +36,19 @@ func TestAccDataSourceApplicationInsights_basic(t *testing.T) { func testAccResourceApplicationInsights_complete(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestRG-%[1]d" - location = "%[2]s" + name = "acctestRG-%[1]d" + location = "%[2]s" } resource "azurerm_application_insights" "test" { - name = "acctestappinsights-%[1]d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - application_type = "other" - - tags = { - "foo" = "bar" - } + name = "acctestappinsights-%[1]d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_type = "other" + + tags = { + "foo" = "bar" + } } data "azurerm_application_insights" "test" { diff --git a/azurerm/data_source_application_security_group.go b/azurerm/data_source_application_security_group.go index ac2310f92df6..fd6732c1690f 100644 --- a/azurerm/data_source_application_security_group.go +++ b/azurerm/data_source_application_security_group.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -17,17 +19,17 @@ func dataSourceArmApplicationSecurityGroup() *schema.Resource { Required: true, }, - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmApplicationSecurityGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationSecurityGroupsClient + client := meta.(*ArmClient).network.ApplicationSecurityGroupsClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) @@ -47,10 +49,8 @@ func dataSourceArmApplicationSecurityGroupRead(d *schema.ResourceData, meta inte d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_application_security_group_test.go b/azurerm/data_source_application_security_group_test.go index 23c561d0a5b6..a846798a7534 100644 --- a/azurerm/data_source_application_security_group_test.go +++ b/azurerm/data_source_application_security_group_test.go @@ -82,7 +82,7 @@ resource "azurerm_application_security_group" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tags = { - "Hello" = "World" + Hello = "World" } } diff --git a/azurerm/data_source_automation_variable_bool.go b/azurerm/data_source_automation_variable_bool.go new file mode 100644 index 000000000000..f133a8315369 --- /dev/null +++ b/azurerm/data_source_automation_variable_bool.go @@ -0,0 +1,17 @@ +package azurerm + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceArmAutomationVariableBool() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmAutomationVariableBoolRead, + + Schema: datasourceAutomationVariableCommonSchema(schema.TypeBool), + } +} + +func dataSourceArmAutomationVariableBoolRead(d *schema.ResourceData, meta interface{}) error { + return datasourceAutomationVariableRead(d, meta, "Bool") +} diff --git a/azurerm/data_source_automation_variable_bool_test.go b/azurerm/data_source_automation_variable_bool_test.go new file mode 100644 index 000000000000..ea3893f0b8bd --- /dev/null +++ b/azurerm/data_source_automation_variable_bool_test.go @@ -0,0 +1,41 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMAutomationVariableBool_basic(t *testing.T) { + dataSourceName := "data.azurerm_automation_variable_bool.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAutomationVariableBool_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "value", "false"), + ), + }, + }, + }) +} + +func testAccDataSourceAutomationVariableBool_basic(rInt int, location string) string { + config := testAccAzureRMAutomationVariableBool_basic(rInt, location) + return fmt.Sprintf(` +%s + +data "azurerm_automation_variable_bool" "test" { + name = "${azurerm_automation_variable_bool.test.name}" + resource_group_name = "${azurerm_automation_variable_bool.test.resource_group_name}" + automation_account_name = "${azurerm_automation_variable_bool.test.automation_account_name}" +} +`, config) +} diff --git a/azurerm/data_source_automation_variable_datetime.go b/azurerm/data_source_automation_variable_datetime.go new file mode 100644 index 000000000000..575413adb7dc --- /dev/null +++ b/azurerm/data_source_automation_variable_datetime.go @@ -0,0 +1,17 @@ +package azurerm + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceArmAutomationVariableDateTime() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmAutomationVariableDateTimeRead, + + Schema: datasourceAutomationVariableCommonSchema(schema.TypeString), + } +} + +func dataSourceArmAutomationVariableDateTimeRead(d *schema.ResourceData, meta interface{}) error { + return datasourceAutomationVariableRead(d, meta, "Datetime") +} diff --git a/azurerm/data_source_automation_variable_datetime_test.go b/azurerm/data_source_automation_variable_datetime_test.go new file mode 100644 index 000000000000..7f89e8c198fa --- /dev/null +++ b/azurerm/data_source_automation_variable_datetime_test.go @@ -0,0 +1,41 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMAutomationVariableDateTime_basic(t *testing.T) { + dataSourceName := "data.azurerm_automation_variable_datetime.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAutomationVariableDateTime_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "value", "2019-04-24T21:40:54.074Z"), + ), + }, + }, + }) +} + +func testAccDataSourceAutomationVariableDateTime_basic(rInt int, location string) string { + config := testAccAzureRMAutomationVariableDateTime_basic(rInt, location) + return fmt.Sprintf(` +%s + +data "azurerm_automation_variable_datetime" "test" { + name = "${azurerm_automation_variable_datetime.test.name}" + resource_group_name = "${azurerm_automation_variable_datetime.test.resource_group_name}" + automation_account_name = "${azurerm_automation_variable_datetime.test.automation_account_name}" +} +`, config) +} diff --git a/azurerm/data_source_automation_variable_int.go b/azurerm/data_source_automation_variable_int.go new file mode 100644 index 000000000000..84cb82667dde --- /dev/null +++ b/azurerm/data_source_automation_variable_int.go @@ -0,0 +1,17 @@ +package azurerm + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceArmAutomationVariableInt() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmAutomationVariableIntRead, + + Schema: datasourceAutomationVariableCommonSchema(schema.TypeInt), + } +} + +func dataSourceArmAutomationVariableIntRead(d *schema.ResourceData, meta interface{}) error { + return datasourceAutomationVariableRead(d, meta, "Int") +} diff --git a/azurerm/data_source_automation_variable_int_test.go b/azurerm/data_source_automation_variable_int_test.go new file mode 100644 index 000000000000..4bf5b417f8b4 --- /dev/null +++ b/azurerm/data_source_automation_variable_int_test.go @@ -0,0 +1,41 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMAutomationVariableInt_basic(t *testing.T) { + dataSourceName := "data.azurerm_automation_variable_int.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAutomationVariableInt_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "value", "1234"), + ), + }, + }, + }) +} + +func testAccDataSourceAutomationVariableInt_basic(rInt int, location string) string { + config := testAccAzureRMAutomationVariableInt_basic(rInt, location) + return fmt.Sprintf(` +%s + +data "azurerm_automation_variable_int" "test" { + name = "${azurerm_automation_variable_int.test.name}" + resource_group_name = "${azurerm_automation_variable_int.test.resource_group_name}" + automation_account_name = "${azurerm_automation_variable_int.test.automation_account_name}" +} +`, config) +} diff --git a/azurerm/data_source_automation_variable_string.go b/azurerm/data_source_automation_variable_string.go new file mode 100644 index 000000000000..6fb94381c592 --- /dev/null +++ b/azurerm/data_source_automation_variable_string.go @@ -0,0 +1,17 @@ +package azurerm + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceArmAutomationVariableString() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmAutomationVariableStringRead, + + Schema: datasourceAutomationVariableCommonSchema(schema.TypeString), + } +} + +func dataSourceArmAutomationVariableStringRead(d *schema.ResourceData, meta interface{}) error { + return datasourceAutomationVariableRead(d, meta, "String") +} diff --git a/azurerm/data_source_automation_variable_string_test.go b/azurerm/data_source_automation_variable_string_test.go new file mode 100644 index 000000000000..68a40d6513a5 --- /dev/null +++ b/azurerm/data_source_automation_variable_string_test.go @@ -0,0 +1,41 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMAutomationVariableString_basic(t *testing.T) { + dataSourceName := "data.azurerm_automation_variable_string.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAutomationVariableString_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "value", "Hello, Terraform Basic Test."), + ), + }, + }, + }) +} + +func testAccDataSourceAutomationVariableString_basic(rInt int, location string) string { + config := testAccAzureRMAutomationVariableString_basic(rInt, location) + return fmt.Sprintf(` +%s + +data "azurerm_automation_variable_string" "test" { + name = "${azurerm_automation_variable_string.test.name}" + resource_group_name = "${azurerm_automation_variable_string.test.resource_group_name}" + automation_account_name = "${azurerm_automation_variable_string.test.automation_account_name}" +} +`, config) +} diff --git a/azurerm/data_source_availability_set.go b/azurerm/data_source_availability_set.go index 2378d1517233..70950abfbc46 100644 --- a/azurerm/data_source_availability_set.go +++ b/azurerm/data_source_availability_set.go @@ -6,7 +6,9 @@ import ( "strings" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -14,7 +16,7 @@ func dataSourceArmAvailabilitySet() *schema.Resource { return &schema.Resource{ Read: dataSourceArmAvailabilitySetRead, Schema: map[string]*schema.Schema{ - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "name": { Type: schema.TypeString, @@ -42,13 +44,13 @@ func dataSourceArmAvailabilitySet() *schema.Resource { Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).availSetClient + client := meta.(*ArmClient).compute.AvailabilitySetsClient ctx := meta.(*ArmClient).StopContext resGroup := d.Get("resource_group_name").(string) @@ -65,7 +67,7 @@ func dataSourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) d.SetId(*resp.ID) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if resp.Sku != nil && resp.Sku.Name != nil { d.Set("managed", strings.EqualFold(*resp.Sku.Name, "Aligned")) @@ -78,7 +80,5 @@ func dataSourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) d.Set("platform_fault_domain_count", strconv.Itoa(int(*v))) } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_availability_set_test.go b/azurerm/data_source_availability_set_test.go index 12d4893443ad..d0b961772357 100644 --- a/azurerm/data_source_availability_set_test.go +++ b/azurerm/data_source_availability_set_test.go @@ -34,8 +34,8 @@ func TestAccDataSourceAvailabilitySet_basic(t *testing.T) { func testAccDataSourceAvailabilitySet_basic(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestRG-%[1]d" - location = "%[2]s" + name = "acctestRG-%[1]d" + location = "%[2]s" } resource "azurerm_availability_set" "test" { @@ -43,9 +43,9 @@ resource "azurerm_availability_set" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - tags = { - "foo" = "bar" - } + tags = { + "foo" = "bar" + } } data "azurerm_availability_set" "test" { diff --git a/azurerm/data_source_azuread_application.go b/azurerm/data_source_azuread_application.go index 49a4d50305c0..edd27afc332e 100644 --- a/azurerm/data_source_azuread_application.go +++ b/azurerm/data_source_azuread_application.go @@ -74,7 +74,7 @@ As such the Azure Active Directory resources within the AzureRM Provider are now } func dataSourceArmAzureADApplicationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationsClient + client := meta.(*ArmClient).graph.ApplicationsClient ctx := meta.(*ArmClient).StopContext var application graphrbac.Application diff --git a/azurerm/data_source_azuread_service_principal.go b/azurerm/data_source_azuread_service_principal.go index 6c6041abcffa..295a03fe9fa6 100644 --- a/azurerm/data_source_azuread_service_principal.go +++ b/azurerm/data_source_azuread_service_principal.go @@ -45,7 +45,7 @@ As such the Azure Active Directory resources within the AzureRM Provider are now } func dataSourceArmActiveDirectoryServicePrincipalRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).servicePrincipalsClient + client := meta.(*ArmClient).graph.ServicePrincipalsClient ctx := meta.(*ArmClient).StopContext var servicePrincipal *graphrbac.ServicePrincipal diff --git a/azurerm/data_source_batch_account.go b/azurerm/data_source_batch_account.go index 45491b9ffd6b..0ee5a4ab2a05 100644 --- a/azurerm/data_source_batch_account.go +++ b/azurerm/data_source_batch_account.go @@ -3,8 +3,10 @@ package azurerm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2017-09-01/batch" + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -19,8 +21,8 @@ func dataSourceArmBatchAccount() *schema.Resource { ForceNew: true, ValidateFunc: validateAzureRMBatchAccountName, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), - "location": locationForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + "location": azure.SchemaLocationForDataSource(), "storage_account_id": { Type: schema.TypeString, Computed: true, @@ -29,6 +31,22 @@ func dataSourceArmBatchAccount() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "key_vault_reference": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, "primary_access_key": { Type: schema.TypeString, Sensitive: true, @@ -43,13 +61,13 @@ func dataSourceArmBatchAccount() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmBatchAccountRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).batchAccountClient + client := meta.(*ArmClient).batch.AccountClient resourceGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) @@ -70,7 +88,7 @@ func dataSourceArmBatchAccountRead(d *schema.ResourceData, meta interface{}) err d.Set("account_endpoint", resp.AccountEndpoint) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.AccountProperties; props != nil { @@ -78,20 +96,26 @@ func dataSourceArmBatchAccountRead(d *schema.ResourceData, meta interface{}) err d.Set("storage_account_id", autoStorage.StorageAccountID) } d.Set("pool_allocation_mode", props.PoolAllocationMode) - } + poolAllocationMode := d.Get("pool_allocation_mode").(string) - if d.Get("pool_allocation_mode").(string) == string(batch.BatchService) { - keys, err := client.GetKeys(ctx, resourceGroup, name) + if poolAllocationMode == string(batch.BatchService) { + keys, err := client.GetKeys(ctx, resourceGroup, name) - if err != nil { - return fmt.Errorf("Cannot read keys for Batch account %q (resource group %q): %v", name, resourceGroup, err) - } + if err != nil { + return fmt.Errorf("Cannot read keys for Batch account %q (resource group %q): %v", name, resourceGroup, err) + } - d.Set("primary_access_key", keys.Primary) - d.Set("secondary_access_key", keys.Secondary) - } + d.Set("primary_access_key", keys.Primary) + d.Set("secondary_access_key", keys.Secondary) - flattenAndSetTags(d, resp.Tags) + // set empty keyvault reference which is not needed in Batch Service allocation mode. + d.Set("key_vault_reference", []interface{}{}) + } else if poolAllocationMode == string(batch.UserSubscription) { + if err := d.Set("key_vault_reference", azure.FlattenBatchAccountKeyvaultReference(props.KeyVaultReference)); err != nil { + return fmt.Errorf("Error flattening `key_vault_reference`: %+v", err) + } + } + } - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_batch_account_test.go b/azurerm/data_source_batch_account_test.go index 3e6a110538e7..0c118a2209ff 100644 --- a/azurerm/data_source_batch_account_test.go +++ b/azurerm/data_source_batch_account_test.go @@ -2,10 +2,12 @@ package azurerm import ( "fmt" + "os" "testing" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" ) @@ -24,7 +26,7 @@ func TestAccDataSourceAzureRMBatchAccount_basic(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(dataSourceName, "name", fmt.Sprintf("testaccbatch%s", rs)), - resource.TestCheckResourceAttr(dataSourceName, "location", azureRMNormalizeLocation(location)), + resource.TestCheckResourceAttr(dataSourceName, "location", azure.NormalizeLocation(location)), resource.TestCheckResourceAttr(dataSourceName, "pool_allocation_mode", "BatchService"), ), }, @@ -47,7 +49,7 @@ func TestAccDataSourceAzureRMBatchAccount_complete(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(dataSourceName, "name", fmt.Sprintf("testaccbatch%s", rs)), - resource.TestCheckResourceAttr(dataSourceName, "location", azureRMNormalizeLocation(location)), + resource.TestCheckResourceAttr(dataSourceName, "location", azure.NormalizeLocation(location)), resource.TestCheckResourceAttr(dataSourceName, "pool_allocation_mode", "BatchService"), resource.TestCheckResourceAttr(dataSourceName, "tags.%", "1"), resource.TestCheckResourceAttr(dataSourceName, "tags.env", "test"), @@ -57,10 +59,38 @@ func TestAccDataSourceAzureRMBatchAccount_complete(t *testing.T) { }) } +func TestAccDataSourceAzureRMBatchAccount_userSubscription(t *testing.T) { + dataSourceName := "data.azurerm_batch_account.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + + tenantID := os.Getenv("ARM_TENANT_ID") + subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") + + config := testAccDataSourceAzureBatchAccount_userSubscription(ri, rs, location, tenantID, subscriptionID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "name", fmt.Sprintf("testaccbatch%s", rs)), + resource.TestCheckResourceAttr(dataSourceName, "location", azure.NormalizeLocation(location)), + resource.TestCheckResourceAttr(dataSourceName, "pool_allocation_mode", "UserSubscription"), + resource.TestCheckResourceAttr(dataSourceName, "key_vault_reference.#", "1"), + ), + }, + }, + }) +} + func testAccDataSourceAzureRMBatchAccount_basic(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "testaccbatch%d" + name = "testaccRG-%d-batch" location = "%s" } @@ -81,7 +111,7 @@ data "azurerm_batch_account" "test" { func testAccDataSourceAzureRMBatchAccount_complete(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "testaccbatch%d" + name = "testaccRG-%d-batch" location = "%s" } @@ -111,3 +141,67 @@ data "azurerm_batch_account" "test" { } `, rInt, location, rString, rString) } + +func testAccDataSourceAzureBatchAccount_userSubscription(rInt int, rString string, location string, tenantID string, subscriptionID string) string { + return fmt.Sprintf(` +data "azurerm_azuread_service_principal" "test" { + display_name = "Microsoft Azure Batch" +} + +resource "azurerm_resource_group" "test" { + name = "testaccRG-%d-batchaccount" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "batchkv%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + enabled_for_disk_encryption = true + enabled_for_deployment = true + enabled_for_template_deployment = true + tenant_id = "%s" + + sku { + name = "standard" + } + + access_policy { + tenant_id = "%s" + object_id = "${data.azurerm_azuread_service_principal.test.object_id}" + + secret_permissions = [ + "get", + "list", + "set", + "delete" + ] + + } +} + +resource "azurerm_role_assignment" "contribrole" { + scope = "/subscriptions/%s" + role_definition_name = "Contributor" + principal_id = "${data.azurerm_azuread_service_principal.test.object_id}" +} + +resource "azurerm_batch_account" "test" { + name = "testaccbatch%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + pool_allocation_mode = "UserSubscription" + + key_vault_reference { + id = "${azurerm_key_vault.test.id}" + url = "${azurerm_key_vault.test.vault_uri}" + } +} + +data "azurerm_batch_account" "test" { + name = "${azurerm_batch_account.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rString, tenantID, tenantID, subscriptionID, rString) +} diff --git a/azurerm/data_source_batch_certificate.go b/azurerm/data_source_batch_certificate.go new file mode 100644 index 000000000000..f86599cc42c1 --- /dev/null +++ b/azurerm/data_source_batch_certificate.go @@ -0,0 +1,90 @@ +package azurerm + +import ( + "fmt" + "regexp" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmBatchCertificate() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmBatchCertificateRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateAzureRMBatchCertificateName, + }, + + "account_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateAzureRMBatchAccountName, + }, + + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "public_data": { + Type: schema.TypeString, + Computed: true, + }, + "format": { + Type: schema.TypeString, + Computed: true, + }, + "thumbprint": { + Type: schema.TypeString, + Computed: true, + }, + "thumbprint_algorithm": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceArmBatchCertificateRead(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).batch.CertificateClient + + resourceGroupName := d.Get("resource_group_name").(string) + accountName := d.Get("account_name").(string) + name := d.Get("name").(string) + + resp, err := client.Get(ctx, resourceGroupName, accountName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Error: Batch certificate %q (Account %q / Resource Group %q) was not found", name, accountName, resourceGroupName) + } + return fmt.Errorf("Error making Read request on AzureRM Batch certificate %q: %+v", name, err) + } + + d.SetId(*resp.ID) + + d.Set("name", resp.Name) + d.Set("account_name", accountName) + d.Set("resource_group_name", resourceGroupName) + + if props := resp.CertificateProperties; props != nil { + d.Set("format", props.Format) + d.Set("public_data", props.PublicData) + d.Set("thumbprint", props.Thumbprint) + d.Set("thumbprint_algorithm", props.ThumbprintAlgorithm) + } + + return nil +} +func validateAzureRMBatchCertificateName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + if !regexp.MustCompile(`^[\w]+-[\w]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "must be made up of algorithm and thumbprint separated by a dash in %q: %q", k, value)) + } + + return warnings, errors +} diff --git a/azurerm/data_source_batch_certificate_test.go b/azurerm/data_source_batch_certificate_test.go new file mode 100644 index 000000000000..904f1d3516e9 --- /dev/null +++ b/azurerm/data_source_batch_certificate_test.go @@ -0,0 +1,68 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMBatchCertificate_basic(t *testing.T) { + dataSourceName := "data.azurerm_batch_certificate.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + config := testAccDataSourceAzureRMBatchCertificate_basic(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "name", "sha1-42c107874fd0e4a9583292a2f1098e8fe4b2edda"), + resource.TestCheckResourceAttr(dataSourceName, "account_name", fmt.Sprintf("testaccbatch%s", rs)), + resource.TestCheckResourceAttr(dataSourceName, "format", "Pfx"), + resource.TestCheckResourceAttr(dataSourceName, "public_data", "MIIFqzCCA5OgAwIBAgIJAMs4jwMPq7T1MA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMRgwFgYDVQQKDA9UZXJyYWZvcm0gVGVzdHMxDjAMBgNVBAsMBUF6dXJlMR4wHAYDVQQDDBVUZXJyYWZvcm0gQXBwIEdhdGV3YXkwHhcNMTYxMTAxMTcxOTEyWhcNMjYxMDMwMTcxOTEyWjBsMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTEYMBYGA1UECgwPVGVycmFmb3JtIFRlc3RzMQ4wDAYDVQQLDAVBenVyZTEeMBwGA1UEAwwVVGVycmFmb3JtIEFwcCBHYXRld2F5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA49HW2pYIlW/mlaadLA1AsXiV48xVhXAvGVk3DEl1ffjp5bN8rap5WV1D83uMg1Ii7CJM8yNHkRkvN8n5WXFng4R5V1jPxGOTAj+xLybvEASi++GZelWdpOuMk8/nAoKPMbQ5NyKFy5WzlOduMldR7Awt2pwdId3akqm1i9ITG9Js+4P4nYXM8vfJCajILqi4YfhEoCNvS1EUgvlpSFE7pfNhc2W+zsfUWxWmB2SpWwX9MgQ1D4OmdKp+Eo+b6vzst3XArKMHMadPTUAk8H+ZgAnlX9yO+3vQ6z86vma/WgrG2LH6GCGXBjmKlhxVCPMLA5LeRUwEGc/Q7X/ClitGWY9umPN1XVj5e5Di1K2M082Y14mgbTTRTpv/nx7Xlph+MHnVhEWvaGMpqCHuM1W1y7wIS1IREYQ2q+K54xxZSPKYJMSnmj6A0hR/LBV0rL1uVhedEpdviduuO76qCyZrGG4HwBlW4hnIaahLzgqlvlmbDUQonAVPDgi3brVdXJgLv2zi7/ZHFW3IHgDylUVIdig0ccbzxKymlkGQ0RsLBjWOyxak2J8bN5JNVyxSwX43NZqxJ8yOv5xjB+rVMri9SX3Dl5NbFzOjynov601Pmwvb7zYnyttG2Hl5EKrkahjijGRjGy3EWEiBiArLkdTKCDHBlHxykTEvY6ZH5B9waP0CAwEAAaNQME4wHQYDVR0OBBYEFD2/Hq3IivZ5RMOKrPsM7ijIFHmMMB8GA1UdIwQYMBaAFD2/Hq3IivZ5RMOKrPsM7ijIFHmMMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAKxHWO/Q4labjnCVxYi+kaMRCPJUdHj7lga8yi8EGHaL+CbwynkaiyTfPvtmcqiuaZM9BaXsuNMRcHMtXM0EHBsjViwAHk6SrqLXd/opFvMI2QbG93koFUCpczrpyO9GvnRN4iOIYbSPXAdGOB6bkpMbm/XajORoDrua+/ET/X/1FP0GZBTmEFwojuCfOI/VuJXj0OW8XzkLmsXiLpOiakjU1obBup/1lz9DtOEBsiB9Ury+f5gZ+FnZuqhgQxeDxlZ69P6YYAfkzhcfbf7HO+nMKhppAj1BFeR4SBb+F/fLchCGO5yohwkxWz3i2q9gTDhBgo31416viyCKFWSVW3Vn7jbsjZ+Q9MK1jVSOSxC7qoQkRoNy9SKpqylunXZb+K6F3HfBkDQvn3OwsxYiSOcX9JaWpQAInNIZVg+WrJ1PXm8PFIaVPJfMgP3GOdm9vRAMjOM5Bc9iqGr2spimFd5h0GmgLvh35B3jHHWF4i3NupJQ6hUvHQZtYZOxfwxnY0/LVBTyLTVlniFA7dGSI+5Uexm+Pjh7IMGI532jTONlfNm9Bz/jdf1o0FlOclzG6Eif22gml3GM3xCUVlaElylYNAjO2lfvZuRVo5GKdMwtV9acNl0OwSx+0zbMYY2Ni3jQCI4kOL5Csctryf0rHXTlCCvnzBYVDPKmFJPna61T"), + resource.TestCheckResourceAttr(dataSourceName, "thumbprint", "42c107874fd0e4a9583292a2f1098e8fe4b2edda"), + resource.TestCheckResourceAttr(dataSourceName, "thumbprint_algorithm", "sha1"), // api now always returns this as lowercase + ), + }, + }, + }) +} + +func testAccDataSourceAzureRMBatchCertificate_basic(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "testaccbatch%d" + location = "%s" +} + +resource "azurerm_batch_account" "test" { + name = "testaccbatch%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + pool_allocation_mode = "BatchService" +} + +resource "azurerm_batch_certificate" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + certificate = "${filebase64("testdata/batch_certificate.pfx")}" + format = "Pfx" + password = "terraform" + thumbprint = "42c107874fd0e4a9583292a2f1098e8fe4b2edda" + thumbprint_algorithm = "SHA1" +} + +data "azurerm_batch_certificate" "test" { + name = "${azurerm_batch_certificate.test.name}" + account_name = "${azurerm_batch_account.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rString) +} diff --git a/azurerm/data_source_batch_pool.go b/azurerm/data_source_batch_pool.go index 32204d397570..4220998db675 100644 --- a/azurerm/data_source_batch_pool.go +++ b/azurerm/data_source_batch_pool.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -18,7 +20,7 @@ func dataSourceArmBatchPool() *schema.Resource { Required: true, ValidateFunc: azure.ValidateAzureRMBatchPoolName, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "account_name": { Type: schema.TypeString, Required: true, @@ -108,6 +110,72 @@ func dataSourceArmBatchPool() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "container_configuration": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Computed: true, + }, + "container_registries": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "registry_server": { + Type: schema.TypeString, + Computed: true, + }, + "user_name": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, + }, + }, + }, + }, + }, + "certificate": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + "store_location": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "CurrentUser", + "LocalMachine", + }, false), + }, + "store_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "visibility": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, "start_task": { Type: schema.TypeList, Optional: true, @@ -164,6 +232,39 @@ func dataSourceArmBatchPool() *schema.Resource { }, }, }, + + "resource_file": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "auto_storage_container_name": { + Type: schema.TypeString, + Computed: true, + }, + "blob_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "file_mode": { + Type: schema.TypeString, + Computed: true, + }, + "file_path": { + Type: schema.TypeString, + Computed: true, + }, + "http_url": { + Type: schema.TypeString, + Computed: true, + }, + "storage_container_url": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, }, }, }, @@ -172,7 +273,7 @@ func dataSourceArmBatchPool() *schema.Resource { } func dataSourceArmBatchPoolRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).batchPoolClient + client := meta.(*ArmClient).batch.PoolClient name := d.Get("name").(string) accountName := d.Get("account_name").(string) @@ -206,14 +307,24 @@ func dataSourceArmBatchPoolRead(d *schema.ResourceData, meta interface{}) error } } - if props.DeploymentConfiguration != nil && - props.DeploymentConfiguration.VirtualMachineConfiguration != nil && - props.DeploymentConfiguration.VirtualMachineConfiguration.ImageReference != nil { + if dcfg := props.DeploymentConfiguration; dcfg != nil { + if vmcfg := dcfg.VirtualMachineConfiguration; vmcfg != nil { + if err := d.Set("container_configuration", azure.FlattenBatchPoolContainerConfiguration(d, vmcfg.ContainerConfiguration)); err != nil { + return fmt.Errorf("error setting `container_configuration`: %v", err) + } + + if err := d.Set("storage_image_reference", azure.FlattenBatchPoolImageReference(vmcfg.ImageReference)); err != nil { + return fmt.Errorf("error setting `storage_image_reference`: %v", err) + } - imageReference := props.DeploymentConfiguration.VirtualMachineConfiguration.ImageReference + if err := d.Set("node_agent_sku_id", vmcfg.NodeAgentSkuID); err != nil { + return fmt.Errorf("error setting `node_agent_sku_id`: %v", err) + } + } + } - d.Set("storage_image_reference", azure.FlattenBatchPoolImageReference(imageReference)) - d.Set("node_agent_sku_id", props.DeploymentConfiguration.VirtualMachineConfiguration.NodeAgentSkuID) + if err := d.Set("certificate", azure.FlattenBatchPoolCertificateReferences(props.Certificates)); err != nil { + return fmt.Errorf("error setting `certificate`: %v", err) } d.Set("start_task", azure.FlattenBatchPoolStartTask(props.StartTask)) diff --git a/azurerm/data_source_batch_pool_test.go b/azurerm/data_source_batch_pool_test.go index 06cb3214d8de..d348183b63a0 100644 --- a/azurerm/data_source_batch_pool_test.go +++ b/azurerm/data_source_batch_pool_test.go @@ -29,9 +29,9 @@ func TestAccDataSourceAzureRMBatchPool_complete(t *testing.T) { resource.TestCheckResourceAttr(dataSourceName, "account_name", fmt.Sprintf("testaccbatch%s", rs)), resource.TestCheckResourceAttr(dataSourceName, "vm_size", "STANDARD_A1"), resource.TestCheckResourceAttr(dataSourceName, "storage_image_reference.#", "1"), - resource.TestCheckResourceAttr(dataSourceName, "storage_image_reference.0.publisher", "Canonical"), - resource.TestCheckResourceAttr(dataSourceName, "storage_image_reference.0.sku", "16.04.0-LTS"), - resource.TestCheckResourceAttr(dataSourceName, "storage_image_reference.0.offer", "UbuntuServer"), + resource.TestCheckResourceAttr(dataSourceName, "storage_image_reference.0.publisher", "microsoft-azure-batch"), + resource.TestCheckResourceAttr(dataSourceName, "storage_image_reference.0.sku", "16-04-lts"), + resource.TestCheckResourceAttr(dataSourceName, "storage_image_reference.0.offer", "ubuntu-server-container"), resource.TestCheckResourceAttr(dataSourceName, "fixed_scale.#", "1"), resource.TestCheckResourceAttr(dataSourceName, "fixed_scale.0.target_dedicated_nodes", "2"), resource.TestCheckResourceAttr(dataSourceName, "fixed_scale.0.resize_timeout", "PT15M"), @@ -46,6 +46,17 @@ func TestAccDataSourceAzureRMBatchPool_complete(t *testing.T) { resource.TestCheckResourceAttr(dataSourceName, "start_task.0.user_identity.0.auto_user.#", "1"), resource.TestCheckResourceAttr(dataSourceName, "start_task.0.user_identity.0.auto_user.0.scope", "Task"), resource.TestCheckResourceAttr(dataSourceName, "start_task.0.user_identity.0.auto_user.0.elevation_level", "NonAdmin"), + resource.TestCheckResourceAttr(dataSourceName, "certificate.#", "1"), + resource.TestCheckResourceAttrSet(dataSourceName, "certificate.0.id"), + resource.TestCheckResourceAttr(dataSourceName, "certificate.0.store_location", "CurrentUser"), + resource.TestCheckResourceAttr(dataSourceName, "certificate.0.store_name", ""), + resource.TestCheckResourceAttr(dataSourceName, "certificate.0.visibility.#", "2"), + resource.TestCheckResourceAttr(dataSourceName, "certificate.0.visibility.3294600504", "StartTask"), + resource.TestCheckResourceAttr(dataSourceName, "certificate.0.visibility.4077195354", "RemoteUser"), + resource.TestCheckResourceAttr(dataSourceName, "container_configuration.0.type", "DockerCompatible"), + resource.TestCheckResourceAttr(dataSourceName, "container_configuration.0.container_registries.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "container_configuration.0.container_registries.0.registry_server", "myContainerRegistry.azurecr.io"), + resource.TestCheckResourceAttr(dataSourceName, "container_configuration.0.container_registries.0.user_name", "myUserName"), ), }, }, @@ -55,7 +66,7 @@ func TestAccDataSourceAzureRMBatchPool_complete(t *testing.T) { func testAccDataSourceAzureRMBatchPool_complete(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "testaccbatch%d" + name = "testaccRG-%d-batch" location = "%s" } @@ -79,14 +90,24 @@ resource "azurerm_batch_account" "test" { } } +resource "azurerm_batch_certificate" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + certificate = "${filebase64("testdata/batch_certificate.pfx")}" + format = "Pfx" + password = "terraform" + thumbprint = "42c107874fd0e4a9583292a2f1098e8fe4b2edda" + thumbprint_algorithm = "SHA1" +} + resource "azurerm_batch_pool" "test" { - name = "testaccpool%s" - resource_group_name = "${azurerm_resource_group.test.name}" - account_name = "${azurerm_batch_account.test.name}" - display_name = "Test Acc Pool" - vm_size = "Standard_A1" - node_agent_sku_id = "batch.node.ubuntu 16.04" - max_tasks_per_node = 2 + name = "testaccpool%s" + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + display_name = "Test Acc Pool" + vm_size = "Standard_A1" + node_agent_sku_id = "batch.node.ubuntu 16.04" + max_tasks_per_node = 2 fixed_scale { target_dedicated_nodes = 2 @@ -94,12 +115,29 @@ resource "azurerm_batch_pool" "test" { } storage_image_reference { - publisher = "Canonical" - offer = "UbuntuServer" - sku = "16.04.0-LTS" + publisher = "microsoft-azure-batch" + offer = "ubuntu-server-container" + sku = "16-04-lts" version = "latest" } + certificate { + id = "${azurerm_batch_certificate.test.id}" + store_location = "CurrentUser" + visibility = ["StartTask", "RemoteUser"] + } + + container_configuration { + type = "DockerCompatible" + container_registries= [ + { + registry_server = "myContainerRegistry.azurecr.io" + user_name = "myUserName" + password = "myPassword" + }, + ] + } + start_task { command_line = "echo 'Hello World from $env'" max_task_retry_count = 1 diff --git a/azurerm/data_source_builtin_role_definition.go b/azurerm/data_source_builtin_role_definition.go index 0b6af0a8a1af..982646d4f0be 100644 --- a/azurerm/data_source_builtin_role_definition.go +++ b/azurerm/data_source_builtin_role_definition.go @@ -3,7 +3,7 @@ package azurerm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-01-01-preview/authorization" + "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-09-01-preview/authorization" "github.com/hashicorp/terraform/helper/schema" ) @@ -81,7 +81,7 @@ As such this Data Source will be removed in v2.0 of the AzureRM Provider. } func dataSourceArmBuiltInRoleDefinitionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).roleDefinitionsClient + client := meta.(*ArmClient).authorization.RoleDefinitionsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) diff --git a/azurerm/data_source_cdn_profile.go b/azurerm/data_source_cdn_profile.go index f68952c538df..816b0b5f70b3 100644 --- a/azurerm/data_source_cdn_profile.go +++ b/azurerm/data_source_cdn_profile.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -17,22 +19,22 @@ func dataSourceArmCdnProfile() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "sku": { Type: schema.TypeString, Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmCdnProfileRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).cdnProfilesClient + client := meta.(*ArmClient).cdn.ProfilesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -51,14 +53,12 @@ func dataSourceArmCdnProfileRead(d *schema.ResourceData, meta interface{}) error d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { d.Set("sku", string(sku.Name)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_client_config.go b/azurerm/data_source_client_config.go index 9b97cf5e3caa..d1ca6f8bdbda 100644 --- a/azurerm/data_source_client_config.go +++ b/azurerm/data_source_client_config.go @@ -43,7 +43,7 @@ func dataSourceArmClientConfigRead(d *schema.ResourceData, meta interface{}) err var servicePrincipal *graphrbac.ServicePrincipal if client.usingServicePrincipal { - spClient := client.servicePrincipalsClient + spClient := client.graph.ServicePrincipalsClient // Application & Service Principal is 1:1 per tenant. Since we know the appId (client_id) // here, we can query for the Service Principal whose appId matches. filter := fmt.Sprintf("appId eq '%s'", client.clientId) diff --git a/azurerm/data_source_container_registry.go b/azurerm/data_source_container_registry.go index aa1e85111a75..3e2ff2dc6d8a 100644 --- a/azurerm/data_source_container_registry.go +++ b/azurerm/data_source_container_registry.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -19,9 +21,9 @@ func dataSourceArmContainerRegistry() *schema.Resource { ValidateFunc: validateAzureRMContainerRegistryName, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "admin_enabled": { Type: schema.TypeBool, @@ -53,13 +55,13 @@ func dataSourceArmContainerRegistry() *schema.Resource { Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).containerRegistryClient + client := meta.(*ArmClient).containers.RegistriesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -78,7 +80,7 @@ func dataSourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{} d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("admin_enabled", resp.AdminUserEnabled) d.Set("login_server", resp.LoginServer) @@ -107,7 +109,5 @@ func dataSourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{} d.Set("admin_password", "") } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_cosmos_db_account.go b/azurerm/data_source_cosmos_db_account.go index a4445239bc60..1c131e50511e 100644 --- a/azurerm/data_source_cosmos_db_account.go +++ b/azurerm/data_source_cosmos_db_account.go @@ -5,14 +5,16 @@ import ( "log" "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func dataSourceArmCosmosDBAccount() *schema.Resource { +func dataSourceArmCosmosDbAccount() *schema.Resource { return &schema.Resource{ - Read: dataSourceArmCosmosDBAccountRead, + Read: dataSourceArmCosmosDbAccountRead, Schema: map[string]*schema.Schema{ "name": { @@ -20,11 +22,11 @@ func dataSourceArmCosmosDBAccount() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), "offer_type": { Type: schema.TypeString, @@ -176,8 +178,8 @@ func dataSourceArmCosmosDBAccount() *schema.Resource { } } -func dataSourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).cosmosDBClient +func dataSourceArmCosmosDbAccountRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) @@ -197,10 +199,9 @@ func dataSourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{}) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("kind", string(resp.Kind)) - flattenAndSetTags(d, resp.Tags) if props := resp.DatabaseAccountProperties; props != nil { d.Set("offer_type", string(props.DatabaseAccountOfferType)) @@ -218,7 +219,7 @@ func dataSourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{}) for _, l := range *props.FailoverPolicies { locations[*l.FailoverPriority] = map[string]interface{}{ "id": *l.ID, - "location": azureRMNormalizeLocation(*l.LocationName), + "location": azure.NormalizeLocation(*l.LocationName), "failover_priority": int(*l.FailoverPriority), } } @@ -237,18 +238,30 @@ func dataSourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{}) readEndpoints := make([]string, 0) if locations := props.ReadLocations; locations != nil { for _, l := range *locations { + if l.DocumentEndpoint == nil { + continue + } + readEndpoints = append(readEndpoints, *l.DocumentEndpoint) } } - d.Set("read_endpoints", readEndpoints) + if err := d.Set("read_endpoints", readEndpoints); err != nil { + return fmt.Errorf("Error setting `read_endpoints`: %s", err) + } writeEndpoints := make([]string, 0) if locations := props.WriteLocations; locations != nil { for _, l := range *locations { + if l.DocumentEndpoint == nil { + continue + } + writeEndpoints = append(writeEndpoints, *l.DocumentEndpoint) } } - d.Set("write_endpoints", writeEndpoints) + if err := d.Set("write_endpoints", writeEndpoints); err != nil { + return fmt.Errorf("Error setting `write_endpoints`: %s", err) + } d.Set("enable_multiple_write_locations", resp.EnableMultipleWriteLocations) } @@ -269,7 +282,7 @@ func dataSourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{}) d.Set("secondary_readonly_master_key", readonlyKeys.SecondaryReadonlyMasterKey) } - return nil + return tags.FlattenAndSet(d, resp.Tags) } func flattenAzureRmCosmosDBAccountCapabilitiesAsList(capabilities *[]documentdb.Capability) *[]map[string]interface{} { diff --git a/azurerm/data_source_data_lake_store.go b/azurerm/data_source_data_lake_store.go index 4c49094ca2a9..4da6e65e5630 100644 --- a/azurerm/data_source_data_lake_store.go +++ b/azurerm/data_source_data_lake_store.go @@ -5,6 +5,8 @@ import ( "log" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -18,9 +20,9 @@ func dataSourceArmDataLakeStoreAccount() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "tier": { Type: schema.TypeString, @@ -47,13 +49,13 @@ func dataSourceArmDataLakeStoreAccount() *schema.Resource { Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmDateLakeStoreAccountRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreAccountClient + client := meta.(*ArmClient).datalake.StoreAccountsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -74,7 +76,7 @@ func dataSourceArmDateLakeStoreAccountRead(d *schema.ResourceData, meta interfac d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if properties := resp.DataLakeStoreAccountProperties; properties != nil { @@ -89,7 +91,5 @@ func dataSourceArmDateLakeStoreAccountRead(d *schema.ResourceData, meta interfac } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_dev_test_lab.go b/azurerm/data_source_dev_test_lab.go index 2e9b4f4551d0..ab972349301d 100644 --- a/azurerm/data_source_dev_test_lab.go +++ b/azurerm/data_source_dev_test_lab.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -19,16 +21,16 @@ func dataSourceArmDevTestLab() *schema.Resource { ValidateFunc: validate.DevTestLabName(), }, - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "storage_type": { Type: schema.TypeString, Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), "artifacts_storage_account_id": { Type: schema.TypeString, @@ -64,7 +66,7 @@ func dataSourceArmDevTestLab() *schema.Resource { } func dataSourceArmDevTestLabRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestLabsClient + client := meta.(*ArmClient).devTestLabs.LabsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -84,7 +86,7 @@ func dataSourceArmDevTestLabRead(d *schema.ResourceData, meta interface{}) error d.Set("name", read.Name) d.Set("resource_group_name", resourceGroup) if location := read.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := read.LabProperties; props != nil { @@ -99,7 +101,5 @@ func dataSourceArmDevTestLabRead(d *schema.ResourceData, meta interface{}) error d.Set("unique_identifier", props.UniqueIdentifier) } - flattenAndSetTags(d, read.Tags) - - return nil + return tags.FlattenAndSet(d, read.Tags) } diff --git a/azurerm/data_source_dev_test_lab_test.go b/azurerm/data_source_dev_test_lab_test.go index fd54694e6d2a..af41c21e0b60 100644 --- a/azurerm/data_source_dev_test_lab_test.go +++ b/azurerm/data_source_dev_test_lab_test.go @@ -83,7 +83,7 @@ resource "azurerm_dev_test_lab" "test" { storage_type = "Standard" tags = { - "Hello" = "World" + Hello = "World" } } diff --git a/azurerm/data_source_dev_test_virtual_network.go b/azurerm/data_source_dev_test_virtual_network.go new file mode 100644 index 000000000000..3f4a358734f5 --- /dev/null +++ b/azurerm/data_source_dev_test_virtual_network.go @@ -0,0 +1,181 @@ +package azurerm + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmDevTestVirtualNetwork() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmDevTestVnetRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "lab_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.DevTestLabName(), + }, + + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "unique_identifier": { + Type: schema.TypeString, + Computed: true, + }, + + "allowed_subnets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "allow_public_ip": { + Type: schema.TypeString, + Computed: true, + }, + "lab_subnet_name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "subnet_overrides": { + Type: schema.TypeList, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "lab_subnet_name": { + Type: schema.TypeString, + Computed: true, + }, + "resource_id": { + Type: schema.TypeString, + Computed: true, + }, + "use_in_vm_creation_permission": { + Type: schema.TypeString, + Computed: true, + }, + "use_public_ip_address_permission": { + Type: schema.TypeString, + Computed: true, + }, + "virtual_network_pool_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceArmDevTestVnetRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestLabs.VirtualNetworksClient + ctx := meta.(*ArmClient).StopContext + + resGroup := d.Get("resource_group_name").(string) + labName := d.Get("lab_name").(string) + name := d.Get("name").(string) + + resp, err := client.Get(ctx, resGroup, labName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Error: Virtual Network %q in Dev Test Lab %q (Resource Group %q) was not found", name, labName, resGroup) + } + + return fmt.Errorf("Error making Read request on Virtual Network %q in Dev Test Lab %q (Resource Group %q): %+v", name, labName, resGroup, err) + } + + if resp.ID == nil || *resp.ID == "" { + return fmt.Errorf("API returns a nil/empty id on Virtual Network %q in Dev Test Lab %q (Resource Group %q): %+v", name, labName, resGroup, err) + } + d.SetId(*resp.ID) + + if props := resp.VirtualNetworkProperties; props != nil { + if as := props.AllowedSubnets; as != nil { + if err := d.Set("allowed_subnets", flattenDevTestVirtualNetworkAllowedSubnets(as)); err != nil { + return fmt.Errorf("error setting `allowed_subnets`: %v", err) + } + } + if so := props.SubnetOverrides; so != nil { + if err := d.Set("subnet_overrides", flattenDevTestVirtualNetworkSubnetOverrides(so)); err != nil { + return fmt.Errorf("error setting `subnet_overrides`: %v", err) + } + } + d.Set("unique_identifier", props.UniqueIdentifier) + } + return nil +} + +func flattenDevTestVirtualNetworkAllowedSubnets(input *[]dtl.Subnet) []interface{} { + result := make([]interface{}, 0) + + if input == nil { + return result + } + + for _, v := range *input { + allowedSubnet := make(map[string]interface{}) + + allowedSubnet["allow_public_ip"] = string(v.AllowPublicIP) + + if resourceID := v.ResourceID; resourceID != nil { + allowedSubnet["resource_id"] = *resourceID + } + + if labSubnetName := v.LabSubnetName; labSubnetName != nil { + allowedSubnet["lab_subnet_name"] = *labSubnetName + } + + result = append(result, allowedSubnet) + } + + return result +} + +func flattenDevTestVirtualNetworkSubnetOverrides(input *[]dtl.SubnetOverride) []interface{} { + result := make([]interface{}, 0) + + if input == nil { + return result + } + + for _, v := range *input { + subnetOverride := make(map[string]interface{}) + if v.LabSubnetName != nil { + subnetOverride["lab_subnet_name"] = *v.LabSubnetName + } + if v.ResourceID != nil { + subnetOverride["resource_id"] = *v.ResourceID + } + + subnetOverride["use_public_ip_address_permission"] = string(v.UsePublicIPAddressPermission) + subnetOverride["use_in_vm_creation_permission"] = string(v.UseInVMCreationPermission) + + if v.VirtualNetworkPoolName != nil { + subnetOverride["virtual_network_pool_name"] = *v.VirtualNetworkPoolName + } + + result = append(result, subnetOverride) + } + + return result +} diff --git a/azurerm/data_source_dev_test_virtual_network_test.go b/azurerm/data_source_dev_test_virtual_network_test.go new file mode 100644 index 000000000000..a6ebb2b0f696 --- /dev/null +++ b/azurerm/data_source_dev_test_virtual_network_test.go @@ -0,0 +1,80 @@ +package azurerm + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceArmDevTestVirtualNetwork_basic(t *testing.T) { + dataSourceName := "data.azurerm_dev_test_virtual_network.test" + ri := tf.AccRandTimeInt() + + name := fmt.Sprintf("acctestdtvn%d", ri) + labName := fmt.Sprintf("acctestdtl%d", ri) + resGroup := fmt.Sprintf("acctestRG-%d", ri) + subnetName := name + "Subnet" + subnetResourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s", os.Getenv("ARM_SUBSCRIPTION_ID"), resGroup, name, subnetName) + + config := testAccDataSourceArmDevTestVirtualNetwork_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "name", name), + resource.TestCheckResourceAttr(dataSourceName, "lab_name", labName), + resource.TestCheckResourceAttr(dataSourceName, "resource_group_name", resGroup), + resource.TestCheckResourceAttr(dataSourceName, "allowed_subnets.0.allow_public_ip", "Allow"), + resource.TestCheckResourceAttr(dataSourceName, "allowed_subnets.0.lab_subnet_name", subnetName), + resource.TestCheckResourceAttr(dataSourceName, "allowed_subnets.0.resource_id", subnetResourceID), + resource.TestCheckResourceAttr(dataSourceName, "subnet_overrides.0.lab_subnet_name", subnetName), + resource.TestCheckResourceAttr(dataSourceName, "subnet_overrides.0.resource_id", subnetResourceID), + resource.TestCheckResourceAttr(dataSourceName, "subnet_overrides.0.use_in_vm_creation_permission", "Allow"), + resource.TestCheckResourceAttr(dataSourceName, "subnet_overrides.0.use_public_ip_address_permission", "Allow"), + resource.TestCheckResourceAttr(dataSourceName, "subnet_overrides.0.virtual_network_pool_name", ""), + ), + }, + }, + }) +} + +func testAccDataSourceArmDevTestVirtualNetwork_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_dev_test_lab" "test" { + name = "acctestdtl%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_dev_test_virtual_network" "test" { + name = "acctestdtvn%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + use_public_ip_address = "Allow" + use_in_virtual_machine_creation = "Allow" + } +} + +data "azurerm_dev_test_virtual_network" "test" { + name = "${azurerm_dev_test_virtual_network.test.name}" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + + +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/data_source_dns_zone.go b/azurerm/data_source_dns_zone.go index bc12e908d7b7..33de32d82c61 100644 --- a/azurerm/data_source_dns_zone.go +++ b/azurerm/data_source_dns_zone.go @@ -7,6 +7,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -44,8 +45,9 @@ func dataSourceArmDnsZone() *schema.Resource { }, "zone_type": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Computed: true, + Deprecated: "Private DNS Zones are now supported through a separate resource in Azure & Terraform", }, "registration_virtual_network_ids": { @@ -60,13 +62,13 @@ func dataSourceArmDnsZone() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmDnsZoneRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).zonesClient + client := meta.(*ArmClient).dns.ZonesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -85,7 +87,7 @@ func dataSourceArmDnsZoneRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error reading DNS Zone %q (Resource Group %q): %+v", name, resourceGroup, err) } } else { - rgClient := meta.(*ArmClient).resourceGroupsClient + rgClient := meta.(*ArmClient).resource.GroupsClient resp, resourceGroup, err = findZone(client, rgClient, ctx, name) if err != nil { @@ -135,12 +137,10 @@ func dataSourceArmDnsZoneRead(d *schema.ResourceData, meta interface{}) error { } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } -func findZone(client dns.ZonesClient, rgClient resources.GroupsClient, ctx context.Context, name string) (dns.Zone, string, error) { +func findZone(client *dns.ZonesClient, rgClient *resources.GroupsClient, ctx context.Context, name string) (dns.Zone, string, error) { groups, err := rgClient.List(ctx, "", nil) if err != nil { return dns.Zone{}, "", fmt.Errorf("Error listing Resource Groups: %+v", err) diff --git a/azurerm/data_source_eventhub_namespace.go b/azurerm/data_source_eventhub_namespace.go index ca002984b1c2..0e2d98ecbfc4 100644 --- a/azurerm/data_source_eventhub_namespace.go +++ b/azurerm/data_source_eventhub_namespace.go @@ -5,6 +5,8 @@ import ( "log" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -18,9 +20,9 @@ func dataSourceEventHubNamespace() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "sku": { Type: schema.TypeString, @@ -71,13 +73,13 @@ func dataSourceEventHubNamespace() *schema.Resource { Sensitive: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceEventHubNamespaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubNamespacesClient + client := meta.(*ArmClient).eventhub.NamespacesClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) @@ -97,7 +99,7 @@ func dataSourceEventHubNamespaceRead(d *schema.ResourceData, meta interface{}) e d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("sku", string(resp.Sku.Name)) @@ -119,7 +121,5 @@ func dataSourceEventHubNamespaceRead(d *schema.ResourceData, meta interface{}) e d.Set("maximum_throughput_units", int(*props.MaximumThroughputUnits)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_express_route_circuit.go b/azurerm/data_source_express_route_circuit.go new file mode 100644 index 000000000000..6414941b996c --- /dev/null +++ b/azurerm/data_source_express_route_circuit.go @@ -0,0 +1,227 @@ +package azurerm + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmExpressRouteCircuit() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmExpressRouteCircuitRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "location": azure.SchemaLocationForDataSource(), + + "peerings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "peering_type": { + Type: schema.TypeString, + Computed: true, + }, + "primary_peer_address_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "secondary_peer_address_prefix": { + Type: schema.TypeString, + Computed: true, + }, + "azure_asn": { + Type: schema.TypeInt, + Computed: true, + }, + "peer_asn": { + Type: schema.TypeInt, + Computed: true, + }, + "vlan_id": { + Type: schema.TypeInt, + Computed: true, + }, + "shared_key": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "service_key": { + Type: schema.TypeString, + Computed: true, + }, + + "service_provider_properties": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "service_provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "peering_location": { + Type: schema.TypeString, + Computed: true, + }, + "bandwidth_in_mbps": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + + "service_provider_provisioning_state": { + Type: schema.TypeString, + Computed: true, + }, + + "sku": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tier": { + Type: schema.TypeString, + Computed: true, + }, + + "family": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceArmExpressRouteCircuitRead(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).network.ExpressRouteCircuitsClient + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Error: Express Route Circuit %q (Resource Group %q) was not found", name, resourceGroup) + } + return fmt.Errorf("Error making Read request on the Express Route Circuit %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*resp.ID) + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if properties := resp.ExpressRouteCircuitPropertiesFormat; properties != nil { + peerings := flattenExpressRouteCircuitPeerings(properties.Peerings) + if err := d.Set("peerings", peerings); err != nil { + return err + } + + d.Set("service_key", properties.ServiceKey) + d.Set("service_provider_provisioning_state", properties.ServiceProviderProvisioningState) + + if serviceProviderProperties := flattenExpressRouteCircuitServiceProviderProperties(properties.ServiceProviderProperties); serviceProviderProperties != nil { + if err := d.Set("service_provider_properties", serviceProviderProperties); err != nil { + return fmt.Errorf("Error setting `service_provider_properties`: %+v", err) + } + } + + } + + if resp.Sku != nil { + sku := flattenExpressRouteCircuitSku(resp.Sku) + if err := d.Set("sku", sku); err != nil { + return fmt.Errorf("Error setting `sku`: %+v", err) + } + } + + return nil +} + +func flattenExpressRouteCircuitPeerings(input *[]network.ExpressRouteCircuitPeering) []interface{} { + peerings := make([]interface{}, 0) + + if input != nil { + for _, peering := range *input { + props := peering.ExpressRouteCircuitPeeringPropertiesFormat + p := make(map[string]interface{}) + + p["peering_type"] = string(props.PeeringType) + + if primaryPeerAddressPrefix := props.PrimaryPeerAddressPrefix; primaryPeerAddressPrefix != nil { + p["primary_peer_address_prefix"] = *primaryPeerAddressPrefix + } + + if secondaryPeerAddressPrefix := props.SecondaryPeerAddressPrefix; secondaryPeerAddressPrefix != nil { + p["secondary_peer_address_prefix"] = *secondaryPeerAddressPrefix + } + + if azureAsn := props.AzureASN; azureAsn != nil { + p["azure_asn"] = *azureAsn + } + + if peerAsn := props.PeerASN; peerAsn != nil { + p["peer_asn"] = *peerAsn + } + + if vlanID := props.VlanID; vlanID != nil { + p["vlan_id"] = *vlanID + } + + if sharedKey := props.SharedKey; sharedKey != nil { + p["shared_key"] = *sharedKey + } + + peerings = append(peerings, p) + } + } + + return peerings +} + +func flattenExpressRouteCircuitServiceProviderProperties(input *network.ExpressRouteCircuitServiceProviderProperties) []interface{} { + serviceProviderProperties := make([]interface{}, 0) + + if input != nil { + p := make(map[string]interface{}) + + if serviceProviderName := input.ServiceProviderName; serviceProviderName != nil { + p["service_provider_name"] = *serviceProviderName + } + + if peeringLocation := input.PeeringLocation; peeringLocation != nil { + p["peering_location"] = *peeringLocation + } + + if bandwidthInMbps := input.BandwidthInMbps; bandwidthInMbps != nil { + p["bandwidth_in_mbps"] = *bandwidthInMbps + } + + serviceProviderProperties = append(serviceProviderProperties, p) + } + + return serviceProviderProperties +} diff --git a/azurerm/data_source_express_route_circuit_test.go b/azurerm/data_source_express_route_circuit_test.go new file mode 100644 index 000000000000..f533beaf57b6 --- /dev/null +++ b/azurerm/data_source_express_route_circuit_test.go @@ -0,0 +1,47 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func testAccDataSourceAzureRMExpressRoute_basicMetered(t *testing.T) { + dataSourceName := "data.azurerm_express_route_circuit.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMExpressRouteCircuitDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAzureRMExpressRoute_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "service_provider_properties.0.service_provider_name", "Equinix"), + resource.TestCheckResourceAttr(dataSourceName, "service_provider_properties.0.peering_location", "Silicon Valley"), + resource.TestCheckResourceAttr(dataSourceName, "service_provider_properties.0.bandwidth_in_mbps", "50"), + resource.TestCheckResourceAttr(dataSourceName, "sku.0.tier", "Standard"), + resource.TestCheckResourceAttr(dataSourceName, "sku.0.family", "MeteredData"), + resource.TestCheckResourceAttr(dataSourceName, "service_provider_provisioning_state", "NotProvisioned"), + ), + }, + }, + }) +} + +func testAccDataSourceAzureRMExpressRoute_basic(rInt int, location string) string { + config := testAccAzureRMExpressRouteCircuit_basicMeteredConfig(rInt, location) + + return fmt.Sprintf(` + %s + + data "azurerm_express_route_circuit" test { + resource_group_name = "${azurerm_resource_group.test.name}" + name = "${azurerm_express_route_circuit.test.name}" + } +`, config) +} diff --git a/azurerm/data_source_firewall.go b/azurerm/data_source_firewall.go new file mode 100644 index 000000000000..2fafb96ae980 --- /dev/null +++ b/azurerm/data_source_firewall.go @@ -0,0 +1,98 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmFirewall() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmFirewallRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureFirewallName, + }, + + "location": azure.SchemaLocationForDataSource(), + + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "ip_configuration": { + Type: schema.TypeList, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "subnet_id": { + Type: schema.TypeString, + Computed: true, + }, + "internal_public_ip_address_id": { + Type: schema.TypeString, + Computed: true, + }, + "public_ip_address_id": { + Type: schema.TypeString, + Computed: true, + }, + "private_ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "tags": tags.SchemaDataSource(), + }, + } +} + +func dataSourceArmFirewallRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.AzureFirewallsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] Firewall %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Azure Firewall %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*read.ID) + d.Set("name", read.Name) + d.Set("resource_group_name", resourceGroup) + + if location := read.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := read.AzureFirewallPropertiesFormat; props != nil { + ipConfigs := flattenArmFirewallIPConfigurations(props.IPConfigurations) + if err := d.Set("ip_configuration", ipConfigs); err != nil { + return fmt.Errorf("Error setting `ip_configuration`: %+v", err) + } + } + + return tags.FlattenAndSet(d, read.Tags) +} diff --git a/azurerm/data_source_firewall_test.go b/azurerm/data_source_firewall_test.go new file mode 100644 index 000000000000..3519fe4ec166 --- /dev/null +++ b/azurerm/data_source_firewall_test.go @@ -0,0 +1,78 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMFirewall_basic(t *testing.T) { + dataSourceName := "data.azurerm_firewall.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceFirewall_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "ip_configuration.0.name", "configuration"), + resource.TestCheckResourceAttrSet(dataSourceName, "ip_configuration.0.private_ip_address"), + ), + }, + }, + }) +} + +func testAccDataSourceFirewall_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "AzureFirewallSubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.1.0/24" +} + +resource "azurerm_public_ip" "test" { + name = "acctestpip%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_firewall" "test" { + name = "acctestfirewall%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "configuration" + subnet_id = "${azurerm_subnet.test.id}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } +} + +data "azurerm_firewall" "test" { + name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rInt, rInt, rInt) +} diff --git a/azurerm/data_source_hdinsight_cluster.go b/azurerm/data_source_hdinsight_cluster.go new file mode 100644 index 000000000000..632b4a39451d --- /dev/null +++ b/azurerm/data_source_hdinsight_cluster.go @@ -0,0 +1,156 @@ +package azurerm + +import ( + "fmt" + "log" + "strings" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmHDInsightSparkCluster() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmHDInsightClusterRead, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightDataSourceName(), + + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "location": azure.SchemaLocationForDataSource(), + + "cluster_version": { + Type: schema.TypeString, + Computed: true, + }, + + "component_versions": { + Type: schema.TypeMap, + Computed: true, + }, + + "kind": { + Type: schema.TypeString, + Computed: true, + }, + + "tier": { + Type: schema.TypeString, + Computed: true, + }, + + "gateway": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "username": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, + }, + }, + + "tags": tags.SchemaDataSource(), + + "edge_ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceArmHDInsightClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + name := d.Get("name").(string) + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Configuration for HDInsight Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*resp.ID) + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + d.Set("component_versions", flattenHDInsightsDataSourceComponentVersions(def.ComponentVersion)) + if kind := def.Kind; kind != nil { + d.Set("kind", strings.ToLower(*kind)) + } + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + } + + edgeNodeSshEndpoint := azure.FindHDInsightConnectivityEndpoint("EDGESSH", props.ConnectivityEndpoints) + d.Set("edge_ssh_endpoint", edgeNodeSshEndpoint) + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func flattenHDInsightsDataSourceComponentVersions(input map[string]*string) map[string]string { + output := make(map[string]string) + + for k, v := range input { + if v == nil { + continue + } + + output[k] = *v + } + + return output +} diff --git a/azurerm/data_source_hdinsight_cluster_test.go b/azurerm/data_source_hdinsight_cluster_test.go new file mode 100644 index 000000000000..a1b797fc7d95 --- /dev/null +++ b/azurerm/data_source_hdinsight_cluster_test.go @@ -0,0 +1,299 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMHDInsightCluster_hadoop(t *testing.T) { + dataSourceName := "data.azurerm_hdinsight_cluster.test" + rInt := tf.AccRandTimeInt() + rString := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceHDInsightCluster_hadoop(rInt, rString, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "hadoop"), + resource.TestCheckResourceAttr(dataSourceName, "tier", "standard"), + resource.TestCheckResourceAttr(dataSourceName, "edge_ssh_endpoint", ""), + resource.TestCheckResourceAttrSet(dataSourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "ssh_endpoint"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMHDInsightCluster_hbase(t *testing.T) { + dataSourceName := "data.azurerm_hdinsight_cluster.test" + rInt := tf.AccRandTimeInt() + rString := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceHDInsightCluster_hbase(rInt, rString, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "hbase"), + resource.TestCheckResourceAttr(dataSourceName, "tier", "standard"), + resource.TestCheckResourceAttr(dataSourceName, "edge_ssh_endpoint", ""), + resource.TestCheckResourceAttrSet(dataSourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "ssh_endpoint"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMHDInsightCluster_interactiveQuery(t *testing.T) { + dataSourceName := "data.azurerm_hdinsight_cluster.test" + rInt := tf.AccRandTimeInt() + rString := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceHDInsightCluster_interactiveQuery(rInt, rString, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "interactivehive"), + resource.TestCheckResourceAttr(dataSourceName, "tier", "standard"), + resource.TestCheckResourceAttr(dataSourceName, "edge_ssh_endpoint", ""), + resource.TestCheckResourceAttrSet(dataSourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "ssh_endpoint"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMHDInsightCluster_kafka(t *testing.T) { + dataSourceName := "data.azurerm_hdinsight_cluster.test" + rInt := tf.AccRandTimeInt() + rString := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceHDInsightCluster_kafka(rInt, rString, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "kafka"), + resource.TestCheckResourceAttr(dataSourceName, "tier", "standard"), + resource.TestCheckResourceAttr(dataSourceName, "edge_ssh_endpoint", ""), + resource.TestCheckResourceAttrSet(dataSourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "ssh_endpoint"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMHDInsightCluster_mlServices(t *testing.T) { + dataSourceName := "data.azurerm_hdinsight_cluster.test" + rInt := tf.AccRandTimeInt() + rString := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceHDInsightCluster_mlServices(rInt, rString, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "mlservices"), + resource.TestCheckResourceAttr(dataSourceName, "tier", "standard"), + resource.TestCheckResourceAttrSet(dataSourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "ssh_endpoint"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMHDInsightCluster_rserver(t *testing.T) { + dataSourceName := "data.azurerm_hdinsight_cluster.test" + rInt := tf.AccRandTimeInt() + rString := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceHDInsightCluster_rserver(rInt, rString, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "rserver"), + resource.TestCheckResourceAttr(dataSourceName, "tier", "standard"), + resource.TestCheckResourceAttrSet(dataSourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "ssh_endpoint"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMHDInsightCluster_spark(t *testing.T) { + dataSourceName := "data.azurerm_hdinsight_cluster.test" + rInt := tf.AccRandTimeInt() + rString := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceHDInsightCluster_spark(rInt, rString, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "spark"), + resource.TestCheckResourceAttr(dataSourceName, "tier", "standard"), + resource.TestCheckResourceAttr(dataSourceName, "edge_ssh_endpoint", ""), + resource.TestCheckResourceAttrSet(dataSourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "ssh_endpoint"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMHDInsightCluster_storm(t *testing.T) { + dataSourceName := "data.azurerm_hdinsight_cluster.test" + rInt := tf.AccRandTimeInt() + rString := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceHDInsightCluster_storm(rInt, rString, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "kind", "storm"), + resource.TestCheckResourceAttr(dataSourceName, "tier", "standard"), + resource.TestCheckResourceAttr(dataSourceName, "edge_ssh_endpoint", ""), + resource.TestCheckResourceAttrSet(dataSourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "ssh_endpoint"), + ), + }, + }, + }) +} + +func testAccDataSourceHDInsightCluster_hadoop(rInt int, rString, location string) string { + template := testAccAzureRMHDInsightHadoopCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +data "azurerm_hdinsight_cluster" "test" { + name = "${azurerm_hdinsight_hadoop_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_hadoop_cluster.test.resource_group_name}" +} +`, template) +} + +func testAccDataSourceHDInsightCluster_hbase(rInt int, rString, location string) string { + template := testAccAzureRMHDInsightHBaseCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +data "azurerm_hdinsight_cluster" "test" { + name = "${azurerm_hdinsight_hbase_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_hbase_cluster.test.resource_group_name}" +} +`, template) +} + +func testAccDataSourceHDInsightCluster_interactiveQuery(rInt int, rString, location string) string { + template := testAccAzureRMHDInsightInteractiveQueryCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +data "azurerm_hdinsight_cluster" "test" { + name = "${azurerm_hdinsight_interactive_query_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_interactive_query_cluster.test.resource_group_name}" +} +`, template) +} + +func testAccDataSourceHDInsightCluster_kafka(rInt int, rString, location string) string { + template := testAccAzureRMHDInsightKafkaCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +data "azurerm_hdinsight_cluster" "test" { + name = "${azurerm_hdinsight_kafka_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_kafka_cluster.test.resource_group_name}" +} +`, template) +} + +func testAccDataSourceHDInsightCluster_mlServices(rInt int, rString, location string) string { + template := testAccAzureRMHDInsightMLServicesCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +data "azurerm_hdinsight_cluster" "test" { + name = "${azurerm_hdinsight_ml_services_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_ml_services_cluster.test.resource_group_name}" +} +`, template) +} + +func testAccDataSourceHDInsightCluster_rserver(rInt int, rString, location string) string { + template := testAccAzureRMHDInsightRServerCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +data "azurerm_hdinsight_cluster" "test" { + name = "${azurerm_hdinsight_rserver_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_rserver_cluster.test.resource_group_name}" +} +`, template) +} + +func testAccDataSourceHDInsightCluster_spark(rInt int, rString, location string) string { + template := testAccAzureRMHDInsightSparkCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +data "azurerm_hdinsight_cluster" "test" { + name = "${azurerm_hdinsight_spark_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_spark_cluster.test.resource_group_name}" +} +`, template) +} + +func testAccDataSourceHDInsightCluster_storm(rInt int, rString, location string) string { + template := testAccAzureRMHDInsightStormCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +data "azurerm_hdinsight_cluster" "test" { + name = "${azurerm_hdinsight_storm_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_storm_cluster.test.resource_group_name}" +} +`, template) +} diff --git a/azurerm/data_source_image.go b/azurerm/data_source_image.go index 3c2f7e2c9640..c35f29bef7b7 100644 --- a/azurerm/data_source_image.go +++ b/azurerm/data_source_image.go @@ -9,6 +9,8 @@ import ( "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,9 +38,14 @@ func dataSourceArmImage() *schema.Resource { ConflictsWith: []string{"name_regex"}, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), + + "zone_resilient": { + Type: schema.TypeBool, + Computed: true, + }, "os_disk": { Type: schema.TypeList, @@ -102,13 +109,13 @@ func dataSourceArmImage() *schema.Resource { }, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmImageRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).imageClient + client := meta.(*ArmClient).compute.ImagesClient ctx := meta.(*ArmClient).StopContext resGroup := d.Get("resource_group_name").(string) @@ -137,7 +144,7 @@ func dataSourceArmImageRead(d *schema.ResourceData, meta interface{}) error { resp, err := client.ListByResourceGroupComplete(ctx, resGroup) if err != nil { if utils.ResponseWasNotFound(resp.Response().Response) { - return fmt.Errorf("Error: Image %q (Resource Group %q) was not found", name, resGroup) + return fmt.Errorf("Error: Unable to list images for Resource Group %q", resGroup) } return fmt.Errorf("[ERROR] Error getting list of images (resource group %q): %+v", resGroup, err) } @@ -176,7 +183,7 @@ func dataSourceArmImageRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", img.Name) d.Set("resource_group_name", resGroup) if location := img.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if profile := img.StorageProfile; profile != nil { @@ -191,9 +198,9 @@ func dataSourceArmImageRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("[DEBUG] Error setting AzureRM Image Data Disks error: %+v", err) } } - } - flattenAndSetTags(d, img.Tags) + d.Set("zone_resilient", profile.ZoneResilient) + } - return nil + return tags.FlattenAndSet(d, img.Tags) } diff --git a/azurerm/data_source_image_test.go b/azurerm/data_source_image_test.go index e33945e10393..89b93f8c7dc5 100644 --- a/azurerm/data_source_image_test.go +++ b/azurerm/data_source_image_test.go @@ -334,13 +334,13 @@ resource "azurerm_image" "def" { data "azurerm_image" "test1" { name_regex = "^def-acctest-\\d+" - resource_group_name = "${azurerm_resource_group.test.name}${substr(azurerm_image.abc.name, 0, 0)}${substr(azurerm_image.def.name, 0, 0)}" + resource_group_name = "${azurerm_resource_group.test.name}" } data "azurerm_image" "test2" { name_regex = "^[a-z]+-acctest-\\d+" sort_descending = true - resource_group_name = "${azurerm_resource_group.test.name}${substr(azurerm_image.abc.name, 0, 0)}${substr(azurerm_image.def.name, 0, 0)}" + resource_group_name = "${azurerm_resource_group.test.name}" } output "location" { diff --git a/azurerm/data_source_key_vault.go b/azurerm/data_source_key_vault.go index 5bbcae0df4e1..b860cd153883 100644 --- a/azurerm/data_source_key_vault.go +++ b/azurerm/data_source_key_vault.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -22,10 +23,11 @@ func dataSourceArmKeyVault() *schema.Resource { ValidateFunc: validateKeyVaultName, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), + // Remove in 2.0 "sku": { Type: schema.TypeList, Computed: true, @@ -39,6 +41,11 @@ func dataSourceArmKeyVault() *schema.Resource { }, }, + "sku_name": { + Type: schema.TypeString, + Computed: true, + }, + "vault_uri": { Type: schema.TypeString, Computed: true, @@ -87,6 +94,13 @@ func dataSourceArmKeyVault() *schema.Resource { Type: schema.TypeString, }, }, + "storage_permissions": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, }, }, }, @@ -135,13 +149,13 @@ func dataSourceArmKeyVault() *schema.Resource { }, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).keyVaultClient + client := meta.(*ArmClient).keyvault.VaultsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -160,7 +174,7 @@ func dataSourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.Properties; props != nil { @@ -170,8 +184,17 @@ func dataSourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { d.Set("enabled_for_template_deployment", props.EnabledForTemplateDeployment) d.Set("vault_uri", props.VaultURI) - if err := d.Set("sku", flattenKeyVaultDataSourceSku(props.Sku)); err != nil { - return fmt.Errorf("Error setting `sku` for KeyVault %q: %+v", *resp.Name, err) + if sku := props.Sku; sku != nil { + // Remove in 2.0 + if err := d.Set("sku", flattenKeyVaultDataSourceSku(sku)); err != nil { + return fmt.Errorf("Error setting `sku` for KeyVault %q: %+v", *resp.Name, err) + } + + if err := d.Set("sku_name", string(sku.Name)); err != nil { + return fmt.Errorf("Error setting `sku_name` for KeyVault %q: %+v", *resp.Name, err) + } + } else { + return fmt.Errorf("Error making Read request on KeyVault %q: Unable to retrieve 'sku' value", *resp.Name) } flattenedPolicies := azure.FlattenKeyVaultAccessPolicies(props.AccessPolicies) @@ -184,11 +207,10 @@ func dataSourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } +// Remove in 2.0 func flattenKeyVaultDataSourceSku(sku *keyvault.Sku) []interface{} { result := map[string]interface{}{ "name": string(sku.Name), diff --git a/azurerm/data_source_key_vault_key.go b/azurerm/data_source_key_vault_key.go index f7b39e9d16be..29255402df6a 100644 --- a/azurerm/data_source_key_vault_key.go +++ b/azurerm/data_source_key_vault_key.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -73,14 +74,14 @@ func dataSourceArmKeyVaultKey() *schema.Resource { Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmKeyVaultKeyRead(d *schema.ResourceData, meta interface{}) error { - vaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + vaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext keyVaultBaseUri := d.Get("vault_uri").(string) @@ -140,9 +141,7 @@ func dataSourceArmKeyVaultKeyRead(d *schema.ResourceData, meta interface{}) erro d.Set("version", parsedId.Version) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func flattenKeyVaultKeyDataSourceOptions(input *[]string) []interface{} { diff --git a/azurerm/data_source_key_vault_secret.go b/azurerm/data_source_key_vault_secret.go index 98ab090d01ca..b03d2177e674 100644 --- a/azurerm/data_source_key_vault_secret.go +++ b/azurerm/data_source_key_vault_secret.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -57,14 +58,14 @@ func dataSourceArmKeyVaultSecret() *schema.Resource { Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmKeyVaultSecretRead(d *schema.ResourceData, meta interface{}) error { - vaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + vaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -118,6 +119,5 @@ func dataSourceArmKeyVaultSecretRead(d *schema.ResourceData, meta interface{}) e d.Set("version", respID.Version) d.Set("content_type", resp.ContentType) - flattenAndSetTags(d, resp.Tags) - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_key_vault_test.go b/azurerm/data_source_key_vault_test.go index be6e9f587667..288273fe631e 100644 --- a/azurerm/data_source_key_vault_test.go +++ b/azurerm/data_source_key_vault_test.go @@ -14,6 +14,34 @@ func TestAccDataSourceAzureRMKeyVault_basic(t *testing.T) { location := testLocation() config := testAccDataSourceAzureRMKeyVault_basic(ri, location) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "tenant_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "sku_name"), + resource.TestCheckResourceAttrSet(dataSourceName, "access_policy.0.tenant_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "access_policy.0.object_id"), + resource.TestCheckResourceAttr(dataSourceName, "access_policy.0.key_permissions.0", "create"), + resource.TestCheckResourceAttr(dataSourceName, "access_policy.0.secret_permissions.0", "set"), + resource.TestCheckResourceAttr(dataSourceName, "tags.%", "0"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMKeyVault_basicClassic(t *testing.T) { + dataSourceName := "data.azurerm_key_vault.test" + ri := tf.AccRandTimeInt() + location := testLocation() + config := testAccDataSourceAzureRMKeyVault_basic(ri, location) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, diff --git a/azurerm/data_source_kubernetes_cluster.go b/azurerm/data_source_kubernetes_cluster.go index 37fc2193f0ab..5b3a00bd3e43 100644 --- a/azurerm/data_source_kubernetes_cluster.go +++ b/azurerm/data_source_kubernetes_cluster.go @@ -4,9 +4,11 @@ import ( "fmt" "strings" - "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2018-03-31/containerservice" + "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2019-06-01/containerservice" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/kubernetes" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -20,9 +22,9 @@ func dataSourceArmKubernetesCluster() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "addon_profile": { Type: schema.TypeList, @@ -62,6 +64,19 @@ func dataSourceArmKubernetesCluster() *schema.Resource { }, }, }, + + "kube_dashboard": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, }, }, }, @@ -76,11 +91,39 @@ func dataSourceArmKubernetesCluster() *schema.Resource { Computed: true, }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "count": { Type: schema.TypeInt, Computed: true, }, + "max_count": { + Type: schema.TypeInt, + Computed: true, + }, + + "min_count": { + Type: schema.TypeInt, + Computed: true, + }, + + "enable_auto_scaling": { + Type: schema.TypeBool, + Computed: true, + }, + + "availability_zones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + // TODO: remove this in a future version "dns_prefix": { Type: schema.TypeString, @@ -112,6 +155,12 @@ func dataSourceArmKubernetesCluster() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + + "node_taints": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, }, }, @@ -239,6 +288,19 @@ func dataSourceArmKubernetesCluster() *schema.Resource { }, }, + "windows_profile": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "admin_username": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "network_profile": { Type: schema.TypeList, Computed: true, @@ -249,6 +311,11 @@ func dataSourceArmKubernetesCluster() *schema.Resource { Computed: true, }, + "network_policy": { + Type: schema.TypeString, + Computed: true, + }, + "service_cidr": { Type: schema.TypeString, Computed: true, @@ -268,6 +335,11 @@ func dataSourceArmKubernetesCluster() *schema.Resource { Type: schema.TypeString, Computed: true, }, + + "load_balancer_sku": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, @@ -325,13 +397,13 @@ func dataSourceArmKubernetesCluster() *schema.Resource { }, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).kubernetesClustersClient + client := meta.(*ArmClient).containers.KubernetesClustersClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -356,7 +428,7 @@ func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{} d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.ManagedClusterProperties; props != nil { @@ -380,6 +452,11 @@ func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{} return fmt.Errorf("Error setting `linux_profile`: %+v", err) } + windowsProfile := flattenKubernetesClusterDataSourceWindowsProfile(props.WindowsProfile) + if err := d.Set("windows_profile", windowsProfile); err != nil { + return fmt.Errorf("Error setting `windows_profile`: %+v", err) + } + networkProfile := flattenKubernetesClusterDataSourceNetworkProfile(props.NetworkProfile) if err := d.Set("network_profile", networkProfile); err != nil { return fmt.Errorf("Error setting `network_profile`: %+v", err) @@ -419,9 +496,7 @@ func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{} return fmt.Errorf("Error setting `kube_config`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func flattenKubernetesClusterDataSourceRoleBasedAccessControl(input *containerservice.ManagedClusterProperties) []interface{} { @@ -533,6 +608,20 @@ func flattenKubernetesClusterDataSourceAddonProfiles(profile map[string]*contain } values["oms_agent"] = agents + kubeDashboards := make([]interface{}, 0) + if kubeDashboard := profile["kubeDashboard"]; kubeDashboard != nil { + enabled := false + if enabledVal := kubeDashboard.Enabled; enabledVal != nil { + enabled = *enabledVal + } + + output := map[string]interface{}{ + "enabled": enabled, + } + kubeDashboards = append(kubeDashboards, output) + } + values["kube_dashboard"] = kubeDashboards + return []interface{}{values} } @@ -546,10 +635,28 @@ func flattenKubernetesClusterDataSourceAgentPoolProfiles(input *[]containerservi for _, profile := range *input { agentPoolProfile := make(map[string]interface{}) + if profile.Type != "" { + agentPoolProfile["type"] = string(profile.Type) + } + if profile.Count != nil { agentPoolProfile["count"] = int(*profile.Count) } + if profile.MinCount != nil { + agentPoolProfile["min_count"] = int(*profile.MinCount) + } + + if profile.MaxCount != nil { + agentPoolProfile["max_count"] = int(*profile.MaxCount) + } + + if profile.EnableAutoScaling != nil { + agentPoolProfile["enable_auto_scaling"] = *profile.EnableAutoScaling + } + + agentPoolProfile["availability_zones"] = utils.FlattenStringSlice(profile.AvailabilityZones) + if profile.Name != nil { agentPoolProfile["name"] = *profile.Name } @@ -574,6 +681,10 @@ func flattenKubernetesClusterDataSourceAgentPoolProfiles(input *[]containerservi agentPoolProfile["max_pods"] = int(*profile.MaxPods) } + if profile.NodeTaints != nil { + agentPoolProfile["node_taints"] = *profile.NodeTaints + } + agentPoolProfiles = append(agentPoolProfiles, agentPoolProfile) } @@ -607,11 +718,28 @@ func flattenKubernetesClusterDataSourceLinuxProfile(input *containerservice.Linu return []interface{}{values} } -func flattenKubernetesClusterDataSourceNetworkProfile(profile *containerservice.NetworkProfile) []interface{} { +func flattenKubernetesClusterDataSourceWindowsProfile(input *containerservice.ManagedClusterWindowsProfile) []interface{} { + if input == nil { + return []interface{}{} + } + values := make(map[string]interface{}) + + if username := input.AdminUsername; username != nil { + values["admin_username"] = *username + } + + return []interface{}{values} +} + +func flattenKubernetesClusterDataSourceNetworkProfile(profile *containerservice.NetworkProfileType) []interface{} { values := make(map[string]interface{}) values["network_plugin"] = profile.NetworkPlugin + if profile.NetworkPolicy != "" { + values["network_policy"] = string(profile.NetworkPolicy) + } + if profile.ServiceCidr != nil { values["service_cidr"] = *profile.ServiceCidr } @@ -628,6 +756,10 @@ func flattenKubernetesClusterDataSourceNetworkProfile(profile *containerservice. values["pod_cidr"] = *profile.PodCidr } + if profile.LoadBalancerSku != "" { + values["load_balancer_sku"] = string(profile.LoadBalancerSku) + } + return []interface{}{values} } diff --git a/azurerm/data_source_kubernetes_cluster_test.go b/azurerm/data_source_kubernetes_cluster_test.go index d50f23674c71..bfef2b5d7904 100644 --- a/azurerm/data_source_kubernetes_cluster_test.go +++ b/azurerm/data_source_kubernetes_cluster_test.go @@ -152,6 +152,67 @@ func TestAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzure(t *testin }, }) } +func TestAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureCalicoPolicy(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + location := testLocation() + config := testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureCalicoPolicy(ri, clientId, clientSecret, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "agent_pool_profile.0.vnet_subnet_id"), + resource.TestCheckResourceAttr(dataSourceName, "network_profile.0.network_plugin", "azure"), + resource.TestCheckResourceAttr(dataSourceName, "network_profile.0.network_policy", "calico"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.network_plugin"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.network_policy"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.dns_service_ip"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.docker_bridge_cidr"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.service_cidr"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureNPMPolicy(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + location := testLocation() + config := testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureNPMPolicy(ri, clientId, clientSecret, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "agent_pool_profile.0.vnet_subnet_id"), + resource.TestCheckResourceAttr(dataSourceName, "network_profile.0.network_plugin", "azure"), + resource.TestCheckResourceAttr(dataSourceName, "network_profile.0.network_policy", "azure"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.network_plugin"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.network_policy"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.dns_service_ip"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.docker_bridge_cidr"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.service_cidr"), + ), + }, + }, + }) +} func TestAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureComplete(t *testing.T) { dataSourceName := "data.azurerm_kubernetes_cluster.test" @@ -182,6 +243,68 @@ func TestAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureComplete(t }) } +func TestAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureCalicoPolicyComplete(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + location := testLocation() + config := testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureCalicoPolicyComplete(ri, clientId, clientSecret, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "agent_pool_profile.0.vnet_subnet_id"), + resource.TestCheckResourceAttr(dataSourceName, "network_profile.0.network_plugin", "azure"), + resource.TestCheckResourceAttr(dataSourceName, "network_profile.0.network_policy", "calico"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.network_plugin"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.network_policy"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.dns_service_ip"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.docker_bridge_cidr"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.service_cidr"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureNPMPolicyComplete(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + location := testLocation() + config := testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureNPMPolicyComplete(ri, clientId, clientSecret, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "agent_pool_profile.0.vnet_subnet_id"), + resource.TestCheckResourceAttr(dataSourceName, "network_profile.0.network_plugin", "azure"), + resource.TestCheckResourceAttr(dataSourceName, "network_profile.0.network_policy", "azure"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.network_plugin"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.network_policy"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.dns_service_ip"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.docker_bridge_cidr"), + resource.TestCheckResourceAttrSet(dataSourceName, "network_profile.0.service_cidr"), + ), + }, + }, + }) +} + func TestAccDataSourceAzureRMKubernetesCluster_advancedNetworkingKubenet(t *testing.T) { dataSourceName := "data.azurerm_kubernetes_cluster.test" ri := tf.AccRandTimeInt() @@ -267,6 +390,32 @@ func TestAccDataSourceAzureRMKubernetesCluster_addOnProfileOMS(t *testing.T) { }) } +func TestAccDataSourceAzureRMKubernetesCluster_addOnProfileKubeDashboard(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + location := testLocation() + config := testAccDataSourceAzureRMKubernetesCluster_addOnProfileKubeDashboard(ri, clientId, clientSecret, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(dataSourceName), + resource.TestCheckResourceAttr(dataSourceName, "addon_profile.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "addon_profile.0.kube_dashboard.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "addon_profile.0.kube_dashboard.0.enabled", "false"), + ), + }, + }, + }) +} + func TestAccDataSourceAzureRMKubernetesCluster_addOnProfileRouting(t *testing.T) { dataSourceName := "data.azurerm_kubernetes_cluster.test" ri := tf.AccRandTimeInt() @@ -294,6 +443,88 @@ func TestAccDataSourceAzureRMKubernetesCluster_addOnProfileRouting(t *testing.T) }) } +func TestAccDataSourceAzureRMKubernetesCluster_autoscalingNoAvailabilityZones(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + + config := testAccDataSourceAzureRMKubernetesCluster_autoScalingNoAvailabilityZones(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(dataSourceName), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.min_count", "1"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.max_count", "2"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.type", "VirtualMachineScaleSets"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.enable_auto_scaling", "true"), + resource.TestCheckNoResourceAttr(dataSourceName, "agent_pool_profile.0.availability_zones"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMKubernetesCluster_autoscalingWithAvailabilityZones(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + + config := testAccDataSourceAzureRMKubernetesCluster_autoScalingWithAvailabilityZones(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(dataSourceName), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.min_count", "1"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.max_count", "2"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.type", "VirtualMachineScaleSets"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.enable_auto_scaling", "true"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.availability_zones.#", "2"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.availability_zones.0", "1"), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.0.availability_zones.1", "2"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMKubernetesCluster_nodeTaints(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + + config := testAccDataSourceAzureRMKubernetesCluster_nodeTaints(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(dataSourceName), + resource.TestCheckResourceAttr(dataSourceName, "agent_pool_profile.1.node_taints.0", "key=value:NoSchedule"), + ), + }, + }, + }) +} + func testAccDataSourceAzureRMKubernetesCluster_basic(rInt int, clientId string, clientSecret string, location string) string { r := testAccAzureRMKubernetesCluster_basic(rInt, clientId, clientSecret, location) return fmt.Sprintf(` @@ -354,6 +585,30 @@ data "azurerm_kubernetes_cluster" "test" { `, r) } +func testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureCalicoPolicy(rInt int, clientId string, clientSecret string, location string) string { + r := testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicy(rInt, clientId, clientSecret, location, "azure", "calico") + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = "${azurerm_kubernetes_cluster.test.name}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" +} +`, r) +} + +func testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureNPMPolicy(rInt int, clientId string, clientSecret string, location string) string { + r := testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicy(rInt, clientId, clientSecret, location, "azure", "azure") + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = "${azurerm_kubernetes_cluster.test.name}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" +} +`, r) +} + func testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureComplete(rInt int, clientId string, clientSecret string, location string) string { r := testAccAzureRMKubernetesCluster_advancedNetworkingComplete(rInt, clientId, clientSecret, location, "azure") return fmt.Sprintf(` @@ -366,6 +621,30 @@ data "azurerm_kubernetes_cluster" "test" { `, r) } +func testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureCalicoPolicyComplete(rInt int, clientId string, clientSecret string, location string) string { + r := testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicyComplete(rInt, clientId, clientSecret, location, "azure", "calico") + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = "${azurerm_kubernetes_cluster.test.name}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" +} +`, r) +} + +func testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingAzureNPMPolicyComplete(rInt int, clientId string, clientSecret string, location string) string { + r := testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicyComplete(rInt, clientId, clientSecret, location, "azure", "azure") + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = "${azurerm_kubernetes_cluster.test.name}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" +} +`, r) +} + func testAccDataSourceAzureRMKubernetesCluster_advancedNetworkingKubenet(rInt int, clientId string, clientSecret string, location string) string { r := testAccAzureRMKubernetesCluster_advancedNetworking(rInt, clientId, clientSecret, location, "kubenet") return fmt.Sprintf(` @@ -402,6 +681,18 @@ data "azurerm_kubernetes_cluster" "test" { `, r) } +func testAccDataSourceAzureRMKubernetesCluster_addOnProfileKubeDashboard(rInt int, clientId string, clientSecret string, location string) string { + r := testAccAzureRMKubernetesCluster_addonProfileKubeDashboard(rInt, clientId, clientSecret, location) + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = "${azurerm_kubernetes_cluster.test.name}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" +} +`, r) +} + func testAccDataSourceAzureRMKubernetesCluster_addOnProfileRouting(rInt int, clientId string, clientSecret string, location string) string { r := testAccAzureRMKubernetesCluster_addonProfileRouting(rInt, clientId, clientSecret, location) return fmt.Sprintf(` @@ -413,3 +704,39 @@ data "azurerm_kubernetes_cluster" "test" { } `, r) } + +func testAccDataSourceAzureRMKubernetesCluster_autoScalingNoAvailabilityZones(rInt int, clientId string, clientSecret string, location string) string { + r := testAccAzureRMKubernetesCluster_autoscaleNoAvailabilityZones(rInt, clientId, clientSecret, location) + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = "${azurerm_kubernetes_cluster.test.name}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" +} +`, r) +} + +func testAccDataSourceAzureRMKubernetesCluster_autoScalingWithAvailabilityZones(rInt int, clientId string, clientSecret string, location string) string { + r := testAccAzureRMKubernetesCluster_autoscaleWithAvailabilityZones(rInt, clientId, clientSecret, location) + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = "${azurerm_kubernetes_cluster.test.name}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" +} +`, r) +} + +func testAccDataSourceAzureRMKubernetesCluster_nodeTaints(rInt int, clientId string, clientSecret string, location string) string { + r := testAccAzureRMKubernetesCluster_nodeTaints(rInt, clientId, clientSecret, location) + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = "${azurerm_kubernetes_cluster.test.name}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" +} +`, r) +} diff --git a/azurerm/data_source_kubernetes_service_version.go b/azurerm/data_source_kubernetes_service_version.go new file mode 100644 index 000000000000..5b837b1ee192 --- /dev/null +++ b/azurerm/data_source_kubernetes_service_version.go @@ -0,0 +1,101 @@ +package azurerm + +import ( + "fmt" + "log" + "strings" + + "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmKubernetesServiceVersions() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmKubernetesServiceVersionsRead, + + Schema: map[string]*schema.Schema{ + "location": azure.SchemaLocation(), + + "version_prefix": { + Type: schema.TypeString, + Optional: true, + }, + + "versions": { + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + }, + + "latest_version": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceArmKubernetesServiceVersionsRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).containers.ServicesClient + ctx := meta.(*ArmClient).StopContext + + location := azure.NormalizeLocation(d.Get("location").(string)) + + listResp, err := client.ListOrchestrators(ctx, location, "managedClusters") + if err != nil { + if utils.ResponseWasNotFound(listResp.Response) { + return fmt.Errorf("Error: No Kubernetes Service versions found for location %q", location) + } + return fmt.Errorf("Error retrieving Kubernetes Versions in %q: %+v", location, err) + } + + lv, err := version.NewVersion("0.0.0") + if err != nil { + return fmt.Errorf("Cannot set version baseline (likely an issue in go-version): %+v", err) + } + + var versions []string + versionPrefix := d.Get("version_prefix").(string) + + if props := listResp.OrchestratorVersionProfileProperties; props != nil { + if orchestrators := props.Orchestrators; orchestrators != nil { + for _, rawV := range *orchestrators { + if rawV.OrchestratorType == nil || rawV.OrchestratorVersion == nil { + continue + } + + orchestratorType := *rawV.OrchestratorType + kubeVersion := *rawV.OrchestratorVersion + + if !strings.EqualFold(orchestratorType, "Kubernetes") { + log.Printf("[DEBUG] Orchestrator %q was not Kubernetes", orchestratorType) + continue + } + + if versionPrefix != "" && !strings.HasPrefix(kubeVersion, versionPrefix) { + log.Printf("[DEBUG] Version %q doesn't match the prefix %q", kubeVersion, versionPrefix) + continue + } + + versions = append(versions, kubeVersion) + v, err := version.NewVersion(kubeVersion) + if err != nil { + log.Printf("[WARN] Cannot parse orchestrator version %q - skipping: %s", kubeVersion, err) + continue + } + + if v.GreaterThan(lv) { + lv = v + } + } + } + } + + d.SetId(*listResp.ID) + d.Set("versions", versions) + d.Set("latest_version", lv.Original()) + + return nil +} diff --git a/azurerm/data_source_kubernetes_service_version_test.go b/azurerm/data_source_kubernetes_service_version_test.go new file mode 100644 index 000000000000..e9b7201a2a53 --- /dev/null +++ b/azurerm/data_source_kubernetes_service_version_test.go @@ -0,0 +1,72 @@ +package azurerm + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +const k8sVersionRX = `[0-9]+\.[0-9]+\.[0-9]*` + +func TestAccDataSourceAzureRMKubernetesServiceVersions_basic(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_service_versions.test" + location := testLocation() + kvrx := regexp.MustCompile(k8sVersionRX) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAzureRMKubernetesServiceVersions_basic(location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(dataSourceName, "versions.#"), + resource.TestMatchResourceAttr(dataSourceName, "versions.0", kvrx), + resource.TestCheckResourceAttrSet(dataSourceName, "latest_version"), + resource.TestMatchResourceAttr(dataSourceName, "latest_version", kvrx), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMKubernetesServiceVersions_filtered(t *testing.T) { + dataSourceName := "data.azurerm_kubernetes_service_versions.test" + location := testLocation() + kvrx := regexp.MustCompile(k8sVersionRX) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAzureRMKubernetesServiceVersions_filtered(location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(dataSourceName, "versions.#"), + resource.TestMatchResourceAttr(dataSourceName, "versions.0", kvrx), + resource.TestCheckResourceAttrSet(dataSourceName, "latest_version"), + resource.TestMatchResourceAttr(dataSourceName, "latest_version", kvrx), + ), + }, + }, + }) +} + +func testAccDataSourceAzureRMKubernetesServiceVersions_basic(location string) string { + return fmt.Sprintf(` +data "azurerm_kubernetes_service_versions" "test" { + location = "%s" +} +`, location) +} + +func testAccDataSourceAzureRMKubernetesServiceVersions_filtered(location string) string { + return fmt.Sprintf(` +data "azurerm_kubernetes_service_versions" "test" { + location = "%s" + version_prefix = "1." +} +`, location) +} diff --git a/azurerm/data_source_loadbalancer.go b/azurerm/data_source_loadbalancer.go index 4ae9bf793e3d..ee1c465dcd22 100644 --- a/azurerm/data_source_loadbalancer.go +++ b/azurerm/data_source_loadbalancer.go @@ -3,9 +3,11 @@ package azurerm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -21,9 +23,9 @@ func dataSourceArmLoadBalancer() *schema.Resource { ValidateFunc: validation.NoZeroValues, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "sku": { Type: schema.TypeString, @@ -60,7 +62,7 @@ func dataSourceArmLoadBalancer() *schema.Resource { Computed: true, }, - "zones": zonesSchemaComputed(), + "zones": azure.SchemaZonesComputed(), }, }, }, @@ -78,7 +80,7 @@ func dataSourceArmLoadBalancer() *schema.Resource { }, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } @@ -87,7 +89,7 @@ func dataSourceArmLoadBalancerRead(d *schema.ResourceData, meta interface{}) err name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name, "") @@ -102,7 +104,7 @@ func dataSourceArmLoadBalancerRead(d *schema.ResourceData, meta interface{}) err d.SetId(*resp.ID) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { @@ -134,9 +136,7 @@ func dataSourceArmLoadBalancerRead(d *schema.ResourceData, meta interface{}) err } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func flattenLoadBalancerDataSourceFrontendIpConfiguration(ipConfigs *[]network.FrontendIPConfiguration) []interface{} { diff --git a/azurerm/data_source_log_analytics_workspace.go b/azurerm/data_source_log_analytics_workspace.go index 0604ac864fc0..bdceb89a77d0 100644 --- a/azurerm/data_source_log_analytics_workspace.go +++ b/azurerm/data_source_log_analytics_workspace.go @@ -5,6 +5,8 @@ import ( "log" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -17,9 +19,9 @@ func dataSourceLogAnalyticsWorkspace() *schema.Resource { Required: true, }, - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "sku": { Type: schema.TypeString, @@ -53,14 +55,14 @@ func dataSourceLogAnalyticsWorkspace() *schema.Resource { Sensitive: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceLogAnalyticsWorkspaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).workspacesClient + client := meta.(*ArmClient).logAnalytics.WorkspacesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -79,7 +81,7 @@ func dataSourceLogAnalyticsWorkspaceRead(d *schema.ResourceData, meta interface{ d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("workspace_id", resp.CustomerID) @@ -97,6 +99,5 @@ func dataSourceLogAnalyticsWorkspaceRead(d *schema.ResourceData, meta interface{ d.Set("secondary_shared_key", sharedKeys.SecondarySharedKey) } - flattenAndSetTags(d, resp.Tags) - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_logic_app_workflow.go b/azurerm/data_source_logic_app_workflow.go index e5fff8f414b8..d638e3136225 100644 --- a/azurerm/data_source_logic_app_workflow.go +++ b/azurerm/data_source_logic_app_workflow.go @@ -6,6 +6,8 @@ import ( "github.com/Azure/azure-sdk-for-go/services/logic/mgmt/2016-06-01/logic" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -19,9 +21,9 @@ func dataSourceArmLogicAppWorkflow() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), // TODO: should Parameters be split out into their own object to allow validation on the different sub-types? "parameters": { @@ -39,7 +41,7 @@ func dataSourceArmLogicAppWorkflow() *schema.Resource { Computed: true, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), "access_endpoint": { Type: schema.TypeString, @@ -49,7 +51,7 @@ func dataSourceArmLogicAppWorkflow() *schema.Resource { } } func dataSourceArmLogicAppWorkflowRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).logicWorkflowsClient + client := meta.(*ArmClient).logic.WorkflowsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -67,7 +69,7 @@ func dataSourceArmLogicAppWorkflowRead(d *schema.ResourceData, meta interface{}) d.SetId(*resp.ID) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.WorkflowProperties; props != nil { @@ -86,9 +88,7 @@ func dataSourceArmLogicAppWorkflowRead(d *schema.ResourceData, meta interface{}) } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func flattenLogicAppDataSourceWorkflowParameters(input map[string]*logic.WorkflowParameter) map[string]interface{} { diff --git a/azurerm/data_source_managed_disk.go b/azurerm/data_source_managed_disk.go index 5b895d978e1b..58c0fcd9fb12 100644 --- a/azurerm/data_source_managed_disk.go +++ b/azurerm/data_source_managed_disk.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -17,9 +19,9 @@ func dataSourceArmManagedDisk() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "zones": zonesSchemaComputed(), + "zones": azure.SchemaZonesComputed(), "storage_account_type": { Type: schema.TypeString, @@ -51,13 +53,13 @@ func dataSourceArmManagedDisk() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func dataSourceArmManagedDiskRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).diskClient + client := meta.(*ArmClient).compute.DisksClient ctx := meta.(*ArmClient).StopContext resGroup := d.Get("resource_group_name").(string) @@ -92,7 +94,5 @@ func dataSourceArmManagedDiskRead(d *schema.ResourceData, meta interface{}) erro d.Set("zones", resp.Zones) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_management_group.go b/azurerm/data_source_management_group.go index 7941f844ed3f..2b9b2a0081b2 100644 --- a/azurerm/data_source_management_group.go +++ b/azurerm/data_source_management_group.go @@ -39,7 +39,7 @@ func dataSourceArmManagementGroup() *schema.Resource { } func dataSourceArmManagementGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).managementGroupsClient + client := meta.(*ArmClient).managementGroups.GroupsClient ctx := meta.(*ArmClient).StopContext groupId := d.Get("group_id").(string) @@ -54,6 +54,10 @@ func dataSourceArmManagementGroupRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error reading Management Group %q: %+v", d.Id(), err) } + if resp.ID == nil { + return fmt.Errorf("Client returned an nil ID for Management Group %q", groupId) + } + d.SetId(*resp.ID) d.Set("group_id", groupId) diff --git a/azurerm/data_source_maps_account.go b/azurerm/data_source_maps_account.go new file mode 100644 index 000000000000..55f446a185ea --- /dev/null +++ b/azurerm/data_source_maps_account.go @@ -0,0 +1,89 @@ +package azurerm + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/maps" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmMapsAccount() *schema.Resource { + return &schema.Resource{ + Read: dataSourceMapsAccountRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: maps.ValidateName(), + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "sku_name": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tags.Schema(), + + "x_ms_client_id": { + Type: schema.TypeString, + Computed: true, + }, + + "primary_access_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + + "secondary_access_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, + } +} + +func dataSourceMapsAccountRead(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).maps.AccountsClient + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Maps Account %q was not found in Resource Group %q", name, resourceGroup) + } + + return fmt.Errorf("Error making Read request on Maps Account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*resp.ID) + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if sku := resp.Sku; sku != nil { + d.Set("sku_name", sku.Name) + } + if props := resp.Properties; props != nil { + d.Set("x_ms_client_id", props.XMsClientID) + } + + keysResp, err := client.ListKeys(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error reading Access Keys request for Maps Account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("primary_access_key", keysResp.PrimaryKey) + d.Set("secondary_access_key", keysResp.SecondaryKey) + + return tags.FlattenAndSet(d, resp.Tags) +} diff --git a/azurerm/data_source_maps_account_test.go b/azurerm/data_source_maps_account_test.go new file mode 100644 index 000000000000..3f26868d1b58 --- /dev/null +++ b/azurerm/data_source_maps_account_test.go @@ -0,0 +1,48 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMMapsAccount(t *testing.T) { + dataSourceName := "data.azurerm_maps_account.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAzureRMMapsAccount(rInt, location), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(dataSourceName, "id"), + resource.TestCheckResourceAttrSet(dataSourceName, "name"), + resource.TestCheckResourceAttrSet(dataSourceName, "resource_group_name"), + resource.TestCheckResourceAttr(dataSourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(dataSourceName, "tags.environment", "testing"), + resource.TestCheckResourceAttr(dataSourceName, "sku_name", "s0"), + resource.TestCheckResourceAttrSet(dataSourceName, "x_ms_client_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "primary_access_key"), + resource.TestCheckResourceAttrSet(dataSourceName, "secondary_access_key"), + ), + }, + }, + }) +} + +func testAccDataSourceAzureRMMapsAccount(rInt int, location string) string { + template := testAccAzureRMMapsAccount_tags(rInt, location) + return fmt.Sprintf(` +%s + +data "azurerm_maps_account" "test" { + name = azurerm_maps_account.test.name + resource_group_name = azurerm_resource_group.test.name +} +`, template) +} diff --git a/azurerm/data_source_monitor_action_group.go b/azurerm/data_source_monitor_action_group.go index 647ec1cdfd33..b5b5fb22b15f 100644 --- a/azurerm/data_source_monitor_action_group.go +++ b/azurerm/data_source_monitor_action_group.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -18,7 +19,7 @@ func dataSourceArmMonitorActionGroup() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "short_name": { Type: schema.TypeString, @@ -89,7 +90,7 @@ func dataSourceArmMonitorActionGroup() *schema.Resource { } func dataSourceArmMonitorActionGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorActionGroupsClient + client := meta.(*ArmClient).monitor.ActionGroupsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) diff --git a/azurerm/data_source_monitor_diagnostic_categories.go b/azurerm/data_source_monitor_diagnostic_categories.go index 473458aff2d5..6c610774ed40 100644 --- a/azurerm/data_source_monitor_diagnostic_categories.go +++ b/azurerm/data_source_monitor_diagnostic_categories.go @@ -37,7 +37,7 @@ func dataSourceArmMonitorDiagnosticCategories() *schema.Resource { } func dataSourceArmMonitorDiagnosticCategoriesRead(d *schema.ResourceData, meta interface{}) error { - categoriesClient := meta.(*ArmClient).monitorDiagnosticSettingsCategoryClient + categoriesClient := meta.(*ArmClient).monitor.DiagnosticSettingsCategoryClient ctx := meta.(*ArmClient).StopContext actualResourceId := d.Get("resource_id").(string) diff --git a/azurerm/data_source_monitor_diagnostic_categories_test.go b/azurerm/data_source_monitor_diagnostic_categories_test.go index 6ac94c0598d9..6529d2c3b5cc 100644 --- a/azurerm/data_source_monitor_diagnostic_categories_test.go +++ b/azurerm/data_source_monitor_diagnostic_categories_test.go @@ -22,7 +22,7 @@ func TestAccDataSourceArmMonitorDiagnosticCategories_appService(t *testing.T) { Config: testAccDataSourceArmMonitorDiagnosticCategories_appService(ri, location), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(dataSourceName, "metrics.#", "1"), - resource.TestCheckResourceAttr(dataSourceName, "logs.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "logs.#", "6"), ), }, }, @@ -52,7 +52,7 @@ func TestAccDataSourceArmMonitorDiagnosticCategories_storageAccount(t *testing.T func testAccDataSourceArmMonitorDiagnosticCategories_appService(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%d" + name = "acctestRG-%d" location = "%s" } @@ -83,7 +83,7 @@ data "azurerm_monitor_diagnostic_categories" "test" { func testAccDataSourceArmMonitorDiagnosticCategories_storageAccount(rString, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%s" + name = "acctestRG-%s" location = "%s" } diff --git a/azurerm/data_source_monitor_log_profile.go b/azurerm/data_source_monitor_log_profile.go index fd6e8526a3a9..fe939e509640 100644 --- a/azurerm/data_source_monitor_log_profile.go +++ b/azurerm/data_source_monitor_log_profile.go @@ -59,7 +59,7 @@ func dataSourceArmMonitorLogProfile() *schema.Resource { } func dataSourceArmLogProfileRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorLogProfilesClient + client := meta.(*ArmClient).monitor.LogProfilesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) diff --git a/azurerm/data_source_monitor_log_profile_test.go b/azurerm/data_source_monitor_log_profile_test.go index 192d2f290c06..032c7b68b577 100644 --- a/azurerm/data_source_monitor_log_profile_test.go +++ b/azurerm/data_source_monitor_log_profile_test.go @@ -70,7 +70,7 @@ func testAccDataSourceAzureRMMonitorLogProfile_eventhub(t *testing.T) { func testAccDataSourceAzureRMMonitorLogProfile_storageaccountConfig(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%d" + name = "acctestRG-%d" location = "%s" } @@ -110,7 +110,7 @@ data "azurerm_monitor_log_profile" "test" { func testAccDataSourceAzureRMMonitorLogProfile_eventhubConfig(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%d" + name = "acctestRG-%d" location = "%s" } diff --git a/azurerm/data_source_mssql_elasticpool.go b/azurerm/data_source_mssql_elasticpool.go new file mode 100644 index 000000000000..423a5b6a5c86 --- /dev/null +++ b/azurerm/data_source_mssql_elasticpool.go @@ -0,0 +1,102 @@ +package azurerm + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmMsSqlElasticpool() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmMsSqlElasticpoolRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "server_name": { + Type: schema.TypeString, + Required: true, + }, + + "location": azure.SchemaLocationForDataSource(), + + "max_size_bytes": { + Type: schema.TypeInt, + Computed: true, + }, + + "max_size_gb": { + Type: schema.TypeFloat, + Computed: true, + }, + + "per_db_min_capacity": { + Type: schema.TypeInt, + Computed: true, + }, + + "per_db_max_capacity": { + Type: schema.TypeInt, + Computed: true, + }, + + "tags": tags.SchemaDataSource(), + + "zone_redundant": { + Type: schema.TypeBool, + Computed: true, + }, + }, + } +} + +func dataSourceArmMsSqlElasticpoolRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mssql.ElasticPoolsClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + elasticPoolName := d.Get("name").(string) + serverName := d.Get("server_name").(string) + + resp, err := client.Get(ctx, resourceGroup, serverName, elasticPoolName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Error: Elasticpool %q (Resource Group %q, SQL Server %q) was not found", elasticPoolName, resourceGroup, serverName) + } + + return fmt.Errorf("Error making Read request on AzureRM Elasticpool %s (Resource Group %q, SQL Server %q): %+v", elasticPoolName, resourceGroup, serverName, err) + } + + if id := resp.ID; id != nil { + d.SetId(*resp.ID) + } + d.Set("name", elasticPoolName) + d.Set("resource_group_name", resourceGroup) + d.Set("server_name", serverName) + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.ElasticPoolProperties; props != nil { + d.Set("max_size_gb", float64(*props.MaxSizeBytes/int64(1073741824))) + d.Set("max_size_bytes", props.MaxSizeBytes) + + d.Set("zone_redundant", props.ZoneRedundant) + + if perDbSettings := props.PerDatabaseSettings; perDbSettings != nil { + d.Set("per_db_min_capacity", perDbSettings.MinCapacity) + d.Set("per_db_max_capacity", perDbSettings.MaxCapacity) + } + } + + return tags.FlattenAndSet(d, resp.Tags) +} diff --git a/azurerm/data_source_mssql_elasticpool_test.go b/azurerm/data_source_mssql_elasticpool_test.go new file mode 100644 index 000000000000..64d0cdcde7ed --- /dev/null +++ b/azurerm/data_source_mssql_elasticpool_test.go @@ -0,0 +1,83 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMMsSqlElasticPool_basic(t *testing.T) { + dataSourceName := "data.azurerm_mssql_elasticpool.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAzureRMMsSqlElasticPool_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlElasticPoolExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "name"), + resource.TestCheckResourceAttrSet(dataSourceName, "resource_group_name"), + resource.TestCheckResourceAttrSet(dataSourceName, "server_name"), + resource.TestCheckResourceAttr(dataSourceName, "location", location), + resource.TestCheckResourceAttr(dataSourceName, "max_size_gb", "50"), + resource.TestCheckResourceAttr(dataSourceName, "per_db_min_capacity", "0"), + resource.TestCheckResourceAttr(dataSourceName, "per_db_max_capacity", "4"), + resource.TestCheckResourceAttr(dataSourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(dataSourceName, "zone_redundant", "false"), + ), + }, + }, + }) +} + +func testAccDataSourceAzureRMMsSqlElasticPool_basic(rInt int, location string) string { + return fmt.Sprintf(` + resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%s" + } + + resource "azurerm_sql_server" "test" { + name = "acctest%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + version = "12.0" + administrator_login = "4dm1n157r470r" + administrator_login_password = "4-v3ry-53cr37-p455w0rd" + } + + resource "azurerm_mssql_elasticpool" "test" { + name = "acctest-pool-dtu-%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + server_name = "${azurerm_sql_server.test.name}" + max_size_gb = 50 + zone_redundant = false + + sku { + name = "GP_Gen5" + tier = "GeneralPurpose" + capacity = 4 + family = "Gen5" + } + + per_database_settings { + min_capacity = 0 + max_capacity = 4 + } + } + + data "azurerm_mssql_elasticpool" "test" { + name = "${azurerm_mssql_elasticpool.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test.name}" + } + `, rInt, location) +} diff --git a/azurerm/data_source_network_interface.go b/azurerm/data_source_network_interface.go index 50eced28cfc7..7d5b1d6ebe60 100644 --- a/azurerm/data_source_network_interface.go +++ b/azurerm/data_source_network_interface.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -17,7 +19,7 @@ func dataSourceArmNetworkInterface() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), "location": { Type: schema.TypeString, @@ -167,13 +169,13 @@ func dataSourceArmNetworkInterface() *schema.Resource { }, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext resGroup := d.Get("resource_group_name").(string) @@ -247,7 +249,7 @@ func dataSourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("applied_dns_servers", appliedDNSServers) @@ -255,7 +257,5 @@ func dataSourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) d.Set("enable_ip_forwarding", resp.EnableIPForwarding) d.Set("enable_accelerated_networking", resp.EnableAcceleratedNetworking) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_network_security_group.go b/azurerm/data_source_network_security_group.go index ceb96522af3e..1bce3f009c39 100644 --- a/azurerm/data_source_network_security_group.go +++ b/azurerm/data_source_network_security_group.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -16,9 +18,9 @@ func dataSourceArmNetworkSecurityGroup() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "security_rule": { Type: schema.TypeList, @@ -120,13 +122,13 @@ func dataSourceArmNetworkSecurityGroup() *schema.Resource { }, }, - "tags": tagsForDataSourceSchema(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmNetworkSecurityGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).secGroupClient + client := meta.(*ArmClient).network.SecurityGroupClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) @@ -145,7 +147,7 @@ func dataSourceArmNetworkSecurityGroupRead(d *schema.ResourceData, meta interfac d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.SecurityGroupPropertiesFormat; props != nil { @@ -155,7 +157,5 @@ func dataSourceArmNetworkSecurityGroupRead(d *schema.ResourceData, meta interfac } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_network_watcher.go b/azurerm/data_source_network_watcher.go index 5cfb25b36686..e5332b03a2b2 100644 --- a/azurerm/data_source_network_watcher.go +++ b/azurerm/data_source_network_watcher.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -19,15 +21,15 @@ func dataSourceArmNetworkWatcher() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), - "location": locationForDataSourceSchema(), - "tags": tagsForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + "location": azure.SchemaLocationForDataSource(), + "tags": tags.SchemaDataSource(), }, } } func dataSourceArmNetworkWatcherRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).watcherClient + client := meta.(*ArmClient).network.WatcherClient name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) @@ -46,9 +48,7 @@ func dataSourceArmNetworkWatcherRead(d *schema.ResourceData, meta interface{}) e d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/data_source_network_watcher_test.go b/azurerm/data_source_network_watcher_test.go index ea60cbfd8938..14deda910e27 100644 --- a/azurerm/data_source_network_watcher_test.go +++ b/azurerm/data_source_network_watcher_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" ) @@ -25,7 +26,7 @@ func testAccDataSourceAzureRMNetworkWatcher_basic(t *testing.T) { resource.TestCheckResourceAttrSet(dataSourceName, "id"), resource.TestCheckResourceAttr(dataSourceName, "name", name), resource.TestCheckResourceAttrSet(dataSourceName, "resource_group_name"), - resource.TestCheckResourceAttr(dataSourceName, "location", azureRMNormalizeLocation(location)), + resource.TestCheckResourceAttr(dataSourceName, "location", azure.NormalizeLocation(location)), resource.TestCheckResourceAttr(dataSourceName, "tags.%", "1"), resource.TestCheckResourceAttr(dataSourceName, "tags.env", "test"), ), @@ -37,7 +38,7 @@ func testAccDataSourceAzureRMNetworkWatcher_basic(t *testing.T) { func testAccDataSourceAzureRMNetworkWatcher_basicConfig(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%d" + name = "acctestRG-%d" location = "%s" } diff --git a/azurerm/data_source_notification_hub.go b/azurerm/data_source_notification_hub.go index c951f4474688..e712185d048f 100644 --- a/azurerm/data_source_notification_hub.go +++ b/azurerm/data_source_notification_hub.go @@ -5,6 +5,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/notificationhubs/mgmt/2017-04-01/notificationhubs" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -23,9 +24,9 @@ func dataSourceNotificationHub() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "apns_credential": { Type: schema.TypeList, @@ -74,13 +75,13 @@ func dataSourceNotificationHub() *schema.Resource { // NOTE: skipping tags as there's a bug in the API where the Keys for Tags are returned in lower-case // Azure Rest API Specs issue: https://github.com/Azure/azure-sdk-for-go/issues/2239 - //"tags": tagsForDataSourceSchema(), + // "tags": tags.SchemaDataSource(), }, } } func dataSourceNotificationHubRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationHubsClient + client := meta.(*ArmClient).notificationHubs.HubsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -107,7 +108,7 @@ func dataSourceNotificationHubRead(d *schema.ResourceData, meta interface{}) err d.Set("namespace_name", namespaceName) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := credentials.PnsCredentialsProperties; props != nil { diff --git a/azurerm/data_source_notification_hub_namespace.go b/azurerm/data_source_notification_hub_namespace.go index 9c4bf559ad6d..6398b9dad42b 100644 --- a/azurerm/data_source_notification_hub_namespace.go +++ b/azurerm/data_source_notification_hub_namespace.go @@ -5,6 +5,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/notificationhubs/mgmt/2017-04-01/notificationhubs" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -18,9 +19,9 @@ func dataSourceNotificationHubNamespace() *schema.Resource { Required: true, }, - "resource_group_name": resourceGroupNameForDataSourceSchema(), + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - "location": locationForDataSourceSchema(), + "location": azure.SchemaLocationForDataSource(), "sku": { Type: schema.TypeList, @@ -47,7 +48,7 @@ func dataSourceNotificationHubNamespace() *schema.Resource { // NOTE: skipping tags as there's a bug in the API where the Keys for Tags are returned in lower-case // Azure Rest API Specs issue: https://github.com/Azure/azure-sdk-for-go/issues/2239 - //"tags": tagsForDataSourceSchema(), + // "tags": tags.SchemaDataSource(), "servicebus_endpoint": { Type: schema.TypeString, @@ -58,7 +59,7 @@ func dataSourceNotificationHubNamespace() *schema.Resource { } func resourceArmDataSourceNotificationHubNamespaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationNamespacesClient + client := meta.(*ArmClient).notificationHubs.NamespacesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -78,7 +79,7 @@ func resourceArmDataSourceNotificationHubNamespaceRead(d *schema.ResourceData, m d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } sku := flattenNotificationHubDataSourceNamespacesSku(resp.Sku) diff --git a/azurerm/data_source_platform_image.go b/azurerm/data_source_platform_image.go index c9b67a526f55..8772dab88df9 100644 --- a/azurerm/data_source_platform_image.go +++ b/azurerm/data_source_platform_image.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -11,7 +12,7 @@ func dataSourceArmPlatformImage() *schema.Resource { return &schema.Resource{ Read: dataSourceArmPlatformImageRead, Schema: map[string]*schema.Schema{ - "location": locationSchema(), + "location": azure.SchemaLocation(), "publisher": { Type: schema.TypeString, @@ -37,10 +38,10 @@ func dataSourceArmPlatformImage() *schema.Resource { } func dataSourceArmPlatformImageRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).vmImageClient + client := meta.(*ArmClient).compute.VMImageClient ctx := meta.(*ArmClient).StopContext - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) publisher := d.Get("publisher").(string) offer := d.Get("offer").(string) sku := d.Get("sku").(string) @@ -55,7 +56,7 @@ func dataSourceArmPlatformImageRead(d *schema.ResourceData, meta interface{}) er d.SetId(*latestVersion.ID) if location := latestVersion.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("publisher", publisher) diff --git a/azurerm/data_source_platform_image_test.go b/azurerm/data_source_platform_image_test.go index 3c550a3f62e4..c2a5bdb7a71a 100644 --- a/azurerm/data_source_platform_image_test.go +++ b/azurerm/data_source_platform_image_test.go @@ -12,9 +12,8 @@ func TestAccDataSourceAzureRMPlatformImage_basic(t *testing.T) { config := testAccDataSourceAzureRMPlatformImageBasic(testLocation()) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMPublicIpDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, Steps: []resource.TestStep{ { Config: config, diff --git a/azurerm/data_source_policy_definition.go b/azurerm/data_source_policy_definition.go index 006a91617f6d..0b2d66c79fda 100644 --- a/azurerm/data_source_policy_definition.go +++ b/azurerm/data_source_policy_definition.go @@ -56,7 +56,7 @@ func dataSourceArmPolicyDefinition() *schema.Resource { } func dataSourceArmPolicyDefinitionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policyDefinitionsClient + client := meta.(*ArmClient).policy.DefinitionsClient ctx := meta.(*ArmClient).StopContext name := d.Get("display_name").(string) diff --git a/azurerm/data_source_policy_definition_test.go b/azurerm/data_source_policy_definition_test.go index 3053bdb0ab7e..d7163daebd40 100644 --- a/azurerm/data_source_policy_definition_test.go +++ b/azurerm/data_source_policy_definition_test.go @@ -62,7 +62,7 @@ func TestAccDataSourceAzureRMPolicyDefinition_custom(t *testing.T) { resource.TestCheckResourceAttr(dataSourceName, "policy_type", "Custom"), resource.TestCheckResourceAttr(dataSourceName, "policy_rule", "{\"if\":{\"not\":{\"field\":\"location\",\"in\":\"[parameters('allowedLocations')]\"}},\"then\":{\"effect\":\"audit\"}}"), resource.TestCheckResourceAttr(dataSourceName, "parameters", "{\"allowedLocations\":{\"metadata\":{\"description\":\"The list of allowed locations for resources.\",\"displayName\":\"Allowed locations\",\"strongType\":\"location\"},\"type\":\"Array\"}}"), - resource.TestCheckResourceAttr(dataSourceName, "metadata", "{\"note\":\"azurerm acceptance test\"}"), + resource.TestCheckResourceAttrSet(dataSourceName, "metadata"), ), }, }, @@ -79,7 +79,6 @@ data "azurerm_policy_definition" "test" { func testAccDataSourceBuiltInPolicyDefinitionAtManagementGroup(name string) string { return fmt.Sprintf(` - data "azurerm_client_config" "current" {} data "azurerm_policy_definition" "test" { @@ -97,7 +96,7 @@ resource "azurerm_policy_definition" "test_policy" { mode = "All" display_name = "acctestpol-%d" - policy_rule = < 0 { + return false, fmt.Errorf(strings.Join(errorStrings, "\n")) + } + + return true, nil +} diff --git a/azurerm/express_route_circuit.go b/azurerm/express_route_circuit.go deleted file mode 100644 index 5cae3ec3c3b8..000000000000 --- a/azurerm/express_route_circuit.go +++ /dev/null @@ -1,37 +0,0 @@ -package azurerm - -import ( - "fmt" - - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" -) - -func extractResourceGroupAndErcName(resourceId string) (resourceGroup string, name string, e error) { - id, err := parseAzureResourceID(resourceId) - if err != nil { - return "", "", err - } - - return id.ResourceGroup, id.Path["expressRouteCircuits"], err -} - -func retrieveErcByResourceId(resourceId string, meta interface{}) (erc *network.ExpressRouteCircuit, resourceGroup string, e error) { - ercClient := meta.(*ArmClient).expressRouteCircuitClient - ctx := meta.(*ArmClient).StopContext - - resGroup, name, err := extractResourceGroupAndErcName(resourceId) - if err != nil { - return nil, "", fmt.Errorf("Error Parsing Azure Resource ID -: %+v", err) - } - - resp, err := ercClient.Get(ctx, resGroup, name) - if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return nil, "", nil - } - return nil, "", fmt.Errorf("Error making Read request on Express Route Circuit %s: %+v", name, err) - } - - return &resp, resGroup, nil -} diff --git a/azurerm/feature_flags.go b/azurerm/feature_flags.go deleted file mode 100644 index 4bd34992eeaf..000000000000 --- a/azurerm/feature_flags.go +++ /dev/null @@ -1,13 +0,0 @@ -package azurerm - -import ( - "os" - "strings" -) - -// NOTE: we'll need to add an infobox to MySQL|PostgreSQL Configuration when this goes live -// since these resources can't support import -// in addition the virtual resources will need adjusting - -// This file contains feature flags for functionality which will prove more challenging to implement en-mass -var requireResourcesToBeImported = strings.EqualFold(os.Getenv("ARM_PROVIDER_STRICT"), "true") diff --git a/azurerm/helpers/azure/api_management.go b/azurerm/helpers/azure/api_management.go index 8eced21d8b8f..3d1bf66b5490 100644 --- a/azurerm/helpers/azure/api_management.go +++ b/azurerm/helpers/azure/api_management.go @@ -1,8 +1,13 @@ package azure import ( + "fmt" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func SchemaApiManagementName() *schema.Schema { @@ -22,6 +27,17 @@ func SchemaApiManagementDataSourceName() *schema.Schema { } } +// SchemaApiManagementChildID returns the Schema for the identifier +// used by resources within nested under the API Management Service resource +func SchemaApiManagementChildID() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: ValidateResourceID, + } +} + // SchemaApiManagementChildName returns the Schema for the identifier // used by resources within nested under the API Management Service resource func SchemaApiManagementChildName() *schema.Schema { @@ -59,3 +75,225 @@ func SchemaApiManagementUserDataSourceName() *schema.Schema { ValidateFunc: validate.ApiManagementUserName, } } + +func SchemaApiManagementOperationRepresentation() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "content_type": { + Type: schema.TypeString, + Required: true, + }, + + "form_parameter": SchemaApiManagementOperationParameterContract(), + + "sample": { + Type: schema.TypeString, + Optional: true, + }, + + "schema_id": { + Type: schema.TypeString, + Optional: true, + }, + + "type_name": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + } +} + +func ExpandApiManagementOperationRepresentation(input []interface{}) (*[]apimanagement.RepresentationContract, error) { + if len(input) == 0 { + return &[]apimanagement.RepresentationContract{}, nil + } + + outputs := make([]apimanagement.RepresentationContract, 0) + + for _, v := range input { + vs := v.(map[string]interface{}) + + contentType := vs["content_type"].(string) + formParametersRaw := vs["form_parameter"].([]interface{}) + formParameters := ExpandApiManagementOperationParameterContract(formParametersRaw) + sample := vs["sample"].(string) + schemaId := vs["schema_id"].(string) + typeName := vs["type_name"].(string) + + output := apimanagement.RepresentationContract{ + ContentType: utils.String(contentType), + Sample: utils.String(sample), + } + + contentTypeIsFormData := strings.EqualFold(contentType, "multipart/form-data") || strings.EqualFold(contentType, "application/x-www-form-urlencoded") + + // Representation formParameters can only be specified for form data content types (multipart/form-data, application/x-www-form-urlencoded) + if contentTypeIsFormData { + output.FormParameters = formParameters + } else if len(*formParameters) > 0 { + return nil, fmt.Errorf("`form_parameter` cannot be specified for form data content types (multipart/form-data, application/x-www-form-urlencoded)") + } + + // Representation schemaId can only be specified for non form data content types (multipart/form-data, application/x-www-form-urlencoded). + // Representation typeName can only be specified for non form data content types (multipart/form-data, application/x-www-form-urlencoded). + if !contentTypeIsFormData { + output.SchemaID = utils.String(schemaId) + output.TypeName = utils.String(typeName) + } else if schemaId != "" { + return nil, fmt.Errorf("`schema_id` cannot be specified for non-form data content types (multipart/form-data, application/x-www-form-urlencoded)") + } else if typeName != "" { + return nil, fmt.Errorf("`type_name` cannot be specified for non-form data content types (multipart/form-data, application/x-www-form-urlencoded)") + } + + outputs = append(outputs, output) + } + + return &outputs, nil +} + +func FlattenApiManagementOperationRepresentation(input *[]apimanagement.RepresentationContract) []interface{} { + if input == nil { + return []interface{}{} + } + + outputs := make([]interface{}, 0) + + for _, v := range *input { + output := make(map[string]interface{}) + + if v.ContentType != nil { + output["content_type"] = *v.ContentType + } + + output["form_parameter"] = FlattenApiManagementOperationParameterContract(v.FormParameters) + + if v.Sample != nil { + output["sample"] = *v.Sample + } + + if v.SchemaID != nil { + output["schema_id"] = *v.SchemaID + } + + if v.TypeName != nil { + output["type_name"] = *v.TypeName + } + + outputs = append(outputs, output) + } + + return outputs +} + +func SchemaApiManagementOperationParameterContract() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "required": { + Type: schema.TypeBool, + Required: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + "type": { + Type: schema.TypeString, + Required: true, + }, + "default_value": { + Type: schema.TypeString, + Optional: true, + }, + "values": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Set: schema.HashString, + }, + }, + }, + } +} + +func ExpandApiManagementOperationParameterContract(input []interface{}) *[]apimanagement.ParameterContract { + if len(input) == 0 { + return &[]apimanagement.ParameterContract{} + } + + outputs := make([]apimanagement.ParameterContract, 0) + + for _, v := range input { + vs := v.(map[string]interface{}) + + name := vs["name"].(string) + description := vs["description"].(string) + paramType := vs["type"].(string) + defaultValue := vs["default_value"].(string) + required := vs["required"].(bool) + valuesRaw := vs["values"].(*schema.Set).List() + + output := apimanagement.ParameterContract{ + Name: utils.String(name), + Description: utils.String(description), + Type: utils.String(paramType), + Required: utils.Bool(required), + DefaultValue: utils.String(defaultValue), + Values: utils.ExpandStringSlice(valuesRaw), + } + outputs = append(outputs, output) + } + + return &outputs +} + +func FlattenApiManagementOperationParameterContract(input *[]apimanagement.ParameterContract) []interface{} { + if input == nil { + return []interface{}{} + } + + outputs := make([]interface{}, 0) + for _, v := range *input { + output := map[string]interface{}{} + + if v.Name != nil { + output["name"] = *v.Name + } + + if v.Description != nil { + output["description"] = *v.Description + } + + if v.Type != nil { + output["type"] = *v.Type + } + + if v.Required != nil { + output["required"] = *v.Required + } + + if v.DefaultValue != nil { + output["default_value"] = *v.DefaultValue + } + + output["values"] = schema.NewSet(schema.HashString, utils.FlattenStringSlice(v.Values)) + + outputs = append(outputs, output) + } + + return outputs +} diff --git a/azurerm/helpers/azure/app_service.go b/azurerm/helpers/azure/app_service.go index 5751ad9acb6b..e368a29d3974 100644 --- a/azurerm/helpers/azure/app_service.go +++ b/azurerm/helpers/azure/app_service.go @@ -1,6 +1,7 @@ package azure import ( + "fmt" "log" "net" "strings" @@ -9,9 +10,245 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +func SchemaAppServiceAadAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "allowed_audiences": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + +func SchemaAppServiceFacebookAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "app_id": { + Type: schema.TypeString, + Required: true, + }, + "app_secret": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "oauth_scopes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + +func SchemaAppServiceGoogleAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "oauth_scopes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + +func SchemaAppServiceMicrosoftAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "oauth_scopes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + +func SchemaAppServiceTwitterAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "consumer_key": { + Type: schema.TypeString, + Required: true, + }, + "consumer_secret": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + }, + }, + } +} + +func SchemaAppServiceAuthSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + "additional_login_params": { + Type: schema.TypeMap, + Optional: true, + }, + "allowed_external_redirect_urls": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "default_provider": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.AzureActiveDirectory), + string(web.Facebook), + string(web.Google), + string(web.MicrosoftAccount), + string(web.Twitter), + }, false), + }, + "issuer": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.URLIsHTTPOrHTTPS, + }, + "runtime_version": { + Type: schema.TypeString, + Optional: true, + }, + "token_refresh_extension_hours": { + Type: schema.TypeFloat, + Optional: true, + Default: 72, + }, + "token_store_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "unauthenticated_client_action": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.AllowAnonymous), + string(web.RedirectToLoginPage), + }, false), + }, + "active_directory": SchemaAppServiceAadAuthSettings(), + "facebook": SchemaAppServiceFacebookAuthSettings(), + "google": SchemaAppServiceGoogleAuthSettings(), + "microsoft": SchemaAppServiceMicrosoftAuthSettings(), + "twitter": SchemaAppServiceTwitterAuthSettings(), + }, + }, + } +} + +func SchemaAppServiceIdentity() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.ManagedServiceIdentityTypeNone), + string(web.ManagedServiceIdentityTypeSystemAssigned), + string(web.ManagedServiceIdentityTypeSystemAssignedUserAssigned), + string(web.ManagedServiceIdentityTypeUserAssigned), + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + "principal_id": { + Type: schema.TypeString, + Computed: true, + }, + "tenant_id": { + Type: schema.TypeString, + Computed: true, + }, + "identity_ids": { + Type: schema.TypeList, + Optional: true, + MinItems: 1, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.NoZeroValues, + }, + }, + }, + }, + } +} + func SchemaAppServiceSiteConfig() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, @@ -26,213 +263,1058 @@ func SchemaAppServiceSiteConfig() *schema.Schema { Default: false, }, - "app_command_line": { - Type: schema.TypeString, - Optional: true, - }, + "app_command_line": { + Type: schema.TypeString, + Optional: true, + }, + + "default_documents": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "dotnet_framework_version": { + Type: schema.TypeString, + Optional: true, + Default: "v4.0", + ValidateFunc: validation.StringInSlice([]string{ + "v2.0", + "v4.0", + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + + "http2_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "ip_restriction": { + Type: schema.TypeList, + Optional: true, + Computed: true, + ConfigMode: schema.SchemaConfigModeAttr, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_address": { + Type: schema.TypeString, + Optional: true, + }, + "virtual_network_subnet_id": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "subnet_mask": { + Type: schema.TypeString, + Optional: true, + Computed: true, + // TODO we should fix this in 2.0 + // This attribute was made with the assumption that `ip_address` was the only valid option + // but `virtual_network_subnet_id` is being added and doesn't need a `subnet_mask`. + // We'll assume a default of "255.255.255.255" in the expand code when `ip_address` is specified + // and `subnet_mask` is not. + // Default: "255.255.255.255", + }, + }, + }, + }, + + "java_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "1.7", + "1.8", + "11", + }, false), + }, + + "java_container": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "JETTY", + "TOMCAT", + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + + "java_container_version": { + Type: schema.TypeString, + Optional: true, + }, + + "local_mysql_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + + "managed_pipeline_mode": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.Classic), + string(web.Integrated), + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + + "php_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "5.5", + "5.6", + "7.0", + "7.1", + "7.2", + }, false), + }, + + "python_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "2.7", + "3.4", + }, false), + }, + + "remote_debugging_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "remote_debugging_version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + "VS2012", + "VS2013", + "VS2015", + "VS2017", + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + + "scm_type": { + Type: schema.TypeString, + Optional: true, + Default: string(web.ScmTypeNone), + ValidateFunc: validation.StringInSlice([]string{ + string(web.ScmTypeBitbucketGit), + string(web.ScmTypeBitbucketHg), + string(web.ScmTypeCodePlexGit), + string(web.ScmTypeCodePlexHg), + string(web.ScmTypeDropbox), + string(web.ScmTypeExternalGit), + string(web.ScmTypeExternalHg), + string(web.ScmTypeGitHub), + string(web.ScmTypeLocalGit), + string(web.ScmTypeNone), + string(web.ScmTypeOneDrive), + string(web.ScmTypeTfs), + string(web.ScmTypeVSO), + // Not in the specs, but is set by Azure Pipelines + // https://github.com/Microsoft/azure-pipelines-tasks/blob/master/Tasks/AzureRmWebAppDeploymentV4/operations/AzureAppServiceUtility.ts#L19 + // upstream issue: https://github.com/Azure/azure-rest-api-specs/issues/5345 + "VSTSRM", + }, false), + }, + + "use_32_bit_worker_process": { + Type: schema.TypeBool, + Optional: true, + }, + + "websockets_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + + "ftps_state": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.AllAllowed), + string(web.Disabled), + string(web.FtpsOnly), + }, false), + }, + + "linux_fx_version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "windows_fx_version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "min_tls_version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.OneFullStopZero), + string(web.OneFullStopOne), + string(web.OneFullStopTwo), + }, false), + }, + + "virtual_network_name": { + Type: schema.TypeString, + Optional: true, + }, + + "cors": SchemaWebCorsSettings(), + }, + }, + } +} + +func SchemaAppServiceLogsConfig() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "application_logs": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "azure_blob_storage": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "level": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.Error), + string(web.Information), + string(web.Off), + string(web.Verbose), + string(web.Warning), + }, false), + }, + "sas_url": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "retention_in_days": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "http_logs": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "file_system": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "retention_in_mb": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(25, 100), + }, + "retention_in_days": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(0), + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func SchemaAppServiceStorageAccounts() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(web.AzureBlob), + string(web.AzureFiles), + }, false), + }, + + "account_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "share_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "access_key": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "mount_path": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + } +} + +func SchemaAppServiceDataSourceSiteConfig() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "always_on": { + Type: schema.TypeBool, + Computed: true, + }, + + "app_command_line": { + Type: schema.TypeString, + Computed: true, + }, + + "default_documents": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "dotnet_framework_version": { + Type: schema.TypeString, + Computed: true, + }, + + "http2_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + + "ip_restriction": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "virtual_network_subnet_id": { + Type: schema.TypeString, + Computed: true, + }, + "subnet_mask": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "java_version": { + Type: schema.TypeString, + Computed: true, + }, + + "java_container": { + Type: schema.TypeString, + Computed: true, + }, + + "java_container_version": { + Type: schema.TypeString, + Computed: true, + }, + + "local_mysql_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + + "managed_pipeline_mode": { + Type: schema.TypeString, + Computed: true, + }, + + "php_version": { + Type: schema.TypeString, + Computed: true, + }, + + "python_version": { + Type: schema.TypeString, + Computed: true, + }, + + "remote_debugging_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + + "remote_debugging_version": { + Type: schema.TypeString, + Computed: true, + }, + + "scm_type": { + Type: schema.TypeString, + Computed: true, + }, + + "use_32_bit_worker_process": { + Type: schema.TypeBool, + Computed: true, + }, + + "websockets_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + + "ftps_state": { + Type: schema.TypeString, + Computed: true, + }, + + "linux_fx_version": { + Type: schema.TypeString, + Computed: true, + }, + + "windows_fx_version": { + Type: schema.TypeString, + Computed: true, + }, + + "min_tls_version": { + Type: schema.TypeString, + Computed: true, + }, + + "virtual_network_name": { + Type: schema.TypeString, + Computed: true, + }, + + "cors": { + Type: schema.TypeList, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "allowed_origins": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "support_credentials": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + }, + }, + } +} + +func ExpandAppServiceAuthSettings(input []interface{}) web.SiteAuthSettingsProperties { + siteAuthSettingsProperties := web.SiteAuthSettingsProperties{} + + if len(input) == 0 { + return siteAuthSettingsProperties + } + + setting := input[0].(map[string]interface{}) + + if v, ok := setting["enabled"]; ok { + siteAuthSettingsProperties.Enabled = utils.Bool(v.(bool)) + } + + if v, ok := setting["additional_login_params"]; ok { + input := v.(map[string]interface{}) + + additionalLoginParams := make([]string, 0) + for k, v := range input { + additionalLoginParams = append(additionalLoginParams, fmt.Sprintf("%s=%s", k, v.(string))) + } + + siteAuthSettingsProperties.AdditionalLoginParams = &additionalLoginParams + } + + if v, ok := setting["allowed_external_redirect_urls"]; ok { + input := v.([]interface{}) + + allowedExternalRedirectUrls := make([]string, 0) + for _, param := range input { + allowedExternalRedirectUrls = append(allowedExternalRedirectUrls, param.(string)) + } + + siteAuthSettingsProperties.AllowedExternalRedirectUrls = &allowedExternalRedirectUrls + } + + if v, ok := setting["default_provider"]; ok { + siteAuthSettingsProperties.DefaultProvider = web.BuiltInAuthenticationProvider(v.(string)) + } + + if v, ok := setting["issuer"]; ok { + siteAuthSettingsProperties.Issuer = utils.String(v.(string)) + } + + if v, ok := setting["runtime_version"]; ok { + siteAuthSettingsProperties.RuntimeVersion = utils.String(v.(string)) + } + + if v, ok := setting["token_refresh_extension_hours"]; ok { + siteAuthSettingsProperties.TokenRefreshExtensionHours = utils.Float(v.(float64)) + } + + if v, ok := setting["token_store_enabled"]; ok { + siteAuthSettingsProperties.TokenStoreEnabled = utils.Bool(v.(bool)) + } + + if v, ok := setting["unauthenticated_client_action"]; ok { + siteAuthSettingsProperties.UnauthenticatedClientAction = web.UnauthenticatedClientAction(v.(string)) + } + + if v, ok := setting["active_directory"]; ok { + activeDirectorySettings := v.([]interface{}) + + for _, setting := range activeDirectorySettings { + if setting == nil { + continue + } + + activeDirectorySetting := setting.(map[string]interface{}) + + if v, ok := activeDirectorySetting["client_id"]; ok { + siteAuthSettingsProperties.ClientID = utils.String(v.(string)) + } + + if v, ok := activeDirectorySetting["client_secret"]; ok { + siteAuthSettingsProperties.ClientSecret = utils.String(v.(string)) + } + + if v, ok := activeDirectorySetting["allowed_audiences"]; ok { + input := v.([]interface{}) + + allowedAudiences := make([]string, 0) + for _, param := range input { + allowedAudiences = append(allowedAudiences, param.(string)) + } + + siteAuthSettingsProperties.AllowedAudiences = &allowedAudiences + } + } + } + + if v, ok := setting["facebook"]; ok { + facebookSettings := v.([]interface{}) + + for _, setting := range facebookSettings { + facebookSetting := setting.(map[string]interface{}) + + if v, ok := facebookSetting["app_id"]; ok { + siteAuthSettingsProperties.FacebookAppID = utils.String(v.(string)) + } + + if v, ok := facebookSetting["app_secret"]; ok { + siteAuthSettingsProperties.FacebookAppSecret = utils.String(v.(string)) + } + + if v, ok := facebookSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.FacebookOAuthScopes = &oauthScopes + } + } + } + + if v, ok := setting["google"]; ok { + googleSettings := v.([]interface{}) + + for _, setting := range googleSettings { + googleSetting := setting.(map[string]interface{}) + + if v, ok := googleSetting["client_id"]; ok { + siteAuthSettingsProperties.GoogleClientID = utils.String(v.(string)) + } + + if v, ok := googleSetting["client_secret"]; ok { + siteAuthSettingsProperties.GoogleClientSecret = utils.String(v.(string)) + } + + if v, ok := googleSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.GoogleOAuthScopes = &oauthScopes + } + } + } + + if v, ok := setting["microsoft"]; ok { + microsoftSettings := v.([]interface{}) + + for _, setting := range microsoftSettings { + microsoftSetting := setting.(map[string]interface{}) + + if v, ok := microsoftSetting["client_id"]; ok { + siteAuthSettingsProperties.MicrosoftAccountClientID = utils.String(v.(string)) + } + + if v, ok := microsoftSetting["client_secret"]; ok { + siteAuthSettingsProperties.MicrosoftAccountClientSecret = utils.String(v.(string)) + } + + if v, ok := microsoftSetting["oauth_scopes"]; ok { + input := v.([]interface{}) + + oauthScopes := make([]string, 0) + for _, param := range input { + oauthScopes = append(oauthScopes, param.(string)) + } + + siteAuthSettingsProperties.MicrosoftAccountOAuthScopes = &oauthScopes + } + } + } + + if v, ok := setting["twitter"]; ok { + twitterSettings := v.([]interface{}) + + for _, setting := range twitterSettings { + twitterSetting := setting.(map[string]interface{}) + + if v, ok := twitterSetting["consumer_key"]; ok { + siteAuthSettingsProperties.TwitterConsumerKey = utils.String(v.(string)) + } + + if v, ok := twitterSetting["consumer_secret"]; ok { + siteAuthSettingsProperties.TwitterConsumerSecret = utils.String(v.(string)) + } + } + } + + return siteAuthSettingsProperties +} + +func FlattenAdditionalLoginParams(input *[]string) map[string]interface{} { + result := make(map[string]interface{}) + + if input == nil { + return result + } + + for _, k := range *input { + parts := strings.Split(k, "=") + if len(parts) != 2 { + continue // Params not following the format `key=value` is considered malformed and will be ignored. + } + key := parts[0] + value := parts[1] + + result[key] = value + } + + return result +} + +func FlattenAppServiceAuthSettings(input *web.SiteAuthSettingsProperties) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + result := make(map[string]interface{}) + + if input.Enabled != nil { + result["enabled"] = *input.Enabled + } + + result["additional_login_params"] = FlattenAdditionalLoginParams(input.AdditionalLoginParams) + + allowedExternalRedirectUrls := make([]string, 0) + if s := input.AllowedExternalRedirectUrls; s != nil { + allowedExternalRedirectUrls = *s + } + result["allowed_external_redirect_urls"] = allowedExternalRedirectUrls + + if input.DefaultProvider != "" { + result["default_provider"] = input.DefaultProvider + } + + if input.Issuer != nil { + result["issuer"] = *input.Issuer + } + + if input.RuntimeVersion != nil { + result["runtime_version"] = *input.RuntimeVersion + } + + if input.TokenRefreshExtensionHours != nil { + result["token_refresh_extension_hours"] = *input.TokenRefreshExtensionHours + } + + if input.TokenStoreEnabled != nil { + result["token_store_enabled"] = *input.TokenStoreEnabled + } + + if input.UnauthenticatedClientAction != "" { + result["unauthenticated_client_action"] = input.UnauthenticatedClientAction + } + + activeDirectorySettings := make([]interface{}, 0) + + if input.ClientID != nil { + activeDirectorySetting := make(map[string]interface{}) + + activeDirectorySetting["client_id"] = *input.ClientID + + if input.ClientSecret != nil { + activeDirectorySetting["client_secret"] = *input.ClientSecret + } + + if input.AllowedAudiences != nil { + activeDirectorySetting["allowed_audiences"] = *input.AllowedAudiences + } + + activeDirectorySettings = append(activeDirectorySettings, activeDirectorySetting) + } + + result["active_directory"] = activeDirectorySettings + + facebookSettings := make([]interface{}, 0) + + if input.FacebookAppID != nil { + facebookSetting := make(map[string]interface{}) + + facebookSetting["app_id"] = *input.FacebookAppID + + if input.FacebookAppSecret != nil { + facebookSetting["app_secret"] = *input.FacebookAppSecret + } + + if input.FacebookOAuthScopes != nil { + facebookSetting["oauth_scopes"] = *input.FacebookOAuthScopes + } + + facebookSettings = append(facebookSettings, facebookSetting) + } + + result["facebook"] = facebookSettings + + googleSettings := make([]interface{}, 0) + + if input.GoogleClientID != nil { + googleSetting := make(map[string]interface{}) + + googleSetting["client_id"] = *input.GoogleClientID + + if input.GoogleClientSecret != nil { + googleSetting["client_secret"] = *input.GoogleClientSecret + } + + if input.GoogleOAuthScopes != nil { + googleSetting["oauth_scopes"] = *input.GoogleOAuthScopes + } + + googleSettings = append(googleSettings, googleSetting) + } + + result["google"] = googleSettings + + microsoftSettings := make([]interface{}, 0) + + if input.MicrosoftAccountClientID != nil { + microsoftSetting := make(map[string]interface{}) + + microsoftSetting["client_id"] = *input.MicrosoftAccountClientID + + if input.MicrosoftAccountClientSecret != nil { + microsoftSetting["client_secret"] = *input.MicrosoftAccountClientSecret + } + + if input.MicrosoftAccountOAuthScopes != nil { + microsoftSetting["oauth_scopes"] = *input.MicrosoftAccountOAuthScopes + } + + microsoftSettings = append(microsoftSettings, microsoftSetting) + } + + result["microsoft"] = microsoftSettings + + twitterSettings := make([]interface{}, 0) + + if input.TwitterConsumerKey != nil { + twitterSetting := make(map[string]interface{}) + + twitterSetting["consumer_key"] = *input.TwitterConsumerKey + + if input.TwitterConsumerSecret != nil { + twitterSetting["consumer_secret"] = *input.TwitterConsumerSecret + } + + twitterSettings = append(twitterSettings, twitterSetting) + } + + result["twitter"] = twitterSettings + + return append(results, result) +} + +func FlattenAppServiceLogs(input *web.SiteLogsConfigProperties) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + result := make(map[string]interface{}) + + appLogs := make([]interface{}, 0) + if input.ApplicationLogs != nil { + + appLogsItem := make(map[string]interface{}) + + blobStorage := make([]interface{}, 0) + if blobStorageInput := input.ApplicationLogs.AzureBlobStorage; blobStorageInput != nil { + blobStorageItem := make(map[string]interface{}) + + blobStorageItem["level"] = string(blobStorageInput.Level) + + if blobStorageInput.SasURL != nil { + blobStorageItem["sas_url"] = *blobStorageInput.SasURL + } + + if blobStorageInput.RetentionInDays != nil { + blobStorageItem["retention_in_days"] = *blobStorageInput.RetentionInDays + } + + // The API returns a non nil application logs object when other logs are specified so we'll check that this structure is empty before adding it to the statefile. + if blobStorageInput.SasURL != nil && *blobStorageInput.SasURL != "" { + blobStorage = append(blobStorage, blobStorageItem) + } + } + appLogsItem["azure_blob_storage"] = blobStorage + appLogs = append(appLogs, appLogsItem) + } + result["application_logs"] = appLogs - "default_documents": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, + httpLogs := make([]interface{}, 0) + if input.HTTPLogs != nil { + httpLogsItem := make(map[string]interface{}) - "dotnet_framework_version": { - Type: schema.TypeString, - Optional: true, - Default: "v4.0", - ValidateFunc: validation.StringInSlice([]string{ - "v2.0", - "v4.0", - }, true), - DiffSuppressFunc: suppress.CaseDifference, - }, + fileSystem := make([]interface{}, 0) + if fileSystemInput := input.HTTPLogs.FileSystem; fileSystemInput != nil { - "http2_enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, + fileSystemItem := make(map[string]interface{}) - "ip_restriction": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip_address": { - Type: schema.TypeString, - Required: true, - }, - "subnet_mask": { - Type: schema.TypeString, - Optional: true, - Default: "255.255.255.255", - }, - }, - }, - }, + if fileSystemInput.RetentionInDays != nil { + fileSystemItem["retention_in_days"] = *fileSystemInput.RetentionInDays + } - "java_version": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{ - "1.7", - "1.8", - }, false), - }, + if fileSystemInput.RetentionInMb != nil { + fileSystemItem["retention_in_mb"] = *fileSystemInput.RetentionInMb + } - "java_container": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{ - "JETTY", - "TOMCAT", - }, true), - DiffSuppressFunc: suppress.CaseDifference, - }, + // The API returns a non nil filesystem logs object when other logs are specified so we'll check that this is disabled before adding it to the statefile. + if fileSystemInput.Enabled != nil && *fileSystemInput.Enabled { + fileSystem = append(fileSystem, fileSystemItem) + } + } + httpLogsItem["file_system"] = fileSystem + httpLogs = append(httpLogs, httpLogsItem) + } + result["http_logs"] = httpLogs - "java_container_version": { - Type: schema.TypeString, - Optional: true, - }, + return append(results, result) +} - "local_mysql_enabled": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, +func ExpandAppServiceLogs(input interface{}) web.SiteLogsConfigProperties { + configs := input.([]interface{}) + logs := web.SiteLogsConfigProperties{} - "managed_pipeline_mode": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice([]string{ - string(web.Classic), - string(web.Integrated), - }, true), - DiffSuppressFunc: suppress.CaseDifference, - }, + if len(configs) == 0 { + return logs + } - "php_version": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{ - "5.5", - "5.6", - "7.0", - "7.1", - "7.2", - }, false), - }, + config := configs[0].(map[string]interface{}) - "python_version": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{ - "2.7", - "3.4", - }, false), - }, + if v, ok := config["application_logs"]; ok { + appLogsConfigs := v.([]interface{}) - "remote_debugging_enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, + for _, config := range appLogsConfigs { + appLogsConfig := config.(map[string]interface{}) - "remote_debugging_version": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice([]string{ - "VS2012", - "VS2013", - "VS2015", - "VS2017", - }, true), - DiffSuppressFunc: suppress.CaseDifference, - }, + logs.ApplicationLogs = &web.ApplicationLogsConfig{} - "scm_type": { - Type: schema.TypeString, - Optional: true, - Default: string(web.ScmTypeNone), - ValidateFunc: validation.StringInSlice([]string{ - string(web.ScmTypeBitbucketGit), - string(web.ScmTypeBitbucketHg), - string(web.ScmTypeCodePlexGit), - string(web.ScmTypeCodePlexHg), - string(web.ScmTypeDropbox), - string(web.ScmTypeExternalGit), - string(web.ScmTypeExternalHg), - string(web.ScmTypeGitHub), - string(web.ScmTypeLocalGit), - string(web.ScmTypeNone), - string(web.ScmTypeOneDrive), - string(web.ScmTypeTfs), - string(web.ScmTypeVSO), - // Not in the specs, but is set by Azure Pipelines - // https://github.com/Microsoft/azure-pipelines-tasks/blob/master/Tasks/AzureRmWebAppDeploymentV4/operations/AzureAppServiceUtility.ts#L19 - // upstream issue: https://github.com/Azure/azure-rest-api-specs/issues/5345 - "VSTSRM", - }, false), - }, + if v, ok := appLogsConfig["azure_blob_storage"]; ok { + storageConfigs := v.([]interface{}) - "use_32_bit_worker_process": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, + for _, config := range storageConfigs { + storageConfig := config.(map[string]interface{}) - "websockets_enabled": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, + logs.ApplicationLogs.AzureBlobStorage = &web.AzureBlobStorageApplicationLogsConfig{ + Level: web.LogLevel(storageConfig["level"].(string)), + SasURL: utils.String(storageConfig["sas_url"].(string)), + RetentionInDays: utils.Int32(int32(storageConfig["retention_in_days"].(int))), + } + } + } + } + } - "ftps_state": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice([]string{ - string(web.AllAllowed), - string(web.Disabled), - string(web.FtpsOnly), - }, false), - }, - "linux_fx_version": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, + if v, ok := config["http_logs"]; ok { + httpLogsConfigs := v.([]interface{}) - "min_tls_version": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice([]string{ - string(web.OneFullStopZero), - string(web.OneFullStopOne), - string(web.OneFullStopTwo), - }, false), - }, + for _, config := range httpLogsConfigs { + httpLogsConfig := config.(map[string]interface{}) - "virtual_network_name": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, + logs.HTTPLogs = &web.HTTPLogsConfig{} + + if v, ok := httpLogsConfig["file_system"]; ok { + fileSystemConfigs := v.([]interface{}) + + for _, config := range fileSystemConfigs { + fileSystemConfig := config.(map[string]interface{}) + + logs.HTTPLogs.FileSystem = &web.FileSystemHTTPLogsConfig{ + RetentionInMb: utils.Int32(int32(fileSystemConfig["retention_in_mb"].(int))), + RetentionInDays: utils.Int32(int32(fileSystemConfig["retention_in_days"].(int))), + Enabled: utils.Bool(true), + } + } + } + } + } + + return logs +} + +func ExpandAppServiceIdentity(d *schema.ResourceData) *web.ManagedServiceIdentity { + identities := d.Get("identity").([]interface{}) + if len(identities) == 0 { + return nil + } + identity := identities[0].(map[string]interface{}) + identityType := web.ManagedServiceIdentityType(identity["type"].(string)) + + identityIds := make(map[string]*web.ManagedServiceIdentityUserAssignedIdentitiesValue) + for _, id := range identity["identity_ids"].([]interface{}) { + identityIds[id.(string)] = &web.ManagedServiceIdentityUserAssignedIdentitiesValue{} + } + + managedServiceIdentity := web.ManagedServiceIdentity{ + Type: identityType, + } + + if managedServiceIdentity.Type == web.ManagedServiceIdentityTypeUserAssigned || managedServiceIdentity.Type == web.ManagedServiceIdentityTypeSystemAssignedUserAssigned { + managedServiceIdentity.UserAssignedIdentities = identityIds + } + + return &managedServiceIdentity +} + +func FlattenAppServiceIdentity(identity *web.ManagedServiceIdentity) []interface{} { + if identity == nil { + return make([]interface{}, 0) + } + + result := make(map[string]interface{}) + result["type"] = string(identity.Type) + + if identity.PrincipalID != nil { + result["principal_id"] = *identity.PrincipalID + } + if identity.TenantID != nil { + result["tenant_id"] = *identity.TenantID } + + identityIds := make([]string, 0) + if identity.UserAssignedIdentities != nil { + for key := range identity.UserAssignedIdentities { + identityIds = append(identityIds, key) + } + } + result["identity_ids"] = identityIds + + return []interface{}{result} } -func ExpandAppServiceSiteConfig(input interface{}) web.SiteConfig { +func ExpandAppServiceSiteConfig(input interface{}) (*web.SiteConfig, error) { configs := input.([]interface{}) - siteConfig := web.SiteConfig{} + siteConfig := &web.SiteConfig{} if len(configs) == 0 { - return siteConfig + return siteConfig, nil } config := configs[0].(map[string]interface{}) @@ -276,6 +1358,10 @@ func ExpandAppServiceSiteConfig(input interface{}) web.SiteConfig { siteConfig.LinuxFxVersion = utils.String(v.(string)) } + if v, ok := config["windows_fx_version"]; ok { + siteConfig.WindowsFxVersion = utils.String(v.(string)) + } + if v, ok := config["http2_enabled"]; ok { siteConfig.HTTP20Enabled = utils.Bool(v.(bool)) } @@ -283,26 +1369,45 @@ func ExpandAppServiceSiteConfig(input interface{}) web.SiteConfig { if v, ok := config["ip_restriction"]; ok { ipSecurityRestrictions := v.([]interface{}) restrictions := make([]web.IPSecurityRestriction, 0) - for _, ipSecurityRestriction := range ipSecurityRestrictions { + for i, ipSecurityRestriction := range ipSecurityRestrictions { restriction := ipSecurityRestriction.(map[string]interface{}) ipAddress := restriction["ip_address"].(string) - mask := restriction["subnet_mask"].(string) - // the 2018-02-01 API expects a blank subnet mask and an IP address in CIDR format: a.b.c.d/x - // so translate the IP and mask if necessary - restrictionMask := "" - cidrAddress := ipAddress - if mask != "" { - ipNet := net.IPNet{IP: net.ParseIP(ipAddress), Mask: net.IPMask(net.ParseIP(mask))} - cidrAddress = ipNet.String() - } else if !strings.Contains(ipAddress, "/") { - cidrAddress += "/32" + vNetSubnetID := restriction["virtual_network_subnet_id"].(string) + if vNetSubnetID != "" && ipAddress != "" { + return siteConfig, fmt.Errorf(fmt.Sprintf("only one of `ip_address` or `virtual_network_subnet_id` can set set for `site_config.0.ip_restriction.%d`", i)) + } + + if vNetSubnetID == "" && ipAddress == "" { + return siteConfig, fmt.Errorf(fmt.Sprintf("one of `ip_address` or `virtual_network_subnet_id` must be set set for `site_config.0.ip_restriction.%d`", i)) + } + + ipSecurityRestriction := web.IPSecurityRestriction{} + if ipAddress != "" { + mask := restriction["subnet_mask"].(string) + if mask == "" { + mask = "255.255.255.255" + } + // the 2018-02-01 API expects a blank subnet mask and an IP address in CIDR format: a.b.c.d/x + // so translate the IP and mask if necessary + restrictionMask := "" + cidrAddress := ipAddress + if mask != "" { + ipNet := net.IPNet{IP: net.ParseIP(ipAddress), Mask: net.IPMask(net.ParseIP(mask))} + cidrAddress = ipNet.String() + } else if !strings.Contains(ipAddress, "/") { + cidrAddress += "/32" + } + ipSecurityRestriction.IPAddress = &cidrAddress + ipSecurityRestriction.SubnetMask = &restrictionMask } - restrictions = append(restrictions, web.IPSecurityRestriction{ - IPAddress: &cidrAddress, - SubnetMask: &restrictionMask, - }) + if vNetSubnetID != "" { + ipSecurityRestriction.VnetSubnetResourceID = &vNetSubnetID + } + + restrictions = append(restrictions, ipSecurityRestriction) + } siteConfig.IPSecurityRestrictions = &restrictions } @@ -355,7 +1460,13 @@ func ExpandAppServiceSiteConfig(input interface{}) web.SiteConfig { siteConfig.VnetName = utils.String(v.(string)) } - return siteConfig + if v, ok := config["cors"]; ok { + corsSettings := v.(interface{}) + expand := ExpandWebCorsSettings(corsSettings) + siteConfig.Cors = &expand + } + + return siteConfig, nil } func FlattenAppServiceSiteConfig(input *web.SiteConfig) []interface{} { @@ -423,6 +1534,9 @@ func FlattenAppServiceSiteConfig(input *web.SiteConfig) []interface{} { if subnet := v.SubnetMask; subnet != nil { block["subnet_mask"] = *subnet } + if vNetSubnetID := v.VnetSubnetResourceID; vNetSubnetID != nil { + block["virtual_network_subnet_id"] = *vNetSubnetID + } restrictions = append(restrictions, block) } } @@ -458,6 +1572,10 @@ func FlattenAppServiceSiteConfig(input *web.SiteConfig) []interface{} { result["linux_fx_version"] = *input.LinuxFxVersion } + if input.WindowsFxVersion != nil { + result["windows_fx_version"] = *input.WindowsFxVersion + } + if input.VnetName != nil { result["virtual_network_name"] = *input.VnetName } @@ -466,5 +1584,58 @@ func FlattenAppServiceSiteConfig(input *web.SiteConfig) []interface{} { result["ftps_state"] = string(input.FtpsState) result["min_tls_version"] = string(input.MinTLSVersion) + result["cors"] = FlattenWebCorsSettings(input.Cors) + return append(results, result) } + +func ExpandAppServiceStorageAccounts(d *schema.ResourceData) map[string]*web.AzureStorageInfoValue { + input := d.Get("storage_account").(*schema.Set).List() + output := make(map[string]*web.AzureStorageInfoValue, len(input)) + + for _, v := range input { + vals := v.(map[string]interface{}) + + saName := vals["name"].(string) + saType := vals["type"].(string) + saAccountName := vals["account_name"].(string) + saShareName := vals["share_name"].(string) + saAccessKey := vals["access_key"].(string) + saMountPath := vals["mount_path"].(string) + + output[saName] = &web.AzureStorageInfoValue{ + Type: web.AzureStorageType(saType), + AccountName: utils.String(saAccountName), + ShareName: utils.String(saShareName), + AccessKey: utils.String(saAccessKey), + MountPath: utils.String(saMountPath), + } + } + + return output +} + +func FlattenAppServiceStorageAccounts(input map[string]*web.AzureStorageInfoValue) []interface{} { + results := make([]interface{}, 0) + + for k, v := range input { + result := make(map[string]interface{}) + result["name"] = k + result["type"] = string(v.Type) + if v.AccountName != nil { + result["account_name"] = *v.AccountName + } + if v.ShareName != nil { + result["share_name"] = *v.ShareName + } + if v.AccessKey != nil { + result["access_key"] = *v.AccessKey + } + if v.MountPath != nil { + result["mount_path"] = *v.MountPath + } + results = append(results, result) + } + + return results +} diff --git a/azurerm/helpers/azure/app_service_schedule_backup.go b/azurerm/helpers/azure/app_service_schedule_backup.go new file mode 100644 index 000000000000..e4d19a852579 --- /dev/null +++ b/azurerm/helpers/azure/app_service_schedule_backup.go @@ -0,0 +1,188 @@ +package azure + +import ( + "time" + + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + + "github.com/Azure/go-autorest/autorest/date" + + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" +) + +func SchemaAppServiceBackup() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "storage_account_url": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.URLIsHTTPS, + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "schedule": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "frequency_interval": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 1000), + }, + + "frequency_unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "Day", + "Hour", + }, false), + }, + + "keep_at_least_one_backup": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "retention_period_in_days": { + Type: schema.TypeInt, + Optional: true, + Default: 30, + ValidateFunc: validation.IntBetween(0, 9999999), + }, + + "start_time": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: suppress.RFC3339Time, + ValidateFunc: validate.RFC3339Time, + }, + }, + }, + }, + }, + }, + } +} + +func ExpandAppServiceBackup(input []interface{}) *web.BackupRequest { + if len(input) == 0 { + return nil + } + + vals := input[0].(map[string]interface{}) + + name := vals["name"].(string) + storageAccountUrl := vals["storage_account_url"].(string) + enabled := vals["enabled"].(bool) + + request := &web.BackupRequest{ + BackupRequestProperties: &web.BackupRequestProperties{ + BackupName: utils.String(name), + StorageAccountURL: utils.String(storageAccountUrl), + Enabled: utils.Bool(enabled), + }, + } + + scheduleRaw := vals["schedule"].([]interface{}) + if len(scheduleRaw) > 0 { + schedule := scheduleRaw[0].(map[string]interface{}) + backupSchedule := web.BackupSchedule{} + + if v, ok := schedule["frequency_interval"].(int); ok { + backupSchedule.FrequencyInterval = utils.Int32(int32(v)) + } + + if v, ok := schedule["frequency_unit"]; ok { + backupSchedule.FrequencyUnit = web.FrequencyUnit(v.(string)) + } + + if v, ok := schedule["keep_at_least_one_backup"]; ok { + backupSchedule.KeepAtLeastOneBackup = utils.Bool(v.(bool)) + } + + if v, ok := schedule["retention_period_in_days"].(int); ok { + backupSchedule.RetentionPeriodInDays = utils.Int32(int32(v)) + } + + if v, ok := schedule["start_time"].(string); ok { + dateTimeToStart, _ := time.Parse(time.RFC3339, v) //validated by schema + backupSchedule.StartTime = &date.Time{Time: dateTimeToStart} + } + + request.BackupRequestProperties.BackupSchedule = &backupSchedule + } + + return request +} + +func FlattenAppServiceBackup(input *web.BackupRequestProperties) []interface{} { + if input == nil { + return []interface{}{} + } + + output := make(map[string]interface{}) + + if input.BackupName != nil { + output["name"] = *input.BackupName + } + if input.Enabled != nil { + output["enabled"] = *input.Enabled + } + if input.StorageAccountURL != nil { + output["storage_account_url"] = *input.StorageAccountURL + } + + schedules := make([]interface{}, 0) + if input.BackupSchedule != nil { + v := *input.BackupSchedule + + schedule := make(map[string]interface{}) + + if v.FrequencyInterval != nil { + schedule["frequency_interval"] = int(*v.FrequencyInterval) + } + + schedule["frequency_unit"] = string(v.FrequencyUnit) + + if v.KeepAtLeastOneBackup != nil { + schedule["keep_at_least_one_backup"] = *v.KeepAtLeastOneBackup + } + if v.RetentionPeriodInDays != nil { + schedule["retention_period_in_days"] = int(*v.RetentionPeriodInDays) + } + if v.StartTime != nil && !v.StartTime.IsZero() { + schedule["start_time"] = v.StartTime.Format(time.RFC3339) + } + + schedules = append(schedules, schedule) + } + output["schedule"] = schedules + + return []interface{}{ + output, + } +} diff --git a/azurerm/helpers/azure/batch_account.go b/azurerm/helpers/azure/batch_account.go new file mode 100644 index 000000000000..464792a9ecc2 --- /dev/null +++ b/azurerm/helpers/azure/batch_account.go @@ -0,0 +1,45 @@ +package azure + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" +) + +// ExpandBatchAccountKeyVaultReference expands Batch account KeyVault reference +func ExpandBatchAccountKeyVaultReference(list []interface{}) (*batch.KeyVaultReference, error) { + if len(list) == 0 { + return nil, fmt.Errorf("Error: key vault reference should be defined") + } + + keyVaultRef := list[0].(map[string]interface{}) + + keyVaultRefID := keyVaultRef["id"].(string) + keyVaultRefURL := keyVaultRef["url"].(string) + + ref := &batch.KeyVaultReference{ + ID: &keyVaultRefID, + URL: &keyVaultRefURL, + } + + return ref, nil +} + +// FlattenBatchAccountKeyvaultReference flattens a Batch account keyvault reference +func FlattenBatchAccountKeyvaultReference(keyVaultReference *batch.KeyVaultReference) interface{} { + result := make(map[string]interface{}) + + if keyVaultReference == nil { + return []interface{}{} + } + + if keyVaultReference.ID != nil { + result["id"] = *keyVaultReference.ID + } + + if keyVaultReference.URL != nil { + result["url"] = *keyVaultReference.URL + } + + return []interface{}{result} +} diff --git a/azurerm/helpers/azure/batch_pool.go b/azurerm/helpers/azure/batch_pool.go index 02e66b0efeac..74af6ade8cd8 100644 --- a/azurerm/helpers/azure/batch_pool.go +++ b/azurerm/helpers/azure/batch_pool.go @@ -5,7 +5,9 @@ import ( "log" "regexp" - "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2017-09-01/batch" + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) // FlattenBatchPoolAutoScaleSettings flattens the auto scale settings for a Batch pool @@ -123,6 +125,32 @@ func FlattenBatchPoolStartTask(startTask *batch.StartTask) []interface{} { result["user_identity"] = []interface{}{userIdentity} } + resourceFiles := make([]interface{}, 0) + if startTask.ResourceFiles != nil { + for _, armResourceFile := range *startTask.ResourceFiles { + resourceFile := make(map[string]interface{}) + if armResourceFile.AutoStorageContainerName != nil { + resourceFile["auto_storage_container_name"] = *armResourceFile.AutoStorageContainerName + } + if armResourceFile.StorageContainerURL != nil { + resourceFile["storage_container_url"] = *armResourceFile.StorageContainerURL + } + if armResourceFile.HTTPURL != nil { + resourceFile["http_url"] = *armResourceFile.HTTPURL + } + if armResourceFile.BlobPrefix != nil { + resourceFile["blob_prefix"] = *armResourceFile.BlobPrefix + } + if armResourceFile.FilePath != nil { + resourceFile["file_path"] = *armResourceFile.FilePath + } + if armResourceFile.FileMode != nil { + resourceFile["file_mode"] = *armResourceFile.FileMode + } + resourceFiles = append(resourceFiles, resourceFile) + } + } + if startTask.EnvironmentSettings != nil { environment := make(map[string]interface{}) for _, envSetting := range *startTask.EnvironmentSettings { @@ -131,10 +159,112 @@ func FlattenBatchPoolStartTask(startTask *batch.StartTask) []interface{} { result["environment"] = environment } + result["resource_file"] = resourceFiles return append(results, result) } +// FlattenBatchPoolCertificateReferences flattens a Batch pool certificate reference +func FlattenBatchPoolCertificateReferences(armCertificates *[]batch.CertificateReference) []interface{} { + if armCertificates == nil { + return []interface{}{} + } + output := make([]interface{}, 0) + + for _, armCertificate := range *armCertificates { + certificate := map[string]interface{}{} + if armCertificate.ID != nil { + certificate["id"] = *armCertificate.ID + } + certificate["store_location"] = string(armCertificate.StoreLocation) + if armCertificate.StoreName != nil { + certificate["store_name"] = *armCertificate.StoreName + } + visibility := &schema.Set{F: schema.HashString} + if armCertificate.Visibility != nil { + for _, armVisibility := range *armCertificate.Visibility { + visibility.Add(string(armVisibility)) + } + } + certificate["visibility"] = visibility + output = append(output, certificate) + } + return output +} + +// FlattenBatchPoolContainerConfiguration flattens a Batch pool container configuration +func FlattenBatchPoolContainerConfiguration(d *schema.ResourceData, armContainerConfiguration *batch.ContainerConfiguration) interface{} { + result := make(map[string]interface{}) + + if armContainerConfiguration == nil { + return nil + } + + if armContainerConfiguration.Type != nil { + result["type"] = *armContainerConfiguration.Type + } + result["container_registries"] = flattenBatchPoolContainerRegistries(d, armContainerConfiguration.ContainerRegistries) + + return []interface{}{result} +} + +func flattenBatchPoolContainerRegistries(d *schema.ResourceData, armContainerRegistries *[]batch.ContainerRegistry) []interface{} { + results := make([]interface{}, 0) + + if armContainerRegistries == nil { + return results + } + for _, armContainerRegistry := range *armContainerRegistries { + result := flattenBatchPoolContainerRegistry(d, &armContainerRegistry) + results = append(results, result) + } + return results +} + +func flattenBatchPoolContainerRegistry(d *schema.ResourceData, armContainerRegistry *batch.ContainerRegistry) map[string]interface{} { + result := make(map[string]interface{}) + + if armContainerRegistry == nil { + return result + } + if registryServer := armContainerRegistry.RegistryServer; registryServer != nil { + result["registry_server"] = *registryServer + } + if userName := armContainerRegistry.UserName; userName != nil { + result["user_name"] = *userName + } + + // If we didn't specify a registry server and user name, just return what we have now rather than trying to locate the password + if len(result) != 2 { + return result + } + + result["password"] = findBatchPoolContainerRegistryPassword(d, result["registry_server"].(string), result["user_name"].(string)) + + return result +} + +func findBatchPoolContainerRegistryPassword(d *schema.ResourceData, armServer string, armUsername string) interface{} { + numContainerRegistries := 0 + if n, ok := d.GetOk("container_configuration.0.container_registries.#"); ok { + numContainerRegistries = n.(int) + } else { + return "" + } + + for i := 0; i < numContainerRegistries; i++ { + if server, ok := d.GetOk(fmt.Sprintf("container_configuration.0.container_registries.%d.registry_server", i)); !ok || server != armServer { + continue + } + if username, ok := d.GetOk(fmt.Sprintf("container_configuration.0.container_registries.%d.user_name", i)); !ok || username != armUsername { + continue + } + return d.Get(fmt.Sprintf("container_configuration.0.container_registries.%d.password", i)) + } + + return "" +} + // ExpandBatchPoolImageReference expands Batch pool image reference func ExpandBatchPoolImageReference(list []interface{}) (*batch.ImageReference, error) { if len(list) == 0 { @@ -142,22 +272,124 @@ func ExpandBatchPoolImageReference(list []interface{}) (*batch.ImageReference, e } storageImageRef := list[0].(map[string]interface{}) + imageRef := &batch.ImageReference{} - storageImageRefOffer := storageImageRef["offer"].(string) - storageImageRefPublisher := storageImageRef["publisher"].(string) - storageImageRefSku := storageImageRef["sku"].(string) - storageImageRefVersion := storageImageRef["version"].(string) + if storageImageRef["id"] != nil && storageImageRef["id"] != "" { + storageImageRefID := storageImageRef["id"].(string) + imageRef.ID = &storageImageRefID + } - imageRef := &batch.ImageReference{ - Offer: &storageImageRefOffer, - Publisher: &storageImageRefPublisher, - Sku: &storageImageRefSku, - Version: &storageImageRefVersion, + if storageImageRef["offer"] != nil && storageImageRef["offer"] != "" { + storageImageRefOffer := storageImageRef["offer"].(string) + imageRef.Offer = &storageImageRefOffer + } + + if storageImageRef["publisher"] != nil && storageImageRef["publisher"] != "" { + storageImageRefPublisher := storageImageRef["publisher"].(string) + imageRef.Publisher = &storageImageRefPublisher + } + + if storageImageRef["sku"] != nil && storageImageRef["sku"] != "" { + storageImageRefSku := storageImageRef["sku"].(string) + imageRef.Sku = &storageImageRefSku + } + + if storageImageRef["version"] != nil && storageImageRef["version"] != "" { + storageImageRefVersion := storageImageRef["version"].(string) + imageRef.Version = &storageImageRefVersion } return imageRef, nil } +// ExpandBatchPoolContainerConfiguration expands the Batch pool container configuration +func ExpandBatchPoolContainerConfiguration(list []interface{}) (*batch.ContainerConfiguration, error) { + if len(list) == 0 { + return nil, nil + } + + containerConfiguration := list[0].(map[string]interface{}) + containerType := containerConfiguration["type"].(string) + containerRegistries, err := expandBatchPoolContainerRegistries(containerConfiguration["container_registries"].([]interface{})) + if err != nil { + return nil, err + } + + containerConf := &batch.ContainerConfiguration{ + Type: &containerType, + ContainerRegistries: containerRegistries, + } + + return containerConf, nil +} + +func expandBatchPoolContainerRegistries(list []interface{}) (*[]batch.ContainerRegistry, error) { + result := []batch.ContainerRegistry{} + + for _, tempItem := range list { + item := tempItem.(map[string]interface{}) + containerRegistry, err := expandBatchPoolContainerRegistry(item) + if err != nil { + return nil, err + } + result = append(result, *containerRegistry) + } + return &result, nil +} + +func expandBatchPoolContainerRegistry(ref map[string]interface{}) (*batch.ContainerRegistry, error) { + if len(ref) == 0 { + return nil, fmt.Errorf("Error: container registry reference should be defined") + } + + containerRegistry := batch.ContainerRegistry{ + RegistryServer: utils.String(ref["registry_server"].(string)), + UserName: utils.String(ref["user_name"].(string)), + Password: utils.String(ref["password"].(string)), + } + return &containerRegistry, nil +} + +// ExpandBatchPoolCertificateReferences expands Batch pool certificate references +func ExpandBatchPoolCertificateReferences(list []interface{}) (*[]batch.CertificateReference, error) { + var result []batch.CertificateReference + + for _, tempItem := range list { + item := tempItem.(map[string]interface{}) + certificateReference, err := expandBatchPoolCertificateReference(item) + if err != nil { + return nil, err + } + result = append(result, *certificateReference) + } + return &result, nil +} + +func expandBatchPoolCertificateReference(ref map[string]interface{}) (*batch.CertificateReference, error) { + if len(ref) == 0 { + return nil, fmt.Errorf("Error: storage image reference should be defined") + } + + id := ref["id"].(string) + storeLocation := ref["store_location"].(string) + storeName := ref["store_name"].(string) + visibilityRefs := ref["visibility"].(*schema.Set) + var visibility []batch.CertificateVisibility + if visibilityRefs != nil { + for _, visibilityRef := range visibilityRefs.List() { + visibility = append(visibility, batch.CertificateVisibility(visibilityRef.(string))) + } + } + + certificateReference := &batch.CertificateReference{ + ID: &id, + StoreLocation: batch.CertificateStoreLocation(storeLocation), + StoreName: &storeName, + Visibility: &visibility, + } + return certificateReference, nil +} + // ExpandBatchPoolStartTask expands Batch pool start task func ExpandBatchPoolStartTask(list []interface{}) (*batch.StartTask, error) { if len(list) == 0 { @@ -195,11 +427,56 @@ func ExpandBatchPoolStartTask(list []interface{}) (*batch.StartTask, error) { return nil, fmt.Errorf("Error: either auto_user or user_name should be speicfied for Batch pool start task") } + resourceFileList := startTaskValue["resource_file"].([]interface{}) + resourceFiles := make([]batch.ResourceFile, 0) + for _, resourceFileValueTemp := range resourceFileList { + resourceFileValue := resourceFileValueTemp.(map[string]interface{}) + resourceFile := batch.ResourceFile{} + if v, ok := resourceFileValue["auto_storage_container_name"]; ok { + autoStorageContainerName := v.(string) + if autoStorageContainerName != "" { + resourceFile.AutoStorageContainerName = &autoStorageContainerName + } + } + if v, ok := resourceFileValue["storage_container_url"]; ok { + storageContainerURL := v.(string) + if storageContainerURL != "" { + resourceFile.StorageContainerURL = &storageContainerURL + } + } + if v, ok := resourceFileValue["http_url"]; ok { + httpURL := v.(string) + if httpURL != "" { + resourceFile.HTTPURL = &httpURL + } + } + if v, ok := resourceFileValue["blob_prefix"]; ok { + blobPrefix := v.(string) + if blobPrefix != "" { + resourceFile.BlobPrefix = &blobPrefix + } + } + if v, ok := resourceFileValue["file_path"]; ok { + filePath := v.(string) + if filePath != "" { + resourceFile.FilePath = &filePath + } + } + if v, ok := resourceFileValue["file_mode"]; ok { + fileMode := v.(string) + if fileMode != "" { + resourceFile.FileMode = &fileMode + } + } + resourceFiles = append(resourceFiles, resourceFile) + } + startTask := &batch.StartTask{ CommandLine: &startTaskCmdLine, MaxTaskRetryCount: &maxTaskRetryCount, WaitForSuccess: &waitForSuccess, UserIdentity: &userIdentity, + ResourceFiles: &resourceFiles, } // populate environment settings, if defined diff --git a/azurerm/helpers/azure/container_group.go b/azurerm/helpers/azure/container_group.go new file mode 100644 index 000000000000..ca59efbfc616 --- /dev/null +++ b/azurerm/helpers/azure/container_group.go @@ -0,0 +1,90 @@ +package azure + +import ( + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" +) + +func SchemaContainerGroupProbe() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "exec": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.NoZeroValues, + }, + }, + + "http_get": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "port": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + ValidateFunc: validate.PortNumber, + }, + "scheme": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + "Http", + "Https", + }, false), + }, + }, + }, + }, + + "initial_delay_seconds": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "period_seconds": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "failure_threshold": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "success_threshold": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "timeout_seconds": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + }, + }, + } +} diff --git a/azurerm/helpers/azure/cosmos.go b/azurerm/helpers/azure/cosmos.go new file mode 100644 index 000000000000..c3a9b09675a6 --- /dev/null +++ b/azurerm/helpers/azure/cosmos.go @@ -0,0 +1,157 @@ +package azure + +import ( + "fmt" + + "github.com/Azure/go-autorest/autorest" +) + +// it seems the cosmos API is not returning any sort of valid ID in the main response body +// so lets grab it from the response.request.url.path +func CosmosGetIDFromResponse(resp autorest.Response) (string, error) { + if resp.Response == nil { + return "", fmt.Errorf("Error: Unable to get Cosmos ID from Response: http response is nil") + } + + if resp.Response.Request == nil { + return "", fmt.Errorf("Error: Unable to get Cosmos ID from Response: Request is nil") + } + + if resp.Response.Request.URL == nil { + return "", fmt.Errorf("Error: Unable to get Cosmos ID from Response: URL is nil") + } + + return resp.Response.Request.URL.Path, nil +} + +type CosmosAccountID struct { + ResourceID + Account string +} + +func ParseCosmosAccountID(id string) (*CosmosAccountID, error) { + subid, err := ParseAzureResourceID(id) + if err != nil { + return nil, err + } + + account, ok := subid.Path["databaseAccounts"] + if !ok { + return nil, fmt.Errorf("Error: Unable to parse Cosmos Database Resource ID: databaseAccounts is missing from: %s", id) + } + + return &CosmosAccountID{ + ResourceID: *subid, + Account: account, + }, nil +} + +type CosmosDatabaseID struct { + CosmosAccountID + Database string +} + +func ParseCosmosDatabaseID(id string) (*CosmosDatabaseID, error) { + subid, err := ParseCosmosAccountID(id) + if err != nil { + return nil, err + } + + db, ok := subid.Path["databases"] + if !ok { + return nil, fmt.Errorf("Error: Unable to parse Cosmos Database Resource ID: databases is missing from: %s", id) + } + + return &CosmosDatabaseID{ + CosmosAccountID: *subid, + Database: db, + }, nil +} + +type CosmosDatabaseCollectionID struct { + CosmosDatabaseID + Collection string +} + +func ParseCosmosDatabaseCollectionID(id string) (*CosmosDatabaseCollectionID, error) { + subid, err := ParseCosmosDatabaseID(id) + if err != nil { + return nil, err + } + + collection, ok := subid.Path["collections"] + if !ok { + return nil, fmt.Errorf("Error: Unable to parse Cosmos Database Resource ID: collections is missing from: %s", id) + } + + return &CosmosDatabaseCollectionID{ + CosmosDatabaseID: *subid, + Collection: collection, + }, nil +} + +type CosmosDatabaseContainerID struct { + CosmosDatabaseID + Container string +} + +func ParseCosmosDatabaseContainerID(id string) (*CosmosDatabaseContainerID, error) { + subid, err := ParseCosmosDatabaseID(id) + if err != nil { + return nil, err + } + + container, ok := subid.Path["containers"] + if !ok { + return nil, fmt.Errorf("Error: Unable to parse Cosmos Database Container Resource ID: containers is missing from: %s", id) + } + + return &CosmosDatabaseContainerID{ + CosmosDatabaseID: *subid, + Container: container, + }, nil +} + +type CosmosKeyspaceID struct { + CosmosAccountID + Keyspace string +} + +func ParseCosmosKeyspaceID(id string) (*CosmosKeyspaceID, error) { + subid, err := ParseCosmosAccountID(id) + if err != nil { + return nil, err + } + + ks, ok := subid.Path["keyspaces"] + if !ok { + return nil, fmt.Errorf("Error: Unable to parse Cosmos Keyspace Resource ID: keyspaces is missing from: %s", id) + } + + return &CosmosKeyspaceID{ + CosmosAccountID: *subid, + Keyspace: ks, + }, nil +} + +type CosmosTableID struct { + CosmosAccountID + Table string +} + +func ParseCosmosTableID(id string) (*CosmosTableID, error) { + subid, err := ParseCosmosAccountID(id) + if err != nil { + return nil, err + } + + table, ok := subid.Path["tables"] + if !ok { + return nil, fmt.Errorf("Error: Unable to parse Cosmos Table Resource ID: tables is missing from: %s", id) + } + + return &CosmosTableID{ + CosmosAccountID: *subid, + Table: table, + }, nil +} diff --git a/azurerm/helpers/azure/hdinsight.go b/azurerm/helpers/azure/hdinsight.go new file mode 100644 index 000000000000..264f4efc168e --- /dev/null +++ b/azurerm/helpers/azure/hdinsight.go @@ -0,0 +1,567 @@ +package azure + +import ( + "fmt" + "strconv" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/go-getter/helper/url" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func SchemaHDInsightName() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.HDInsightName, + } +} + +func SchemaHDInsightDataSourceName() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.HDInsightName, + } +} + +func SchemaHDInsightTier() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(hdinsight.Standard), + string(hdinsight.Premium), + }, false), + // TODO: file a bug about this + DiffSuppressFunc: SuppressLocationDiff, + } +} + +func SchemaHDInsightClusterVersion() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.HDInsightClusterVersion, + DiffSuppressFunc: hdinsightClusterVersionDiffSuppressFunc, + } +} + +func hdinsightClusterVersionDiffSuppressFunc(_, old, new string, _ *schema.ResourceData) bool { + // `3.6` gets converted to `3.6.1000.67`; so let's just compare major/minor if possible + o := strings.Split(old, ".") + n := strings.Split(new, ".") + + if len(o) >= 2 && len(n) >= 2 { + oldMajor := o[0] + oldMinor := o[1] + newMajor := n[0] + newMinor := n[1] + + return oldMajor == newMajor && oldMinor == newMinor + } + + return false +} + +func SchemaHDInsightsGateway() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + ForceNew: true, + }, + // NOTE: these are Required since if these aren't present you get a `500 bad request` + "username": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "password": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Sensitive: true, + }, + }, + }, + } +} + +func ExpandHDInsightsConfigurations(input []interface{}) map[string]interface{} { + vs := input[0].(map[string]interface{}) + + // NOTE: Admin username must be different from SSH Username + enabled := vs["enabled"].(bool) + username := vs["username"].(string) + password := vs["password"].(string) + + return map[string]interface{}{ + "gateway": map[string]interface{}{ + "restAuthCredential.isEnabled": enabled, + "restAuthCredential.username": username, + "restAuthCredential.password": password, + }, + } +} + +func FlattenHDInsightsConfigurations(input map[string]*string) []interface{} { + enabled := false + if v, exists := input["restAuthCredential.isEnabled"]; exists && v != nil { + e, err := strconv.ParseBool(*v) + if err == nil { + enabled = e + } + } + + username := "" + if v, exists := input["restAuthCredential.username"]; exists && v != nil { + username = *v + } + + password := "" + if v, exists := input["restAuthCredential.password"]; exists && v != nil { + password = *v + } + + return []interface{}{ + map[string]interface{}{ + "enabled": enabled, + "username": username, + "password": password, + }, + } +} + +func SchemaHDInsightsStorageAccounts() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "storage_account_key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "storage_container_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "is_default": { + Type: schema.TypeBool, + Required: true, + ForceNew: true, + }, + }, + }, + } +} + +func ExpandHDInsightsStorageAccounts(input []interface{}) (*[]hdinsight.StorageAccount, error) { + results := make([]hdinsight.StorageAccount, 0) + + for _, vs := range input { + v := vs.(map[string]interface{}) + + storageAccountKey := v["storage_account_key"].(string) + storageContainerId := v["storage_container_id"].(string) + isDefault := v["is_default"].(bool) + + // https://foo.blob.core.windows.net/example + uri, err := url.Parse(storageContainerId) + if err != nil { + return nil, fmt.Errorf("Error parsing %q: %s", storageContainerId, err) + } + + result := hdinsight.StorageAccount{ + Name: utils.String(uri.Host), + Container: utils.String(strings.TrimPrefix(uri.Path, "/")), + Key: utils.String(storageAccountKey), + IsDefault: utils.Bool(isDefault), + } + results = append(results, result) + } + + return &results, nil +} + +type HDInsightNodeDefinition struct { + CanSpecifyInstanceCount bool + MinInstanceCount int + MaxInstanceCount int + CanSpecifyDisks bool + MaxNumberOfDisksPerNode *int + FixedMinInstanceCount *int32 + FixedTargetInstanceCount *int32 +} + +func SchemaHDInsightNodeDefinition(schemaLocation string, definition HDInsightNodeDefinition) *schema.Schema { + result := map[string]*schema.Schema{ + "vm_size": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + // short of deploying every VM Sku for every node type for every HDInsight Cluster + // this is the list I've (@tombuildsstuff) found for valid SKU's from an endpoint in the Portal + // using another SKU causes a bad request from the API - as such this is a best effort UX + "ExtraSmall", + "Small", + "Medium", + "Large", + "ExtraLarge", + "A5", + "A6", + "A7", + "A8", + "A9", + "A10", + "A11", + "Standard_A1_V2", + "Standard_A2_V2", + "Standard_A2m_V2", + "Standard_A3", + "Standard_A4_V2", + "Standard_A4m_V2", + "Standard_A8_V2", + "Standard_A8m_V2", + "Standard_D1", + "Standard_D2", + "Standard_D3", + "Standard_D4", + "Standard_D11", + "Standard_D12", + "Standard_D13", + "Standard_D14", + "Standard_D1_V2", + "Standard_D2_V2", + "Standard_D3_V2", + "Standard_D4_V2", + "Standard_D5_V2", + "Standard_D11_V2", + "Standard_D12_V2", + "Standard_D13_V2", + "Standard_D14_V2", + "Standard_DS1_V2", + "Standard_DS2_V2", + "Standard_DS3_V2", + "Standard_DS4_V2", + "Standard_DS5_V2", + "Standard_DS11_V2", + "Standard_DS12_V2", + "Standard_DS13_V2", + "Standard_DS14_V2", + "Standard_E2_V3", + "Standard_E4_V3", + "Standard_E8_V3", + "Standard_E16_V3", + "Standard_E20_V3", + "Standard_E32_V3", + "Standard_E64_V3", + "Standard_E64i_V3", + "Standard_E2s_V3", + "Standard_E4s_V3", + "Standard_E8s_V3", + "Standard_E16s_V3", + "Standard_E20s_V3", + "Standard_E32s_V3", + "Standard_E64s_V3", + "Standard_E64is_V3", + "Standard_G1", + "Standard_G2", + "Standard_G3", + "Standard_G4", + "Standard_G5", + "Standard_F2s_V2", + "Standard_F4s_V2", + "Standard_F8s_V2", + "Standard_F16s_V2", + "Standard_F32s_V2", + "Standard_F64s_V2", + "Standard_F72s_V2", + "Standard_GS1", + "Standard_GS2", + "Standard_GS3", + "Standard_GS4", + "Standard_GS5", + "Standard_NC24", + }, true), + }, + "username": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "password": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Sensitive: true, + }, + "ssh_keys": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + Set: schema.HashString, + ConflictsWith: []string{ + fmt.Sprintf("%s.0.password", schemaLocation), + }, + }, + + "subnet_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: ValidateResourceIDOrEmpty, + }, + + "virtual_network_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: ValidateResourceIDOrEmpty, + }, + } + + if definition.CanSpecifyInstanceCount { + result["min_instance_count"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(definition.MinInstanceCount, definition.MaxInstanceCount), + } + result["target_instance_count"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(definition.MinInstanceCount, definition.MaxInstanceCount), + } + } + + if definition.CanSpecifyDisks { + result["number_of_disks_per_node"] = &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(1, *definition.MaxNumberOfDisksPerNode), + } + } + + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: result, + }, + } +} + +func ExpandHDInsightNodeDefinition(name string, input []interface{}, definition HDInsightNodeDefinition) (*hdinsight.Role, error) { + v := input[0].(map[string]interface{}) + vmSize := v["vm_size"].(string) + username := v["username"].(string) + password := v["password"].(string) + virtualNetworkId := v["virtual_network_id"].(string) + subnetId := v["subnet_id"].(string) + + role := hdinsight.Role{ + Name: utils.String(name), + HardwareProfile: &hdinsight.HardwareProfile{ + VMSize: utils.String(vmSize), + }, + OsProfile: &hdinsight.OsProfile{ + LinuxOperatingSystemProfile: &hdinsight.LinuxOperatingSystemProfile{ + Username: utils.String(username), + }, + }, + } + + virtualNetworkSpecified := virtualNetworkId != "" + subnetSpecified := subnetId != "" + if virtualNetworkSpecified && subnetSpecified { + role.VirtualNetworkProfile = &hdinsight.VirtualNetworkProfile{ + ID: utils.String(virtualNetworkId), + Subnet: utils.String(subnetId), + } + } else if (virtualNetworkSpecified && !subnetSpecified) || (subnetSpecified && !virtualNetworkSpecified) { + return nil, fmt.Errorf("`virtual_network_id` and `subnet_id` must both either be set or empty!") + } + + if password != "" { + role.OsProfile.LinuxOperatingSystemProfile.Password = utils.String(password) + } else { + sshKeysRaw := v["ssh_keys"].(*schema.Set).List() + sshKeys := make([]hdinsight.SSHPublicKey, 0) + for _, v := range sshKeysRaw { + sshKeys = append(sshKeys, hdinsight.SSHPublicKey{ + CertificateData: utils.String(v.(string)), + }) + } + + if len(sshKeys) == 0 { + return nil, fmt.Errorf("Either a `password` or `ssh_key` must be specified!") + } + + role.OsProfile.LinuxOperatingSystemProfile.SSHProfile = &hdinsight.SSHProfile{ + PublicKeys: &sshKeys, + } + } + + if definition.CanSpecifyInstanceCount { + minInstanceCount := v["min_instance_count"].(int) + if minInstanceCount > 0 { + role.MinInstanceCount = utils.Int32(int32(minInstanceCount)) + } + + targetInstanceCount := v["target_instance_count"].(int) + role.TargetInstanceCount = utils.Int32(int32(targetInstanceCount)) + } else { + role.MinInstanceCount = definition.FixedMinInstanceCount + role.TargetInstanceCount = definition.FixedTargetInstanceCount + } + + if definition.CanSpecifyDisks { + numberOfDisksPerNode := v["number_of_disks_per_node"].(int) + if numberOfDisksPerNode > 0 { + role.DataDisksGroups = &[]hdinsight.DataDisksGroups{ + { + DisksPerNode: utils.Int32(int32(numberOfDisksPerNode)), + }, + } + } + } + + return &role, nil +} + +func FlattenHDInsightNodeDefinition(input *hdinsight.Role, existing []interface{}, definition HDInsightNodeDefinition) []interface{} { + if input == nil { + return []interface{}{} + } + + output := map[string]interface{}{ + "vm_size": "", + "username": "", + "password": "", + "ssh_keys": schema.NewSet(schema.HashString, []interface{}{}), + "subnet_id": "", + "virtual_network_id": "", + } + + if profile := input.OsProfile; profile != nil { + if osProfile := profile.LinuxOperatingSystemProfile; osProfile != nil { + if username := osProfile.Username; username != nil { + output["username"] = *username + } + } + } + + // neither Password / SSH Keys are returned from the API, so we need to look them up to not force a diff + if len(existing) > 0 { + existingV := existing[0].(map[string]interface{}) + output["password"] = existingV["password"].(string) + + sshKeys := existingV["ssh_keys"].(*schema.Set).List() + output["ssh_keys"] = schema.NewSet(schema.HashString, sshKeys) + + // whilst the VMSize can be returned from `input.HardwareProfile.VMSize` - it can be malformed + // for example, `small`, `medium`, `large` and `extralarge` can be returned inside of actual VM Size + // after extensive experimentation it appears multiple instance sizes fit `extralarge`, as such + // unfortunately we can't transform these; since it can't be changed + // we should be "safe" to try and pull it from the state instead, but clearly this isn't ideal + vmSize := existingV["vm_size"].(string) + output["vm_size"] = vmSize + } + + if profile := input.VirtualNetworkProfile; profile != nil { + if profile.ID != nil { + output["virtual_network_id"] = *profile.ID + } + if profile.Subnet != nil { + output["subnet_id"] = *profile.Subnet + } + } + + if definition.CanSpecifyInstanceCount { + output["min_instance_count"] = 0 + output["target_instance_count"] = 0 + + if input.MinInstanceCount != nil { + output["min_instance_count"] = int(*input.MinInstanceCount) + } + + if input.TargetInstanceCount != nil { + output["target_instance_count"] = int(*input.TargetInstanceCount) + } + } + + if definition.CanSpecifyDisks { + output["number_of_disks_per_node"] = 0 + if input.DataDisksGroups != nil && len(*input.DataDisksGroups) > 0 { + group := (*input.DataDisksGroups)[0] + if group.DisksPerNode != nil { + output["number_of_disks_per_node"] = int(*group.DisksPerNode) + } + } + } + + return []interface{}{output} +} + +func FindHDInsightRole(input *[]hdinsight.Role, name string) *hdinsight.Role { + if input == nil { + return nil + } + + for _, v := range *input { + if v.Name == nil { + continue + } + + actualName := *v.Name + if strings.EqualFold(name, actualName) { + return &v + } + } + + return nil +} + +func FindHDInsightConnectivityEndpoint(name string, input *[]hdinsight.ConnectivityEndpoint) string { + if input == nil { + return "" + } + + for _, v := range *input { + if v.Name == nil || v.Location == nil { + continue + } + + if strings.EqualFold(*v.Name, name) { + return *v.Location + } + } + + return "" +} diff --git a/azurerm/helpers/azure/hdinsight_test.go b/azurerm/helpers/azure/hdinsight_test.go new file mode 100644 index 000000000000..2fe2ac6e96e9 --- /dev/null +++ b/azurerm/helpers/azure/hdinsight_test.go @@ -0,0 +1,51 @@ +package azure + +import "testing" + +func TestHDInsightClusterVersionDiffSuppress(t *testing.T) { + tests := []struct { + name string + userInput string + azureResponse string + suppressed bool + }{ + { + name: "empty name", + userInput: "", + azureResponse: "", + suppressed: false, + }, + { + name: "missing user input", + userInput: "", + azureResponse: "1.2.3.4", + suppressed: false, + }, + { + name: "missing api response", + userInput: "1.2", + azureResponse: "", + suppressed: false, + }, + { + name: "major minor user input", + userInput: "3.6", + azureResponse: "3.6.1000.67", + suppressed: true, + }, + { + name: "full version user input", + userInput: "3.6.1000.67", + azureResponse: "3.6.1000.67", + suppressed: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wasSuppressed := hdinsightClusterVersionDiffSuppressFunc("", tt.userInput, tt.azureResponse, nil) + if tt.suppressed != wasSuppressed { + t.Errorf("Expected %q to be %t but got %t", tt.name, tt.suppressed, wasSuppressed) + } + }) + } +} diff --git a/azurerm/helpers/azure/key_vault.go b/azurerm/helpers/azure/key_vault.go index abdb28865c15..3b63eb973ce5 100644 --- a/azurerm/helpers/azure/key_vault.go +++ b/azurerm/helpers/azure/key_vault.go @@ -3,11 +3,12 @@ package azure import ( "context" "fmt" + "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2018-02-14/keyvault" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func GetKeyVaultBaseUrlFromID(ctx context.Context, client keyvault.VaultsClient, keyVaultId string) (string, error) { +func GetKeyVaultBaseUrlFromID(ctx context.Context, client *keyvault.VaultsClient, keyVaultId string) (string, error) { if keyVaultId == "" { return "", fmt.Errorf("keyVaultId is empty") @@ -39,7 +40,7 @@ func GetKeyVaultBaseUrlFromID(ctx context.Context, client keyvault.VaultsClient, return *resp.Properties.VaultURI, nil } -func GetKeyVaultIDFromBaseUrl(ctx context.Context, client keyvault.VaultsClient, keyVaultUrl string) (*string, error) { +func GetKeyVaultIDFromBaseUrl(ctx context.Context, client *keyvault.VaultsClient, keyVaultUrl string) (*string, error) { list, err := client.ListComplete(ctx, utils.Int32(1000)) if err != nil { return nil, fmt.Errorf("Error GetKeyVaultId unable to list Key Vaults %v", err) @@ -88,7 +89,7 @@ func GetKeyVaultIDFromBaseUrl(ctx context.Context, client keyvault.VaultsClient, return nil, nil } -func KeyVaultExists(ctx context.Context, client keyvault.VaultsClient, keyVaultId string) (bool, error) { +func KeyVaultExists(ctx context.Context, client *keyvault.VaultsClient, keyVaultId string) (bool, error) { if keyVaultId == "" { return false, fmt.Errorf("keyVaultId is empty") diff --git a/azurerm/helpers/azure/key_vault_access_policy.go b/azurerm/helpers/azure/key_vault_access_policy.go index 270b72773910..1720d252cecb 100644 --- a/azurerm/helpers/azure/key_vault_access_policy.go +++ b/azurerm/helpers/azure/key_vault_access_policy.go @@ -87,6 +87,32 @@ func SchemaKeyVaultSecretPermissions() *schema.Schema { } } +func SchemaKeyVaultStoragePermissions() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(keyvault.StoragePermissionsBackup), + string(keyvault.StoragePermissionsDelete), + string(keyvault.StoragePermissionsDeletesas), + string(keyvault.StoragePermissionsGet), + string(keyvault.StoragePermissionsGetsas), + string(keyvault.StoragePermissionsList), + string(keyvault.StoragePermissionsListsas), + string(keyvault.StoragePermissionsPurge), + string(keyvault.StoragePermissionsRecover), + string(keyvault.StoragePermissionsRegeneratekey), + string(keyvault.StoragePermissionsRestore), + string(keyvault.StoragePermissionsSet), + string(keyvault.StoragePermissionsSetsas), + string(keyvault.StoragePermissionsUpdate), + }, false), + }, + } +} + func ExpandKeyVaultAccessPolicies(input []interface{}) (*[]keyvault.AccessPolicyEntry, error) { output := make([]keyvault.AccessPolicyEntry, 0) @@ -96,12 +122,14 @@ func ExpandKeyVaultAccessPolicies(input []interface{}) (*[]keyvault.AccessPolicy certificatePermissionsRaw := policyRaw["certificate_permissions"].([]interface{}) keyPermissionsRaw := policyRaw["key_permissions"].([]interface{}) secretPermissionsRaw := policyRaw["secret_permissions"].([]interface{}) + storagePermissionsRaw := policyRaw["storage_permissions"].([]interface{}) policy := keyvault.AccessPolicyEntry{ Permissions: &keyvault.Permissions{ Certificates: ExpandCertificatePermissions(certificatePermissionsRaw), Keys: ExpandKeyPermissions(keyPermissionsRaw), Secrets: ExpandSecretPermissions(secretPermissionsRaw), + Storage: ExpandStoragePermissions(storagePermissionsRaw), }, } @@ -152,6 +180,9 @@ func FlattenKeyVaultAccessPolicies(policies *[]keyvault.AccessPolicyEntry) []map secrets := FlattenSecretPermissions(permissions.Secrets) policyRaw["secret_permissions"] = secrets + + storage := FlattenStoragePermissions(permissions.Storage) + policyRaw["storage_permissions"] = storage } result = append(result, policyRaw) @@ -224,3 +255,25 @@ func FlattenSecretPermissions(input *[]keyvault.SecretPermissions) []interface{} return output } + +func ExpandStoragePermissions(input []interface{}) *[]keyvault.StoragePermissions { + output := make([]keyvault.StoragePermissions, 0) + + for _, permission := range input { + output = append(output, keyvault.StoragePermissions(permission.(string))) + } + + return &output +} + +func FlattenStoragePermissions(input *[]keyvault.StoragePermissions) []interface{} { + output := make([]interface{}, 0) + + if input != nil { + for _, storagePermission := range *input { + output = append(output, string(storagePermission)) + } + } + + return output +} diff --git a/azurerm/helpers/azure/location.go b/azurerm/helpers/azure/location.go index 2aeb9a242f27..64c6bb78732d 100644 --- a/azurerm/helpers/azure/location.go +++ b/azurerm/helpers/azure/location.go @@ -45,7 +45,7 @@ func SchemaLocationDeprecated() *schema.Schema { } } -// azureRMNormalizeLocation is a function which normalises human-readable region/location +// azure.NormalizeLocation is a function which normalises human-readable region/location // names (e.g. "West US") to the values used and returned by the Azure API (e.g. "westus"). // In state we track the API internal version as it is easier to go from the human form // to the canonical form than the other way around. @@ -54,7 +54,7 @@ func NormalizeLocation(location interface{}) string { return strings.Replace(strings.ToLower(input), " ", "", -1) } -func SuppressLocationDiff(k, old, new string, d *schema.ResourceData) bool { +func SuppressLocationDiff(_, old, new string, _ *schema.ResourceData) bool { return NormalizeLocation(old) == NormalizeLocation(new) } diff --git a/azurerm/helpers/azure/mssql.go b/azurerm/helpers/azure/mssql.go index 188bd78fdd8e..de9e37befe34 100644 --- a/azurerm/helpers/azure/mssql.go +++ b/azurerm/helpers/azure/mssql.go @@ -24,6 +24,14 @@ func ValidateMsSqlDatabaseName(i interface{}, k string) (_ []string, errors []er return nil, errors } +func ValidateMsSqlFailoverGroupName(i interface{}, k string) (_ []string, errors []error) { + if m, regexErrs := validate.RegExHelper(i, k, `^[0-9a-z]([-0-9a-z]{0,61}[0-9a-z])?$`); !m { + errors = append(regexErrs, fmt.Errorf("%q can contain only lowercase letters, numbers, and '-', but can't start or end with '-'.", k)) + } + + return nil, errors +} + //Following characters and any control characters are not allowed for resource name '%,&,\\\\,?,/'.\" //The name can not end with characters: '. ' //TODO: unsure about length, was able to deploy one at 120 diff --git a/azurerm/helpers/azure/mysql.go b/azurerm/helpers/azure/mysql.go new file mode 100644 index 000000000000..a54fe7f79973 --- /dev/null +++ b/azurerm/helpers/azure/mysql.go @@ -0,0 +1,15 @@ +package azure + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" +) + +func ValidateMySqlServerName(i interface{}, k string) (_ []string, errors []error) { + if m, regexErrs := validate.RegExHelper(i, k, `^[0-9a-z]([-0-9a-z]{0,61}[0-9a-z])?$`); !m { + errors = append(regexErrs, fmt.Errorf("%q can contain only lowercase letters, numbers, and '-', but can't start or end with '-' or have more than 63 characters.", k)) + } + + return nil, errors +} diff --git a/azurerm/helpers/azure/network_interface.go b/azurerm/helpers/azure/network_interface.go index d568e990b0e3..f7df6ee3a2da 100644 --- a/azurerm/helpers/azure/network_interface.go +++ b/azurerm/helpers/azure/network_interface.go @@ -1,6 +1,6 @@ package azure -import "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" +import "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" func FindNetworkInterfaceIPConfiguration(input *[]network.InterfaceIPConfiguration, name string) *network.InterfaceIPConfiguration { if input == nil { diff --git a/azurerm/helpers/azure/recovery_services_vault.go b/azurerm/helpers/azure/recovery_services_vault.go new file mode 100644 index 000000000000..e25e3bcb0d97 --- /dev/null +++ b/azurerm/helpers/azure/recovery_services_vault.go @@ -0,0 +1,21 @@ +package azure + +import ( + "regexp" + "strings" + + "github.com/hashicorp/terraform/helper/validation" +) + +func ValidateRecoveryServicesVaultName(v interface{}, k string) (warnings []string, errors []error) { + regexpValidator := validation.StringMatch( + regexp.MustCompile("^[a-zA-Z][-a-zA-Z0-9]{1,49}$"), + "Recovery Service Vault name must be 2 - 50 characters long, start with a letter, contain only letters, numbers and hyphens.", + ) + return regexpValidator(v, k) +} + +// This code is a workaround for this bug https://github.com/Azure/azure-sdk-for-go/issues/2824 +func HandleAzureSdkForGoBug2824(id string) string { + return strings.Replace(id, "/Subscriptions/", "/subscriptions/", 1) +} diff --git a/azurerm/helpers/azure/resource_group.go b/azurerm/helpers/azure/resource_group.go index 2a782c129f10..f59a1b272bd5 100644 --- a/azurerm/helpers/azure/resource_group.go +++ b/azurerm/helpers/azure/resource_group.go @@ -18,6 +18,15 @@ func SchemaResourceGroupName() *schema.Schema { } } +func SchemaResourceGroupNameDeprecated() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + Deprecated: "This field has been deprecated and is no longer used - will be removed in 2.0 of the Azure Provider", + } +} + func SchemaResourceGroupNameDiffSuppress() *schema.Schema { return &schema.Schema{ Type: schema.TypeString, diff --git a/azurerm/helpers/azure/resource_group_test.go b/azurerm/helpers/azure/resource_group_test.go index 004beb31151a..328a1edeec85 100644 --- a/azurerm/helpers/azure/resource_group_test.go +++ b/azurerm/helpers/azure/resource_group_test.go @@ -61,7 +61,8 @@ func TestValidateResourceGroupName(t *testing.T) { _, errors := validateResourceGroupName(tc.Value, "azurerm_resource_group") if len(errors) != tc.ErrCount { - t.Fatalf("Expected validateResourceGroupName to trigger '%d' errors for '%s' - got '%d'", tc.ErrCount, tc.Value, len(errors)) + t.Fatalf("Expected "+ + "validateResourceGroupName to trigger '%d' errors for '%s' - got '%d'", tc.ErrCount, tc.Value, len(errors)) } } } diff --git a/azurerm/helpers/azure/resourceid_test.go b/azurerm/helpers/azure/resourceid_test.go index 1217cc415e9f..5bc6f5b63aef 100644 --- a/azurerm/helpers/azure/resourceid_test.go +++ b/azurerm/helpers/azure/resourceid_test.go @@ -127,6 +127,19 @@ func TestParseAzureResourceID(t *testing.T) { }, false, }, + { + "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/example-resources/providers/Microsoft.ApiManagement/service/service1/subscriptions/22222222-2222-2222-2222-222222222222", + &ResourceID{ + SubscriptionID: "11111111-1111-1111-1111-111111111111", + ResourceGroup: "example-resources", + Provider: "Microsoft.ApiManagement", + Path: map[string]string{ + "service": "service1", + "subscriptions": "22222222-2222-2222-2222-222222222222", + }, + }, + false, + }, } for _, test := range testCases { diff --git a/azurerm/helpers/azure/sender.go b/azurerm/helpers/azure/sender.go deleted file mode 100644 index 901e0068d676..000000000000 --- a/azurerm/helpers/azure/sender.go +++ /dev/null @@ -1,57 +0,0 @@ -package azure - -import ( - "log" - "net/http" - "net/http/httputil" - - "github.com/Azure/go-autorest/autorest" -) - -func BuildSender() autorest.Sender { - return autorest.DecorateSender(&http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - }, - }, withRequestLogging()) -} - -func withRequestLogging() autorest.SendDecorator { - return func(s autorest.Sender) autorest.Sender { - return autorest.SenderFunc(func(r *http.Request) (*http.Response, error) { - // strip the authorization header prior to printing - authHeaderName := "Authorization" - auth := r.Header.Get(authHeaderName) - if auth != "" { - r.Header.Del(authHeaderName) - } - - // dump request to wire format - if dump, err := httputil.DumpRequestOut(r, true); err == nil { - log.Printf("[DEBUG] AzureRM Request: \n%s\n", dump) - } else { - // fallback to basic message - log.Printf("[DEBUG] AzureRM Request: %s to %s\n", r.Method, r.URL) - } - - // add the auth header back - if auth != "" { - r.Header.Add(authHeaderName, auth) - } - - resp, err := s.Do(r) - if resp != nil { - // dump response to wire format - if dump, err2 := httputil.DumpResponse(resp, true); err2 == nil { - log.Printf("[DEBUG] AzureRM Response for %s: \n%s\n", r.URL, dump) - } else { - // fallback to basic message - log.Printf("[DEBUG] AzureRM Response: %s for %s\n", resp.Status, r.URL) - } - } else { - log.Printf("[DEBUG] Request to %s completed with no response", r.URL) - } - return resp, err - }) - } -} diff --git a/azurerm/helpers/azure/stream_analytics_output.go b/azurerm/helpers/azure/stream_analytics_output.go new file mode 100644 index 000000000000..6bbbab92fa4b --- /dev/null +++ b/azurerm/helpers/azure/stream_analytics_output.go @@ -0,0 +1,166 @@ +package azure + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + + "github.com/hashicorp/terraform/helper/validation" + + "github.com/Azure/azure-sdk-for-go/services/streamanalytics/mgmt/2016-03-01/streamanalytics" + "github.com/hashicorp/terraform/helper/schema" +) + +func SchemaStreamAnalyticsOutputSerialization() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(streamanalytics.TypeAvro), + string(streamanalytics.TypeCsv), + string(streamanalytics.TypeJSON), + }, false), + }, + + "field_delimiter": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + " ", + ",", + " ", + "|", + ";", + }, false), + }, + + "encoding": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(streamanalytics.UTF8), + }, false), + }, + + "format": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(streamanalytics.Array), + string(streamanalytics.LineSeparated), + }, false), + }, + }, + }, + } +} + +func ExpandStreamAnalyticsOutputSerialization(input []interface{}) (streamanalytics.BasicSerialization, error) { + v := input[0].(map[string]interface{}) + + outputType := streamanalytics.Type(v["type"].(string)) + encoding := v["encoding"].(string) + fieldDelimiter := v["field_delimiter"].(string) + format := v["format"].(string) + + switch outputType { + case streamanalytics.TypeAvro: + if encoding != "" { + return nil, fmt.Errorf("`encoding` cannot be set when `type` is set to `Avro`") + } + if fieldDelimiter != "" { + return nil, fmt.Errorf("`field_delimiter` cannot be set when `type` is set to `Avro`") + } + if format != "" { + return nil, fmt.Errorf("`format` cannot be set when `type` is set to `Avro`") + } + return streamanalytics.AvroSerialization{ + Type: streamanalytics.TypeAvro, + Properties: map[string]interface{}{}, + }, nil + + case streamanalytics.TypeCsv: + if encoding == "" { + return nil, fmt.Errorf("`encoding` must be specified when `type` is set to `Csv`") + } + if fieldDelimiter == "" { + return nil, fmt.Errorf("`field_delimiter` must be set when `type` is set to `Csv`") + } + if format != "" { + return nil, fmt.Errorf("`format` cannot be set when `type` is set to `Csv`") + } + return streamanalytics.CsvSerialization{ + Type: streamanalytics.TypeCsv, + CsvSerializationProperties: &streamanalytics.CsvSerializationProperties{ + Encoding: streamanalytics.Encoding(encoding), + FieldDelimiter: utils.String(fieldDelimiter), + }, + }, nil + + case streamanalytics.TypeJSON: + if encoding == "" { + return nil, fmt.Errorf("`encoding` must be specified when `type` is set to `Json`") + } + if format == "" { + return nil, fmt.Errorf("`format` must be specified when `type` is set to `Json`") + } + if fieldDelimiter != "" { + return nil, fmt.Errorf("`field_delimiter` cannot be set when `type` is set to `Json`") + } + + return streamanalytics.JSONSerialization{ + Type: streamanalytics.TypeJSON, + JSONSerializationProperties: &streamanalytics.JSONSerializationProperties{ + Encoding: streamanalytics.Encoding(encoding), + Format: streamanalytics.JSONOutputSerializationFormat(format), + }, + }, nil + } + + return nil, fmt.Errorf("Unsupported Output Type %q", outputType) +} + +func FlattenStreamAnalyticsOutputSerialization(input streamanalytics.BasicSerialization) []interface{} { + var encoding string + var outputType string + var fieldDelimiter string + var format string + + if _, ok := input.AsAvroSerialization(); ok { + outputType = string(streamanalytics.TypeAvro) + } + + if v, ok := input.AsCsvSerialization(); ok { + if props := v.CsvSerializationProperties; props != nil { + encoding = string(props.Encoding) + if props.FieldDelimiter != nil { + fieldDelimiter = *props.FieldDelimiter + } + } + + outputType = string(streamanalytics.TypeCsv) + } + + if v, ok := input.AsJSONSerialization(); ok { + if props := v.JSONSerializationProperties; props != nil { + encoding = string(props.Encoding) + format = string(props.Format) + } + + outputType = string(streamanalytics.TypeJSON) + } + return []interface{}{ + map[string]interface{}{ + "encoding": encoding, + "type": outputType, + "format": format, + "field_delimiter": fieldDelimiter, + }, + } +} diff --git a/azurerm/helpers/azure/stream_analytics_stream_input.go b/azurerm/helpers/azure/stream_analytics_stream_input.go new file mode 100644 index 000000000000..4074b3c0fa62 --- /dev/null +++ b/azurerm/helpers/azure/stream_analytics_stream_input.go @@ -0,0 +1,134 @@ +package azure + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/streamanalytics/mgmt/2016-03-01/streamanalytics" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func SchemaStreamAnalyticsStreamInputSerialization() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(streamanalytics.TypeAvro), + string(streamanalytics.TypeCsv), + string(streamanalytics.TypeJSON), + }, false), + }, + + "field_delimiter": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + " ", + ",", + " ", + "|", + ";", + }, false), + }, + + "encoding": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(streamanalytics.UTF8), + }, false), + }, + }, + }, + } +} + +func ExpandStreamAnalyticsStreamInputSerialization(input []interface{}) (streamanalytics.BasicSerialization, error) { + v := input[0].(map[string]interface{}) + + inputType := streamanalytics.Type(v["type"].(string)) + encoding := v["encoding"].(string) + fieldDelimiter := v["field_delimiter"].(string) + + switch inputType { + case streamanalytics.TypeAvro: + return streamanalytics.AvroSerialization{ + Type: streamanalytics.TypeAvro, + Properties: map[string]interface{}{}, + }, nil + + case streamanalytics.TypeCsv: + if encoding == "" { + return nil, fmt.Errorf("`encoding` must be specified when `type` is set to `Csv`") + } + if fieldDelimiter == "" { + return nil, fmt.Errorf("`field_delimiter` must be set when `type` is set to `Csv`") + } + return streamanalytics.CsvSerialization{ + Type: streamanalytics.TypeCsv, + CsvSerializationProperties: &streamanalytics.CsvSerializationProperties{ + Encoding: streamanalytics.Encoding(encoding), + FieldDelimiter: utils.String(fieldDelimiter), + }, + }, nil + + case streamanalytics.TypeJSON: + if encoding == "" { + return nil, fmt.Errorf("`encoding` must be specified when `type` is set to `Json`") + } + + return streamanalytics.JSONSerialization{ + Type: streamanalytics.TypeJSON, + JSONSerializationProperties: &streamanalytics.JSONSerializationProperties{ + Encoding: streamanalytics.Encoding(encoding), + }, + }, nil + } + + return nil, fmt.Errorf("Unsupported Input Type %q", inputType) +} + +func FlattenStreamAnalyticsStreamInputSerialization(input streamanalytics.BasicSerialization) []interface{} { + var encoding string + var fieldDelimiter string + var inputType string + + if _, ok := input.AsAvroSerialization(); ok { + inputType = string(streamanalytics.TypeAvro) + } + + if v, ok := input.AsCsvSerialization(); ok { + if props := v.CsvSerializationProperties; props != nil { + encoding = string(props.Encoding) + + if props.FieldDelimiter != nil { + fieldDelimiter = *props.FieldDelimiter + } + } + + inputType = string(streamanalytics.TypeCsv) + } + + if v, ok := input.AsJSONSerialization(); ok { + if props := v.JSONSerializationProperties; props != nil { + encoding = string(props.Encoding) + } + + inputType = string(streamanalytics.TypeJSON) + } + + return []interface{}{ + map[string]interface{}{ + "encoding": encoding, + "type": inputType, + "field_delimiter": fieldDelimiter, + }, + } +} diff --git a/azurerm/helpers/azure/subscription.go b/azurerm/helpers/azure/subscription.go index 38bf5c23a46d..b4333375b824 100644 --- a/azurerm/helpers/azure/subscription.go +++ b/azurerm/helpers/azure/subscription.go @@ -12,6 +12,11 @@ func SchemaSubscription(subscriptionIDOptional bool) map[string]*schema.Schema { Computed: true, }, + "tenant_id": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { Type: schema.TypeString, Computed: true, diff --git a/azurerm/helpers/azure/web.go b/azurerm/helpers/azure/web.go new file mode 100644 index 000000000000..beeeb2298c6b --- /dev/null +++ b/azurerm/helpers/azure/web.go @@ -0,0 +1,81 @@ +package azure + +import ( + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func SchemaWebCorsSettings() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "allowed_origins": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "support_credentials": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + }, + }, + } +} + +func ExpandWebCorsSettings(input interface{}) web.CorsSettings { + settings := input.([]interface{}) + corsSettings := web.CorsSettings{} + + if len(settings) == 0 { + return corsSettings + } + + setting := settings[0].(map[string]interface{}) + + if v, ok := setting["allowed_origins"]; ok { + input := v.(*schema.Set).List() + + allowedOrigins := make([]string, 0) + for _, param := range input { + allowedOrigins = append(allowedOrigins, param.(string)) + } + + corsSettings.AllowedOrigins = &allowedOrigins + } + + if v, ok := setting["support_credentials"]; ok { + corsSettings.SupportCredentials = utils.Bool(v.(bool)) + } + + return corsSettings +} + +func FlattenWebCorsSettings(input *web.CorsSettings) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + result := make(map[string]interface{}) + + allowedOrigins := make([]interface{}, 0) + if s := input.AllowedOrigins; s != nil { + for _, v := range *s { + allowedOrigins = append(allowedOrigins, v) + } + } + result["allowed_origins"] = schema.NewSet(schema.HashString, allowedOrigins) + + if input.SupportCredentials != nil { + result["support_credentials"] = *input.SupportCredentials + } + + return append(results, result) +} diff --git a/azurerm/helpers/azure/zones.go b/azurerm/helpers/azure/zones.go index 04fcac6c6577..4a63d600973a 100644 --- a/azurerm/helpers/azure/zones.go +++ b/azurerm/helpers/azure/zones.go @@ -7,7 +7,6 @@ func SchemaZones() *schema.Schema { Type: schema.TypeList, Optional: true, ForceNew: true, - MinItems: 1, Elem: &schema.Schema{ Type: schema.TypeString, }, diff --git a/azurerm/helpers/suppress/xml.go b/azurerm/helpers/suppress/xml.go new file mode 100644 index 000000000000..372176c4c41d --- /dev/null +++ b/azurerm/helpers/suppress/xml.go @@ -0,0 +1,47 @@ +package suppress + +import ( + "encoding/xml" + "io" + "reflect" + "strings" + + "github.com/hashicorp/terraform/helper/schema" +) + +func XmlDiff(_, old, new string, _ *schema.ResourceData) bool { + oldTokens, err := expandXmlTokensFromString(old) + if err != nil { + return false + } + + newTokens, err := expandXmlTokensFromString(new) + if err != nil { + return false + } + + return reflect.DeepEqual(oldTokens, newTokens) +} + +// This function will extract all XML tokens from a string, but ignoring all white-space tokens +func expandXmlTokensFromString(input string) ([]xml.Token, error) { + decoder := xml.NewDecoder(strings.NewReader(input)) + tokens := make([]xml.Token, 0) + for { + token, err := decoder.Token() + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + if chars, ok := token.(xml.CharData); ok { + text := string(chars) + if strings.TrimSpace(text) == "" { + continue + } + } + tokens = append(tokens, xml.CopyToken(token)) + } + return tokens, nil +} diff --git a/azurerm/helpers/suppress/xml_test.go b/azurerm/helpers/suppress/xml_test.go new file mode 100644 index 000000000000..b0bd860b456e --- /dev/null +++ b/azurerm/helpers/suppress/xml_test.go @@ -0,0 +1,81 @@ +package suppress + +import "testing" + +func TestXmlDiff(t *testing.T) { + cases := []struct { + Name string + XmlA string + XmlB string + Suppress bool + }{ + { + Name: "empty", + XmlA: "", + XmlB: "", + Suppress: true, + }, + { + Name: "neither are xml", + XmlA: "this is not an xml", + XmlB: "neither is this", + Suppress: false, + }, + { + Name: "identical texts", + XmlA: "this is not an xml", + XmlB: "this is not an xml", + Suppress: true, + }, + { + Name: "xml vs text", + XmlA: "", + XmlB: "this is not an xml", + Suppress: false, + }, + { + Name: "text vs xml", + XmlA: "this is not an xml", + XmlB: "", + Suppress: false, + }, + { + Name: "identical xml", + XmlA: "", + XmlB: "", + Suppress: true, + }, + { + Name: "xml with different line endings", + XmlA: "\n\n\n", + XmlB: "\r\n\r\n\r\n", + Suppress: true, + }, + { + Name: "xml with different indentations", + XmlA: "\n \n \n", + XmlB: "\r\n\t\r\n\t\r\n", + Suppress: true, + }, + { + Name: "xml with different quotation marks", + XmlA: "", + XmlB: "\r\n\t\r\n\t\r\n", + Suppress: true, + }, + { + Name: "xml with different spaces", + XmlA: "", + XmlB: "\r\n\t\r\n\t\r\n", + Suppress: true, + }, + } + + for _, tc := range cases { + t.Run(tc.Name, func(t *testing.T) { + if XmlDiff("test", tc.XmlA, tc.XmlB, nil) != tc.Suppress { + t.Fatalf("Expected XmlDiff to return %t for '%q' == '%q'", tc.Suppress, tc.XmlA, tc.XmlB) + } + }) + } +} diff --git a/azurerm/helpers/validate/api_management.go b/azurerm/helpers/validate/api_management.go index d3d2867a821d..66f850cb896b 100644 --- a/azurerm/helpers/validate/api_management.go +++ b/azurerm/helpers/validate/api_management.go @@ -71,8 +71,19 @@ func ApiManagementApiName(v interface{}, k string) (ws []string, es []error) { func ApiManagementApiPath(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if matched := regexp.MustCompile(`^[\w][\w-/.]+[\w-]$`).Match([]byte(value)); !matched { - es = append(es, fmt.Errorf("%q may only be up to 256 characters in length, not start or end with `/` and only contain valid url characters", k)) + if matched := regexp.MustCompile(`^(?:|[\w][\w-/.]{0,398}[\w-])$`).Match([]byte(value)); !matched { + es = append(es, fmt.Errorf("%q may only be up to 400 characters in length, not start or end with `/` and only contain valid url characters", k)) } return ws, es } + +func ApiManagementBackendName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + // From https://docs.microsoft.com/en-us/rest/api/apimanagement/2018-01-01/backend/createorupdate#uri-parameters + if matched := regexp.MustCompile(`(^[\w]+$)|(^[\w][\w\-]+[\w]$)`).Match([]byte(value)); !matched { + errors = append(errors, fmt.Errorf("%q may only contain alphanumeric characters and dashes up to 50 characters in length", k)) + } + + return warnings, errors +} diff --git a/azurerm/helpers/validate/api_management_test.go b/azurerm/helpers/validate/api_management_test.go index 62ea30a3cdd8..e3b5e6ed616c 100644 --- a/azurerm/helpers/validate/api_management_test.go +++ b/azurerm/helpers/validate/api_management_test.go @@ -1,6 +1,7 @@ package validate import ( + s "strings" "testing" ) @@ -103,7 +104,7 @@ func TestAzureRMApiManagementApiPath_validation(t *testing.T) { }{ { Value: "", - ErrCount: 1, + ErrCount: 0, }, { Value: "/", @@ -125,6 +126,10 @@ func TestAzureRMApiManagementApiPath_validation(t *testing.T) { Value: "api1/sub", ErrCount: 0, }, + { + Value: s.Repeat("x", 401), + ErrCount: 1, + }, } for _, tc := range cases { diff --git a/azurerm/helpers/validate/compute.go b/azurerm/helpers/validate/compute.go index df6cf2982ab8..ab5978b1d79c 100644 --- a/azurerm/helpers/validate/compute.go +++ b/azurerm/helpers/validate/compute.go @@ -3,6 +3,9 @@ package validate import ( "fmt" "regexp" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" ) func SharedImageGalleryName(v interface{}, k string) (warnings []string, errors []error) { @@ -48,3 +51,117 @@ func SharedImageVersionName(v interface{}, k string) (warnings []string, errors return warnings, errors } + +func VirtualMachineTimeZone() schema.SchemaValidateFunc { + // Candidates are listed here: http://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/ + candidates := []string{ + "", + "Afghanistan Standard Time", + "Alaskan Standard Time", + "Arab Standard Time", + "Arabian Standard Time", + "Arabic Standard Time", + "Argentina Standard Time", + "Atlantic Standard Time", + "AUS Central Standard Time", + "AUS Eastern Standard Time", + "Azerbaijan Standard Time", + "Azores Standard Time", + "Bahia Standard Time", + "Bangladesh Standard Time", + "Belarus Standard Time", + "Canada Central Standard Time", + "Cape Verde Standard Time", + "Caucasus Standard Time", + "Cen. Australia Standard Time", + "Central America Standard Time", + "Central Asia Standard Time", + "Central Brazilian Standard Time", + "Central Europe Standard Time", + "Central European Standard Time", + "Central Pacific Standard Time", + "Central Standard Time (Mexico)", + "Central Standard Time", + "China Standard Time", + "Dateline Standard Time", + "E. Africa Standard Time", + "E. Australia Standard Time", + "E. Europe Standard Time", + "E. South America Standard Time", + "Eastern Standard Time (Mexico)", + "Eastern Standard Time", + "Egypt Standard Time", + "Ekaterinburg Standard Time", + "Fiji Standard Time", + "FLE Standard Time", + "Georgian Standard Time", + "GMT Standard Time", + "Greenland Standard Time", + "Greenwich Standard Time", + "GTB Standard Time", + "Hawaiian Standard Time", + "India Standard Time", + "Iran Standard Time", + "Israel Standard Time", + "Jordan Standard Time", + "Kaliningrad Standard Time", + "Korea Standard Time", + "Libya Standard Time", + "Line Islands Standard Time", + "Magadan Standard Time", + "Mauritius Standard Time", + "Middle East Standard Time", + "Montevideo Standard Time", + "Morocco Standard Time", + "Mountain Standard Time (Mexico)", + "Mountain Standard Time", + "Myanmar Standard Time", + "N. Central Asia Standard Time", + "Namibia Standard Time", + "Nepal Standard Time", + "New Zealand Standard Time", + "Newfoundland Standard Time", + "North Asia East Standard Time", + "North Asia Standard Time", + "Pacific SA Standard Time", + "Pacific Standard Time (Mexico)", + "Pacific Standard Time", + "Pakistan Standard Time", + "Paraguay Standard Time", + "Romance Standard Time", + "Russia Time Zone 10", + "Russia Time Zone 11", + "Russia Time Zone 3", + "Russian Standard Time", + "SA Eastern Standard Time", + "SA Pacific Standard Time", + "SA Western Standard Time", + "Samoa Standard Time", + "SE Asia Standard Time", + "Singapore Standard Time", + "South Africa Standard Time", + "Sri Lanka Standard Time", + "Syria Standard Time", + "Taipei Standard Time", + "Tasmania Standard Time", + "Tokyo Standard Time", + "Tonga Standard Time", + "Turkey Standard Time", + "Ulaanbaatar Standard Time", + "US Eastern Standard Time", + "US Mountain Standard Time", + "UTC", + "UTC+12", + "UTC-02", + "UTC-11", + "Venezuela Standard Time", + "Vladivostok Standard Time", + "W. Australia Standard Time", + "W. Central Africa Standard Time", + "W. Europe Standard Time", + "West Asia Standard Time", + "West Pacific Standard Time", + "Yakutsk Standard Time", + } + return validation.StringInSlice(candidates, true) +} diff --git a/azurerm/helpers/validate/compute_test.go b/azurerm/helpers/validate/compute_test.go index 6131a4d24cdc..d7118287ec79 100644 --- a/azurerm/helpers/validate/compute_test.go +++ b/azurerm/helpers/validate/compute_test.go @@ -174,3 +174,41 @@ func TestSharedImageVersionName(t *testing.T) { }) } } + +func TestVirtualMachineTimeZone(t *testing.T) { + cases := []struct { + Value string + Errors int + }{ + { + Value: "", + Errors: 0, + }, + { + Value: "UTC", + Errors: 0, + }, + { + Value: "China Standard Time", + Errors: 0, + }, + { + // Valid UTC time zone + Value: "utc-11", + Errors: 0, + }, + { + // Invalid UTC time zone + Value: "UTC-30", + Errors: 1, + }, + } + + for _, tc := range cases { + _, errors := VirtualMachineTimeZone()(tc.Value, "unittest") + + if len(errors) != tc.Errors { + t.Fatalf("Expected VirtualMachineTimeZone to trigger '%d' errors for '%s' - got '%d'", tc.Errors, tc.Value, len(errors)) + } + } +} diff --git a/azurerm/helpers/validate/cosmos.go b/azurerm/helpers/validate/cosmos.go new file mode 100644 index 000000000000..3172f496b198 --- /dev/null +++ b/azurerm/helpers/validate/cosmos.go @@ -0,0 +1,28 @@ +package validate + +import ( + "fmt" + "regexp" +) + +func CosmosAccountName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + // Portal: The value must contain only alphanumeric characters or the following: - + if matched := regexp.MustCompile("^[-a-z0-9]{3,50}$").Match([]byte(value)); !matched { + errors = append(errors, fmt.Errorf("%s name must be 3 - 50 characters long, contain only letters, numbers and hyphens.", k)) + } + + return warnings, errors +} + +func CosmosEntityName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if len(value) < 1 || len(value) > 255 { + errors = append(errors, fmt.Errorf( + "%q must be between 1 and 255 characters: %q", k, value)) + } + + return warnings, errors +} diff --git a/azurerm/helpers/validate/database.go b/azurerm/helpers/validate/database.go new file mode 100644 index 000000000000..bda83f52b22a --- /dev/null +++ b/azurerm/helpers/validate/database.go @@ -0,0 +1,23 @@ +package validate + +import ( + "fmt" + "regexp" +) + +func DatabaseCollation(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %s to be string", k)) + return + } + + matched, _ := regexp.MatchString(`^[A-Za-z0-9_. ]+$`, v) + + if !matched { + errors = append(errors, fmt.Errorf("%s contains invalid characters, only underscores are supported, got %s", k, v)) + return + } + + return warnings, errors +} diff --git a/azurerm/helpers/validate/database_test.go b/azurerm/helpers/validate/database_test.go new file mode 100644 index 000000000000..773ee5a203d0 --- /dev/null +++ b/azurerm/helpers/validate/database_test.go @@ -0,0 +1,34 @@ +package validate + +import "testing" + +func TestDatabaseCollation(t *testing.T) { + cases := []struct { + Value string + Errors int + }{ + { + Value: "en-US", + Errors: 1, + }, + { + Value: "en_US", + Errors: 0, + }, + { + Value: "en US", + Errors: 0, + }, + { + Value: "English_United States.1252", + Errors: 0, + }, + } + + for _, tc := range cases { + _, errors := DatabaseCollation(tc.Value, "collation") + if len(errors) != tc.Errors { + t.Fatalf("Expected DatabaseCollation to trigger '%d' errors for '%s' - got '%d'", tc.Errors, tc.Value, len(errors)) + } + } +} diff --git a/azurerm/helpers/validate/hdinsight.go b/azurerm/helpers/validate/hdinsight.go new file mode 100644 index 000000000000..432bc50adab9 --- /dev/null +++ b/azurerm/helpers/validate/hdinsight.go @@ -0,0 +1,34 @@ +package validate + +import ( + "fmt" + "regexp" +) + +func HDInsightClusterVersion(i interface{}, k string) (warnings []string, errors []error) { + version := i.(string) + + // 3.6, 3333.6666 or 1.2.3000.45 + // `major minor` + re := regexp.MustCompile(`^(\d)+(.){1}(\d)+$`) + if re != nil && !re.MatchString(version) { + // otherwise retry using `major minor build release` + re = regexp.MustCompile(`^(\d)+(.)(\d)+(.)(\d)+(.)(\d)+$`) + if re != nil && !re.MatchString(version) { + errors = append(errors, fmt.Errorf("%s must be a version in the format `x.y` or `a.b.c.d` - got %q.", k, version)) + } + } + + return warnings, errors +} + +func HDInsightName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + // The name must be 59 characters or less and can contain letters, numbers, and hyphens (but the first and last character must be a letter or number). + if matched := regexp.MustCompile(`(^[a-zA-Z0-9])([a-zA-Z0-9-]{1,57})([a-zA-Z0-9]$)`).Match([]byte(value)); !matched { + errors = append(errors, fmt.Errorf("%q must be 59 characters or less and can contain letters, numbers, and hyphens (but the first and last character must be a letter or number).", k)) + } + + return warnings, errors +} diff --git a/azurerm/helpers/validate/hdinsight_test.go b/azurerm/helpers/validate/hdinsight_test.go new file mode 100644 index 000000000000..a0c53661142d --- /dev/null +++ b/azurerm/helpers/validate/hdinsight_test.go @@ -0,0 +1,59 @@ +package validate + +import "testing" + +func TestHDInsightClusterVersion(t *testing.T) { + tests := []struct { + name string + input string + valid bool + }{ + { + name: "empty name", + input: "", + valid: false, + }, + { + name: "major only", + input: "1", + valid: false, + }, + { + name: "major minor", + input: "1.2", + valid: true, + }, + { + name: "major minor large", + input: "1000.2000", + valid: true, + }, + { + name: "major minor build", + input: "1.2.3", + valid: false, + }, + { + name: "major minor build revision", + input: "1.2.3.4", + valid: true, + }, + { + name: "real-world-example", + input: "3.6.1000.67", + valid: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, errors := HDInsightClusterVersion(tt.input, "cluster_version") + validationFailed := len(errors) > 0 + + if tt.valid && validationFailed { + t.Errorf("Expected %q to be valid but got %+v", tt.input, errors) + } else if !tt.valid && !validationFailed { + t.Errorf("Expected %q to be invalid but didn't get an error", tt.input) + } + }) + } +} diff --git a/azurerm/helpers/validate/mariadb.go b/azurerm/helpers/validate/mariadb.go new file mode 100644 index 000000000000..0cd951947bf6 --- /dev/null +++ b/azurerm/helpers/validate/mariadb.go @@ -0,0 +1,28 @@ +package validate + +import ( + "fmt" + "regexp" +) + +func MariaDBFirewallRuleName(v interface{}, _ string) (warnings []string, errors []error) { + value := v.(string) + + // Firewall rule name can contain alphanumeric characters and hyphens and must be 1 - 128 characters long + if matched := regexp.MustCompile("^[-a-z0-9]{1,128}$").Match([]byte(value)); !matched { + errors = append(errors, fmt.Errorf("Firewall rule name must be 1 - 128 characters long, contain only letters, numbers and hyphens.")) + } + + return warnings, errors +} + +func MariaDBServerName(v interface{}, _ string) (warnings []string, errors []error) { + value := v.(string) + + // MariaDB server name can contain alphanumeric characters and hyphens and must be 3 - 63 characters long + if matched := regexp.MustCompile("^[-a-z0-9]{3,63}$").Match([]byte(value)); !matched { + errors = append(errors, fmt.Errorf("Server name must be 3 - 63 characters long, contain only letters, numbers and hyphens.")) + } + + return warnings, errors +} diff --git a/azurerm/helpers/validate/storage.go b/azurerm/helpers/validate/storage.go new file mode 100644 index 000000000000..445bac547097 --- /dev/null +++ b/azurerm/helpers/validate/storage.go @@ -0,0 +1,25 @@ +package validate + +import ( + "fmt" + "regexp" + "strings" +) + +func StorageShareDirectoryName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + // File share names can contain only uppercase and lowercase letters, numbers, and hyphens, + // and must begin and end with a letter or a number. + // however they can be nested (e.g. foo/bar) + if !regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9-]+[A-Za-z0-9]$`).MatchString(value) && !regexp.MustCompile(`^[A-Za-z0-9]{1,}/[A-Za-z0-9]{1,}$`).MatchString(value) { + errors = append(errors, fmt.Errorf("%s must contain only uppercase and lowercase alphanumeric characters, numbers and hyphens. It must start and end with a letter and end only with a number or letter", k)) + } + + // The name cannot contain two consecutive hyphens. + if strings.Contains(value, "--") { + errors = append(errors, fmt.Errorf("%s cannot contain two concecutive hyphens", k)) + } + + return warnings, errors +} diff --git a/azurerm/helpers/validate/storage_test.go b/azurerm/helpers/validate/storage_test.go new file mode 100644 index 000000000000..d0b29c96b1a3 --- /dev/null +++ b/azurerm/helpers/validate/storage_test.go @@ -0,0 +1,73 @@ +package validate + +import "testing" + +func TestValidateStorageShareDirectoryName(t *testing.T) { + testCases := []struct { + Input string + Expected bool + }{ + { + Input: "", + Expected: false, + }, + { + Input: "abc123", + Expected: true, + }, + { + Input: "123abc", + Expected: true, + }, + { + Input: "123-abc", + Expected: true, + }, + { + Input: "-123-abc", + Expected: false, + }, + { + Input: "123-abc-", + Expected: false, + }, + { + Input: "123--abc", + Expected: false, + }, + { + Input: "hello/world", + Expected: true, + }, + { + Input: "hello/", + Expected: false, + }, + { + Input: "Abc123", + Expected: true, + }, + { + Input: "abc123A", + Expected: true, + }, + { + Input: "abC123", + Expected: true, + }, + } + + for _, v := range testCases { + t.Logf("[DEBUG] Test Input %q", v.Input) + + warnings, errors := StorageShareDirectoryName(v.Input, "name") + if len(warnings) != 0 { + t.Fatalf("Expected no warnings but got %d", len(warnings)) + } + + result := len(errors) == 0 + if result != v.Expected { + t.Fatalf("Expected the result to be %t but got %t (and %d errors)", v.Expected, result, len(errors)) + } + } +} diff --git a/azurerm/helpers/validate/stream_analytics.go b/azurerm/helpers/validate/stream_analytics.go new file mode 100644 index 000000000000..adc19794a417 --- /dev/null +++ b/azurerm/helpers/validate/stream_analytics.go @@ -0,0 +1,28 @@ +package validate + +import "fmt" + +func StreamAnalyticsJobStreamingUnits(i interface{}, k string) (w []string, es []error) { + v, ok := i.(int) + if !ok { + es = append(es, fmt.Errorf("expected type of %s to be int", k)) + return + } + + // Property 'streamingUnits' value '5' is not in the acceptable set: '1','3','6','12', and multiples of 6 up to your quota" + if v == 1 || v == 3 { + return + } + + if v < 1 || v > 120 { + es = append(es, fmt.Errorf("expected %s to be in the range (1 - 120), got %d", k, v)) + return + } + + if v%6 != 0 { + es = append(es, fmt.Errorf("expected %s to be divisible by 6, got %d", k, v)) + return + } + + return +} diff --git a/azurerm/helpers/validate/stream_analytics_test.go b/azurerm/helpers/validate/stream_analytics_test.go new file mode 100644 index 000000000000..f53fd548322e --- /dev/null +++ b/azurerm/helpers/validate/stream_analytics_test.go @@ -0,0 +1,34 @@ +package validate + +import ( + "testing" +) + +func TestStreamAnalyticsJobStreamingUnits(t *testing.T) { + cases := map[int]bool{ + 0: false, + 1: true, + 2: false, + 3: true, + 4: false, + 5: false, + 6: true, + 7: false, + 8: false, + 9: false, + 10: false, + 11: false, + 12: true, + 18: true, + 24: true, + 30: true, + } + for i, shouldBeValid := range cases { + _, errors := StreamAnalyticsJobStreamingUnits(i, "streaming_units") + + isValid := len(errors) == 0 + if shouldBeValid != isValid { + t.Fatalf("Expected %d to be %t but got %t", i, shouldBeValid, isValid) + } + } +} diff --git a/azurerm/helpers/validate/time.go b/azurerm/helpers/validate/time.go index 5e694c682fc8..c4ee63dff049 100644 --- a/azurerm/helpers/validate/time.go +++ b/azurerm/helpers/validate/time.go @@ -2,13 +2,30 @@ package validate import ( "fmt" + "regexp" "time" "github.com/Azure/go-autorest/autorest/date" + iso8601 "github.com/btubbs/datetime" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" ) +func ISO8601Duration(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %s to be string", k)) + return + } + + matched, _ := regexp.MatchString(`^P([0-9]+Y)?([0-9]+M)?([0-9]+W)?([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+(\.?[0-9]+)?S)?)?$`, v) + + if !matched { + errors = append(errors, fmt.Errorf("expected %s to be in ISO 8601 duration format, got %s", k, v)) + } + return warnings, errors +} + //todo, now in terraform helper, switch over once vended // -> https://github.com/hashicorp/terraform/blob/master/helper/validation/validation.go#L263 func RFC3339Time(i interface{}, k string) (warnings []string, errors []error) { @@ -25,6 +42,20 @@ func RFC3339Time(i interface{}, k string) (warnings []string, errors []error) { return warnings, errors } +func ISO8601DateTime(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return + } + + if _, err := iso8601.Parse(v, time.UTC); err != nil { + errors = append(errors, fmt.Errorf("%q has the invalid ISO8601 date format %q: %+v", k, i, err)) + } + + return warnings, errors +} + // RFC3339 date is duration d or greater into the future func RFC3339DateInFutureBy(d time.Duration) schema.SchemaValidateFunc { return func(i interface{}, k string) (warnings []string, errors []error) { diff --git a/azurerm/helpers/validate/time_test.go b/azurerm/helpers/validate/time_test.go index 7daf5a0ca545..b9751d6398f9 100644 --- a/azurerm/helpers/validate/time_test.go +++ b/azurerm/helpers/validate/time_test.go @@ -47,7 +47,61 @@ func TestRFC3339Time(t *testing.T) { } } -func TestRfc3339DateInFutureBy(t *testing.T) { +func TestISO8601DateTime(t *testing.T) { + cases := []struct { + Time string + Errors int + }{ + { + Time: "", + Errors: 1, + }, + { + Time: "this is not a date", + Errors: 1, + }, + { + Time: "2000-06-31", // No 31st of 6th + Errors: 1, + }, + { + Time: "01/21/2015", // not valid US date with slashes + Errors: 1, + }, + { + Time: "01-21-2015", // not valid US date with dashes + Errors: 1, + }, + { + Time: "2000-01-01", + Errors: 0, + }, + { + Time: "2000-01-01T01:23:45", + Errors: 0, + }, + { + Time: "2000-01-01T01:23:45Z", + Errors: 0, + }, + { + Time: "2000-01-01T01:23:45+00:00", + Errors: 0, + }, + } + + for _, tc := range cases { + t.Run(tc.Time, func(t *testing.T) { + _, errors := ISO8601DateTime(tc.Time, "test") + + if len(errors) != tc.Errors { + t.Fatalf("Expected ISO8601DateTime to have %d but got %d errors for %q", tc.Errors, len(errors), tc.Time) + } + }) + } +} + +func TestRFC3339DateInFutureBy(t *testing.T) { cases := []struct { Name string Time string @@ -102,3 +156,43 @@ func TestRfc3339DateInFutureBy(t *testing.T) { }) } } +func TestISO8601Duration(t *testing.T) { + cases := []struct { + Value string + Errors int + }{ + { + // Date components only + Value: "P1Y2M3D", + Errors: 0, + }, + { + // Time components only + Value: "PT7H42M3S", + Errors: 0, + }, + { + // Date and time components + Value: "P1Y2M3DT7H42M3S", + Errors: 0, + }, + { + // Invalid prefix + Value: "1Y2M3DT7H42M3S", + Errors: 1, + }, + { + // Wrong order of components, i.e. invalid format + Value: "PT7H42M3S1Y2M3D", + Errors: 1, + }, + } + + for _, tc := range cases { + _, errors := ISO8601Duration(tc.Value, "example") + + if len(errors) != tc.Errors { + t.Fatalf("Expected ISO8601Duration to trigger '%d' errors for '%s' - got '%d'", tc.Errors, tc.Value, len(errors)) + } + } +} diff --git a/azurerm/internal/authorizers/authorizer_shared_key_lite.go b/azurerm/internal/authorizers/authorizer_shared_key_lite.go new file mode 100644 index 000000000000..ae960691de65 --- /dev/null +++ b/azurerm/internal/authorizers/authorizer_shared_key_lite.go @@ -0,0 +1,90 @@ +package authorizers + +import ( + "net/http" + "strings" + + "github.com/Azure/go-autorest/autorest" +) + +// TODO: switch to using the version from github.com/Azure/go-autorest +// once https://github.com/Azure/go-autorest/pull/416 has been merged + +// SharedKeyLiteAuthorizer implements an authorization for Shared Key Lite +// this can be used for interaction with Blob, File and Queue Storage Endpoints +type SharedKeyLiteAuthorizer struct { + storageAccountName string + storageAccountKey string +} + +// NewSharedKeyLiteAuthorizer crates a SharedKeyLiteAuthorizer using the given credentials +func NewSharedKeyLiteAuthorizer(accountName, accountKey string) *SharedKeyLiteAuthorizer { + return &SharedKeyLiteAuthorizer{ + storageAccountName: accountName, + storageAccountKey: accountKey, + } +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose +// value is "SharedKeyLite " followed by the computed key. +// This can be used for the Blob, Queue, and File Services +// +// from: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key +// You may use Shared Key Lite authorization to authorize a request made against the +// 2009-09-19 version and later of the Blob and Queue services, +// and version 2014-02-14 and later of the File services. +func (skl *SharedKeyLiteAuthorizer) WithAuthorization() autorest.PrepareDecorator { + return func(p autorest.Preparer) autorest.Preparer { + return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err != nil { + return r, err + } + + key, err := buildSharedKeyLite(skl.storageAccountName, skl.storageAccountKey, r) + if err != nil { + return r, err + } + + sharedKeyHeader := formatSharedKeyLiteAuthorizationHeader(skl.storageAccountName, *key) + return autorest.Prepare(r, autorest.WithHeader(HeaderAuthorization, sharedKeyHeader)) + }) + } +} +func buildSharedKeyLite(accountName, storageAccountKey string, r *http.Request) (*string, error) { + // first ensure the relevant headers are configured + prepareHeadersForRequest(r) + + sharedKey, err := computeSharedKeyLite(r.Method, r.URL.String(), accountName, r.Header) + if err != nil { + return nil, err + } + + // we then need to HMAC that value + hmacdValue := hmacValue(storageAccountKey, *sharedKey) + return &hmacdValue, nil +} + +// computeSharedKeyLite computes the Shared Key Lite required for Storage Authentication +// NOTE: this function assumes that the `x-ms-date` field is set +func computeSharedKeyLite(verb, url string, accountName string, headers http.Header) (*string, error) { + canonicalizedResource, err := buildCanonicalizedResource(url, accountName) + if err != nil { + return nil, err + } + + canonicalizedHeaders := buildCanonicalizedHeader(headers) + canonicalizedString := buildCanonicalizedStringForSharedKeyLite(verb, headers, canonicalizedHeaders, *canonicalizedResource) + return &canonicalizedString, nil +} + +func buildCanonicalizedStringForSharedKeyLite(verb string, headers http.Header, canonicalizedHeaders, canonicalizedResource string) string { + return strings.Join([]string{ + verb, + headers.Get(HeaderContentMD5), // TODO: this appears to always be empty? + headers.Get(HeaderContentType), + "", // date should be nil, apparently :shrug: + canonicalizedHeaders, + canonicalizedResource, + }, "\n") +} diff --git a/azurerm/internal/authorizers/authorizer_shared_key_lite_table.go b/azurerm/internal/authorizers/authorizer_shared_key_lite_table.go new file mode 100644 index 000000000000..8becc41cf0b6 --- /dev/null +++ b/azurerm/internal/authorizers/authorizer_shared_key_lite_table.go @@ -0,0 +1,87 @@ +package authorizers + +import ( + "net/http" + "strings" + + "github.com/Azure/go-autorest/autorest" +) + +// TODO: switch to using the version from github.com/Azure/go-autorest +// once https://github.com/Azure/go-autorest/pull/416 has been merged + +// SharedKeyLiteTableAuthorizer implements an authorization for Shared Key Lite +// this can be used for interaction with Table Storage Endpoints +type SharedKeyLiteTableAuthorizer struct { + storageAccountName string + storageAccountKey string +} + +// NewSharedKeyLiteAuthorizer crates a SharedKeyLiteAuthorizer using the given credentials +func NewSharedKeyLiteTableAuthorizer(accountName, accountKey string) *SharedKeyLiteTableAuthorizer { + return &SharedKeyLiteTableAuthorizer{ + storageAccountName: accountName, + storageAccountKey: accountKey, + } +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose +// value is "SharedKeyLite " followed by the computed key. +// This can be used for the Blob, Queue, and File Services +// +// from: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key +// You may use Shared Key Lite authorization to authorize a request made against the +// 2009-09-19 version and later of the Blob and Queue services, +// and version 2014-02-14 and later of the File services. +func (skl *SharedKeyLiteTableAuthorizer) WithAuthorization() autorest.PrepareDecorator { + return func(p autorest.Preparer) autorest.Preparer { + return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err != nil { + return r, err + } + + key, err := buildSharedKeyLiteTable(skl.storageAccountName, skl.storageAccountKey, r) + if err != nil { + return r, err + } + + sharedKeyHeader := formatSharedKeyLiteAuthorizationHeader(skl.storageAccountName, *key) + return autorest.Prepare(r, autorest.WithHeader(HeaderAuthorization, sharedKeyHeader)) + }) + } +} + +func buildSharedKeyLiteTable(accountName, storageAccountKey string, r *http.Request) (*string, error) { + // first ensure the relevant headers are configured + prepareHeadersForRequest(r) + + sharedKey, err := computeSharedKeyLiteTable(r.URL.String(), accountName, r.Header) + if err != nil { + return nil, err + } + + // we then need to HMAC that value + hmacdValue := hmacValue(storageAccountKey, *sharedKey) + return &hmacdValue, nil +} + +// computeSharedKeyLite computes the Shared Key Lite required for Storage Authentication +// NOTE: this function assumes that the `x-ms-date` field is set +func computeSharedKeyLiteTable(url string, accountName string, headers http.Header) (*string, error) { + dateHeader := headers.Get("x-ms-date") + canonicalizedResource, err := buildCanonicalizedResource(url, accountName) + if err != nil { + return nil, err + } + + canonicalizedString := buildCanonicalizedStringForSharedKeyLiteTable(*canonicalizedResource, dateHeader) + return &canonicalizedString, nil +} + +func buildCanonicalizedStringForSharedKeyLiteTable(canonicalizedResource, dateHeader string) string { + return strings.Join([]string{ + dateHeader, + canonicalizedResource, + }, "\n") +} diff --git a/azurerm/internal/authorizers/authorizer_shared_key_lite_test.go b/azurerm/internal/authorizers/authorizer_shared_key_lite_test.go new file mode 100644 index 000000000000..2fa5d322b97c --- /dev/null +++ b/azurerm/internal/authorizers/authorizer_shared_key_lite_test.go @@ -0,0 +1,103 @@ +package authorizers + +import ( + "net/http" + "testing" +) + +func TestBuildCanonicalizedStringForSharedKeyLite(t *testing.T) { + testData := []struct { + name string + headers map[string][]string + canonicalizedHeaders string + canonicalizedResource string + verb string + expected string + }{ + { + name: "completed", + verb: "NOM", + headers: map[string][]string{ + "Content-MD5": {"abc123"}, + "Content-Type": {"vnd/panda-pops+v1"}, + }, + canonicalizedHeaders: "all-the-headers", + canonicalizedResource: "all-the-resources", + expected: "NOM\n\nvnd/panda-pops+v1\n\nall-the-headers\nall-the-resources", + }, + } + + for _, test := range testData { + t.Logf("Test: %q", test.name) + actual := buildCanonicalizedStringForSharedKeyLite(test.verb, test.headers, test.canonicalizedHeaders, test.canonicalizedResource) + if actual != test.expected { + t.Fatalf("Expected %q but got %q", test.expected, actual) + } + } +} + +func TestComputeSharedKey(t *testing.T) { + testData := []struct { + name string + accountName string + method string + url string + headers map[string]string + expected string + }{ + { + name: "No Path", + accountName: "unlikely23exst2acct23wi", + method: "GET", + url: "https://unlikely23exst2acct23wi.queue.core.windows.net?comp=properties&restype=service", + headers: map[string]string{ + "Content-Type": "application/xml; charset=utf-8", + "X-Ms-Date": "Wed, 21 Aug 2019 11:00:25 GMT", + "X-Ms-Version": "2018-11-09", + }, + expected: `GET + +application/xml; charset=utf-8 + +x-ms-date:Wed, 21 Aug 2019 11:00:25 GMT +x-ms-version:2018-11-09 +/unlikely23exst2acct23wi?comp=properties`, + }, + { + name: "With Path", + accountName: "unlikely23exst2accti1t0", + method: "GET", + url: "https://unlikely23exst2accti1t0.queue.core.windows.net/?comp=properties&restype=service", + headers: map[string]string{ + "Content-Type": "application/xml; charset=utf-8", + "X-Ms-Date": "Wed, 21 Aug 2019 11:53:48 GMT", + "X-Ms-Version": "2018-11-09", + }, + expected: `GET + +application/xml; charset=utf-8 + +x-ms-date:Wed, 21 Aug 2019 11:53:48 GMT +x-ms-version:2018-11-09 +/unlikely23exst2accti1t0/?comp=properties`, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Test %q", v.name) + + headers := http.Header{} + for hn, hv := range v.headers { + headers.Add(hn, hv) + } + + actual, err := computeSharedKeyLite(v.method, v.url, v.accountName, headers) + if err != nil { + t.Fatalf("Error computing shared key: %s", err) + } + + if *actual != v.expected { + t.Fatalf("Expected %q but got %q", v.expected, *actual) + } + } +} diff --git a/azurerm/internal/authorizers/consts.go b/azurerm/internal/authorizers/consts.go new file mode 100644 index 000000000000..86e73314029b --- /dev/null +++ b/azurerm/internal/authorizers/consts.go @@ -0,0 +1,19 @@ +package authorizers + +var ( + HeaderAuthorization = "Authorization" + HeaderContentLength = "Content-Length" + HeaderContentEncoding = "Content-Encoding" + HeaderContentLanguage = "Content-Language" + HeaderContentType = "Content-Type" + HeaderContentMD5 = "Content-MD5" + HeaderIfModifiedSince = "If-Modified-Since" + HeaderIfMatch = "If-Match" + HeaderIfNoneMatch = "If-None-Match" + HeaderIfUnmodifiedSince = "If-Unmodified-Since" + HeaderMSDate = "X-Ms-Date" + HeaderRange = "Range" + + StorageEmulatorAccountName = "devstoreaccount1" + StorageEmulatorAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" +) diff --git a/azurerm/internal/authorizers/helpers.go b/azurerm/internal/authorizers/helpers.go new file mode 100644 index 000000000000..741bef2632a1 --- /dev/null +++ b/azurerm/internal/authorizers/helpers.go @@ -0,0 +1,120 @@ +package authorizers + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "fmt" + "net/http" + "net/url" + "sort" + "strings" + "time" +) + +// buildCanonicalizedHeader builds the Canonicalized Header required to sign Storage Requests +func buildCanonicalizedHeader(headers http.Header) string { + cm := make(map[string]string) + + for k, v := range headers { + headerName := strings.TrimSpace(strings.ToLower(k)) + if strings.HasPrefix(headerName, "x-ms-") { + cm[headerName] = v[0] + } + } + + if len(cm) == 0 { + return "" + } + + var keys []string + for key := range cm { + keys = append(keys, key) + } + + sort.Strings(keys) + + ch := bytes.NewBufferString("") + + for _, key := range keys { + ch.WriteString(key) + ch.WriteRune(':') + ch.WriteString(cm[key]) + ch.WriteRune('\n') + } + + return strings.TrimSuffix(ch.String(), "\n") +} + +// buildCanonicalizedResource builds the Canonical Resource required for to sign Storage Account requests +func buildCanonicalizedResource(uri, accountName string) (*string, error) { + u, err := url.Parse(uri) + if err != nil { + return nil, err + } + + cr := bytes.NewBufferString("") + if accountName != StorageEmulatorAccountName { + cr.WriteString("/") + cr.WriteString(primaryStorageAccountName(accountName)) + } + + if len(u.Path) > 0 { + // Any portion of the CanonicalizedResource string that is derived from + // the resource's URI should be encoded exactly as it is in the URI. + // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx + cr.WriteString(u.EscapedPath()) + } + + // TODO: replace this with less of a hack + if comp := u.Query().Get("comp"); comp != "" { + cr.WriteString(fmt.Sprintf("?comp=%s", comp)) + } + + out := cr.String() + return &out, nil +} + +func formatSharedKeyLiteAuthorizationHeader(accountName, key string) string { + canonicalizedAccountName := primaryStorageAccountName(accountName) + return fmt.Sprintf("SharedKeyLite %s:%s", canonicalizedAccountName, key) +} + +// hmacValue base-64 decodes the storageAccountKey, then signs the string with it +// as outlined here: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key +func hmacValue(storageAccountKey, canonicalizedString string) string { + key, err := base64.StdEncoding.DecodeString(storageAccountKey) + if err != nil { + return "" + } + + encr := hmac.New(sha256.New, key) + _, _ = encr.Write([]byte(canonicalizedString)) + return base64.StdEncoding.EncodeToString(encr.Sum(nil)) +} + +// prepareHeadersForRequest prepares a request so that it can be signed +// by ensuring the `date` and `x-ms-date` headers are set +func prepareHeadersForRequest(r *http.Request) { + if r.Header == nil { + r.Header = http.Header{} + } + + date := time.Now().UTC().Format(http.TimeFormat) + + // a date must be set, X-Ms-Date should be used when both are set; but let's set both for completeness + r.Header.Set("date", date) + r.Header.Set("x-ms-date", date) +} + +// primaryStorageAccountName returns the name of the primary for a given Storage Account +func primaryStorageAccountName(input string) string { + // from https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key + // If you are accessing the secondary location in a storage account for which + // read-access geo-replication (RA-GRS) is enabled, do not include the + // -secondary designation in the authorization header. + // For authorization purposes, the account name is always the name of the primary location, + // even for secondary access. + return strings.TrimSuffix(input, "-secondary") +} diff --git a/azurerm/internal/authorizers/helpers_test.go b/azurerm/internal/authorizers/helpers_test.go new file mode 100644 index 000000000000..b182b7573915 --- /dev/null +++ b/azurerm/internal/authorizers/helpers_test.go @@ -0,0 +1,271 @@ +package authorizers + +import ( + "encoding/base64" + "net/http" + "testing" +) + +func TestBuildCanonicalizedHeader(t *testing.T) { + testData := []struct { + Input http.Header + Expected string + }{ + { + // no headers + Expected: "", + Input: map[string][]string{ + "": {""}, + }, + }, + { + // no x-ms headers + Expected: "", + Input: map[string][]string{ + "panda": {"pops"}, + }, + }, + { + // only a single x-ms header + Expected: "x-ms-panda:nom", + Input: map[string][]string{ + "x-ms-panda": {"nom"}, + }, + }, + { + // multiple x-ms headers + Expected: "x-ms-panda:nom\nx-ms-tiger:rawr", + Input: map[string][]string{ + "x-ms-panda": {"nom"}, + "x-ms-tiger": {"rawr"}, + }, + }, + { + // multiple x-ms headers, out of order + Expected: "x-ms-panda:nom\nx-ms-tiger:rawr", + Input: map[string][]string{ + "x-ms-tiger": {"rawr"}, + "x-ms-panda": {"nom"}, + }, + }, + { + // mixed headers (some ms, some non-ms) + Expected: "x-ms-panda:nom\nx-ms-tiger:rawr", + Input: map[string][]string{ + "x-ms-tiger": {"rawr"}, + "panda": {"pops"}, + "x-ms-panda": {"nom"}, + }, + }, + { + // casing + Expected: "x-ms-panda:nom\nx-ms-tiger:rawr", + Input: map[string][]string{ + "X-Ms-Tiger": {"rawr"}, + "X-Ms-Panda": {"nom"}, + }, + }, + } + + for _, v := range testData { + actual := buildCanonicalizedHeader(v.Input) + if actual != v.Expected { + t.Fatalf("Expected %q but got %q", v.Expected, actual) + } + } +} + +func TestBuildCanonicalizedResource(t *testing.T) { + testData := []struct { + name string + accountName string + uri string + expected string + expectError bool + }{ + { + name: "invalid uri", + accountName: "example", + uri: "://example.com", + expected: "", + expectError: true, + }, + { + name: "storage emulator doesn't get prefix", + accountName: StorageEmulatorAccountName, + uri: "http://www.example.com/foo", + expected: "/foo", + }, + { + name: "non storage emulator gets prefix", + accountName: StorageEmulatorAccountName + "test", + uri: "http://www.example.com/foo", + expected: "/" + StorageEmulatorAccountName + "test/foo", + }, + { + name: "uri encoding", + accountName: "example", + uri: "", + expected: "/example%3Chello%3E", + }, + { + name: "comp-arg", + accountName: "example", + uri: "/endpoint?first=true&comp=bar&second=false&third=panda", + expected: "/example/endpoint?comp=bar", + }, + { + name: "arguments", + accountName: "example", + uri: "/endpoint?first=true&second=false&third=panda", + expected: "/example/endpoint", + }, + } + + for _, test := range testData { + t.Logf("Test %q", test.name) + actual, err := buildCanonicalizedResource(test.uri, test.accountName) + if err != nil { + if test.expectError { + continue + } + + t.Fatalf("Error: %s", err) + } + + if *actual != test.expected { + t.Fatalf("Expected %q but got %q", test.expected, *actual) + } + } +} + +func TestFormatSharedKeyLiteAuthorizationHeader(t *testing.T) { + testData := []struct { + name string + accountName string + accountKey string + expected string + }{ + { + name: "primary", + accountName: "account1", + accountKey: "examplekey", + expected: "SharedKeyLite account1:examplekey", + }, + { + name: "secondary", + accountName: "account1-secondary", + accountKey: "examplekey", + expected: "SharedKeyLite account1:examplekey", + }, + } + + for _, test := range testData { + t.Logf("Test: %q", test.name) + actual := formatSharedKeyLiteAuthorizationHeader(test.accountName, test.accountKey) + + if actual != test.expected { + t.Fatalf("Expected %q but got %q", test.expected, actual) + } + } +} + +func TestHMAC(t *testing.T) { + testData := []struct { + Expected string + StorageAccountKey string + CanonicalizedString string + }{ + { + // When Storage Key isn't base-64 encoded + Expected: "", + StorageAccountKey: "bar", + CanonicalizedString: "foobarzoo", + }, + { + // Valid + Expected: "h5U0ATVX6SpbFX1H6GNuxIMeXXCILLoIvhflPtuQZ30=", + StorageAccountKey: base64.StdEncoding.EncodeToString([]byte("bar")), + CanonicalizedString: "foobarzoo", + }, + } + + for _, v := range testData { + actual := hmacValue(v.StorageAccountKey, v.CanonicalizedString) + if actual != v.Expected { + t.Fatalf("Expected %q but got %q", v.Expected, actual) + } + } +} + +func TestTestPrepareHeadersForRequest(t *testing.T) { + request, err := http.NewRequest("GET", "http://example.com", nil) + if err != nil { + t.Fatal(err) + } + + headers := []string{ + "Date", + "X-Ms-Date", + } + + for _, header := range headers { + existingVal := request.Header.Get(header) + if existingVal != "" { + t.Fatalf("%q had a value prior to being set: %q", header, existingVal) + } + } + + prepareHeadersForRequest(request) + + for _, header := range headers { + updatedVal := request.Header.Get(header) + if updatedVal == "" { + t.Fatalf("%q didn't have a value after being set: %q", header, updatedVal) + } + } +} + +func TestPrepareHeadersForRequestWithNoneConfigured(t *testing.T) { + request, err := http.NewRequest("GET", "http://example.com", nil) + if err != nil { + t.Fatal(err) + } + + request.Header = nil + prepareHeadersForRequest(request) + + if request.Header == nil { + t.Fatalf("Expected `request.Header` to not be nil, but it was!") + } +} + +func TestPrimaryStorageAccountName(t *testing.T) { + testData := []struct { + Expected string + Input string + }{ + { + // Empty + Expected: "", + Input: "", + }, + { + // Primary + Expected: "bar", + Input: "bar", + }, + { + // Secondary + Expected: "bar", + Input: "bar-secondary", + }, + } + + for _, v := range testData { + actual := primaryStorageAccountName(v.Input) + if actual != v.Expected { + t.Fatalf("Expected %q but got %q", v.Expected, actual) + } + } +} diff --git a/azurerm/internal/common/client.go b/azurerm/internal/common/client.go new file mode 100644 index 000000000000..fed2932e0ea3 --- /dev/null +++ b/azurerm/internal/common/client.go @@ -0,0 +1,65 @@ +package common + +import ( + "fmt" + "log" + "os" + "strings" + "time" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/sender" + "github.com/hashicorp/terraform/httpclient" + "github.com/terraform-providers/terraform-provider-azurerm/version" +) + +type ClientOptions struct { + SubscriptionId string + TenantID string + PartnerId string + + GraphAuthorizer autorest.Authorizer + GraphEndpoint string + KeyVaultAuthorizer autorest.Authorizer + ResourceManagerAuthorizer autorest.Authorizer + ResourceManagerEndpoint string + StorageAuthorizer autorest.Authorizer + + PollingDuration time.Duration + SkipProviderReg bool + DisableCorrelationRequestID bool + Environment azure.Environment +} + +func (o ClientOptions) ConfigureClient(c *autorest.Client, authorizer autorest.Authorizer) { + if o.PartnerId != "" { + setUserAgent(c, o.PartnerId) + } + + c.Authorizer = authorizer + c.Sender = sender.BuildSender("AzureRM") + c.PollingDuration = o.PollingDuration + c.SkipResourceProviderRegistration = o.SkipProviderReg + if !o.DisableCorrelationRequestID { + c.RequestInspector = WithCorrelationRequestID(CorrelationRequestID()) + } +} + +func setUserAgent(client *autorest.Client, partnerID string) { + tfUserAgent := httpclient.UserAgentString() + + providerUserAgent := fmt.Sprintf("%s terraform-provider-azurerm/%s", tfUserAgent, version.ProviderVersion) + client.UserAgent = strings.TrimSpace(fmt.Sprintf("%s %s", client.UserAgent, providerUserAgent)) + + // append the CloudShell version to the user agent if it exists + if azureAgent := os.Getenv("AZURE_HTTP_USER_AGENT"); azureAgent != "" { + client.UserAgent = fmt.Sprintf("%s %s", client.UserAgent, azureAgent) + } + + if partnerID != "" { + client.UserAgent = fmt.Sprintf("%s pid-%s", client.UserAgent, partnerID) + } + + log.Printf("[DEBUG] AzureRM Client User Agent: %s\n", client.UserAgent) +} diff --git a/azurerm/internal/common/correlation_id.go b/azurerm/internal/common/correlation_id.go new file mode 100644 index 000000000000..45dadada2236 --- /dev/null +++ b/azurerm/internal/common/correlation_id.go @@ -0,0 +1,43 @@ +package common + +import ( + "log" + "sync" + + "github.com/Azure/go-autorest/autorest" + "github.com/hashicorp/go-uuid" +) + +const ( + // HeaderCorrelationRequestID is the Azure extension header to set a user-specified correlation request ID. + HeaderCorrelationRequestID = "x-ms-correlation-request-id" +) + +var ( + msCorrelationRequestIDOnce sync.Once + msCorrelationRequestID string +) + +// WithCorrelationRequestID returns a PrepareDecorator that adds an HTTP extension header of +// `x-ms-correlation-request-id` whose value is passed, undecorated UUID (e.g.,7F5A6223-F475-4A9C-B9D5-12575AA6B11B`). +// todo 2.0 change to withCorrelationRequestID +func WithCorrelationRequestID(uuid string) autorest.PrepareDecorator { + return autorest.WithHeader(HeaderCorrelationRequestID, uuid) +} + +// CorrelationRequestID generates an UUID to pass through `x-ms-correlation-request-id` header. +// todo 2.0 change to correlationRequestID +func CorrelationRequestID() string { + msCorrelationRequestIDOnce.Do(func() { + var err error + msCorrelationRequestID, err = uuid.GenerateUUID() + + if err != nil { + log.Printf("[WARN] Failed to generate uuid for msCorrelationRequestID: %+v", err) + } + + log.Printf("[DEBUG] Genereated Provider Correlation Request Id: %s", msCorrelationRequestID) + }) + + return msCorrelationRequestID +} diff --git a/azurerm/internal/common/correlation_id_test.go b/azurerm/internal/common/correlation_id_test.go new file mode 100644 index 000000000000..43119a0a9869 --- /dev/null +++ b/azurerm/internal/common/correlation_id_test.go @@ -0,0 +1,31 @@ +package common + +import ( + "net/http" + "testing" + + "github.com/Azure/go-autorest/autorest" +) + +func TestCorrelationRequestID(t *testing.T) { + first := CorrelationRequestID() + + if first == "" { + t.Fatal("no correlation request ID generated") + } + + second := CorrelationRequestID() + if first != second { + t.Fatal("subsequent correlation request ID not the same as the first") + } +} + +func TestWithCorrelationRequestID(t *testing.T) { + uuid := CorrelationRequestID() + req, _ := autorest.Prepare(&http.Request{}, WithCorrelationRequestID(uuid)) + + if req.Header.Get(HeaderCorrelationRequestID) != uuid { + t.Fatalf("azure: withCorrelationRequestID failed to set %s -- expected %s, received %s", + HeaderCorrelationRequestID, uuid, req.Header.Get(HeaderCorrelationRequestID)) + } +} diff --git a/azurerm/internal/features/requires_import.go b/azurerm/internal/features/requires_import.go new file mode 100644 index 000000000000..6ab74fbf09af --- /dev/null +++ b/azurerm/internal/features/requires_import.go @@ -0,0 +1,27 @@ +package features + +import ( + "os" + "strings" +) + +// ShouldResourcesBeImported returns whether the feature Requiring Resources to be Imported +// should be enabled. +// +// This feature prevents Terraform from 'adopting' resources which already exist, which is the +// behaviour used by ARM Templates which will update these resources rather than overwriting them +// Instead existing resources will need to be imported using `terraform import`, as is the case +// with other Terraform Providers. +// +// This feature-toggle defaults to off in 1.x versions of the Azure Provider, however this will +// become the default behaviour in version 2.0 of the Azure Provider. As outlined in the announcement +// for v2.0 of the Azure Provider: https://github.com/terraform-providers/terraform-provider-azurerm/issues/2807 +// +// Operators wishing to adopt this behaviour can opt-into this behaviour in 1.x versions of the +// Azure Provider by setting the Environment Variable 'ARM_PROVIDER_STRICT' to 'true' +func ShouldResourcesBeImported() bool { + // NOTE: we'll need to add an infobox to MySQL|PostgreSQL Configuration when this goes live + // since these resources can't support import + // in addition the virtual resources will need adjusting + return strings.EqualFold(os.Getenv("ARM_PROVIDER_STRICT"), "true") +} diff --git a/azurerm/internal/features/requires_import_test.go b/azurerm/internal/features/requires_import_test.go new file mode 100644 index 000000000000..dd72255dc4b2 --- /dev/null +++ b/azurerm/internal/features/requires_import_test.go @@ -0,0 +1,55 @@ +package features + +import ( + "os" + "testing" +) + +func TestRequiresImport(t *testing.T) { + testData := []struct { + name string + value string + expected bool + }{ + { + name: "unset", + value: "", + expected: false, + }, + { + name: "disabled lower-case", + value: "false", + expected: false, + }, + { + name: "disabled upper-case", + value: "FALSE", + expected: false, + }, + { + name: "enabled lower-case", + value: "true", + expected: true, + }, + { + name: "enabled upper-case", + value: "TRUE", + expected: true, + }, + { + name: "invalid", + value: "pandas", + expected: false, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Test %q..", v.name) + + os.Setenv("ARM_PROVIDER_STRICT", v.value) + actual := ShouldResourcesBeImported() + if v.expected != actual { + t.Fatalf("Expected %t but got %t", v.expected, actual) + } + } +} diff --git a/azurerm/internal/locks/lock.go b/azurerm/internal/locks/lock.go new file mode 100644 index 000000000000..d6e3c49bd2d9 --- /dev/null +++ b/azurerm/internal/locks/lock.go @@ -0,0 +1,37 @@ +package locks + +import "github.com/hashicorp/terraform/helper/mutexkv" + +// armMutexKV is the instance of MutexKV for ARM resources +var armMutexKV = mutexkv.NewMutexKV() + +func ByID(id string) { + armMutexKV.Lock(id) +} + +// handle the case of using the same name for different kinds of resources +func ByName(name string, resourceType string) { + updatedName := resourceType + "." + name + armMutexKV.Lock(updatedName) +} + +func MultipleByName(names *[]string, resourceType string) { + for _, name := range *names { + ByName(name, resourceType) + } +} + +func UnlockByID(id string) { + armMutexKV.Unlock(id) +} + +func UnlockByName(name string, resourceType string) { + updatedName := resourceType + "." + name + armMutexKV.Unlock(updatedName) +} + +func UnlockMultipleByName(names *[]string, resourceType string) { + for _, name := range *names { + UnlockByName(name, resourceType) + } +} diff --git a/azurerm/internal/services/analysisservices/client.go b/azurerm/internal/services/analysisservices/client.go new file mode 100644 index 000000000000..6e0ad0dff5f0 --- /dev/null +++ b/azurerm/internal/services/analysisservices/client.go @@ -0,0 +1,20 @@ +package analysisservices + +import ( + "github.com/Azure/azure-sdk-for-go/services/analysisservices/mgmt/2017-08-01/analysisservices" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ServerClient *analysisservices.ServersClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ServerClient := analysisservices.NewServersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServerClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ServerClient: &ServerClient, + } +} diff --git a/azurerm/internal/services/apimanagement/client.go b/azurerm/internal/services/apimanagement/client.go new file mode 100644 index 000000000000..c1ebce65c8a4 --- /dev/null +++ b/azurerm/internal/services/apimanagement/client.go @@ -0,0 +1,135 @@ +package apimanagement + +import ( + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ApiClient *apimanagement.APIClient + ApiPoliciesClient *apimanagement.APIPolicyClient + ApiOperationsClient *apimanagement.APIOperationClient + ApiOperationPoliciesClient *apimanagement.APIOperationPolicyClient + ApiSchemasClient *apimanagement.APISchemaClient + ApiVersionSetClient *apimanagement.APIVersionSetClient + AuthorizationServersClient *apimanagement.AuthorizationServerClient + BackendClient *apimanagement.BackendClient + CertificatesClient *apimanagement.CertificateClient + GroupClient *apimanagement.GroupClient + GroupUsersClient *apimanagement.GroupUserClient + LoggerClient *apimanagement.LoggerClient + OpenIdConnectClient *apimanagement.OpenIDConnectProviderClient + PolicyClient *apimanagement.PolicyClient + ProductsClient *apimanagement.ProductClient + ProductApisClient *apimanagement.ProductAPIClient + ProductGroupsClient *apimanagement.ProductGroupClient + ProductPoliciesClient *apimanagement.ProductPolicyClient + PropertyClient *apimanagement.PropertyClient + ServiceClient *apimanagement.ServiceClient + SignInClient *apimanagement.SignInSettingsClient + SignUpClient *apimanagement.SignUpSettingsClient + SubscriptionsClient *apimanagement.SubscriptionClient + UsersClient *apimanagement.UserClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ApiClient := apimanagement.NewAPIClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApiClient.Client, o.ResourceManagerAuthorizer) + + ApiPoliciesClient := apimanagement.NewAPIPolicyClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApiPoliciesClient.Client, o.ResourceManagerAuthorizer) + + ApiOperationsClient := apimanagement.NewAPIOperationClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApiOperationsClient.Client, o.ResourceManagerAuthorizer) + + ApiOperationPoliciesClient := apimanagement.NewAPIOperationPolicyClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApiOperationPoliciesClient.Client, o.ResourceManagerAuthorizer) + + ApiSchemasClient := apimanagement.NewAPISchemaClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApiSchemasClient.Client, o.ResourceManagerAuthorizer) + + ApiVersionSetClient := apimanagement.NewAPIVersionSetClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApiVersionSetClient.Client, o.ResourceManagerAuthorizer) + + AuthorizationServersClient := apimanagement.NewAuthorizationServerClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AuthorizationServersClient.Client, o.ResourceManagerAuthorizer) + + BackendClient := apimanagement.NewBackendClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&BackendClient.Client, o.ResourceManagerAuthorizer) + + CertificatesClient := apimanagement.NewCertificateClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&CertificatesClient.Client, o.ResourceManagerAuthorizer) + + GroupClient := apimanagement.NewGroupClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GroupClient.Client, o.ResourceManagerAuthorizer) + + GroupUsersClient := apimanagement.NewGroupUserClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GroupUsersClient.Client, o.ResourceManagerAuthorizer) + + LoggerClient := apimanagement.NewLoggerClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LoggerClient.Client, o.ResourceManagerAuthorizer) + + PolicyClient := apimanagement.NewPolicyClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PolicyClient.Client, o.ResourceManagerAuthorizer) + + ServiceClient := apimanagement.NewServiceClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServiceClient.Client, o.ResourceManagerAuthorizer) + + SignInClient := apimanagement.NewSignInSettingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SignInClient.Client, o.ResourceManagerAuthorizer) + + SignUpClient := apimanagement.NewSignUpSettingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SignUpClient.Client, o.ResourceManagerAuthorizer) + + OpenIdConnectClient := apimanagement.NewOpenIDConnectProviderClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&OpenIdConnectClient.Client, o.ResourceManagerAuthorizer) + + ProductsClient := apimanagement.NewProductClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProductsClient.Client, o.ResourceManagerAuthorizer) + + ProductApisClient := apimanagement.NewProductAPIClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProductApisClient.Client, o.ResourceManagerAuthorizer) + + ProductGroupsClient := apimanagement.NewProductGroupClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProductGroupsClient.Client, o.ResourceManagerAuthorizer) + + ProductPoliciesClient := apimanagement.NewProductPolicyClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProductPoliciesClient.Client, o.ResourceManagerAuthorizer) + + PropertyClient := apimanagement.NewPropertyClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PropertyClient.Client, o.ResourceManagerAuthorizer) + + SubscriptionsClient := apimanagement.NewSubscriptionClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SubscriptionsClient.Client, o.ResourceManagerAuthorizer) + + UsersClient := apimanagement.NewUserClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&UsersClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ApiClient: &ApiClient, + ApiPoliciesClient: &ApiPoliciesClient, + ApiOperationsClient: &ApiOperationsClient, + ApiOperationPoliciesClient: &ApiOperationPoliciesClient, + ApiSchemasClient: &ApiSchemasClient, + ApiVersionSetClient: &ApiVersionSetClient, + AuthorizationServersClient: &AuthorizationServersClient, + BackendClient: &BackendClient, + CertificatesClient: &CertificatesClient, + GroupClient: &GroupClient, + GroupUsersClient: &GroupUsersClient, + LoggerClient: &LoggerClient, + OpenIdConnectClient: &OpenIdConnectClient, + PolicyClient: &PolicyClient, + ProductsClient: &ProductsClient, + ProductApisClient: &ProductApisClient, + ProductGroupsClient: &ProductGroupsClient, + ProductPoliciesClient: &ProductPoliciesClient, + PropertyClient: &PropertyClient, + ServiceClient: &ServiceClient, + SignInClient: &SignInClient, + SignUpClient: &SignUpClient, + SubscriptionsClient: &SubscriptionsClient, + UsersClient: &UsersClient, + } +} diff --git a/azurerm/internal/services/applicationinsights/client.go b/azurerm/internal/services/applicationinsights/client.go new file mode 100644 index 000000000000..a76eee2ec3c4 --- /dev/null +++ b/azurerm/internal/services/applicationinsights/client.go @@ -0,0 +1,30 @@ +package applicationinsights + +import ( + "github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + APIKeyClient *insights.APIKeysClient + ComponentsClient *insights.ComponentsClient + WebTestsClient *insights.WebTestsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + APIKeyClient := insights.NewAPIKeysClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&APIKeyClient.Client, o.ResourceManagerAuthorizer) + + ComponentsClient := insights.NewComponentsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ComponentsClient.Client, o.ResourceManagerAuthorizer) + + WebTestsClient := insights.NewWebTestsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&WebTestsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + APIKeyClient: &APIKeyClient, + ComponentsClient: &ComponentsClient, + WebTestsClient: &WebTestsClient, + } +} diff --git a/azurerm/internal/services/authorization/client.go b/azurerm/internal/services/authorization/client.go new file mode 100644 index 000000000000..2ab939533c59 --- /dev/null +++ b/azurerm/internal/services/authorization/client.go @@ -0,0 +1,25 @@ +package authorization + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-09-01-preview/authorization" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + RoleAssignmentsClient *authorization.RoleAssignmentsClient + RoleDefinitionsClient *authorization.RoleDefinitionsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + RoleAssignmentsClient := authorization.NewRoleAssignmentsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RoleAssignmentsClient.Client, o.ResourceManagerAuthorizer) + + RoleDefinitionsClient := authorization.NewRoleDefinitionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RoleDefinitionsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + RoleAssignmentsClient: &RoleAssignmentsClient, + RoleDefinitionsClient: &RoleDefinitionsClient, + } +} diff --git a/azurerm/internal/services/automation/client.go b/azurerm/internal/services/automation/client.go new file mode 100644 index 000000000000..ce39b25be4b5 --- /dev/null +++ b/azurerm/internal/services/automation/client.go @@ -0,0 +1,65 @@ +package automation + +import ( + "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AccountClient *automation.AccountClient + AgentRegistrationInfoClient *automation.AgentRegistrationInformationClient + CredentialClient *automation.CredentialClient + DscConfigurationClient *automation.DscConfigurationClient + DscNodeConfigurationClient *automation.DscNodeConfigurationClient + ModuleClient *automation.ModuleClient + RunbookClient *automation.RunbookClient + RunbookDraftClient *automation.RunbookDraftClient + ScheduleClient *automation.ScheduleClient + VariableClient *automation.VariableClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AccountClient := automation.NewAccountClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AccountClient.Client, o.ResourceManagerAuthorizer) + + AgentRegistrationInfoClient := automation.NewAgentRegistrationInformationClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AgentRegistrationInfoClient.Client, o.ResourceManagerAuthorizer) + + CredentialClient := automation.NewCredentialClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&CredentialClient.Client, o.ResourceManagerAuthorizer) + + DscConfigurationClient := automation.NewDscConfigurationClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DscConfigurationClient.Client, o.ResourceManagerAuthorizer) + + DscNodeConfigurationClient := automation.NewDscNodeConfigurationClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DscNodeConfigurationClient.Client, o.ResourceManagerAuthorizer) + + ModuleClient := automation.NewModuleClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ModuleClient.Client, o.ResourceManagerAuthorizer) + + RunbookClient := automation.NewRunbookClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RunbookClient.Client, o.ResourceManagerAuthorizer) + + ScheduleClient := automation.NewScheduleClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ScheduleClient.Client, o.ResourceManagerAuthorizer) + + RunbookDraftClient := automation.NewRunbookDraftClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RunbookDraftClient.Client, o.ResourceManagerAuthorizer) + + VariableClient := automation.NewVariableClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VariableClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AccountClient: &AccountClient, + AgentRegistrationInfoClient: &AgentRegistrationInfoClient, + CredentialClient: &CredentialClient, + DscConfigurationClient: &DscConfigurationClient, + DscNodeConfigurationClient: &DscNodeConfigurationClient, + ModuleClient: &ModuleClient, + RunbookClient: &RunbookClient, + RunbookDraftClient: &RunbookDraftClient, + ScheduleClient: &ScheduleClient, + VariableClient: &VariableClient, + } +} diff --git a/azurerm/internal/services/batch/client.go b/azurerm/internal/services/batch/client.go new file mode 100644 index 000000000000..d5727787cf21 --- /dev/null +++ b/azurerm/internal/services/batch/client.go @@ -0,0 +1,35 @@ +package batch + +import ( + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AccountClient *batch.AccountClient + ApplicationClient *batch.ApplicationClient + CertificateClient *batch.CertificateClient + PoolClient *batch.PoolClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AccountClient := batch.NewAccountClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AccountClient.Client, o.ResourceManagerAuthorizer) + + ApplicationClient := batch.NewApplicationClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApplicationClient.Client, o.ResourceManagerAuthorizer) + + CertificateClient := batch.NewCertificateClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&CertificateClient.Client, o.ResourceManagerAuthorizer) + + PoolClient := batch.NewPoolClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PoolClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AccountClient: &AccountClient, + ApplicationClient: &ApplicationClient, + CertificateClient: &CertificateClient, + PoolClient: &PoolClient, + } +} diff --git a/azurerm/internal/services/cdn/client.go b/azurerm/internal/services/cdn/client.go new file mode 100644 index 000000000000..d9d9d8a8505c --- /dev/null +++ b/azurerm/internal/services/cdn/client.go @@ -0,0 +1,30 @@ +package cdn + +import ( + "github.com/Azure/azure-sdk-for-go/services/cdn/mgmt/2017-10-12/cdn" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + CustomDomainsClient *cdn.CustomDomainsClient + EndpointsClient *cdn.EndpointsClient + ProfilesClient *cdn.ProfilesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + CustomDomainsClient := cdn.NewCustomDomainsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&CustomDomainsClient.Client, o.ResourceManagerAuthorizer) + + EndpointsClient := cdn.NewEndpointsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&EndpointsClient.Client, o.ResourceManagerAuthorizer) + + ProfilesClient := cdn.NewProfilesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProfilesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + CustomDomainsClient: &CustomDomainsClient, + EndpointsClient: &EndpointsClient, + ProfilesClient: &ProfilesClient, + } +} diff --git a/azurerm/internal/services/cognitive/client.go b/azurerm/internal/services/cognitive/client.go new file mode 100644 index 000000000000..de8b926b4bf0 --- /dev/null +++ b/azurerm/internal/services/cognitive/client.go @@ -0,0 +1,20 @@ +package cognitive + +import ( + "github.com/Azure/azure-sdk-for-go/services/cognitiveservices/mgmt/2017-04-18/cognitiveservices" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AccountsClient *cognitiveservices.AccountsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AccountsClient := cognitiveservices.NewAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AccountsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AccountsClient: &AccountsClient, + } +} diff --git a/azurerm/internal/services/common/service_registration.go b/azurerm/internal/services/common/service_registration.go new file mode 100644 index 000000000000..12c24aeb699d --- /dev/null +++ b/azurerm/internal/services/common/service_registration.go @@ -0,0 +1,17 @@ +package common + +import "github.com/hashicorp/terraform/helper/schema" + +// NOTE: unfortunately this has to live in it's own package to avoid a circular reference +// since the Services will need to access ArmClient which is moving to `internal/common` + +type ServiceRegistration interface { + // Name is the name of this Service + Name() string + + // SupportedDataSources returns the supported Data Sources supported by this Service + SupportedDataSources() map[string]*schema.Resource + + // SupportedResources returns the supported Resources supported by this Service + SupportedResources() map[string]*schema.Resource +} diff --git a/azurerm/internal/services/compute/client.go b/azurerm/internal/services/compute/client.go new file mode 100644 index 000000000000..8b6d64359be7 --- /dev/null +++ b/azurerm/internal/services/compute/client.go @@ -0,0 +1,80 @@ +package compute + +import ( + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AvailabilitySetsClient *compute.AvailabilitySetsClient + DisksClient *compute.DisksClient + GalleriesClient *compute.GalleriesClient + GalleryImagesClient *compute.GalleryImagesClient + GalleryImageVersionsClient *compute.GalleryImageVersionsClient + ImagesClient *compute.ImagesClient + SnapshotsClient *compute.SnapshotsClient + UsageClient *compute.UsageClient + VMExtensionImageClient *compute.VirtualMachineExtensionImagesClient + VMExtensionClient *compute.VirtualMachineExtensionsClient + VMScaleSetClient *compute.VirtualMachineScaleSetsClient + VMClient *compute.VirtualMachinesClient + VMImageClient *compute.VirtualMachineImagesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AvailabilitySetsClient := compute.NewAvailabilitySetsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AvailabilitySetsClient.Client, o.ResourceManagerAuthorizer) + + DisksClient := compute.NewDisksClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DisksClient.Client, o.ResourceManagerAuthorizer) + + GalleriesClient := compute.NewGalleriesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GalleriesClient.Client, o.ResourceManagerAuthorizer) + + GalleryImagesClient := compute.NewGalleryImagesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GalleryImagesClient.Client, o.ResourceManagerAuthorizer) + + GalleryImageVersionsClient := compute.NewGalleryImageVersionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GalleryImageVersionsClient.Client, o.ResourceManagerAuthorizer) + + ImagesClient := compute.NewImagesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ImagesClient.Client, o.ResourceManagerAuthorizer) + + SnapshotsClient := compute.NewSnapshotsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SnapshotsClient.Client, o.ResourceManagerAuthorizer) + + UsageClient := compute.NewUsageClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&UsageClient.Client, o.ResourceManagerAuthorizer) + + VMExtensionImageClient := compute.NewVirtualMachineExtensionImagesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VMExtensionImageClient.Client, o.ResourceManagerAuthorizer) + + VMExtensionClient := compute.NewVirtualMachineExtensionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VMExtensionClient.Client, o.ResourceManagerAuthorizer) + + VMImageClient := compute.NewVirtualMachineImagesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VMImageClient.Client, o.ResourceManagerAuthorizer) + + VMScaleSetClient := compute.NewVirtualMachineScaleSetsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VMScaleSetClient.Client, o.ResourceManagerAuthorizer) + + VMClient := compute.NewVirtualMachinesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VMClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AvailabilitySetsClient: &AvailabilitySetsClient, + DisksClient: &DisksClient, + GalleriesClient: &GalleriesClient, + GalleryImagesClient: &GalleryImagesClient, + GalleryImageVersionsClient: &GalleryImageVersionsClient, + ImagesClient: &ImagesClient, + SnapshotsClient: &SnapshotsClient, + UsageClient: &UsageClient, + VMExtensionImageClient: &VMExtensionImageClient, + VMExtensionClient: &VMExtensionClient, + VMScaleSetClient: &VMScaleSetClient, + VMClient: &VMClient, + VMImageClient: &VMImageClient, + } +} diff --git a/azurerm/internal/services/containers/client.go b/azurerm/internal/services/containers/client.go new file mode 100644 index 000000000000..fee94ac2e3e4 --- /dev/null +++ b/azurerm/internal/services/containers/client.go @@ -0,0 +1,49 @@ +package containers + +import ( + "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" + "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2018-09-01/containerregistry" + "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2019-06-01/containerservice" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + KubernetesClustersClient *containerservice.ManagedClustersClient + GroupsClient *containerinstance.ContainerGroupsClient + RegistriesClient *containerregistry.RegistriesClient + WebhooksClient *containerregistry.WebhooksClient + ReplicationsClient *containerregistry.ReplicationsClient + ServicesClient *containerservice.ContainerServicesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + RegistriesClient := containerregistry.NewRegistriesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RegistriesClient.Client, o.ResourceManagerAuthorizer) + + WebhooksClient := containerregistry.NewWebhooksClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&WebhooksClient.Client, o.ResourceManagerAuthorizer) + + ReplicationsClient := containerregistry.NewReplicationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ReplicationsClient.Client, o.ResourceManagerAuthorizer) + + GroupsClient := containerinstance.NewContainerGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GroupsClient.Client, o.ResourceManagerAuthorizer) + + // ACS + ServicesClient := containerservice.NewContainerServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServicesClient.Client, o.ResourceManagerAuthorizer) + + // AKS + KubernetesClustersClient := containerservice.NewManagedClustersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&KubernetesClustersClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + KubernetesClustersClient: &KubernetesClustersClient, + GroupsClient: &GroupsClient, + RegistriesClient: &RegistriesClient, + WebhooksClient: &WebhooksClient, + ReplicationsClient: &ReplicationsClient, + ServicesClient: &ServicesClient, + } +} diff --git a/azurerm/internal/services/cosmos/client.go b/azurerm/internal/services/cosmos/client.go new file mode 100644 index 000000000000..9eca73ab7e4e --- /dev/null +++ b/azurerm/internal/services/cosmos/client.go @@ -0,0 +1,20 @@ +package cosmos + +import ( + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + DatabaseClient *documentdb.DatabaseAccountsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + DatabaseClient := documentdb.NewDatabaseAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DatabaseClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + DatabaseClient: &DatabaseClient, + } +} diff --git a/azurerm/internal/services/databricks/client.go b/azurerm/internal/services/databricks/client.go new file mode 100644 index 000000000000..14abd2564c13 --- /dev/null +++ b/azurerm/internal/services/databricks/client.go @@ -0,0 +1,20 @@ +package databricks + +import ( + "github.com/Azure/azure-sdk-for-go/services/databricks/mgmt/2018-04-01/databricks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + WorkspacesClient *databricks.WorkspacesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + WorkspacesClient := databricks.NewWorkspacesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&WorkspacesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + WorkspacesClient: &WorkspacesClient, + } +} diff --git a/azurerm/internal/services/datafactory/client.go b/azurerm/internal/services/datafactory/client.go new file mode 100644 index 000000000000..8cca2f669bea --- /dev/null +++ b/azurerm/internal/services/datafactory/client.go @@ -0,0 +1,35 @@ +package datafactory + +import ( + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + DatasetClient *datafactory.DatasetsClient + FactoriesClient *datafactory.FactoriesClient + LinkedServiceClient *datafactory.LinkedServicesClient + PipelinesClient *datafactory.PipelinesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + DatasetClient := datafactory.NewDatasetsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DatasetClient.Client, o.ResourceManagerAuthorizer) + + FactoriesClient := datafactory.NewFactoriesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&FactoriesClient.Client, o.ResourceManagerAuthorizer) + + LinkedServiceClient := datafactory.NewLinkedServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LinkedServiceClient.Client, o.ResourceManagerAuthorizer) + + PipelinesClient := datafactory.NewPipelinesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PipelinesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + DatasetClient: &DatasetClient, + FactoriesClient: &FactoriesClient, + LinkedServiceClient: &LinkedServiceClient, + PipelinesClient: &PipelinesClient, + } +} diff --git a/azurerm/internal/services/datalake/client.go b/azurerm/internal/services/datalake/client.go new file mode 100644 index 000000000000..826f91ca4688 --- /dev/null +++ b/azurerm/internal/services/datalake/client.go @@ -0,0 +1,45 @@ +package datalake + +import ( + analytics "github.com/Azure/azure-sdk-for-go/services/datalake/analytics/mgmt/2016-11-01/account" + "github.com/Azure/azure-sdk-for-go/services/datalake/store/2016-11-01/filesystem" + store "github.com/Azure/azure-sdk-for-go/services/datalake/store/mgmt/2016-11-01/account" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + // Data Lake Store + StoreAccountsClient *store.AccountsClient + StoreFirewallRulesClient *store.FirewallRulesClient + StoreFilesClient *filesystem.Client + + // Data Lake Analytics + AnalyticsAccountsClient *analytics.AccountsClient + AnalyticsFirewallRulesClient *analytics.FirewallRulesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + StoreAccountsClient := store.NewAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&StoreAccountsClient.Client, o.ResourceManagerAuthorizer) + + StoreFirewallRulesClient := store.NewFirewallRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&StoreFirewallRulesClient.Client, o.ResourceManagerAuthorizer) + + StoreFilesClient := filesystem.NewClient() + o.ConfigureClient(&StoreFilesClient.Client, o.ResourceManagerAuthorizer) + + AnalyticsAccountsClient := analytics.NewAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AnalyticsAccountsClient.Client, o.ResourceManagerAuthorizer) + + AnalyticsFirewallRulesClient := analytics.NewFirewallRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AnalyticsFirewallRulesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + StoreAccountsClient: &StoreAccountsClient, + StoreFirewallRulesClient: &StoreFirewallRulesClient, + StoreFilesClient: &StoreFilesClient, + AnalyticsAccountsClient: &AnalyticsAccountsClient, + AnalyticsFirewallRulesClient: &AnalyticsFirewallRulesClient, + } +} diff --git a/azurerm/internal/services/devspace/client.go b/azurerm/internal/services/devspace/client.go new file mode 100644 index 000000000000..aae7e53d550b --- /dev/null +++ b/azurerm/internal/services/devspace/client.go @@ -0,0 +1,20 @@ +package devspace + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/devspaces/mgmt/2018-06-01-preview/devspaces" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ControllersClient *devspaces.ControllersClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ControllersClient := devspaces.NewControllersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ControllersClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ControllersClient: &ControllersClient, + } +} diff --git a/azurerm/internal/services/devtestlabs/client.go b/azurerm/internal/services/devtestlabs/client.go new file mode 100644 index 000000000000..9b09b51e683b --- /dev/null +++ b/azurerm/internal/services/devtestlabs/client.go @@ -0,0 +1,40 @@ +package devtestlabs + +import ( + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + LabsClient *dtl.LabsClient + LabSchedulesClient *dtl.SchedulesClient + PoliciesClient *dtl.PoliciesClient + VirtualMachinesClient *dtl.VirtualMachinesClient + VirtualNetworksClient *dtl.VirtualNetworksClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + LabsClient := dtl.NewLabsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LabsClient.Client, o.ResourceManagerAuthorizer) + + PoliciesClient := dtl.NewPoliciesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PoliciesClient.Client, o.ResourceManagerAuthorizer) + + VirtualMachinesClient := dtl.NewVirtualMachinesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VirtualMachinesClient.Client, o.ResourceManagerAuthorizer) + + VirtualNetworksClient := dtl.NewVirtualNetworksClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VirtualNetworksClient.Client, o.ResourceManagerAuthorizer) + + LabSchedulesClient := dtl.NewSchedulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LabSchedulesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + LabsClient: &LabsClient, + LabSchedulesClient: &LabSchedulesClient, + PoliciesClient: &PoliciesClient, + VirtualMachinesClient: &VirtualMachinesClient, + VirtualNetworksClient: &VirtualNetworksClient, + } +} diff --git a/azurerm/internal/services/dns/client.go b/azurerm/internal/services/dns/client.go new file mode 100644 index 000000000000..3d2ef000a41e --- /dev/null +++ b/azurerm/internal/services/dns/client.go @@ -0,0 +1,25 @@ +package dns + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + RecordSetsClient *dns.RecordSetsClient + ZonesClient *dns.ZonesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + RecordSetsClient := dns.NewRecordSetsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RecordSetsClient.Client, o.ResourceManagerAuthorizer) + + ZonesClient := dns.NewZonesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ZonesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + RecordSetsClient: &RecordSetsClient, + ZonesClient: &ZonesClient, + } +} diff --git a/azurerm/internal/services/eventgrid/client.go b/azurerm/internal/services/eventgrid/client.go new file mode 100644 index 000000000000..f8daf234d8e1 --- /dev/null +++ b/azurerm/internal/services/eventgrid/client.go @@ -0,0 +1,30 @@ +package eventgrid + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/eventgrid/mgmt/2018-09-15-preview/eventgrid" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + DomainsClient *eventgrid.DomainsClient + EventSubscriptionsClient *eventgrid.EventSubscriptionsClient + TopicsClient *eventgrid.TopicsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + DomainsClient := eventgrid.NewDomainsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DomainsClient.Client, o.ResourceManagerAuthorizer) + + EventSubscriptionsClient := eventgrid.NewEventSubscriptionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&EventSubscriptionsClient.Client, o.ResourceManagerAuthorizer) + + TopicsClient := eventgrid.NewTopicsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&TopicsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + DomainsClient: &DomainsClient, + EventSubscriptionsClient: &EventSubscriptionsClient, + TopicsClient: &TopicsClient, + } +} diff --git a/azurerm/internal/services/eventhub/client.go b/azurerm/internal/services/eventhub/client.go new file mode 100644 index 000000000000..b9355ddbebef --- /dev/null +++ b/azurerm/internal/services/eventhub/client.go @@ -0,0 +1,30 @@ +package eventhub + +import ( + "github.com/Azure/azure-sdk-for-go/services/eventhub/mgmt/2017-04-01/eventhub" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ConsumerGroupClient *eventhub.ConsumerGroupsClient + EventHubsClient *eventhub.EventHubsClient + NamespacesClient *eventhub.NamespacesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + EventHubsClient := eventhub.NewEventHubsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&EventHubsClient.Client, o.ResourceManagerAuthorizer) + + ConsumerGroupClient := eventhub.NewConsumerGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ConsumerGroupClient.Client, o.ResourceManagerAuthorizer) + + NamespacesClient := eventhub.NewNamespacesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&NamespacesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ConsumerGroupClient: &ConsumerGroupClient, + EventHubsClient: &EventHubsClient, + NamespacesClient: &NamespacesClient, + } +} diff --git a/azurerm/internal/services/graph/client.go b/azurerm/internal/services/graph/client.go new file mode 100644 index 000000000000..35e590318e7c --- /dev/null +++ b/azurerm/internal/services/graph/client.go @@ -0,0 +1,25 @@ +package graph + +import ( + "github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ApplicationsClient *graphrbac.ApplicationsClient + ServicePrincipalsClient *graphrbac.ServicePrincipalsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ApplicationsClient := graphrbac.NewApplicationsClientWithBaseURI(o.GraphEndpoint, o.TenantID) + o.ConfigureClient(&ApplicationsClient.Client, o.GraphAuthorizer) + + ServicePrincipalsClient := graphrbac.NewServicePrincipalsClientWithBaseURI(o.GraphEndpoint, o.TenantID) + o.ConfigureClient(&ServicePrincipalsClient.Client, o.GraphAuthorizer) + + return &Client{ + ApplicationsClient: &ApplicationsClient, + ServicePrincipalsClient: &ServicePrincipalsClient, + } +} diff --git a/azurerm/internal/services/hdinsight/client.go b/azurerm/internal/services/hdinsight/client.go new file mode 100644 index 000000000000..05bac3cd402f --- /dev/null +++ b/azurerm/internal/services/hdinsight/client.go @@ -0,0 +1,30 @@ +package hdinsight + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ApplicationsClient *hdinsight.ApplicationsClient + ClustersClient *hdinsight.ClustersClient + ConfigurationsClient *hdinsight.ConfigurationsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ApplicationsClient := hdinsight.NewApplicationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApplicationsClient.Client, o.ResourceManagerAuthorizer) + + ClustersClient := hdinsight.NewClustersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ClustersClient.Client, o.ResourceManagerAuthorizer) + + ConfigurationsClient := hdinsight.NewConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ConfigurationsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ApplicationsClient: &ApplicationsClient, + ClustersClient: &ClustersClient, + ConfigurationsClient: &ConfigurationsClient, + } +} diff --git a/azurerm/internal/services/iothub/client.go b/azurerm/internal/services/iothub/client.go new file mode 100644 index 000000000000..548d45910afc --- /dev/null +++ b/azurerm/internal/services/iothub/client.go @@ -0,0 +1,31 @@ +package iothub + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/iothub/mgmt/2018-12-01-preview/devices" + "github.com/Azure/azure-sdk-for-go/services/provisioningservices/mgmt/2018-01-22/iothub" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ResourceClient *devices.IotHubResourceClient + DPSResourceClient *iothub.IotDpsResourceClient + DPSCertificateClient *iothub.DpsCertificateClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ResourceClient := devices.NewIotHubResourceClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ResourceClient.Client, o.ResourceManagerAuthorizer) + + DPSResourceClient := iothub.NewIotDpsResourceClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DPSResourceClient.Client, o.ResourceManagerAuthorizer) + + DPSCertificateClient := iothub.NewDpsCertificateClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DPSCertificateClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ResourceClient: &ResourceClient, + DPSResourceClient: &DPSResourceClient, + DPSCertificateClient: &DPSCertificateClient, + } +} diff --git a/azurerm/internal/services/keyvault/client.go b/azurerm/internal/services/keyvault/client.go new file mode 100644 index 000000000000..0239e5ef860e --- /dev/null +++ b/azurerm/internal/services/keyvault/client.go @@ -0,0 +1,26 @@ +package keyvault + +import ( + keyvaultmgmt "github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault" + "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2018-02-14/keyvault" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + VaultsClient *keyvault.VaultsClient + ManagementClient *keyvaultmgmt.BaseClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + VaultsClient := keyvault.NewVaultsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VaultsClient.Client, o.ResourceManagerAuthorizer) + + ManagementClient := keyvaultmgmt.New() + o.ConfigureClient(&ManagementClient.Client, o.KeyVaultAuthorizer) + + return &Client{ + VaultsClient: &VaultsClient, + ManagementClient: &ManagementClient, + } +} diff --git a/azurerm/internal/services/kusto/client.go b/azurerm/internal/services/kusto/client.go new file mode 100644 index 000000000000..699620e3e25e --- /dev/null +++ b/azurerm/internal/services/kusto/client.go @@ -0,0 +1,20 @@ +package kusto + +import ( + "github.com/Azure/azure-sdk-for-go/services/kusto/mgmt/2019-01-21/kusto" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ClustersClient *kusto.ClustersClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ClustersClient := kusto.NewClustersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ClustersClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ClustersClient: &ClustersClient, + } +} diff --git a/azurerm/internal/services/loganalytics/client.go b/azurerm/internal/services/loganalytics/client.go new file mode 100644 index 000000000000..c2f8e643e64c --- /dev/null +++ b/azurerm/internal/services/loganalytics/client.go @@ -0,0 +1,31 @@ +package loganalytics + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/operationalinsights/mgmt/2015-11-01-preview/operationalinsights" + "github.com/Azure/azure-sdk-for-go/services/preview/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + LinkedServicesClient *operationalinsights.LinkedServicesClient + SolutionsClient *operationsmanagement.SolutionsClient + WorkspacesClient *operationalinsights.WorkspacesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + WorkspacesClient := operationalinsights.NewWorkspacesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&WorkspacesClient.Client, o.ResourceManagerAuthorizer) + + SolutionsClient := operationsmanagement.NewSolutionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, "Microsoft.OperationsManagement", "solutions", "testing") + o.ConfigureClient(&SolutionsClient.Client, o.ResourceManagerAuthorizer) + + LinkedServicesClient := operationalinsights.NewLinkedServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LinkedServicesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + LinkedServicesClient: &LinkedServicesClient, + SolutionsClient: &SolutionsClient, + WorkspacesClient: &WorkspacesClient, + } +} diff --git a/azurerm/internal/services/logic/client.go b/azurerm/internal/services/logic/client.go new file mode 100644 index 000000000000..04881db897e8 --- /dev/null +++ b/azurerm/internal/services/logic/client.go @@ -0,0 +1,20 @@ +package logic + +import ( + "github.com/Azure/azure-sdk-for-go/services/logic/mgmt/2016-06-01/logic" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + WorkflowsClient *logic.WorkflowsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + WorkflowsClient := logic.NewWorkflowsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&WorkflowsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + WorkflowsClient: &WorkflowsClient, + } +} diff --git a/azurerm/internal/services/managementgroup/client.go b/azurerm/internal/services/managementgroup/client.go new file mode 100644 index 000000000000..e63895a4944e --- /dev/null +++ b/azurerm/internal/services/managementgroup/client.go @@ -0,0 +1,25 @@ +package managementgroup + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/resources/mgmt/2018-03-01-preview/managementgroups" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + GroupsClient *managementgroups.Client + SubscriptionClient *managementgroups.SubscriptionsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + GroupsClient := managementgroups.NewClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&GroupsClient.Client, o.ResourceManagerAuthorizer) + + SubscriptionClient := managementgroups.NewSubscriptionsClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&SubscriptionClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + GroupsClient: &GroupsClient, + SubscriptionClient: &SubscriptionClient, + } +} diff --git a/azurerm/internal/services/maps/client.go b/azurerm/internal/services/maps/client.go new file mode 100644 index 000000000000..e8a21962bcdb --- /dev/null +++ b/azurerm/internal/services/maps/client.go @@ -0,0 +1,20 @@ +package maps + +import ( + "github.com/Azure/azure-sdk-for-go/services/maps/mgmt/2018-05-01/maps" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AccountsClient *maps.AccountsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AccountsClient := maps.NewAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AccountsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AccountsClient: &AccountsClient, + } +} diff --git a/azurerm/internal/services/maps/validation.go b/azurerm/internal/services/maps/validation.go new file mode 100644 index 000000000000..997b2506025d --- /dev/null +++ b/azurerm/internal/services/maps/validation.go @@ -0,0 +1,14 @@ +package maps + +import ( + "regexp" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" +) + +func ValidateName() schema.SchemaValidateFunc { + return validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]{1}[A-Za-z0-9\._-]{1,}$`), + "First character must be alphanumeric. Subsequent character(s) must be any combination of alphanumeric, underscore (_), period (.), or hyphen (-).") +} diff --git a/azurerm/internal/services/maps/validation_test.go b/azurerm/internal/services/maps/validation_test.go new file mode 100644 index 000000000000..dcfdc9eb52c7 --- /dev/null +++ b/azurerm/internal/services/maps/validation_test.go @@ -0,0 +1,69 @@ +package maps + +import "testing" + +func TestValidateName(t *testing.T) { + testData := []struct { + Name string + Expected bool + }{ + { + Name: "", + Expected: false, + }, + { + Name: "hello", + Expected: true, + }, + { + Name: "Hello", + Expected: true, + }, + { + Name: "1hello", + Expected: true, + }, + { + Name: "1he-llo", + Expected: true, + }, + { + Name: "he-llo1", + Expected: true, + }, + { + Name: "he_llo1", + Expected: true, + }, + { + Name: ".hello1", + Expected: false, + }, + { + Name: "_hello1", + Expected: false, + }, + { + Name: "he.llo1", + Expected: true, + }, + { + Name: "he-llo!", + Expected: false, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + warnings, errors := ValidateName()(v.Name, "name") + if len(warnings) != 0 { + t.Fatalf("Expected no warnings but got %d", len(warnings)) + } + + actual := len(errors) == 0 + if v.Expected != actual { + t.Fatalf("Expected %t but got %t for %q: %s", v.Expected, actual, v.Name, errors) + } + } +} diff --git a/azurerm/internal/services/mariadb/client.go b/azurerm/internal/services/mariadb/client.go new file mode 100644 index 000000000000..c5e73ce51ce5 --- /dev/null +++ b/azurerm/internal/services/mariadb/client.go @@ -0,0 +1,40 @@ +package mariadb + +import ( + "github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ConfigurationsClient *mariadb.ConfigurationsClient + DatabasesClient *mariadb.DatabasesClient + FirewallRulesClient *mariadb.FirewallRulesClient + ServersClient *mariadb.ServersClient + VirtualNetworkRulesClient *mariadb.VirtualNetworkRulesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + configurationsClient := mariadb.NewConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&configurationsClient.Client, o.ResourceManagerAuthorizer) + + DatabasesClient := mariadb.NewDatabasesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DatabasesClient.Client, o.ResourceManagerAuthorizer) + + FirewallRulesClient := mariadb.NewFirewallRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&FirewallRulesClient.Client, o.ResourceManagerAuthorizer) + + ServersClient := mariadb.NewServersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServersClient.Client, o.ResourceManagerAuthorizer) + + VirtualNetworkRulesClient := mariadb.NewVirtualNetworkRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VirtualNetworkRulesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ConfigurationsClient: &configurationsClient, + DatabasesClient: &DatabasesClient, + FirewallRulesClient: &FirewallRulesClient, + ServersClient: &ServersClient, + VirtualNetworkRulesClient: &VirtualNetworkRulesClient, + } +} diff --git a/azurerm/internal/services/media/client.go b/azurerm/internal/services/media/client.go new file mode 100644 index 000000000000..5b3ded217043 --- /dev/null +++ b/azurerm/internal/services/media/client.go @@ -0,0 +1,20 @@ +package media + +import ( + "github.com/Azure/azure-sdk-for-go/services/mediaservices/mgmt/2018-07-01/media" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ServicesClient *media.MediaservicesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ServicesClient := media.NewMediaservicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServicesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ServicesClient: &ServicesClient, + } +} diff --git a/azurerm/internal/services/monitor/client.go b/azurerm/internal/services/monitor/client.go new file mode 100644 index 000000000000..a7ebc341615b --- /dev/null +++ b/azurerm/internal/services/monitor/client.go @@ -0,0 +1,58 @@ +package monitor + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/monitor/mgmt/2018-03-01/insights" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + // Autoscale Settings + AutoscaleSettingsClient *insights.AutoscaleSettingsClient + + // Monitor + ActionGroupsClient *insights.ActionGroupsClient + ActivityLogAlertsClient *insights.ActivityLogAlertsClient + AlertRulesClient *insights.AlertRulesClient + DiagnosticSettingsClient *insights.DiagnosticSettingsClient + DiagnosticSettingsCategoryClient *insights.DiagnosticSettingsCategoryClient + LogProfilesClient *insights.LogProfilesClient + MetricAlertsClient *insights.MetricAlertsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AutoscaleSettingsClient := insights.NewAutoscaleSettingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AutoscaleSettingsClient.Client, o.ResourceManagerAuthorizer) + + ActionGroupsClient := insights.NewActionGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ActionGroupsClient.Client, o.ResourceManagerAuthorizer) + + ActivityLogAlertsClient := insights.NewActivityLogAlertsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ActivityLogAlertsClient.Client, o.ResourceManagerAuthorizer) + + AlertRulesClient := insights.NewAlertRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AlertRulesClient.Client, o.ResourceManagerAuthorizer) + + DiagnosticSettingsClient := insights.NewDiagnosticSettingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DiagnosticSettingsClient.Client, o.ResourceManagerAuthorizer) + + DiagnosticSettingsCategoryClient := insights.NewDiagnosticSettingsCategoryClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DiagnosticSettingsCategoryClient.Client, o.ResourceManagerAuthorizer) + + LogProfilesClient := insights.NewLogProfilesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LogProfilesClient.Client, o.ResourceManagerAuthorizer) + + MetricAlertsClient := insights.NewMetricAlertsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&MetricAlertsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AutoscaleSettingsClient: &AutoscaleSettingsClient, + ActionGroupsClient: &ActionGroupsClient, + ActivityLogAlertsClient: &ActivityLogAlertsClient, + AlertRulesClient: &AlertRulesClient, + DiagnosticSettingsClient: &DiagnosticSettingsClient, + DiagnosticSettingsCategoryClient: &DiagnosticSettingsCategoryClient, + LogProfilesClient: &LogProfilesClient, + MetricAlertsClient: &MetricAlertsClient, + } +} diff --git a/azurerm/internal/services/msi/client.go b/azurerm/internal/services/msi/client.go new file mode 100644 index 000000000000..b9af8bd5e304 --- /dev/null +++ b/azurerm/internal/services/msi/client.go @@ -0,0 +1,20 @@ +package msi + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/msi/mgmt/2015-08-31-preview/msi" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + UserAssignedIdentitiesClient *msi.UserAssignedIdentitiesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + UserAssignedIdentitiesClient := msi.NewUserAssignedIdentitiesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&UserAssignedIdentitiesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + UserAssignedIdentitiesClient: &UserAssignedIdentitiesClient, + } +} diff --git a/azurerm/internal/services/mssql/client.go b/azurerm/internal/services/mssql/client.go new file mode 100644 index 000000000000..cd330d84ffc4 --- /dev/null +++ b/azurerm/internal/services/mssql/client.go @@ -0,0 +1,20 @@ +package mssql + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2017-10-01-preview/sql" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ElasticPoolsClient *sql.ElasticPoolsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ElasticPoolsClient := sql.NewElasticPoolsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ElasticPoolsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ElasticPoolsClient: &ElasticPoolsClient, + } +} diff --git a/azurerm/internal/services/mysql/client.go b/azurerm/internal/services/mysql/client.go new file mode 100644 index 000000000000..29d985f3fef2 --- /dev/null +++ b/azurerm/internal/services/mysql/client.go @@ -0,0 +1,40 @@ +package mysql + +import ( + "github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ConfigurationsClient *mysql.ConfigurationsClient + DatabasesClient *mysql.DatabasesClient + FirewallRulesClient *mysql.FirewallRulesClient + ServersClient *mysql.ServersClient + VirtualNetworkRulesClient *mysql.VirtualNetworkRulesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ConfigurationsClient := mysql.NewConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ConfigurationsClient.Client, o.ResourceManagerAuthorizer) + + DatabasesClient := mysql.NewDatabasesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DatabasesClient.Client, o.ResourceManagerAuthorizer) + + FirewallRulesClient := mysql.NewFirewallRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&FirewallRulesClient.Client, o.ResourceManagerAuthorizer) + + ServersClient := mysql.NewServersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServersClient.Client, o.ResourceManagerAuthorizer) + + VirtualNetworkRulesClient := mysql.NewVirtualNetworkRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VirtualNetworkRulesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ConfigurationsClient: &ConfigurationsClient, + DatabasesClient: &DatabasesClient, + FirewallRulesClient: &FirewallRulesClient, + ServersClient: &ServersClient, + VirtualNetworkRulesClient: &VirtualNetworkRulesClient, + } +} diff --git a/azurerm/internal/services/network/client.go b/azurerm/internal/services/network/client.go new file mode 100644 index 000000000000..01c9f37a6f37 --- /dev/null +++ b/azurerm/internal/services/network/client.go @@ -0,0 +1,150 @@ +package network + +import ( + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ApplicationGatewaysClient *network.ApplicationGatewaysClient + ApplicationSecurityGroupsClient *network.ApplicationSecurityGroupsClient + AzureFirewallsClient *network.AzureFirewallsClient + ConnectionMonitorsClient *network.ConnectionMonitorsClient + DDOSProtectionPlansClient *network.DdosProtectionPlansClient + ExpressRouteAuthsClient *network.ExpressRouteCircuitAuthorizationsClient + ExpressRouteCircuitsClient *network.ExpressRouteCircuitsClient + ExpressRoutePeeringsClient *network.ExpressRouteCircuitPeeringsClient + InterfacesClient *network.InterfacesClient + LoadBalancersClient *network.LoadBalancersClient + LocalNetworkGatewaysClient *network.LocalNetworkGatewaysClient + ProfileClient *network.ProfilesClient + PacketCapturesClient *network.PacketCapturesClient + PublicIPsClient *network.PublicIPAddressesClient + PublicIPPrefixesClient *network.PublicIPPrefixesClient + RoutesClient *network.RoutesClient + RouteTablesClient *network.RouteTablesClient + SecurityGroupClient *network.SecurityGroupsClient + SecurityRuleClient *network.SecurityRulesClient + SubnetsClient *network.SubnetsClient + VnetGatewayConnectionsClient *network.VirtualNetworkGatewayConnectionsClient + VnetGatewayClient *network.VirtualNetworkGatewaysClient + VnetClient *network.VirtualNetworksClient + VnetPeeringsClient *network.VirtualNetworkPeeringsClient + VirtualWanClient *network.VirtualWansClient + WatcherClient *network.WatchersClient + WebApplicationFirewallPoliciesClient *network.WebApplicationFirewallPoliciesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ApplicationGatewaysClient := network.NewApplicationGatewaysClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApplicationGatewaysClient.Client, o.ResourceManagerAuthorizer) + + ApplicationSecurityGroupsClient := network.NewApplicationSecurityGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ApplicationSecurityGroupsClient.Client, o.ResourceManagerAuthorizer) + + AzureFirewallsClient := network.NewAzureFirewallsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AzureFirewallsClient.Client, o.ResourceManagerAuthorizer) + + ConnectionMonitorsClient := network.NewConnectionMonitorsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ConnectionMonitorsClient.Client, o.ResourceManagerAuthorizer) + + DDOSProtectionPlansClient := network.NewDdosProtectionPlansClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DDOSProtectionPlansClient.Client, o.ResourceManagerAuthorizer) + + ExpressRouteAuthsClient := network.NewExpressRouteCircuitAuthorizationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ExpressRouteAuthsClient.Client, o.ResourceManagerAuthorizer) + + ExpressRouteCircuitsClient := network.NewExpressRouteCircuitsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ExpressRouteCircuitsClient.Client, o.ResourceManagerAuthorizer) + + ExpressRoutePeeringsClient := network.NewExpressRouteCircuitPeeringsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ExpressRoutePeeringsClient.Client, o.ResourceManagerAuthorizer) + + InterfacesClient := network.NewInterfacesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&InterfacesClient.Client, o.ResourceManagerAuthorizer) + + LoadBalancersClient := network.NewLoadBalancersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LoadBalancersClient.Client, o.ResourceManagerAuthorizer) + + LocalNetworkGatewaysClient := network.NewLocalNetworkGatewaysClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LocalNetworkGatewaysClient.Client, o.ResourceManagerAuthorizer) + + ProfileClient := network.NewProfilesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProfileClient.Client, o.ResourceManagerAuthorizer) + + VnetClient := network.NewVirtualNetworksClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VnetClient.Client, o.ResourceManagerAuthorizer) + + PacketCapturesClient := network.NewPacketCapturesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PacketCapturesClient.Client, o.ResourceManagerAuthorizer) + + VnetPeeringsClient := network.NewVirtualNetworkPeeringsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VnetPeeringsClient.Client, o.ResourceManagerAuthorizer) + + PublicIPsClient := network.NewPublicIPAddressesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PublicIPsClient.Client, o.ResourceManagerAuthorizer) + + PublicIPPrefixesClient := network.NewPublicIPPrefixesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PublicIPPrefixesClient.Client, o.ResourceManagerAuthorizer) + + RoutesClient := network.NewRoutesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RoutesClient.Client, o.ResourceManagerAuthorizer) + + RouteTablesClient := network.NewRouteTablesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RouteTablesClient.Client, o.ResourceManagerAuthorizer) + + SecurityGroupClient := network.NewSecurityGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SecurityGroupClient.Client, o.ResourceManagerAuthorizer) + + SecurityRuleClient := network.NewSecurityRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SecurityRuleClient.Client, o.ResourceManagerAuthorizer) + + SubnetsClient := network.NewSubnetsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SubnetsClient.Client, o.ResourceManagerAuthorizer) + + VnetGatewayClient := network.NewVirtualNetworkGatewaysClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VnetGatewayClient.Client, o.ResourceManagerAuthorizer) + + VnetGatewayConnectionsClient := network.NewVirtualNetworkGatewayConnectionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VnetGatewayConnectionsClient.Client, o.ResourceManagerAuthorizer) + + VirtualWanClient := network.NewVirtualWansClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VirtualWanClient.Client, o.ResourceManagerAuthorizer) + + WatcherClient := network.NewWatchersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&WatcherClient.Client, o.ResourceManagerAuthorizer) + + WebApplicationFirewallPoliciesClient := network.NewWebApplicationFirewallPoliciesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&WebApplicationFirewallPoliciesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ApplicationGatewaysClient: &ApplicationGatewaysClient, + ApplicationSecurityGroupsClient: &ApplicationSecurityGroupsClient, + AzureFirewallsClient: &AzureFirewallsClient, + ConnectionMonitorsClient: &ConnectionMonitorsClient, + DDOSProtectionPlansClient: &DDOSProtectionPlansClient, + ExpressRouteAuthsClient: &ExpressRouteAuthsClient, + ExpressRouteCircuitsClient: &ExpressRouteCircuitsClient, + ExpressRoutePeeringsClient: &ExpressRoutePeeringsClient, + InterfacesClient: &InterfacesClient, + LoadBalancersClient: &LoadBalancersClient, + LocalNetworkGatewaysClient: &LocalNetworkGatewaysClient, + ProfileClient: &ProfileClient, + PacketCapturesClient: &PacketCapturesClient, + PublicIPsClient: &PublicIPsClient, + PublicIPPrefixesClient: &PublicIPPrefixesClient, + RoutesClient: &RoutesClient, + RouteTablesClient: &RouteTablesClient, + SecurityGroupClient: &SecurityGroupClient, + SecurityRuleClient: &SecurityRuleClient, + SubnetsClient: &SubnetsClient, + VnetGatewayConnectionsClient: &VnetGatewayConnectionsClient, + VnetGatewayClient: &VnetGatewayClient, + VnetClient: &VnetClient, + VnetPeeringsClient: &VnetPeeringsClient, + VirtualWanClient: &VirtualWanClient, + WatcherClient: &WatcherClient, + WebApplicationFirewallPoliciesClient: &WebApplicationFirewallPoliciesClient, + } +} diff --git a/azurerm/internal/services/notificationhub/client.go b/azurerm/internal/services/notificationhub/client.go new file mode 100644 index 000000000000..f521aa498ea5 --- /dev/null +++ b/azurerm/internal/services/notificationhub/client.go @@ -0,0 +1,25 @@ +package notificationhub + +import ( + "github.com/Azure/azure-sdk-for-go/services/notificationhubs/mgmt/2017-04-01/notificationhubs" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + HubsClient *notificationhubs.Client + NamespacesClient *notificationhubs.NamespacesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + NamespacesClient := notificationhubs.NewNamespacesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&NamespacesClient.Client, o.ResourceManagerAuthorizer) + + HubsClient := notificationhubs.NewClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&HubsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + HubsClient: &HubsClient, + NamespacesClient: &NamespacesClient, + } +} diff --git a/azurerm/internal/services/policy/client.go b/azurerm/internal/services/policy/client.go new file mode 100644 index 000000000000..882822a13c38 --- /dev/null +++ b/azurerm/internal/services/policy/client.go @@ -0,0 +1,30 @@ +package policy + +import ( + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/policy" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AssignmentsClient *policy.AssignmentsClient + DefinitionsClient *policy.DefinitionsClient + SetDefinitionsClient *policy.SetDefinitionsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AssignmentsClient := policy.NewAssignmentsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AssignmentsClient.Client, o.ResourceManagerAuthorizer) + + DefinitionsClient := policy.NewDefinitionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DefinitionsClient.Client, o.ResourceManagerAuthorizer) + + SetDefinitionsClient := policy.NewSetDefinitionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SetDefinitionsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AssignmentsClient: &AssignmentsClient, + DefinitionsClient: &DefinitionsClient, + SetDefinitionsClient: &SetDefinitionsClient, + } +} diff --git a/azurerm/internal/services/postgres/client.go b/azurerm/internal/services/postgres/client.go new file mode 100644 index 000000000000..e36c9b75296c --- /dev/null +++ b/azurerm/internal/services/postgres/client.go @@ -0,0 +1,40 @@ +package postgres + +import ( + "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ConfigurationsClient *postgresql.ConfigurationsClient + DatabasesClient *postgresql.DatabasesClient + FirewallRulesClient *postgresql.FirewallRulesClient + ServersClient *postgresql.ServersClient + VirtualNetworkRulesClient *postgresql.VirtualNetworkRulesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ConfigurationsClient := postgresql.NewConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ConfigurationsClient.Client, o.ResourceManagerAuthorizer) + + DatabasesClient := postgresql.NewDatabasesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DatabasesClient.Client, o.ResourceManagerAuthorizer) + + FirewallRulesClient := postgresql.NewFirewallRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&FirewallRulesClient.Client, o.ResourceManagerAuthorizer) + + ServersClient := postgresql.NewServersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServersClient.Client, o.ResourceManagerAuthorizer) + + VirtualNetworkRulesClient := postgresql.NewVirtualNetworkRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VirtualNetworkRulesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ConfigurationsClient: &ConfigurationsClient, + DatabasesClient: &DatabasesClient, + FirewallRulesClient: &FirewallRulesClient, + ServersClient: &ServersClient, + VirtualNetworkRulesClient: &VirtualNetworkRulesClient, + } +} diff --git a/azurerm/internal/services/privatedns/client.go b/azurerm/internal/services/privatedns/client.go new file mode 100644 index 000000000000..3b2222dde87b --- /dev/null +++ b/azurerm/internal/services/privatedns/client.go @@ -0,0 +1,25 @@ +package privatedns + +import ( + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + RecordSetsClient *privatedns.RecordSetsClient + PrivateZonesClient *privatedns.PrivateZonesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + RecordSetsClient := privatedns.NewRecordSetsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&RecordSetsClient.Client, o.ResourceManagerAuthorizer) + + PrivateZonesClient := privatedns.NewPrivateZonesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PrivateZonesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + RecordSetsClient: &RecordSetsClient, + PrivateZonesClient: &PrivateZonesClient, + } +} diff --git a/azurerm/internal/services/recoveryservices/client.go b/azurerm/internal/services/recoveryservices/client.go new file mode 100644 index 000000000000..bed456fb3bb5 --- /dev/null +++ b/azurerm/internal/services/recoveryservices/client.go @@ -0,0 +1,80 @@ +package recoveryservices + +import ( + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2016-06-01/recoveryservices" + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2017-07-01/backup" + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2018-01-10/siterecovery" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ProtectedItemsClient *backup.ProtectedItemsGroupClient + ProtectionPoliciesClient *backup.ProtectionPoliciesClient + VaultsClient *recoveryservices.VaultsClient + FabricClient func(resourceGroupName string, vaultName string) siterecovery.ReplicationFabricsClient + ProtectionContainerClient func(resourceGroupName string, vaultName string) siterecovery.ReplicationProtectionContainersClient + ReplicationPoliciesClient func(resourceGroupName string, vaultName string) siterecovery.ReplicationPoliciesClient + ContainerMappingClient func(resourceGroupName string, vaultName string) siterecovery.ReplicationProtectionContainerMappingsClient + NetworkMappingClient func(resourceGroupName string, vaultName string) siterecovery.ReplicationNetworkMappingsClient + ReplicationMigrationItemsClient func(resourceGroupName string, vaultName string) siterecovery.ReplicationProtectedItemsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + VaultsClient := recoveryservices.NewVaultsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VaultsClient.Client, o.ResourceManagerAuthorizer) + + ProtectedItemsClient := backup.NewProtectedItemsGroupClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProtectedItemsClient.Client, o.ResourceManagerAuthorizer) + + ProtectionPoliciesClient := backup.NewProtectionPoliciesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProtectionPoliciesClient.Client, o.ResourceManagerAuthorizer) + + FabricClient := func(resourceGroupName string, vaultName string) siterecovery.ReplicationFabricsClient { + client := siterecovery.NewReplicationFabricsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, resourceGroupName, vaultName) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + return client + } + + ProtectionContainerClient := func(resourceGroupName string, vaultName string) siterecovery.ReplicationProtectionContainersClient { + client := siterecovery.NewReplicationProtectionContainersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, resourceGroupName, vaultName) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + return client + } + + ReplicationPoliciesClient := func(resourceGroupName string, vaultName string) siterecovery.ReplicationPoliciesClient { + client := siterecovery.NewReplicationPoliciesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, resourceGroupName, vaultName) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + return client + } + + ContainerMappingClient := func(resourceGroupName string, vaultName string) siterecovery.ReplicationProtectionContainerMappingsClient { + client := siterecovery.NewReplicationProtectionContainerMappingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, resourceGroupName, vaultName) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + return client + } + + NetworkMappingClient := func(resourceGroupName string, vaultName string) siterecovery.ReplicationNetworkMappingsClient { + client := siterecovery.NewReplicationNetworkMappingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, resourceGroupName, vaultName) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + return client + } + + ReplicationMigrationItemsClient := func(resourceGroupName string, vaultName string) siterecovery.ReplicationProtectedItemsClient { + client := siterecovery.NewReplicationProtectedItemsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, resourceGroupName, vaultName) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + return client + } + + return &Client{ + ProtectedItemsClient: &ProtectedItemsClient, + ProtectionPoliciesClient: &ProtectionPoliciesClient, + VaultsClient: &VaultsClient, + FabricClient: FabricClient, + ProtectionContainerClient: ProtectionContainerClient, + ReplicationPoliciesClient: ReplicationPoliciesClient, + ContainerMappingClient: ContainerMappingClient, + NetworkMappingClient: NetworkMappingClient, + ReplicationMigrationItemsClient: ReplicationMigrationItemsClient, + } +} diff --git a/azurerm/internal/services/redis/client.go b/azurerm/internal/services/redis/client.go new file mode 100644 index 000000000000..ffe42637c8c6 --- /dev/null +++ b/azurerm/internal/services/redis/client.go @@ -0,0 +1,30 @@ +package redis + +import ( + "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + Client *redis.Client + FirewallRulesClient *redis.FirewallRulesClient + PatchSchedulesClient *redis.PatchSchedulesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + client := redis.NewClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + + FirewallRulesClient := redis.NewFirewallRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&FirewallRulesClient.Client, o.ResourceManagerAuthorizer) + + PatchSchedulesClient := redis.NewPatchSchedulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&PatchSchedulesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + Client: &client, + FirewallRulesClient: &FirewallRulesClient, + PatchSchedulesClient: &PatchSchedulesClient, + } +} diff --git a/azurerm/internal/services/relay/client.go b/azurerm/internal/services/relay/client.go new file mode 100644 index 000000000000..6cb806255f12 --- /dev/null +++ b/azurerm/internal/services/relay/client.go @@ -0,0 +1,20 @@ +package relay + +import ( + "github.com/Azure/azure-sdk-for-go/services/relay/mgmt/2017-04-01/relay" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + NamespacesClient *relay.NamespacesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + NamespacesClient := relay.NewNamespacesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&NamespacesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + NamespacesClient: &NamespacesClient, + } +} diff --git a/azurerm/internal/services/resource/client.go b/azurerm/internal/services/resource/client.go new file mode 100644 index 000000000000..ba6cd0a2f41d --- /dev/null +++ b/azurerm/internal/services/resource/client.go @@ -0,0 +1,38 @@ +package resource + +import ( + providers "github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources" + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-09-01/locks" + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + GroupsClient *resources.GroupsClient + DeploymentsClient *resources.DeploymentsClient + LocksClient *locks.ManagementLocksClient + ProvidersClient *providers.ProvidersClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + LocksClient := locks.NewManagementLocksClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LocksClient.Client, o.ResourceManagerAuthorizer) + + DeploymentsClient := resources.NewDeploymentsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DeploymentsClient.Client, o.ResourceManagerAuthorizer) + + GroupsClient := resources.NewGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GroupsClient.Client, o.ResourceManagerAuthorizer) + + // this has to come from the Profile since this is shared with Stack + ProvidersClient := providers.NewProvidersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProvidersClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + GroupsClient: &GroupsClient, + DeploymentsClient: &DeploymentsClient, + LocksClient: &LocksClient, + ProvidersClient: &ProvidersClient, + } +} diff --git a/azurerm/internal/services/scheduler/client.go b/azurerm/internal/services/scheduler/client.go new file mode 100644 index 000000000000..d14ebf61a119 --- /dev/null +++ b/azurerm/internal/services/scheduler/client.go @@ -0,0 +1,26 @@ +package scheduler + +import ( + "github.com/Azure/azure-sdk-for-go/services/scheduler/mgmt/2016-03-01/scheduler" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +// TODO: remove in 2.0 +type Client struct { + JobCollectionsClient *scheduler.JobCollectionsClient //nolint: megacheck + JobsClient *scheduler.JobsClient //nolint: megacheck +} + +func BuildClient(o *common.ClientOptions) *Client { + + JobCollectionsClient := scheduler.NewJobCollectionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) //nolint: megacheck + o.ConfigureClient(&JobCollectionsClient.Client, o.ResourceManagerAuthorizer) + + JobsClient := scheduler.NewJobsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) //nolint: megacheck + o.ConfigureClient(&JobsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + JobCollectionsClient: &JobCollectionsClient, + JobsClient: &JobsClient, + } +} diff --git a/azurerm/internal/services/search/client.go b/azurerm/internal/services/search/client.go new file mode 100644 index 000000000000..b9526ef42a12 --- /dev/null +++ b/azurerm/internal/services/search/client.go @@ -0,0 +1,25 @@ +package search + +import ( + "github.com/Azure/azure-sdk-for-go/services/search/mgmt/2015-08-19/search" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AdminKeysClient *search.AdminKeysClient + ServicesClient *search.ServicesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AdminKeysClient := search.NewAdminKeysClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AdminKeysClient.Client, o.ResourceManagerAuthorizer) + + ServicesClient := search.NewServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServicesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AdminKeysClient: &AdminKeysClient, + ServicesClient: &ServicesClient, + } +} diff --git a/azurerm/internal/services/securitycenter/client.go b/azurerm/internal/services/securitycenter/client.go new file mode 100644 index 000000000000..109230cb6e4c --- /dev/null +++ b/azurerm/internal/services/securitycenter/client.go @@ -0,0 +1,36 @@ +package securitycenter + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v1.0/security" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ContactsClient *security.ContactsClient + PricingClient *security.PricingsClient + WorkspaceClient *security.WorkspaceSettingsClient + AdvancedThreatProtectionClient *security.AdvancedThreatProtectionClient +} + +func BuildClient(o *common.ClientOptions) *Client { + ascLocation := "Global" + + ContactsClient := security.NewContactsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, ascLocation) + o.ConfigureClient(&ContactsClient.Client, o.ResourceManagerAuthorizer) + + PricingClient := security.NewPricingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, ascLocation) + o.ConfigureClient(&PricingClient.Client, o.ResourceManagerAuthorizer) + + WorkspaceClient := security.NewWorkspaceSettingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, ascLocation) + o.ConfigureClient(&WorkspaceClient.Client, o.ResourceManagerAuthorizer) + + AdvancedThreatProtectionClient := security.NewAdvancedThreatProtectionClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, ascLocation) + o.ConfigureClient(&AdvancedThreatProtectionClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ContactsClient: &ContactsClient, + PricingClient: &PricingClient, + WorkspaceClient: &WorkspaceClient, + AdvancedThreatProtectionClient: &AdvancedThreatProtectionClient, + } +} diff --git a/azurerm/internal/services/servicebus/client.go b/azurerm/internal/services/servicebus/client.go new file mode 100644 index 000000000000..77f6c6a7254a --- /dev/null +++ b/azurerm/internal/services/servicebus/client.go @@ -0,0 +1,40 @@ +package servicebus + +import ( + "github.com/Azure/azure-sdk-for-go/services/servicebus/mgmt/2017-04-01/servicebus" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + QueuesClient *servicebus.QueuesClient + NamespacesClient *servicebus.NamespacesClient + TopicsClient *servicebus.TopicsClient + SubscriptionsClient *servicebus.SubscriptionsClient + SubscriptionRulesClient *servicebus.RulesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + QueuesClient := servicebus.NewQueuesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&QueuesClient.Client, o.ResourceManagerAuthorizer) + + NamespacesClient := servicebus.NewNamespacesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&NamespacesClient.Client, o.ResourceManagerAuthorizer) + + TopicsClient := servicebus.NewTopicsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&TopicsClient.Client, o.ResourceManagerAuthorizer) + + SubscriptionsClient := servicebus.NewSubscriptionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SubscriptionsClient.Client, o.ResourceManagerAuthorizer) + + SubscriptionRulesClient := servicebus.NewRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&SubscriptionRulesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + QueuesClient: &QueuesClient, + NamespacesClient: &NamespacesClient, + TopicsClient: &TopicsClient, + SubscriptionsClient: &SubscriptionsClient, + SubscriptionRulesClient: &SubscriptionRulesClient, + } +} diff --git a/azurerm/internal/services/servicefabric/client.go b/azurerm/internal/services/servicefabric/client.go new file mode 100644 index 000000000000..ed7647a9a7b8 --- /dev/null +++ b/azurerm/internal/services/servicefabric/client.go @@ -0,0 +1,20 @@ +package servicefabric + +import ( + "github.com/Azure/azure-sdk-for-go/services/servicefabric/mgmt/2018-02-01/servicefabric" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + ClustersClient *servicefabric.ClustersClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + ClustersClient := servicefabric.NewClustersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ClustersClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + ClustersClient: &ClustersClient, + } +} diff --git a/azurerm/internal/services/signalr/client.go b/azurerm/internal/services/signalr/client.go new file mode 100644 index 000000000000..611f2e0b6b62 --- /dev/null +++ b/azurerm/internal/services/signalr/client.go @@ -0,0 +1,20 @@ +package signalr + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/signalr/mgmt/2018-03-01-preview/signalr" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + Client *signalr.Client +} + +func BuildClient(o *common.ClientOptions) *Client { + + client := signalr.NewClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + + return &Client{ + Client: &client, + } +} diff --git a/azurerm/internal/services/sql/client.go b/azurerm/internal/services/sql/client.go new file mode 100644 index 000000000000..36c05bfd530a --- /dev/null +++ b/azurerm/internal/services/sql/client.go @@ -0,0 +1,56 @@ +package sql + +import ( + "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + DatabasesClient *sql.DatabasesClient + DatabaseThreatDetectionPoliciesClient *sql.DatabaseThreatDetectionPoliciesClient + ElasticPoolsClient *sql.ElasticPoolsClient + FirewallRulesClient *sql.FirewallRulesClient + FailoverGroupsClient *sql.FailoverGroupsClient + ServersClient *sql.ServersClient + ServerAzureADAdministratorsClient *sql.ServerAzureADAdministratorsClient + VirtualNetworkRulesClient *sql.VirtualNetworkRulesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + // SQL Azure + DatabasesClient := sql.NewDatabasesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DatabasesClient.Client, o.ResourceManagerAuthorizer) + + DatabaseThreatDetectionPoliciesClient := sql.NewDatabaseThreatDetectionPoliciesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&DatabaseThreatDetectionPoliciesClient.Client, o.ResourceManagerAuthorizer) + + ElasticPoolsClient := sql.NewElasticPoolsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ElasticPoolsClient.Client, o.ResourceManagerAuthorizer) + + FailoverGroupsClient := sql.NewFailoverGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&FailoverGroupsClient.Client, o.ResourceManagerAuthorizer) + + FirewallRulesClient := sql.NewFirewallRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&FirewallRulesClient.Client, o.ResourceManagerAuthorizer) + + ServersClient := sql.NewServersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServersClient.Client, o.ResourceManagerAuthorizer) + + ServerAzureADAdministratorsClient := sql.NewServerAzureADAdministratorsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ServerAzureADAdministratorsClient.Client, o.ResourceManagerAuthorizer) + + VirtualNetworkRulesClient := sql.NewVirtualNetworkRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&VirtualNetworkRulesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + DatabasesClient: &DatabasesClient, + DatabaseThreatDetectionPoliciesClient: &DatabaseThreatDetectionPoliciesClient, + ElasticPoolsClient: &ElasticPoolsClient, + FailoverGroupsClient: &FailoverGroupsClient, + FirewallRulesClient: &FirewallRulesClient, + ServersClient: &ServersClient, + ServerAzureADAdministratorsClient: &ServerAzureADAdministratorsClient, + VirtualNetworkRulesClient: &VirtualNetworkRulesClient, + } +} diff --git a/azurerm/internal/services/storage/blobs.go b/azurerm/internal/services/storage/blobs.go new file mode 100644 index 000000000000..c292907aa6f8 --- /dev/null +++ b/azurerm/internal/services/storage/blobs.go @@ -0,0 +1,304 @@ +package storage + +import ( + "bytes" + "context" + "fmt" + "io" + "os" + "runtime" + "strings" + "sync" + "time" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs" +) + +const pollingInterval = time.Second * 15 + +type BlobUpload struct { + Client *blobs.Client + + AccountName string + BlobName string + ContainerName string + + BlobType string + ContentType string + MetaData map[string]string + Parallelism int + Size int + Source string + SourceUri string +} + +func (sbu BlobUpload) Create(ctx context.Context) error { + if sbu.SourceUri != "" { + return sbu.copy(ctx) + } + + blobType := strings.ToLower(sbu.BlobType) + + // TODO: new feature for 'append' blobs? + + if blobType == "block" { + if sbu.Source != "" { + return sbu.uploadBlockBlob(ctx) + } + + return sbu.createEmptyBlockBlob(ctx) + } + + if blobType == "page" { + if sbu.Source != "" { + return sbu.uploadPageBlob(ctx) + } + + return sbu.createEmptyPageBlob(ctx) + } + + return fmt.Errorf("Unsupported Blob Type: %q", blobType) +} + +func (sbu BlobUpload) copy(ctx context.Context) error { + input := blobs.CopyInput{ + CopySource: sbu.SourceUri, + MetaData: sbu.MetaData, + } + if err := sbu.Client.CopyAndWait(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input, pollingInterval); err != nil { + return fmt.Errorf("Error copy/waiting: %s", err) + } + + return nil +} + +func (sbu BlobUpload) createEmptyBlockBlob(ctx context.Context) error { + input := blobs.PutBlockBlobInput{ + ContentType: utils.String(sbu.ContentType), + MetaData: sbu.MetaData, + } + if _, err := sbu.Client.PutBlockBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + return fmt.Errorf("Error PutBlockBlob: %s", err) + } + + return nil +} + +func (sbu BlobUpload) uploadBlockBlob(ctx context.Context) error { + file, err := os.Open(sbu.Source) + if err != nil { + return fmt.Errorf("Error opening: %s", err) + } + defer file.Close() + + input := blobs.PutBlockBlobInput{ + ContentType: utils.String(sbu.ContentType), + MetaData: sbu.MetaData, + } + if err := sbu.Client.PutBlockBlobFromFile(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, file, input); err != nil { + return fmt.Errorf("Error PutBlockBlobFromFile: %s", err) + } + + return nil +} + +func (sbu BlobUpload) createEmptyPageBlob(ctx context.Context) error { + if sbu.Size == 0 { + return fmt.Errorf("`size` cannot be zero for a page blob") + } + + input := blobs.PutPageBlobInput{ + BlobContentLengthBytes: int64(sbu.Size), + ContentType: utils.String(sbu.ContentType), + MetaData: sbu.MetaData, + } + if _, err := sbu.Client.PutPageBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + return fmt.Errorf("Error PutPageBlob: %s", err) + } + + return nil +} + +func (sbu BlobUpload) uploadPageBlob(ctx context.Context) error { + if sbu.Size != 0 { + return fmt.Errorf("`size` cannot be set for an uploaded page blob") + } + + // determine the details about the file + file, err := os.Open(sbu.Source) + if err != nil { + return fmt.Errorf("Error opening source file for upload %q: %s", sbu.Source, err) + } + defer file.Close() + + // TODO: all of this ultimately can be moved into Giovanni + + info, err := file.Stat() + if err != nil { + return fmt.Errorf("Could not stat file %q: %s", file.Name(), err) + } + + fileSize := info.Size() + + // first let's create a file of the specified file size + input := blobs.PutPageBlobInput{ + BlobContentLengthBytes: fileSize, + ContentType: utils.String(sbu.ContentType), + MetaData: sbu.MetaData, + } + // TODO: access tiers? + if _, err := sbu.Client.PutPageBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + return fmt.Errorf("Error PutPageBlob: %s", err) + } + + if err := sbu.pageUploadFromSource(ctx, file, fileSize); err != nil { + return fmt.Errorf("Error creating storage blob on Azure: %s", err) + } + + return nil +} + +// TODO: move below here into Giovanni + +type storageBlobPage struct { + offset int64 + section *io.SectionReader +} + +func (sbu BlobUpload) pageUploadFromSource(ctx context.Context, file io.ReaderAt, fileSize int64) error { + workerCount := sbu.Parallelism * runtime.NumCPU() + + // first we chunk the file and assign them to 'pages' + pageList, err := sbu.storageBlobPageSplit(file, fileSize) + if err != nil { + return fmt.Errorf("Error splitting source file %q into pages: %s", sbu.Source, err) + } + + // finally we upload the contents of said file + pages := make(chan storageBlobPage, len(pageList)) + errors := make(chan error, len(pageList)) + wg := &sync.WaitGroup{} + wg.Add(len(pageList)) + + total := int64(0) + for _, page := range pageList { + total += page.section.Size() + pages <- page + } + close(pages) + + for i := 0; i < workerCount; i++ { + go sbu.blobPageUploadWorker(ctx, blobPageUploadContext{ + blobSize: fileSize, + pages: pages, + errors: errors, + wg: wg, + }) + } + + wg.Wait() + + if len(errors) > 0 { + return fmt.Errorf("Error while uploading source file %q: %s", sbu.Source, <-errors) + } + + return nil +} + +const ( + minPageSize int64 = 4 * 1024 + + // TODO: investigate whether this can be bumped to 100MB with the new API + maxPageSize int64 = 4 * 1024 * 1024 +) + +func (sbu BlobUpload) storageBlobPageSplit(file io.ReaderAt, fileSize int64) ([]storageBlobPage, error) { + // whilst the file Size can be any arbitrary Size, it must be uploaded in fixed-Size pages + blobSize := fileSize + if fileSize%minPageSize != 0 { + blobSize = fileSize + (minPageSize - (fileSize % minPageSize)) + } + + emptyPage := make([]byte, minPageSize) + + type byteRange struct { + offset int64 + length int64 + } + + var nonEmptyRanges []byteRange + var currentRange byteRange + for i := int64(0); i < blobSize; i += minPageSize { + pageBuf := make([]byte, minPageSize) + if _, err := file.ReadAt(pageBuf, i); err != nil && err != io.EOF { + return nil, fmt.Errorf("Could not read chunk at %d: %s", i, err) + } + + if bytes.Equal(pageBuf, emptyPage) { + if currentRange.length != 0 { + nonEmptyRanges = append(nonEmptyRanges, currentRange) + } + currentRange = byteRange{ + offset: i + minPageSize, + } + } else { + currentRange.length += minPageSize + if currentRange.length == maxPageSize || (currentRange.offset+currentRange.length == blobSize) { + nonEmptyRanges = append(nonEmptyRanges, currentRange) + currentRange = byteRange{ + offset: i + minPageSize, + } + } + } + } + + var pages []storageBlobPage + for _, nonEmptyRange := range nonEmptyRanges { + pages = append(pages, storageBlobPage{ + offset: nonEmptyRange.offset, + section: io.NewSectionReader(file, nonEmptyRange.offset, nonEmptyRange.length), + }) + } + + return pages, nil +} + +type blobPageUploadContext struct { + blobSize int64 + pages chan storageBlobPage + errors chan error + wg *sync.WaitGroup +} + +func (sbu BlobUpload) blobPageUploadWorker(ctx context.Context, uploadCtx blobPageUploadContext) { + for page := range uploadCtx.pages { + start := page.offset + end := page.offset + page.section.Size() - 1 + if end > uploadCtx.blobSize-1 { + end = uploadCtx.blobSize - 1 + } + size := end - start + 1 + + chunk := make([]byte, size) + if _, err := page.section.Read(chunk); err != nil && err != io.EOF { + uploadCtx.errors <- fmt.Errorf("Error reading source file %q at offset %d: %s", sbu.Source, page.offset, err) + uploadCtx.wg.Done() + continue + } + + input := blobs.PutPageUpdateInput{ + StartByte: start, + EndByte: end, + Content: chunk, + } + + if _, err := sbu.Client.PutPageUpdate(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + uploadCtx.errors <- fmt.Errorf("Error writing page at offset %d for file %q: %s", page.offset, sbu.Source, err) + uploadCtx.wg.Done() + continue + } + + uploadCtx.wg.Done() + } +} diff --git a/azurerm/internal/services/storage/client.go b/azurerm/internal/services/storage/client.go new file mode 100644 index 000000000000..a5016121526b --- /dev/null +++ b/azurerm/internal/services/storage/client.go @@ -0,0 +1,120 @@ +package storage + +import ( + "context" + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage" + az "github.com/Azure/go-autorest/autorest/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/authorizers" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/table/tables" +) + +type Client struct { + AccountsClient storage.AccountsClient + + environment az.Environment +} + +func BuildClient(options *common.ClientOptions) *Client { + accountsClient := storage.NewAccountsClientWithBaseURI(options.ResourceManagerEndpoint, options.SubscriptionId) + options.ConfigureClient(&accountsClient.Client, options.ResourceManagerAuthorizer) + + // TODO: switch Storage Containers to using the storage.BlobContainersClient + // (which should fix #2977) when the storage clients have been moved in here + return &Client{ + AccountsClient: accountsClient, + environment: options.Environment, + } +} + +func (client Client) BlobsClient(ctx context.Context, resourceGroup, accountName string) (*blobs.Client, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + storageAuth := authorizers.NewSharedKeyLiteAuthorizer(accountName, *accountKey) + blobsClient := blobs.NewWithEnvironment(client.environment) + blobsClient.Client.Authorizer = storageAuth + return &blobsClient, nil +} + +func (client Client) ContainersClient(ctx context.Context, resourceGroup, accountName string) (*containers.Client, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + storageAuth := authorizers.NewSharedKeyLiteAuthorizer(accountName, *accountKey) + containersClient := containers.NewWithEnvironment(client.environment) + containersClient.Client.Authorizer = storageAuth + return &containersClient, nil +} + +func (client Client) FileShareDirectoriesClient(ctx context.Context, resourceGroup, accountName string) (*directories.Client, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + storageAuth := authorizers.NewSharedKeyLiteAuthorizer(accountName, *accountKey) + directoriesClient := directories.NewWithEnvironment(client.environment) + directoriesClient.Client.Authorizer = storageAuth + return &directoriesClient, nil +} + +func (client Client) FileSharesClient(ctx context.Context, resourceGroup, accountName string) (*shares.Client, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + storageAuth := authorizers.NewSharedKeyLiteAuthorizer(accountName, *accountKey) + directoriesClient := shares.NewWithEnvironment(client.environment) + directoriesClient.Client.Authorizer = storageAuth + return &directoriesClient, nil +} + +func (client Client) QueuesClient(ctx context.Context, resourceGroup, accountName string) (*queues.Client, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + storageAuth := authorizers.NewSharedKeyLiteAuthorizer(accountName, *accountKey) + queuesClient := queues.NewWithEnvironment(client.environment) + queuesClient.Client.Authorizer = storageAuth + return &queuesClient, nil +} + +func (client Client) TableEntityClient(ctx context.Context, resourceGroup, accountName string) (*entities.Client, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + storageAuth := authorizers.NewSharedKeyLiteTableAuthorizer(accountName, *accountKey) + entitiesClient := entities.NewWithEnvironment(client.environment) + entitiesClient.Client.Authorizer = storageAuth + return &entitiesClient, nil +} + +func (client Client) TablesClient(ctx context.Context, resourceGroup, accountName string) (*tables.Client, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + storageAuth := authorizers.NewSharedKeyLiteTableAuthorizer(accountName, *accountKey) + tablesClient := tables.NewWithEnvironment(client.environment) + tablesClient.Client.Authorizer = storageAuth + return &tablesClient, nil +} diff --git a/azurerm/internal/services/storage/helpers.go b/azurerm/internal/services/storage/helpers.go new file mode 100644 index 000000000000..8512626a3c8a --- /dev/null +++ b/azurerm/internal/services/storage/helpers.go @@ -0,0 +1,54 @@ +package storage + +import ( + "context" + "fmt" + "strings" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +func (client Client) FindResourceGroup(ctx context.Context, accountName string) (*string, error) { + accounts, err := client.AccountsClient.List(ctx) + if err != nil { + return nil, fmt.Errorf("Error listing Storage Accounts (to find Resource Group for %q): %s", accountName, err) + } + + if accounts.Value == nil { + return nil, nil + } + + var resourceGroup *string + for _, account := range *accounts.Value { + if account.Name == nil || account.ID == nil { + continue + } + + if strings.EqualFold(accountName, *account.Name) { + id, err := azure.ParseAzureResourceID(*account.ID) + if err != nil { + return nil, fmt.Errorf("Error parsing ID for Storage Account %q: %s", accountName, err) + } + + resourceGroup = &id.ResourceGroup + break + } + } + + return resourceGroup, nil +} + +func (client Client) findAccountKey(ctx context.Context, resourceGroup, accountName string) (*string, error) { + props, err := client.AccountsClient.ListKeys(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error Listing Keys for Storage Account %q (Resource Group %q): %+v", accountName, resourceGroup, err) + } + + if props.Keys == nil || len(*props.Keys) == 0 { + return nil, fmt.Errorf("Keys were nil for Storage Account %q (Resource Group %q): %+v", accountName, resourceGroup, err) + } + + keys := *props.Keys + firstKey := keys[0].Value + return firstKey, nil +} diff --git a/azurerm/internal/services/storage/legacy.go b/azurerm/internal/services/storage/legacy.go new file mode 100644 index 000000000000..974bc9c93058 --- /dev/null +++ b/azurerm/internal/services/storage/legacy.go @@ -0,0 +1,24 @@ +package storage + +import ( + "context" + "fmt" + + legacy "github.com/Azure/azure-sdk-for-go/storage" +) + +func (client *Client) LegacyBlobClient(ctx context.Context, resourceGroup, accountName string) (*legacy.BlobStorageClient, bool, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, false, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + apiVersion := legacy.DefaultAPIVersion + storageClient, err := legacy.NewClient(accountName, *accountKey, client.environment.StorageEndpointSuffix, apiVersion, true) + if err != nil { + return nil, true, fmt.Errorf("Error creating storage client for storage account %q: %s", accountName, err) + } + + blobClient := storageClient.GetBlobService() + return &blobClient, true, nil +} diff --git a/azurerm/internal/services/storage/metadata.go b/azurerm/internal/services/storage/metadata.go new file mode 100644 index 000000000000..5d0bcfa78513 --- /dev/null +++ b/azurerm/internal/services/storage/metadata.go @@ -0,0 +1,148 @@ +package storage + +import ( + "fmt" + "regexp" + "strings" + + "github.com/hashicorp/terraform/helper/schema" +) + +func MetaDataSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + ValidateFunc: validateMetaDataKeys, + } +} + +func MetaDataComputedSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + Computed: true, + ValidateFunc: validateMetaDataKeys, + } +} + +func ExpandMetaData(input map[string]interface{}) map[string]string { + output := make(map[string]string) + + for k, v := range input { + output[k] = v.(string) + } + + return output +} + +func FlattenMetaData(input map[string]string) map[string]interface{} { + output := make(map[string]interface{}) + + for k, v := range input { + output[k] = v + } + + return output +} + +func validateMetaDataKeys(value interface{}, _ string) (warnings []string, errors []error) { + v, ok := value.(map[string]interface{}) + if !ok { + return + } + + for k := range v { + isCSharpKeyword := cSharpKeywords[strings.ToLower(k)] != nil + if isCSharpKeyword { + errors = append(errors, fmt.Errorf("%q is not a valid key (C# keyword)", k)) + } + + // must begin with a letter, underscore + // the rest: letters, digits and underscores + r, _ := regexp.Compile(`^([a-z_]{1}[a-z0-9_]{1,})$`) + if !r.MatchString(k) { + errors = append(errors, fmt.Errorf("MetaData must start with letters or an underscores. Got %q.", k)) + } + } + + return +} + +var cSharpKeywords = map[string]*struct{}{ + "abstract": {}, + "as": {}, + "base": {}, + "bool": {}, + "break": {}, + "byte": {}, + "case": {}, + "catch": {}, + "char": {}, + "checked": {}, + "class": {}, + "const": {}, + "continue": {}, + "decimal": {}, + "default": {}, + "delegate": {}, + "do": {}, + "double": {}, + "else": {}, + "enum": {}, + "event": {}, + "explicit": {}, + "extern": {}, + "false": {}, + "finally": {}, + "fixed": {}, + "float": {}, + "for": {}, + "foreach": {}, + "goto": {}, + "if": {}, + "implicit": {}, + "in": {}, + "int": {}, + "interface": {}, + "internal": {}, + "is": {}, + "lock": {}, + "long": {}, + "namespace": {}, + "new": {}, + "null": {}, + "object": {}, + "operator": {}, + "out": {}, + "override": {}, + "params": {}, + "private": {}, + "protected": {}, + "public": {}, + "readonly": {}, + "ref": {}, + "return": {}, + "sbyte": {}, + "sealed": {}, + "short": {}, + "sizeof": {}, + "stackalloc": {}, + "static": {}, + "string": {}, + "struct": {}, + "switch": {}, + "this": {}, + "throw": {}, + "true": {}, + "try": {}, + "typeof": {}, + "uint": {}, + "ulong": {}, + "unchecked": {}, + "unsafe": {}, + "ushort": {}, + "using": {}, + "void": {}, + "volatile": {}, + "while": {}, +} diff --git a/azurerm/internal/services/storage/metadata_test.go b/azurerm/internal/services/storage/metadata_test.go new file mode 100644 index 000000000000..84d045f49830 --- /dev/null +++ b/azurerm/internal/services/storage/metadata_test.go @@ -0,0 +1,61 @@ +package storage + +import "testing" + +func TestValidateMetaDataKeys(t *testing.T) { + testData := []struct { + Input string + Expected bool + }{ + { + Input: "", + Expected: false, + }, + { + Input: "Hello", + Expected: false, + }, + { + Input: "hello", + Expected: true, + }, + { + Input: "hello", + Expected: true, + }, + { + // C# keyword + Input: "using", + Expected: false, + }, + { + Input: "0hello", + Expected: false, + }, + { + Input: "heLLo", + Expected: false, + }, + { + Input: "panda_cycle", + Expected: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + value := map[string]interface{}{ + v.Input: "hello", + } + warnings, errors := validateMetaDataKeys(value, "field") + if len(warnings) != 0 { + t.Fatalf("Expected no warnings but got %d", len(warnings)) + } + + actual := len(errors) == 0 + if v.Expected != actual { + t.Fatalf("Expected %t but got %t", v.Expected, actual) + } + } +} diff --git a/azurerm/internal/services/streamanalytics/client.go b/azurerm/internal/services/streamanalytics/client.go new file mode 100644 index 000000000000..e7d816977d75 --- /dev/null +++ b/azurerm/internal/services/streamanalytics/client.go @@ -0,0 +1,39 @@ +package streamanalytics + +import ( + "github.com/Azure/azure-sdk-for-go/services/streamanalytics/mgmt/2016-03-01/streamanalytics" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + FunctionsClient *streamanalytics.FunctionsClient + JobsClient *streamanalytics.StreamingJobsClient + InputsClient *streamanalytics.InputsClient + OutputsClient *streamanalytics.OutputsClient + TransformationsClient *streamanalytics.TransformationsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + FunctionsClient := streamanalytics.NewFunctionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&FunctionsClient.Client, o.ResourceManagerAuthorizer) + + JobsClient := streamanalytics.NewStreamingJobsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&JobsClient.Client, o.ResourceManagerAuthorizer) + + InputsClient := streamanalytics.NewInputsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&InputsClient.Client, o.ResourceManagerAuthorizer) + + OutputsClient := streamanalytics.NewOutputsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&OutputsClient.Client, o.ResourceManagerAuthorizer) + + TransformationsClient := streamanalytics.NewTransformationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&TransformationsClient.Client, o.ResourceManagerAuthorizer) + return &Client{ + FunctionsClient: &FunctionsClient, + JobsClient: &JobsClient, + InputsClient: &InputsClient, + OutputsClient: &OutputsClient, + TransformationsClient: &TransformationsClient, + } +} diff --git a/azurerm/internal/services/subscription/client.go b/azurerm/internal/services/subscription/client.go new file mode 100644 index 000000000000..08700b936170 --- /dev/null +++ b/azurerm/internal/services/subscription/client.go @@ -0,0 +1,20 @@ +package subscription + +import ( + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + Client *subscriptions.Client +} + +func BuildClient(o *common.ClientOptions) *Client { + + client := subscriptions.NewClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer) + + return &Client{ + Client: &client, + } +} diff --git a/azurerm/internal/services/trafficmanager/client.go b/azurerm/internal/services/trafficmanager/client.go new file mode 100644 index 000000000000..7eaaa52e8cad --- /dev/null +++ b/azurerm/internal/services/trafficmanager/client.go @@ -0,0 +1,30 @@ +package trafficmanager + +import ( + "github.com/Azure/azure-sdk-for-go/services/trafficmanager/mgmt/2018-04-01/trafficmanager" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + GeographialHierarchiesClient *trafficmanager.GeographicHierarchiesClient + ProfilesClient *trafficmanager.ProfilesClient + EndpointsClient *trafficmanager.EndpointsClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + EndpointsClient := trafficmanager.NewEndpointsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&EndpointsClient.Client, o.ResourceManagerAuthorizer) + + GeographialHierarchiesClient := trafficmanager.NewGeographicHierarchiesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GeographialHierarchiesClient.Client, o.ResourceManagerAuthorizer) + + ProfilesClient := trafficmanager.NewProfilesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ProfilesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + GeographialHierarchiesClient: &GeographialHierarchiesClient, + ProfilesClient: &ProfilesClient, + EndpointsClient: &EndpointsClient, + } +} diff --git a/azurerm/internal/services/web/client.go b/azurerm/internal/services/web/client.go new file mode 100644 index 000000000000..948885766f1f --- /dev/null +++ b/azurerm/internal/services/web/client.go @@ -0,0 +1,30 @@ +package web + +import ( + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + AppServicePlansClient *web.AppServicePlansClient + AppServicesClient *web.AppsClient + CertificatesClient *web.CertificatesClient +} + +func BuildClient(o *common.ClientOptions) *Client { + + AppServicePlansClient := web.NewAppServicePlansClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AppServicePlansClient.Client, o.ResourceManagerAuthorizer) + + AppServicesClient := web.NewAppsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&AppServicesClient.Client, o.ResourceManagerAuthorizer) + + CertificatesClient := web.NewCertificatesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&CertificatesClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + AppServicePlansClient: &AppServicePlansClient, + AppServicesClient: &AppServicesClient, + CertificatesClient: &CertificatesClient, + } +} diff --git a/azurerm/internal/tags/expand.go b/azurerm/internal/tags/expand.go new file mode 100644 index 000000000000..deb6ce7827de --- /dev/null +++ b/azurerm/internal/tags/expand.go @@ -0,0 +1,13 @@ +package tags + +func Expand(tagsMap map[string]interface{}) map[string]*string { + output := make(map[string]*string, len(tagsMap)) + + for i, v := range tagsMap { + //Validate should have ignored this error already + value, _ := TagValueToString(v) + output[i] = &value + } + + return output +} diff --git a/azurerm/internal/tags/expand_test.go b/azurerm/internal/tags/expand_test.go new file mode 100644 index 000000000000..4911947150da --- /dev/null +++ b/azurerm/internal/tags/expand_test.go @@ -0,0 +1,33 @@ +package tags + +import ( + "fmt" + "testing" +) + +func TestExpand(t *testing.T) { + testData := make(map[string]interface{}) + testData["key1"] = "value1" + testData["key2"] = 21 + testData["key3"] = "value3" + + expanded := Expand(testData) + + if len(expanded) != 3 { + t.Fatalf("Expected 3 results in expanded tag map, got %d", len(expanded)) + } + + for k, v := range testData { + var strVal string + switch v := v.(type) { + case string: + strVal = v + case int: + strVal = fmt.Sprintf("%d", v) + } + + if *expanded[k] != strVal { + t.Fatalf("Expanded value %q incorrect: expected %q, got %q", k, strVal, *expanded[k]) + } + } +} diff --git a/azurerm/internal/tags/filter.go b/azurerm/internal/tags/filter.go new file mode 100644 index 000000000000..aab95faa8eab --- /dev/null +++ b/azurerm/internal/tags/filter.go @@ -0,0 +1,27 @@ +package tags + +import "strings" + +func Filter(tagsMap map[string]*string, tagNames ...string) map[string]*string { + if len(tagNames) == 0 { + return tagsMap + } + + // Build the filter dictionary from passed tag names. + filterDict := make(map[string]bool) + for _, name := range tagNames { + if len(name) > 0 { + filterDict[strings.ToLower(name)] = true + } + } + + // Filter out tag if it exists(case insensitive) in the dictionary. + tagsRet := make(map[string]*string) + for k, v := range tagsMap { + if !filterDict[strings.ToLower(k)] { + tagsRet[k] = v + } + } + + return tagsRet +} diff --git a/azurerm/internal/tags/filter_test.go b/azurerm/internal/tags/filter_test.go new file mode 100644 index 000000000000..9872bffb4a3a --- /dev/null +++ b/azurerm/internal/tags/filter_test.go @@ -0,0 +1,24 @@ +package tags + +import ( + "testing" +) + +func TestFilter(t *testing.T) { + testData := make(map[string]*string) + valueData := [3]string{"value1", "value2", "value3"} + + testData["key1"] = &valueData[0] + testData["key2"] = &valueData[1] + testData["key3"] = &valueData[2] + + filtered := Filter(testData, "key1", "key3", "") + + if len(filtered) != 1 { + t.Fatalf("Expected 1 result in filtered tag map, got %d", len(filtered)) + } + + if filtered["key2"] != &valueData[1] { + t.Fatalf("Expected %v in filtered tag map, got %v", valueData[1], *filtered["key2"]) + } +} diff --git a/azurerm/internal/tags/flatten.go b/azurerm/internal/tags/flatten.go new file mode 100644 index 000000000000..9661ee487a65 --- /dev/null +++ b/azurerm/internal/tags/flatten.go @@ -0,0 +1,31 @@ +package tags + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" +) + +func Flatten(tagMap map[string]*string) map[string]interface{} { + // If tagsMap is nil, len(tagsMap) will be 0. + output := make(map[string]interface{}, len(tagMap)) + + for i, v := range tagMap { + if v == nil { + continue + } + + output[i] = *v + } + + return output +} + +func FlattenAndSet(d *schema.ResourceData, tagMap map[string]*string) error { + flattened := Flatten(tagMap) + if err := d.Set("tags", flattened); err != nil { + return fmt.Errorf("Error setting `tags`: %s", err) + } + + return nil +} diff --git a/azurerm/internal/tags/flatten_test.go b/azurerm/internal/tags/flatten_test.go new file mode 100644 index 000000000000..55920fbb797a --- /dev/null +++ b/azurerm/internal/tags/flatten_test.go @@ -0,0 +1,53 @@ +package tags + +import ( + "reflect" + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestFlatten(t *testing.T) { + testData := []struct { + Name string + Input map[string]*string + Expected map[string]interface{} + }{ + { + Name: "Empty", + Input: map[string]*string{}, + Expected: map[string]interface{}{}, + }, + { + Name: "One Item", + Input: map[string]*string{ + "hello": utils.String("there"), + }, + Expected: map[string]interface{}{ + "hello": "there", + }, + }, + { + Name: "Multiple Items", + Input: map[string]*string{ + "euros": utils.String("3"), + "hello": utils.String("there"), + "panda": utils.String("pops"), + }, + Expected: map[string]interface{}{ + "euros": "3", + "hello": "there", + "panda": "pops", + }, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Test %q", v.Name) + + actual := Flatten(v.Input) + if !reflect.DeepEqual(actual, v.Expected) { + t.Fatalf("Expected %+v but got %+v", actual, v.Expected) + } + } +} diff --git a/azurerm/internal/tags/schema.go b/azurerm/internal/tags/schema.go new file mode 100644 index 000000000000..dda7584fc783 --- /dev/null +++ b/azurerm/internal/tags/schema.go @@ -0,0 +1,35 @@ +package tags + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +// SchemaDataSource returns the Schema which should be used for Tags on a Data Source +func SchemaDataSource() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Computed: true, + } +} + +// ForceNewSchema returns the Schema which should be used for Tags when changes +// require recreation of the resource +func ForceNewSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: Validate, + } +} + +// Schema returns the Schema used for Tags +func Schema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + Computed: true, + ValidateFunc: Validate, + } +} diff --git a/azurerm/internal/tags/validation.go b/azurerm/internal/tags/validation.go new file mode 100644 index 000000000000..1bca2c7d3e61 --- /dev/null +++ b/azurerm/internal/tags/validation.go @@ -0,0 +1,37 @@ +package tags + +import "fmt" + +func Validate(v interface{}, _ string) (warnings []string, errors []error) { + tagsMap := v.(map[string]interface{}) + + if len(tagsMap) > 50 { + errors = append(errors, fmt.Errorf("a maximum of 50 tags can be applied to each ARM resource")) + } + + for k, v := range tagsMap { + if len(k) > 512 { + errors = append(errors, fmt.Errorf("the maximum length for a tag key is 512 characters: %q is %d characters", k, len(k))) + } + + value, err := TagValueToString(v) + if err != nil { + errors = append(errors, err) + } else if len(value) > 256 { + errors = append(errors, fmt.Errorf("the maximum length for a tag value is 256 characters: the value for %q is %d characters", k, len(value))) + } + } + + return warnings, errors +} + +func TagValueToString(v interface{}) (string, error) { + switch value := v.(type) { + case string: + return value, nil + case int: + return fmt.Sprintf("%d", value), nil + default: + return "", fmt.Errorf("unknown tag type %T in tag value", value) + } +} diff --git a/azurerm/internal/tags/validation_test.go b/azurerm/internal/tags/validation_test.go new file mode 100644 index 000000000000..02f749221046 --- /dev/null +++ b/azurerm/internal/tags/validation_test.go @@ -0,0 +1,69 @@ +package tags + +import ( + "fmt" + "strings" + "testing" +) + +func TestValidateMaximumNumberOfTags(t *testing.T) { + tagsMap := make(map[string]interface{}) + for i := 0; i < 51; i++ { + tagsMap[fmt.Sprintf("key%d", i)] = fmt.Sprintf("value%d", i) + } + + _, es := Validate(tagsMap, "tags") + + if len(es) != 1 { + t.Fatal("Expected one validation error for too many tags") + } + + if !strings.Contains(es[0].Error(), "a maximum of 50 tags") { + t.Fatal("Wrong validation error message for too many tags") + } +} + +func TestValidateTagMaxKeyLength(t *testing.T) { + tooLongKey := strings.Repeat("long", 128) + "a" + tagsMap := make(map[string]interface{}) + tagsMap[tooLongKey] = "value" + + _, es := Validate(tagsMap, "tags") + if len(es) != 1 { + t.Fatal("Expected one validation error for a key which is > 512 chars") + } + + if !strings.Contains(es[0].Error(), "maximum length for a tag key") { + t.Fatal("Wrong validation error message maximum tag key length") + } + + if !strings.Contains(es[0].Error(), tooLongKey) { + t.Fatal("Expected validated error to contain the key name") + } + + if !strings.Contains(es[0].Error(), "513") { + t.Fatal("Expected the length in the validation error for tag key") + } +} + +func TestValidateTagMaxValueLength(t *testing.T) { + tagsMap := make(map[string]interface{}) + tagsMap["toolong"] = strings.Repeat("long", 64) + "a" + + _, es := Validate(tagsMap, "tags") + if len(es) != 1 { + t.Fatal("Expected one validation error for a value which is > 256 chars") + } + + if !strings.Contains(es[0].Error(), "maximum length for a tag value") { + t.Fatal("Wrong validation error message for maximum tag value length") + } + + if !strings.Contains(es[0].Error(), "toolong") { + t.Fatal("Expected validated error to contain the key name") + } + + if !strings.Contains(es[0].Error(), "257") { + t.Fatal("Expected the length in the validation error for value") + } +} diff --git a/azurerm/loadbalancer.go b/azurerm/loadbalancer.go index d2c4cef90d2c..89f5a4258a45 100644 --- a/azurerm/loadbalancer.go +++ b/azurerm/loadbalancer.go @@ -6,12 +6,13 @@ import ( "regexp" "strings" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" ) func resourceGroupAndLBNameFromId(loadBalancerId string) (string, string, error) { - id, err := parseAzureResourceID(loadBalancerId) + id, err := azure.ParseAzureResourceID(loadBalancerId) if err != nil { return "", "", err } @@ -22,7 +23,7 @@ func resourceGroupAndLBNameFromId(loadBalancerId string) (string, string, error) } func retrieveLoadBalancerById(loadBalancerId string, meta interface{}) (*network.LoadBalancer, bool, error) { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext resGroup, name, err := resourceGroupAndLBNameFromId(loadBalancerId) @@ -155,7 +156,7 @@ func loadBalancerSubResourceStateImporter(d *schema.ResourceData, _ interface{}) } lbID := strings.TrimSuffix(r.FindString(d.Id()), "/") - parsed, err := parseAzureResourceID(lbID) + parsed, err := azure.ParseAzureResourceID(lbID) if err != nil { return nil, fmt.Errorf("unable to parse loadbalancer id from %s", d.Id()) } diff --git a/azurerm/locks.go b/azurerm/locks.go deleted file mode 100644 index c07bd083aa52..000000000000 --- a/azurerm/locks.go +++ /dev/null @@ -1,24 +0,0 @@ -package azurerm - -// handle the case of using the same name for different kinds of resources -func azureRMLockByName(name string, resourceType string) { - updatedName := resourceType + "." + name - armMutexKV.Lock(updatedName) -} - -func azureRMLockMultipleByName(names *[]string, resourceType string) { - for _, name := range *names { - azureRMLockByName(name, resourceType) - } -} - -func azureRMUnlockByName(name string, resourceType string) { - updatedName := resourceType + "." + name - armMutexKV.Unlock(updatedName) -} - -func azureRMUnlockMultipleByName(names *[]string, resourceType string) { - for _, name := range *names { - azureRMUnlockByName(name, resourceType) - } -} diff --git a/azurerm/logic_apps.go b/azurerm/logic_apps.go index b6e938a14d3e..10fc4d626832 100644 --- a/azurerm/logic_apps.go +++ b/azurerm/logic_apps.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/logic/mgmt/2016-06-01/logic" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -21,10 +24,10 @@ func resourceLogicAppTriggerUpdate(d *schema.ResourceData, meta interface{}, log } func resourceLogicAppComponentUpdate(d *schema.ResourceData, meta interface{}, kind string, propertyName string, logicAppId string, name string, vals map[string]interface{}, resourceName string) error { - client := meta.(*ArmClient).logicWorkflowsClient + client := meta.(*ArmClient).logic.WorkflowsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(logicAppId) + id, err := azure.ParseAzureResourceID(logicAppId) if err != nil { return err } @@ -35,8 +38,8 @@ func resourceLogicAppComponentUpdate(d *schema.ResourceData, meta interface{}, k log.Printf("[DEBUG] Preparing arguments for Logic App Workspace %q (Resource Group %q) %s %q", logicAppName, resourceGroup, kind, name) // lock to prevent against Actions or Triggers conflicting - azureRMLockByName(logicAppName, logicAppResourceName) - defer azureRMUnlockByName(logicAppName, logicAppResourceName) + locks.ByName(logicAppName, logicAppResourceName) + defer locks.UnlockByName(logicAppName, logicAppResourceName) read, err := client.Get(ctx, resourceGroup, logicAppName) if err != nil { @@ -60,7 +63,7 @@ func resourceLogicAppComponentUpdate(d *schema.ResourceData, meta interface{}, k definition := read.WorkflowProperties.Definition.(map[string]interface{}) vs := definition[propertyName].(map[string]interface{}) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { if _, hasExisting := vs[name]; hasExisting { return tf.ImportAsExistsError(resourceName, resourceId) } @@ -98,14 +101,14 @@ func resourceLogicAppTriggerRemove(d *schema.ResourceData, meta interface{}, res } func resourceLogicAppComponentRemove(d *schema.ResourceData, meta interface{}, kind, propertyName, resourceGroup, logicAppName, name string) error { - client := meta.(*ArmClient).logicWorkflowsClient + client := meta.(*ArmClient).logic.WorkflowsClient ctx := meta.(*ArmClient).StopContext log.Printf("[DEBUG] Preparing arguments for Logic App Workspace %q (Resource Group %q) %s %q Deletion", logicAppName, resourceGroup, kind, name) // lock to prevent against Actions, Parameters or Actions conflicting - azureRMLockByName(logicAppName, logicAppResourceName) - defer azureRMUnlockByName(logicAppName, logicAppResourceName) + locks.ByName(logicAppName, logicAppResourceName) + defer locks.UnlockByName(logicAppName, logicAppResourceName) read, err := client.Get(ctx, resourceGroup, logicAppName) if err != nil { @@ -155,14 +158,14 @@ func retrieveLogicAppTrigger(meta interface{}, resourceGroup, logicAppName, name } func retrieveLogicAppComponent(meta interface{}, resourceGroup, kind, propertyName, logicAppName, name string) (*map[string]interface{}, *logic.Workflow, error) { - client := meta.(*ArmClient).logicWorkflowsClient + client := meta.(*ArmClient).logic.WorkflowsClient ctx := meta.(*ArmClient).StopContext log.Printf("[DEBUG] Preparing arguments for Logic App Workspace %q (Resource Group %q) %s %q", logicAppName, resourceGroup, kind, name) // lock to prevent against Actions, Parameters or Actions conflicting - azureRMLockByName(logicAppName, logicAppResourceName) - defer azureRMUnlockByName(logicAppName, logicAppResourceName) + locks.ByName(logicAppName, logicAppResourceName) + defer locks.UnlockByName(logicAppName, logicAppResourceName) read, err := client.Get(ctx, resourceGroup, logicAppName) if err != nil { diff --git a/azurerm/logic_apps_test.go b/azurerm/logic_apps_test.go index 296a585acaeb..cb0452643db3 100644 --- a/azurerm/logic_apps_test.go +++ b/azurerm/logic_apps_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" ) func testCheckAzureRMLogicAppActionExists(resourceName string) resource.TestCheckFunc { @@ -17,7 +18,7 @@ func testCheckAzureRMLogicAppActionExists(resourceName string) resource.TestChec } logicAppId := rs.Primary.Attributes["logic_app_id"] - id, err := parseAzureResourceID(logicAppId) + id, err := azure.ParseAzureResourceID(logicAppId) if err != nil { return err } @@ -26,7 +27,7 @@ func testCheckAzureRMLogicAppActionExists(resourceName string) resource.TestChec workflowName := id.Path["workflows"] resourceGroup := id.ResourceGroup - client := testAccProvider.Meta().(*ArmClient).logicWorkflowsClient + client := testAccProvider.Meta().(*ArmClient).logic.WorkflowsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, workflowName) @@ -65,7 +66,7 @@ func testCheckAzureRMLogicAppTriggerExists(resourceName string) resource.TestChe } logicAppId := rs.Primary.Attributes["logic_app_id"] - id, err := parseAzureResourceID(logicAppId) + id, err := azure.ParseAzureResourceID(logicAppId) if err != nil { return err } @@ -74,7 +75,7 @@ func testCheckAzureRMLogicAppTriggerExists(resourceName string) resource.TestChe workflowName := id.Path["workflows"] resourceGroup := id.ResourceGroup - client := testAccProvider.Meta().(*ArmClient).logicWorkflowsClient + client := testAccProvider.Meta().(*ArmClient).logic.WorkflowsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, workflowName) diff --git a/azurerm/provider.go b/azurerm/provider.go index 22fec4a7150a..783beea2a52a 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -5,55 +5,474 @@ import ( "encoding/base64" "encoding/hex" "fmt" + "log" "strings" "github.com/hashicorp/go-azure-helpers/authentication" - "github.com/hashicorp/terraform/helper/mutexkv" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/common" ) // Provider returns a terraform.ResourceProvider. func Provider() terraform.ResourceProvider { + // NOTE: as part of migrating Data Sources/Resources into Packages - we should be able to use + // the Service Registration interface to gradually migrate Data Sources/Resources over to the + // new pattern. + // However this requires that the following be done first: + // 1. (DONE) Migrating the top level functions into the internal package + // 2. (DONE) Finish migrating the SDK Clients into Packages + // 3. Switch the remaining resources over to the new Storage SDK + // (so we can remove `getBlobStorageClientForStorageAccount` from `config.go`) + // 4. Making the SDK Clients public in the ArmClient prior to moving + // 5. Introducing a parent struct which becomes a nested field in `config.go` + // for those properties, to ease migration (probably internal/common/clients.go) + // 6. Migrating references from the `ArmClient` to the new parent client + // + // For the moment/until that's done, we'll have to continue defining these inline + supportedServices := []common.ServiceRegistration{} + + dataSources := map[string]*schema.Resource{ + "azurerm_api_management": dataSourceApiManagementService(), + "azurerm_api_management_api": dataSourceApiManagementApi(), + "azurerm_api_management_group": dataSourceApiManagementGroup(), + "azurerm_api_management_product": dataSourceApiManagementProduct(), + "azurerm_api_management_user": dataSourceArmApiManagementUser(), + "azurerm_app_service_plan": dataSourceAppServicePlan(), + "azurerm_app_service": dataSourceArmAppService(), + "azurerm_application_insights": dataSourceArmApplicationInsights(), + "azurerm_application_security_group": dataSourceArmApplicationSecurityGroup(), + "azurerm_automation_variable_bool": dataSourceArmAutomationVariableBool(), + "azurerm_automation_variable_datetime": dataSourceArmAutomationVariableDateTime(), + "azurerm_automation_variable_int": dataSourceArmAutomationVariableInt(), + "azurerm_automation_variable_string": dataSourceArmAutomationVariableString(), + "azurerm_availability_set": dataSourceArmAvailabilitySet(), + "azurerm_azuread_application": dataSourceArmAzureADApplication(), + "azurerm_azuread_service_principal": dataSourceArmActiveDirectoryServicePrincipal(), + "azurerm_batch_account": dataSourceArmBatchAccount(), + "azurerm_batch_certificate": dataSourceArmBatchCertificate(), + "azurerm_batch_pool": dataSourceArmBatchPool(), + "azurerm_builtin_role_definition": dataSourceArmBuiltInRoleDefinition(), + "azurerm_cdn_profile": dataSourceArmCdnProfile(), + "azurerm_client_config": dataSourceArmClientConfig(), + "azurerm_kubernetes_service_versions": dataSourceArmKubernetesServiceVersions(), + "azurerm_container_registry": dataSourceArmContainerRegistry(), + "azurerm_cosmosdb_account": dataSourceArmCosmosDbAccount(), + "azurerm_data_lake_store": dataSourceArmDataLakeStoreAccount(), + "azurerm_dev_test_lab": dataSourceArmDevTestLab(), + "azurerm_dev_test_virtual_network": dataSourceArmDevTestVirtualNetwork(), + "azurerm_dns_zone": dataSourceArmDnsZone(), + "azurerm_eventhub_namespace": dataSourceEventHubNamespace(), + "azurerm_express_route_circuit": dataSourceArmExpressRouteCircuit(), + "azurerm_firewall": dataSourceArmFirewall(), + "azurerm_image": dataSourceArmImage(), + "azurerm_hdinsight_cluster": dataSourceArmHDInsightSparkCluster(), + "azurerm_maps_account": dataSourceArmMapsAccount(), + "azurerm_key_vault_access_policy": dataSourceArmKeyVaultAccessPolicy(), + "azurerm_key_vault_key": dataSourceArmKeyVaultKey(), + "azurerm_key_vault_secret": dataSourceArmKeyVaultSecret(), + "azurerm_key_vault": dataSourceArmKeyVault(), + "azurerm_kubernetes_cluster": dataSourceArmKubernetesCluster(), + "azurerm_lb": dataSourceArmLoadBalancer(), + "azurerm_lb_backend_address_pool": dataSourceArmLoadBalancerBackendAddressPool(), + "azurerm_log_analytics_workspace": dataSourceLogAnalyticsWorkspace(), + "azurerm_logic_app_workflow": dataSourceArmLogicAppWorkflow(), + "azurerm_managed_disk": dataSourceArmManagedDisk(), + "azurerm_management_group": dataSourceArmManagementGroup(), + "azurerm_monitor_action_group": dataSourceArmMonitorActionGroup(), + "azurerm_monitor_diagnostic_categories": dataSourceArmMonitorDiagnosticCategories(), + "azurerm_monitor_log_profile": dataSourceArmMonitorLogProfile(), + "azurerm_mssql_elasticpool": dataSourceArmMsSqlElasticpool(), + "azurerm_network_interface": dataSourceArmNetworkInterface(), + "azurerm_network_security_group": dataSourceArmNetworkSecurityGroup(), + "azurerm_network_watcher": dataSourceArmNetworkWatcher(), + "azurerm_notification_hub_namespace": dataSourceNotificationHubNamespace(), + "azurerm_notification_hub": dataSourceNotificationHub(), + "azurerm_platform_image": dataSourceArmPlatformImage(), + "azurerm_policy_definition": dataSourceArmPolicyDefinition(), + "azurerm_public_ip": dataSourceArmPublicIP(), + "azurerm_public_ips": dataSourceArmPublicIPs(), + "azurerm_recovery_services_vault": dataSourceArmRecoveryServicesVault(), + "azurerm_recovery_services_protection_policy_vm": dataSourceArmRecoveryServicesProtectionPolicyVm(), + "azurerm_redis_cache": dataSourceArmRedisCache(), + "azurerm_resource_group": dataSourceArmResourceGroup(), + "azurerm_role_definition": dataSourceArmRoleDefinition(), + "azurerm_route_table": dataSourceArmRouteTable(), + "azurerm_scheduler_job_collection": dataSourceArmSchedulerJobCollection(), + "azurerm_servicebus_namespace": dataSourceArmServiceBusNamespace(), + "azurerm_shared_image_gallery": dataSourceArmSharedImageGallery(), + "azurerm_shared_image_version": dataSourceArmSharedImageVersion(), + "azurerm_shared_image": dataSourceArmSharedImage(), + "azurerm_snapshot": dataSourceArmSnapshot(), + "azurerm_sql_server": dataSourceSqlServer(), + "azurerm_stream_analytics_job": dataSourceArmStreamAnalyticsJob(), + "azurerm_storage_account_sas": dataSourceArmStorageAccountSharedAccessSignature(), + "azurerm_storage_account": dataSourceArmStorageAccount(), + "azurerm_subnet": dataSourceArmSubnet(), + "azurerm_subscription": dataSourceArmSubscription(), + "azurerm_subscriptions": dataSourceArmSubscriptions(), + "azurerm_traffic_manager_geographical_location": dataSourceArmTrafficManagerGeographicalLocation(), + "azurerm_user_assigned_identity": dataSourceArmUserAssignedIdentity(), + "azurerm_virtual_machine": dataSourceArmVirtualMachine(), + "azurerm_virtual_network_gateway": dataSourceArmVirtualNetworkGateway(), + "azurerm_virtual_network_gateway_connection": dataSourceArmVirtualNetworkGatewayConnection(), + "azurerm_virtual_network": dataSourceArmVirtualNetwork(), + } + + resources := map[string]*schema.Resource{ + "azurerm_analysis_services_server": resourceArmAnalysisServicesServer(), + "azurerm_api_management": resourceArmApiManagementService(), + "azurerm_api_management_api": resourceArmApiManagementApi(), + "azurerm_api_management_api_operation": resourceArmApiManagementApiOperation(), + "azurerm_api_management_api_operation_policy": resourceArmApiManagementApiOperationPolicy(), + "azurerm_api_management_api_policy": resourceArmApiManagementApiPolicy(), + "azurerm_api_management_api_schema": resourceArmApiManagementApiSchema(), + "azurerm_api_management_api_version_set": resourceArmApiManagementApiVersionSet(), + "azurerm_api_management_authorization_server": resourceArmApiManagementAuthorizationServer(), + "azurerm_api_management_backend": resourceArmApiManagementBackend(), + "azurerm_api_management_certificate": resourceArmApiManagementCertificate(), + "azurerm_api_management_group": resourceArmApiManagementGroup(), + "azurerm_api_management_group_user": resourceArmApiManagementGroupUser(), + "azurerm_api_management_logger": resourceArmApiManagementLogger(), + "azurerm_api_management_openid_connect_provider": resourceArmApiManagementOpenIDConnectProvider(), + "azurerm_api_management_product": resourceArmApiManagementProduct(), + "azurerm_api_management_product_api": resourceArmApiManagementProductApi(), + "azurerm_api_management_product_group": resourceArmApiManagementProductGroup(), + "azurerm_api_management_product_policy": resourceArmApiManagementProductPolicy(), + "azurerm_api_management_property": resourceArmApiManagementProperty(), + "azurerm_api_management_subscription": resourceArmApiManagementSubscription(), + "azurerm_api_management_user": resourceArmApiManagementUser(), + "azurerm_app_service_active_slot": resourceArmAppServiceActiveSlot(), + "azurerm_app_service_certificate": resourceArmAppServiceCertificate(), + "azurerm_app_service_custom_hostname_binding": resourceArmAppServiceCustomHostnameBinding(), + "azurerm_app_service_plan": resourceArmAppServicePlan(), + "azurerm_app_service_slot": resourceArmAppServiceSlot(), + "azurerm_app_service": resourceArmAppService(), + "azurerm_application_gateway": resourceArmApplicationGateway(), + "azurerm_application_insights_api_key": resourceArmApplicationInsightsAPIKey(), + "azurerm_application_insights": resourceArmApplicationInsights(), + "azurerm_application_insights_web_test": resourceArmApplicationInsightsWebTests(), + "azurerm_application_security_group": resourceArmApplicationSecurityGroup(), + "azurerm_automation_account": resourceArmAutomationAccount(), + "azurerm_automation_credential": resourceArmAutomationCredential(), + "azurerm_automation_dsc_configuration": resourceArmAutomationDscConfiguration(), + "azurerm_automation_dsc_nodeconfiguration": resourceArmAutomationDscNodeConfiguration(), + "azurerm_automation_module": resourceArmAutomationModule(), + "azurerm_automation_runbook": resourceArmAutomationRunbook(), + "azurerm_automation_schedule": resourceArmAutomationSchedule(), + "azurerm_automation_variable_bool": resourceArmAutomationVariableBool(), + "azurerm_automation_variable_datetime": resourceArmAutomationVariableDateTime(), + "azurerm_automation_variable_int": resourceArmAutomationVariableInt(), + "azurerm_automation_variable_string": resourceArmAutomationVariableString(), + "azurerm_autoscale_setting": resourceArmAutoScaleSetting(), + "azurerm_availability_set": resourceArmAvailabilitySet(), + "azurerm_azuread_application": resourceArmActiveDirectoryApplication(), + "azurerm_azuread_service_principal_password": resourceArmActiveDirectoryServicePrincipalPassword(), + "azurerm_azuread_service_principal": resourceArmActiveDirectoryServicePrincipal(), + "azurerm_batch_account": resourceArmBatchAccount(), + "azurerm_batch_application": resourceArmBatchApplication(), + "azurerm_batch_certificate": resourceArmBatchCertificate(), + "azurerm_batch_pool": resourceArmBatchPool(), + "azurerm_cdn_endpoint": resourceArmCdnEndpoint(), + "azurerm_cdn_profile": resourceArmCdnProfile(), + "azurerm_cognitive_account": resourceArmCognitiveAccount(), + "azurerm_connection_monitor": resourceArmConnectionMonitor(), + "azurerm_container_group": resourceArmContainerGroup(), + "azurerm_container_registry_webhook": resourceArmContainerRegistryWebhook(), + "azurerm_container_registry": resourceArmContainerRegistry(), + "azurerm_container_service": resourceArmContainerService(), + "azurerm_cosmosdb_account": resourceArmCosmosDbAccount(), + "azurerm_cosmosdb_cassandra_keyspace": resourceArmCosmosDbCassandraKeyspace(), + "azurerm_cosmosdb_mongo_collection": resourceArmCosmosDbMongoCollection(), + "azurerm_cosmosdb_mongo_database": resourceArmCosmosDbMongoDatabase(), + "azurerm_cosmosdb_sql_container": resourceArmCosmosDbSQLContainer(), + "azurerm_cosmosdb_sql_database": resourceArmCosmosDbSQLDatabase(), + "azurerm_cosmosdb_table": resourceArmCosmosDbTable(), + "azurerm_data_factory": resourceArmDataFactory(), + "azurerm_data_factory_dataset_mysql": resourceArmDataFactoryDatasetMySQL(), + "azurerm_data_factory_dataset_postgresql": resourceArmDataFactoryDatasetPostgreSQL(), + "azurerm_data_factory_dataset_sql_server_table": resourceArmDataFactoryDatasetSQLServerTable(), + "azurerm_data_factory_linked_service_data_lake_storage_gen2": resourceArmDataFactoryLinkedServiceDataLakeStorageGen2(), + "azurerm_data_factory_linked_service_mysql": resourceArmDataFactoryLinkedServiceMySQL(), + "azurerm_data_factory_linked_service_postgresql": resourceArmDataFactoryLinkedServicePostgreSQL(), + "azurerm_data_factory_linked_service_sql_server": resourceArmDataFactoryLinkedServiceSQLServer(), + "azurerm_data_factory_pipeline": resourceArmDataFactoryPipeline(), + "azurerm_data_lake_analytics_account": resourceArmDataLakeAnalyticsAccount(), + "azurerm_data_lake_analytics_firewall_rule": resourceArmDataLakeAnalyticsFirewallRule(), + "azurerm_data_lake_store_file": resourceArmDataLakeStoreFile(), + "azurerm_data_lake_store_firewall_rule": resourceArmDataLakeStoreFirewallRule(), + "azurerm_data_lake_store": resourceArmDataLakeStore(), + "azurerm_databricks_workspace": resourceArmDatabricksWorkspace(), + "azurerm_ddos_protection_plan": resourceArmDDoSProtectionPlan(), + "azurerm_dev_test_lab": resourceArmDevTestLab(), + "azurerm_dev_test_schedule": resourceArmDevTestLabSchedules(), + "azurerm_dev_test_linux_virtual_machine": resourceArmDevTestLinuxVirtualMachine(), + "azurerm_dev_test_policy": resourceArmDevTestPolicy(), + "azurerm_dev_test_virtual_network": resourceArmDevTestVirtualNetwork(), + "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine(), + "azurerm_devspace_controller": resourceArmDevSpaceController(), + "azurerm_dns_a_record": resourceArmDnsARecord(), + "azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(), + "azurerm_dns_caa_record": resourceArmDnsCaaRecord(), + "azurerm_dns_cname_record": resourceArmDnsCNameRecord(), + "azurerm_dns_mx_record": resourceArmDnsMxRecord(), + "azurerm_dns_ns_record": resourceArmDnsNsRecord(), + "azurerm_dns_ptr_record": resourceArmDnsPtrRecord(), + "azurerm_dns_srv_record": resourceArmDnsSrvRecord(), + "azurerm_dns_txt_record": resourceArmDnsTxtRecord(), + "azurerm_dns_zone": resourceArmDnsZone(), + "azurerm_eventgrid_domain": resourceArmEventGridDomain(), + "azurerm_eventgrid_event_subscription": resourceArmEventGridEventSubscription(), + "azurerm_eventgrid_topic": resourceArmEventGridTopic(), + "azurerm_eventhub_authorization_rule": resourceArmEventHubAuthorizationRule(), + "azurerm_eventhub_consumer_group": resourceArmEventHubConsumerGroup(), + "azurerm_eventhub_namespace_authorization_rule": resourceArmEventHubNamespaceAuthorizationRule(), + "azurerm_eventhub_namespace": resourceArmEventHubNamespace(), + "azurerm_eventhub": resourceArmEventHub(), + "azurerm_express_route_circuit_authorization": resourceArmExpressRouteCircuitAuthorization(), + "azurerm_express_route_circuit_peering": resourceArmExpressRouteCircuitPeering(), + "azurerm_express_route_circuit": resourceArmExpressRouteCircuit(), + "azurerm_firewall_application_rule_collection": resourceArmFirewallApplicationRuleCollection(), + "azurerm_firewall_nat_rule_collection": resourceArmFirewallNatRuleCollection(), + "azurerm_firewall_network_rule_collection": resourceArmFirewallNetworkRuleCollection(), + "azurerm_firewall": resourceArmFirewall(), + "azurerm_function_app": resourceArmFunctionApp(), + "azurerm_hdinsight_hadoop_cluster": resourceArmHDInsightHadoopCluster(), + "azurerm_hdinsight_hbase_cluster": resourceArmHDInsightHBaseCluster(), + "azurerm_hdinsight_interactive_query_cluster": resourceArmHDInsightInteractiveQueryCluster(), + "azurerm_hdinsight_kafka_cluster": resourceArmHDInsightKafkaCluster(), + "azurerm_hdinsight_ml_services_cluster": resourceArmHDInsightMLServicesCluster(), + "azurerm_hdinsight_rserver_cluster": resourceArmHDInsightRServerCluster(), + "azurerm_hdinsight_spark_cluster": resourceArmHDInsightSparkCluster(), + "azurerm_hdinsight_storm_cluster": resourceArmHDInsightStormCluster(), + "azurerm_image": resourceArmImage(), + "azurerm_iot_dps": resourceArmIotDPS(), + "azurerm_iot_dps_certificate": resourceArmIotDPSCertificate(), + "azurerm_iothub_consumer_group": resourceArmIotHubConsumerGroup(), + "azurerm_iothub": resourceArmIotHub(), + "azurerm_iothub_shared_access_policy": resourceArmIotHubSharedAccessPolicy(), + "azurerm_key_vault_access_policy": resourceArmKeyVaultAccessPolicy(), + "azurerm_key_vault_certificate": resourceArmKeyVaultCertificate(), + "azurerm_key_vault_key": resourceArmKeyVaultKey(), + "azurerm_key_vault_secret": resourceArmKeyVaultSecret(), + "azurerm_key_vault": resourceArmKeyVault(), + "azurerm_kubernetes_cluster": resourceArmKubernetesCluster(), + "azurerm_kusto_cluster": resourceArmKustoCluster(), + "azurerm_lb_backend_address_pool": resourceArmLoadBalancerBackendAddressPool(), + "azurerm_lb_nat_pool": resourceArmLoadBalancerNatPool(), + "azurerm_lb_nat_rule": resourceArmLoadBalancerNatRule(), + "azurerm_lb_probe": resourceArmLoadBalancerProbe(), + "azurerm_lb_outbound_rule": resourceArmLoadBalancerOutboundRule(), + "azurerm_lb_rule": resourceArmLoadBalancerRule(), + "azurerm_lb": resourceArmLoadBalancer(), + "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), + "azurerm_log_analytics_solution": resourceArmLogAnalyticsSolution(), + "azurerm_log_analytics_linked_service": resourceArmLogAnalyticsLinkedService(), + "azurerm_log_analytics_workspace_linked_service": resourceArmLogAnalyticsWorkspaceLinkedService(), + "azurerm_log_analytics_workspace": resourceArmLogAnalyticsWorkspace(), + "azurerm_logic_app_action_custom": resourceArmLogicAppActionCustom(), + "azurerm_logic_app_action_http": resourceArmLogicAppActionHTTP(), + "azurerm_logic_app_trigger_custom": resourceArmLogicAppTriggerCustom(), + "azurerm_logic_app_trigger_http_request": resourceArmLogicAppTriggerHttpRequest(), + "azurerm_logic_app_trigger_recurrence": resourceArmLogicAppTriggerRecurrence(), + "azurerm_logic_app_workflow": resourceArmLogicAppWorkflow(), + "azurerm_managed_disk": resourceArmManagedDisk(), + "azurerm_management_group": resourceArmManagementGroup(), + "azurerm_management_lock": resourceArmManagementLock(), + "azurerm_maps_account": resourceArmMapsAccount(), + "azurerm_mariadb_configuration": resourceArmMariaDbConfiguration(), + "azurerm_mariadb_database": resourceArmMariaDbDatabase(), + "azurerm_mariadb_firewall_rule": resourceArmMariaDBFirewallRule(), + "azurerm_mariadb_server": resourceArmMariaDbServer(), + "azurerm_mariadb_virtual_network_rule": resourceArmMariaDbVirtualNetworkRule(), + "azurerm_media_services_account": resourceArmMediaServicesAccount(), + "azurerm_metric_alertrule": resourceArmMetricAlertRule(), + "azurerm_monitor_autoscale_setting": resourceArmMonitorAutoScaleSetting(), + "azurerm_monitor_action_group": resourceArmMonitorActionGroup(), + "azurerm_monitor_activity_log_alert": resourceArmMonitorActivityLogAlert(), + "azurerm_monitor_diagnostic_setting": resourceArmMonitorDiagnosticSetting(), + "azurerm_monitor_log_profile": resourceArmMonitorLogProfile(), + "azurerm_monitor_metric_alert": resourceArmMonitorMetricAlert(), + "azurerm_monitor_metric_alertrule": resourceArmMonitorMetricAlertRule(), + "azurerm_mssql_elasticpool": resourceArmMsSqlElasticPool(), + "azurerm_mysql_configuration": resourceArmMySQLConfiguration(), + "azurerm_mysql_database": resourceArmMySqlDatabase(), + "azurerm_mysql_firewall_rule": resourceArmMySqlFirewallRule(), + "azurerm_mysql_server": resourceArmMySqlServer(), + "azurerm_mysql_virtual_network_rule": resourceArmMySqlVirtualNetworkRule(), + "azurerm_network_connection_monitor": resourceArmNetworkConnectionMonitor(), + "azurerm_network_ddos_protection_plan": resourceArmNetworkDDoSProtectionPlan(), + "azurerm_network_interface": resourceArmNetworkInterface(), + "azurerm_network_interface_application_gateway_backend_address_pool_association": resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociation(), + "azurerm_network_interface_application_security_group_association": resourceArmNetworkInterfaceApplicationSecurityGroupAssociation(), + "azurerm_network_interface_backend_address_pool_association": resourceArmNetworkInterfaceBackendAddressPoolAssociation(), + "azurerm_network_interface_nat_rule_association": resourceArmNetworkInterfaceNatRuleAssociation(), + "azurerm_network_packet_capture": resourceArmNetworkPacketCapture(), + "azurerm_network_profile": resourceArmNetworkProfile(), + "azurerm_network_security_group": resourceArmNetworkSecurityGroup(), + "azurerm_network_security_rule": resourceArmNetworkSecurityRule(), + "azurerm_network_watcher": resourceArmNetworkWatcher(), + "azurerm_notification_hub_authorization_rule": resourceArmNotificationHubAuthorizationRule(), + "azurerm_notification_hub_namespace": resourceArmNotificationHubNamespace(), + "azurerm_notification_hub": resourceArmNotificationHub(), + "azurerm_packet_capture": resourceArmPacketCapture(), + "azurerm_policy_assignment": resourceArmPolicyAssignment(), + "azurerm_policy_definition": resourceArmPolicyDefinition(), + "azurerm_policy_set_definition": resourceArmPolicySetDefinition(), + "azurerm_postgresql_configuration": resourceArmPostgreSQLConfiguration(), + "azurerm_postgresql_database": resourceArmPostgreSQLDatabase(), + "azurerm_postgresql_firewall_rule": resourceArmPostgreSQLFirewallRule(), + "azurerm_postgresql_server": resourceArmPostgreSQLServer(), + "azurerm_postgresql_virtual_network_rule": resourceArmPostgreSQLVirtualNetworkRule(), + "azurerm_private_dns_zone": resourceArmPrivateDnsZone(), + "azurerm_private_dns_a_record": resourceArmPrivateDnsARecord(), + "azurerm_private_dns_cname_record": resourceArmPrivateDnsCNameRecord(), + "azurerm_public_ip": resourceArmPublicIp(), + "azurerm_public_ip_prefix": resourceArmPublicIpPrefix(), + "azurerm_recovery_network_mapping": resourceArmRecoveryServicesNetworkMapping(), + "azurerm_recovery_replicated_vm": resourceArmRecoveryServicesReplicatedVm(), + "azurerm_recovery_services_fabric": resourceArmRecoveryServicesFabric(), + "azurerm_recovery_services_protected_vm": resourceArmRecoveryServicesProtectedVm(), + "azurerm_recovery_services_protection_container": resourceArmRecoveryServicesProtectionContainer(), + "azurerm_recovery_services_protection_container_mapping": resourceArmRecoveryServicesProtectionContainerMapping(), + "azurerm_recovery_services_protection_policy_vm": resourceArmRecoveryServicesProtectionPolicyVm(), + "azurerm_recovery_services_replication_policy": resourceArmRecoveryServicesReplicationPolicy(), + "azurerm_recovery_services_vault": resourceArmRecoveryServicesVault(), + "azurerm_redis_cache": resourceArmRedisCache(), + "azurerm_redis_firewall_rule": resourceArmRedisFirewallRule(), + "azurerm_relay_namespace": resourceArmRelayNamespace(), + "azurerm_resource_group": resourceArmResourceGroup(), + "azurerm_role_assignment": resourceArmRoleAssignment(), + "azurerm_role_definition": resourceArmRoleDefinition(), + "azurerm_route_table": resourceArmRouteTable(), + "azurerm_route": resourceArmRoute(), + "azurerm_scheduler_job_collection": resourceArmSchedulerJobCollection(), + "azurerm_scheduler_job": resourceArmSchedulerJob(), + "azurerm_search_service": resourceArmSearchService(), + "azurerm_security_center_contact": resourceArmSecurityCenterContact(), + "azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), + "azurerm_security_center_workspace": resourceArmSecurityCenterWorkspace(), + "azurerm_service_fabric_cluster": resourceArmServiceFabricCluster(), + "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), + "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), + "azurerm_servicebus_queue_authorization_rule": resourceArmServiceBusQueueAuthorizationRule(), + "azurerm_servicebus_queue": resourceArmServiceBusQueue(), + "azurerm_servicebus_subscription_rule": resourceArmServiceBusSubscriptionRule(), + "azurerm_servicebus_subscription": resourceArmServiceBusSubscription(), + "azurerm_servicebus_topic_authorization_rule": resourceArmServiceBusTopicAuthorizationRule(), + "azurerm_servicebus_topic": resourceArmServiceBusTopic(), + "azurerm_shared_image_gallery": resourceArmSharedImageGallery(), + "azurerm_shared_image_version": resourceArmSharedImageVersion(), + "azurerm_shared_image": resourceArmSharedImage(), + "azurerm_signalr_service": resourceArmSignalRService(), + "azurerm_snapshot": resourceArmSnapshot(), + "azurerm_sql_active_directory_administrator": resourceArmSqlAdministrator(), + "azurerm_sql_database": resourceArmSqlDatabase(), + "azurerm_sql_elasticpool": resourceArmSqlElasticPool(), + "azurerm_sql_failover_group": resourceArmSqlFailoverGroup(), + "azurerm_sql_firewall_rule": resourceArmSqlFirewallRule(), + "azurerm_sql_server": resourceArmSqlServer(), + "azurerm_sql_virtual_network_rule": resourceArmSqlVirtualNetworkRule(), + "azurerm_storage_account": resourceArmStorageAccount(), + "azurerm_storage_blob": resourceArmStorageBlob(), + "azurerm_storage_container": resourceArmStorageContainer(), + "azurerm_storage_queue": resourceArmStorageQueue(), + "azurerm_storage_share": resourceArmStorageShare(), + "azurerm_storage_share_directory": resourceArmStorageShareDirectory(), + "azurerm_storage_table": resourceArmStorageTable(), + "azurerm_storage_table_entity": resourceArmStorageTableEntity(), + "azurerm_stream_analytics_job": resourceArmStreamAnalyticsJob(), + "azurerm_stream_analytics_function_javascript_udf": resourceArmStreamAnalyticsFunctionUDF(), + "azurerm_stream_analytics_output_blob": resourceArmStreamAnalyticsOutputBlob(), + "azurerm_stream_analytics_output_mssql": resourceArmStreamAnalyticsOutputSql(), + "azurerm_stream_analytics_output_eventhub": resourceArmStreamAnalyticsOutputEventHub(), + "azurerm_stream_analytics_output_servicebus_queue": resourceArmStreamAnalyticsOutputServiceBusQueue(), + "azurerm_stream_analytics_stream_input_blob": resourceArmStreamAnalyticsStreamInputBlob(), + "azurerm_stream_analytics_stream_input_eventhub": resourceArmStreamAnalyticsStreamInputEventHub(), + "azurerm_stream_analytics_stream_input_iothub": resourceArmStreamAnalyticsStreamInputIoTHub(), + "azurerm_subnet_network_security_group_association": resourceArmSubnetNetworkSecurityGroupAssociation(), + "azurerm_subnet_route_table_association": resourceArmSubnetRouteTableAssociation(), + "azurerm_subnet": resourceArmSubnet(), + "azurerm_template_deployment": resourceArmTemplateDeployment(), + "azurerm_traffic_manager_endpoint": resourceArmTrafficManagerEndpoint(), + "azurerm_traffic_manager_profile": resourceArmTrafficManagerProfile(), + "azurerm_user_assigned_identity": resourceArmUserAssignedIdentity(), + "azurerm_virtual_machine_data_disk_attachment": resourceArmVirtualMachineDataDiskAttachment(), + "azurerm_virtual_machine_extension": resourceArmVirtualMachineExtensions(), + "azurerm_virtual_machine_scale_set": resourceArmVirtualMachineScaleSet(), + "azurerm_virtual_machine": resourceArmVirtualMachine(), + "azurerm_virtual_network_gateway_connection": resourceArmVirtualNetworkGatewayConnection(), + "azurerm_virtual_network_gateway": resourceArmVirtualNetworkGateway(), + "azurerm_virtual_network_peering": resourceArmVirtualNetworkPeering(), + "azurerm_virtual_network": resourceArmVirtualNetwork(), + "azurerm_virtual_wan": resourceArmVirtualWan(), + "azurerm_web_application_firewall_policy": resourceArmWebApplicationFirewallPolicy(), + } + + for _, service := range supportedServices { + log.Printf("[DEBUG] Registering Data Sources for %q..", service.Name()) + for k, v := range service.SupportedDataSources() { + if existing := dataSources[k]; existing != nil { + panic(fmt.Sprintf("An existing Data Source exists for %q", k)) + } + + dataSources[k] = v + } + + log.Printf("[DEBUG] Registering Resources for %q..", service.Name()) + for k, v := range service.SupportedResources() { + if existing := resources[k]; existing != nil { + panic(fmt.Sprintf("An existing Resource exists for %q", k)) + } + + resources[k] = v + } + } + p := &schema.Provider{ Schema: map[string]*schema.Schema{ "subscription_id": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("ARM_SUBSCRIPTION_ID", ""), + Description: "The Subscription ID which should be used.", }, "client_id": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_ID", ""), + Description: "The Client ID which should be used.", }, "tenant_id": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("ARM_TENANT_ID", ""), + Description: "The Tenant ID which should be used.", }, "environment": { Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("ARM_ENVIRONMENT", "public"), + Description: "The Cloud Environment which should be used. Possible values are public, usgovernment, german, and china. Defaults to public.", }, // Client Certificate specific fields - "client_certificate_password": { + "client_certificate_path": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE_PASSWORD", ""), + DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE_PATH", ""), + Description: "The path to the Client Certificate associated with the Service Principal for use when authenticating as a Service Principal using a Client Certificate.", }, - "client_certificate_path": { + "client_certificate_password": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE_PATH", ""), + DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_CERTIFICATE_PASSWORD", ""), + Description: "The password associated with the Client Certificate. For use when authenticating as a Service Principal using a Client Certificate", }, // Client Secret specific fields @@ -61,6 +480,7 @@ func Provider() terraform.ResourceProvider { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("ARM_CLIENT_SECRET", ""), + Description: "The Client Secret which should be used. For use When authenticating as a Service Principal using a Client Secret.", }, // Managed Service Identity specific fields @@ -68,19 +488,29 @@ func Provider() terraform.ResourceProvider { Type: schema.TypeBool, Optional: true, DefaultFunc: schema.EnvDefaultFunc("ARM_USE_MSI", false), + Description: "Allowed Managed Service Identity be used for Authentication.", }, "msi_endpoint": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("ARM_MSI_ENDPOINT", ""), + Description: "The path to a custom endpoint for Managed Service Identity - in most circumstances this should be detected automatically. ", }, // Managed Tracking GUID for User-agent "partner_id": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("ARM_PARTNER_ID", ""), ValidateFunc: validate.UUIDOrEmpty, + DefaultFunc: schema.EnvDefaultFunc("ARM_PARTNER_ID", ""), + Description: "A GUID/UUID that is registered with Microsoft to facilitate partner resource usage attribution.", + }, + + "disable_correlation_request_id": { + Type: schema.TypeBool, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("DISABLE_CORRELATION_REQUEST_ID", false), + Description: "This will disable the x-ms-correlation-request-id header.", }, // Advanced feature flags @@ -88,291 +518,19 @@ func Provider() terraform.ResourceProvider { Type: schema.TypeBool, Optional: true, DefaultFunc: schema.EnvDefaultFunc("ARM_SKIP_CREDENTIALS_VALIDATION", false), + Description: "This will cause the AzureRM Provider to skip verifying the credentials being used are valid.", }, "skip_provider_registration": { Type: schema.TypeBool, Optional: true, DefaultFunc: schema.EnvDefaultFunc("ARM_SKIP_PROVIDER_REGISTRATION", false), + Description: "Should the AzureRM Provider skip registering all of the Resource Providers that it supports, if they're not already registered?", }, }, - DataSourcesMap: map[string]*schema.Resource{ - "azurerm_api_management": dataSourceApiManagementService(), - "azurerm_api_management_api": dataSourceApiManagementApi(), - "azurerm_api_management_group": dataSourceApiManagementGroup(), - "azurerm_api_management_product": dataSourceApiManagementProduct(), - "azurerm_api_management_user": dataSourceArmApiManagementUser(), - "azurerm_app_service_plan": dataSourceAppServicePlan(), - "azurerm_app_service": dataSourceArmAppService(), - "azurerm_application_insights": dataSourceArmApplicationInsights(), - "azurerm_application_security_group": dataSourceArmApplicationSecurityGroup(), - "azurerm_availability_set": dataSourceArmAvailabilitySet(), - "azurerm_azuread_application": dataSourceArmAzureADApplication(), - "azurerm_azuread_service_principal": dataSourceArmActiveDirectoryServicePrincipal(), - "azurerm_batch_account": dataSourceArmBatchAccount(), - "azurerm_batch_pool": dataSourceArmBatchPool(), - "azurerm_builtin_role_definition": dataSourceArmBuiltInRoleDefinition(), - "azurerm_cdn_profile": dataSourceArmCdnProfile(), - "azurerm_client_config": dataSourceArmClientConfig(), - "azurerm_container_registry": dataSourceArmContainerRegistry(), - "azurerm_cosmosdb_account": dataSourceArmCosmosDBAccount(), - "azurerm_data_lake_store": dataSourceArmDataLakeStoreAccount(), - "azurerm_dev_test_lab": dataSourceArmDevTestLab(), - "azurerm_dns_zone": dataSourceArmDnsZone(), - "azurerm_eventhub_namespace": dataSourceEventHubNamespace(), - "azurerm_image": dataSourceArmImage(), - "azurerm_key_vault_access_policy": dataSourceArmKeyVaultAccessPolicy(), - "azurerm_key_vault_key": dataSourceArmKeyVaultKey(), - "azurerm_key_vault_secret": dataSourceArmKeyVaultSecret(), - "azurerm_key_vault": dataSourceArmKeyVault(), - "azurerm_kubernetes_cluster": dataSourceArmKubernetesCluster(), - "azurerm_lb": dataSourceArmLoadBalancer(), - "azurerm_lb_backend_address_pool": dataSourceArmLoadBalancerBackendAddressPool(), - "azurerm_log_analytics_workspace": dataSourceLogAnalyticsWorkspace(), - "azurerm_logic_app_workflow": dataSourceArmLogicAppWorkflow(), - "azurerm_managed_disk": dataSourceArmManagedDisk(), - "azurerm_management_group": dataSourceArmManagementGroup(), - "azurerm_monitor_action_group": dataSourceArmMonitorActionGroup(), - "azurerm_monitor_diagnostic_categories": dataSourceArmMonitorDiagnosticCategories(), - "azurerm_monitor_log_profile": dataSourceArmMonitorLogProfile(), - "azurerm_network_interface": dataSourceArmNetworkInterface(), - "azurerm_network_security_group": dataSourceArmNetworkSecurityGroup(), - "azurerm_network_watcher": dataSourceArmNetworkWatcher(), - "azurerm_notification_hub_namespace": dataSourceNotificationHubNamespace(), - "azurerm_notification_hub": dataSourceNotificationHub(), - "azurerm_platform_image": dataSourceArmPlatformImage(), - "azurerm_policy_definition": dataSourceArmPolicyDefinition(), - "azurerm_public_ip": dataSourceArmPublicIP(), - "azurerm_public_ips": dataSourceArmPublicIPs(), - "azurerm_recovery_services_vault": dataSourceArmRecoveryServicesVault(), - "azurerm_recovery_services_protection_policy_vm": dataSourceArmRecoveryServicesProtectionPolicyVm(), - "azurerm_resource_group": dataSourceArmResourceGroup(), - "azurerm_role_definition": dataSourceArmRoleDefinition(), - "azurerm_route_table": dataSourceArmRouteTable(), - "azurerm_scheduler_job_collection": dataSourceArmSchedulerJobCollection(), - "azurerm_servicebus_namespace": dataSourceArmServiceBusNamespace(), - "azurerm_shared_image_gallery": dataSourceArmSharedImageGallery(), - "azurerm_shared_image_version": dataSourceArmSharedImageVersion(), - "azurerm_shared_image": dataSourceArmSharedImage(), - "azurerm_snapshot": dataSourceArmSnapshot(), - "azurerm_storage_account_sas": dataSourceArmStorageAccountSharedAccessSignature(), - "azurerm_storage_account": dataSourceArmStorageAccount(), - "azurerm_subnet": dataSourceArmSubnet(), - "azurerm_subscription": dataSourceArmSubscription(), - "azurerm_subscriptions": dataSourceArmSubscriptions(), - "azurerm_traffic_manager_geographical_location": dataSourceArmTrafficManagerGeographicalLocation(), - "azurerm_virtual_machine": dataSourceArmVirtualMachine(), - "azurerm_virtual_network_gateway": dataSourceArmVirtualNetworkGateway(), - "azurerm_virtual_network": dataSourceArmVirtualNetwork(), - }, - - ResourcesMap: map[string]*schema.Resource{ - "azurerm_api_management": resourceArmApiManagementService(), - "azurerm_api_management_api": resourceArmApiManagementApi(), - "azurerm_api_management_group": resourceArmApiManagementGroup(), - "azurerm_api_management_group_user": resourceArmApiManagementGroupUser(), - "azurerm_api_management_product": resourceArmApiManagementProduct(), - "azurerm_api_management_product_api": resourceArmApiManagementProductApi(), - "azurerm_api_management_product_group": resourceArmApiManagementProductGroup(), - "azurerm_api_management_property": resourceArmApiManagementProperty(), - "azurerm_api_management_user": resourceArmApiManagementUser(), - "azurerm_app_service_active_slot": resourceArmAppServiceActiveSlot(), - "azurerm_app_service_custom_hostname_binding": resourceArmAppServiceCustomHostnameBinding(), - "azurerm_app_service_plan": resourceArmAppServicePlan(), - "azurerm_app_service_slot": resourceArmAppServiceSlot(), - "azurerm_app_service": resourceArmAppService(), - "azurerm_application_gateway": resourceArmApplicationGateway(), - "azurerm_application_insights_api_key": resourceArmApplicationInsightsAPIKey(), - "azurerm_application_insights": resourceArmApplicationInsights(), - "azurerm_application_security_group": resourceArmApplicationSecurityGroup(), - "azurerm_automation_account": resourceArmAutomationAccount(), - "azurerm_automation_credential": resourceArmAutomationCredential(), - "azurerm_automation_dsc_configuration": resourceArmAutomationDscConfiguration(), - "azurerm_automation_dsc_nodeconfiguration": resourceArmAutomationDscNodeConfiguration(), - "azurerm_automation_module": resourceArmAutomationModule(), - "azurerm_automation_runbook": resourceArmAutomationRunbook(), - "azurerm_automation_schedule": resourceArmAutomationSchedule(), - "azurerm_autoscale_setting": resourceArmAutoScaleSetting(), - "azurerm_availability_set": resourceArmAvailabilitySet(), - "azurerm_azuread_application": resourceArmActiveDirectoryApplication(), - "azurerm_azuread_service_principal_password": resourceArmActiveDirectoryServicePrincipalPassword(), - "azurerm_azuread_service_principal": resourceArmActiveDirectoryServicePrincipal(), - "azurerm_batch_account": resourceArmBatchAccount(), - "azurerm_batch_pool": resourceArmBatchPool(), - "azurerm_cdn_endpoint": resourceArmCdnEndpoint(), - "azurerm_cdn_profile": resourceArmCdnProfile(), - "azurerm_cognitive_account": resourceArmCognitiveAccount(), - "azurerm_connection_monitor": resourceArmConnectionMonitor(), - "azurerm_container_group": resourceArmContainerGroup(), - "azurerm_container_registry": resourceArmContainerRegistry(), - "azurerm_container_service": resourceArmContainerService(), - "azurerm_cosmosdb_account": resourceArmCosmosDBAccount(), - "azurerm_data_lake_analytics_account": resourceArmDataLakeAnalyticsAccount(), - "azurerm_data_lake_analytics_firewall_rule": resourceArmDataLakeAnalyticsFirewallRule(), - "azurerm_data_lake_store_file": resourceArmDataLakeStoreFile(), - "azurerm_data_lake_store_firewall_rule": resourceArmDataLakeStoreFirewallRule(), - "azurerm_data_lake_store": resourceArmDataLakeStore(), - "azurerm_databricks_workspace": resourceArmDatabricksWorkspace(), - "azurerm_ddos_protection_plan": resourceArmDDoSProtectionPlan(), - "azurerm_dev_test_lab": resourceArmDevTestLab(), - "azurerm_dev_test_linux_virtual_machine": resourceArmDevTestLinuxVirtualMachine(), - "azurerm_dev_test_policy": resourceArmDevTestPolicy(), - "azurerm_dev_test_virtual_network": resourceArmDevTestVirtualNetwork(), - "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine(), - "azurerm_devspace_controller": resourceArmDevSpaceController(), - "azurerm_dns_a_record": resourceArmDnsARecord(), - "azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(), - "azurerm_dns_caa_record": resourceArmDnsCaaRecord(), - "azurerm_dns_cname_record": resourceArmDnsCNameRecord(), - "azurerm_dns_mx_record": resourceArmDnsMxRecord(), - "azurerm_dns_ns_record": resourceArmDnsNsRecord(), - "azurerm_dns_ptr_record": resourceArmDnsPtrRecord(), - "azurerm_dns_srv_record": resourceArmDnsSrvRecord(), - "azurerm_dns_txt_record": resourceArmDnsTxtRecord(), - "azurerm_dns_zone": resourceArmDnsZone(), - "azurerm_eventgrid_domain": resourceArmEventGridDomain(), - "azurerm_eventgrid_event_subscription": resourceArmEventGridEventSubscription(), - "azurerm_eventgrid_topic": resourceArmEventGridTopic(), - "azurerm_eventhub_authorization_rule": resourceArmEventHubAuthorizationRule(), - "azurerm_eventhub_consumer_group": resourceArmEventHubConsumerGroup(), - "azurerm_eventhub_namespace_authorization_rule": resourceArmEventHubNamespaceAuthorizationRule(), - "azurerm_eventhub_namespace": resourceArmEventHubNamespace(), - "azurerm_eventhub": resourceArmEventHub(), - "azurerm_express_route_circuit_authorization": resourceArmExpressRouteCircuitAuthorization(), - "azurerm_express_route_circuit_peering": resourceArmExpressRouteCircuitPeering(), - "azurerm_express_route_circuit": resourceArmExpressRouteCircuit(), - "azurerm_firewall_application_rule_collection": resourceArmFirewallApplicationRuleCollection(), - "azurerm_firewall_network_rule_collection": resourceArmFirewallNetworkRuleCollection(), - "azurerm_firewall": resourceArmFirewall(), - "azurerm_function_app": resourceArmFunctionApp(), - "azurerm_image": resourceArmImage(), - "azurerm_iothub_consumer_group": resourceArmIotHubConsumerGroup(), - "azurerm_iothub": resourceArmIotHub(), - "azurerm_key_vault_access_policy": resourceArmKeyVaultAccessPolicy(), - "azurerm_key_vault_certificate": resourceArmKeyVaultCertificate(), - "azurerm_key_vault_key": resourceArmKeyVaultKey(), - "azurerm_key_vault_secret": resourceArmKeyVaultSecret(), - "azurerm_key_vault": resourceArmKeyVault(), - "azurerm_kubernetes_cluster": resourceArmKubernetesCluster(), - "azurerm_lb_backend_address_pool": resourceArmLoadBalancerBackendAddressPool(), - "azurerm_lb_nat_pool": resourceArmLoadBalancerNatPool(), - "azurerm_lb_nat_rule": resourceArmLoadBalancerNatRule(), - "azurerm_lb_probe": resourceArmLoadBalancerProbe(), - "azurerm_lb_outbound_rule": resourceArmLoadBalancerOutboundRule(), - "azurerm_lb_rule": resourceArmLoadBalancerRule(), - "azurerm_lb": resourceArmLoadBalancer(), - "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), - "azurerm_log_analytics_solution": resourceArmLogAnalyticsSolution(), - "azurerm_log_analytics_linked_service": resourceArmLogAnalyticsLinkedService(), - "azurerm_log_analytics_workspace_linked_service": resourceArmLogAnalyticsWorkspaceLinkedService(), - "azurerm_log_analytics_workspace": resourceArmLogAnalyticsWorkspace(), - "azurerm_logic_app_action_custom": resourceArmLogicAppActionCustom(), - "azurerm_logic_app_action_http": resourceArmLogicAppActionHTTP(), - "azurerm_logic_app_trigger_custom": resourceArmLogicAppTriggerCustom(), - "azurerm_logic_app_trigger_http_request": resourceArmLogicAppTriggerHttpRequest(), - "azurerm_logic_app_trigger_recurrence": resourceArmLogicAppTriggerRecurrence(), - "azurerm_logic_app_workflow": resourceArmLogicAppWorkflow(), - "azurerm_managed_disk": resourceArmManagedDisk(), - "azurerm_management_group": resourceArmManagementGroup(), - "azurerm_management_lock": resourceArmManagementLock(), - "azurerm_mariadb_database": resourceArmMariaDbDatabase(), - "azurerm_mariadb_server": resourceArmMariaDbServer(), - "azurerm_media_services_account": resourceArmMediaServicesAccount(), - "azurerm_metric_alertrule": resourceArmMetricAlertRule(), - "azurerm_monitor_autoscale_setting": resourceArmMonitorAutoScaleSetting(), - "azurerm_monitor_action_group": resourceArmMonitorActionGroup(), - "azurerm_monitor_activity_log_alert": resourceArmMonitorActivityLogAlert(), - "azurerm_monitor_diagnostic_setting": resourceArmMonitorDiagnosticSetting(), - "azurerm_monitor_log_profile": resourceArmMonitorLogProfile(), - "azurerm_monitor_metric_alert": resourceArmMonitorMetricAlert(), - "azurerm_monitor_metric_alertrule": resourceArmMonitorMetricAlertRule(), - "azurerm_mssql_elasticpool": resourceArmMsSqlElasticPool(), - "azurerm_mysql_configuration": resourceArmMySQLConfiguration(), - "azurerm_mysql_database": resourceArmMySqlDatabase(), - "azurerm_mysql_firewall_rule": resourceArmMySqlFirewallRule(), - "azurerm_mysql_server": resourceArmMySqlServer(), - "azurerm_mysql_virtual_network_rule": resourceArmMySqlVirtualNetworkRule(), - "azurerm_network_interface_application_gateway_backend_address_pool_association": resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociation(), - "azurerm_network_interface_application_security_group_association": resourceArmNetworkInterfaceApplicationSecurityGroupAssociation(), - "azurerm_network_interface_backend_address_pool_association": resourceArmNetworkInterfaceBackendAddressPoolAssociation(), - "azurerm_network_interface_nat_rule_association": resourceArmNetworkInterfaceNatRuleAssociation(), - "azurerm_network_interface": resourceArmNetworkInterface(), - "azurerm_network_security_group": resourceArmNetworkSecurityGroup(), - "azurerm_network_security_rule": resourceArmNetworkSecurityRule(), - "azurerm_network_watcher": resourceArmNetworkWatcher(), - "azurerm_notification_hub_authorization_rule": resourceArmNotificationHubAuthorizationRule(), - "azurerm_notification_hub_namespace": resourceArmNotificationHubNamespace(), - "azurerm_notification_hub": resourceArmNotificationHub(), - "azurerm_packet_capture": resourceArmPacketCapture(), - "azurerm_policy_assignment": resourceArmPolicyAssignment(), - "azurerm_policy_definition": resourceArmPolicyDefinition(), - "azurerm_policy_set_definition": resourceArmPolicySetDefinition(), - "azurerm_postgresql_configuration": resourceArmPostgreSQLConfiguration(), - "azurerm_postgresql_database": resourceArmPostgreSQLDatabase(), - "azurerm_postgresql_firewall_rule": resourceArmPostgreSQLFirewallRule(), - "azurerm_postgresql_server": resourceArmPostgreSQLServer(), - "azurerm_postgresql_virtual_network_rule": resourceArmPostgreSQLVirtualNetworkRule(), - "azurerm_public_ip": resourceArmPublicIp(), - "azurerm_recovery_services_protected_vm": resourceArmRecoveryServicesProtectedVm(), - "azurerm_recovery_services_protection_policy_vm": resourceArmRecoveryServicesProtectionPolicyVm(), - "azurerm_recovery_services_vault": resourceArmRecoveryServicesVault(), - "azurerm_redis_cache": resourceArmRedisCache(), - "azurerm_redis_firewall_rule": resourceArmRedisFirewallRule(), - "azurerm_relay_namespace": resourceArmRelayNamespace(), - "azurerm_resource_group": resourceArmResourceGroup(), - "azurerm_role_assignment": resourceArmRoleAssignment(), - "azurerm_role_definition": resourceArmRoleDefinition(), - "azurerm_route_table": resourceArmRouteTable(), - "azurerm_route": resourceArmRoute(), - "azurerm_scheduler_job_collection": resourceArmSchedulerJobCollection(), - "azurerm_scheduler_job": resourceArmSchedulerJob(), - "azurerm_search_service": resourceArmSearchService(), - "azurerm_security_center_contact": resourceArmSecurityCenterContact(), - "azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), - "azurerm_security_center_workspace": resourceArmSecurityCenterWorkspace(), - "azurerm_service_fabric_cluster": resourceArmServiceFabricCluster(), - "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), - "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), - "azurerm_servicebus_queue_authorization_rule": resourceArmServiceBusQueueAuthorizationRule(), - "azurerm_servicebus_queue": resourceArmServiceBusQueue(), - "azurerm_servicebus_subscription_rule": resourceArmServiceBusSubscriptionRule(), - "azurerm_servicebus_subscription": resourceArmServiceBusSubscription(), - "azurerm_servicebus_topic_authorization_rule": resourceArmServiceBusTopicAuthorizationRule(), - "azurerm_servicebus_topic": resourceArmServiceBusTopic(), - "azurerm_shared_image_gallery": resourceArmSharedImageGallery(), - "azurerm_shared_image_version": resourceArmSharedImageVersion(), - "azurerm_shared_image": resourceArmSharedImage(), - "azurerm_signalr_service": resourceArmSignalRService(), - "azurerm_snapshot": resourceArmSnapshot(), - "azurerm_sql_active_directory_administrator": resourceArmSqlAdministrator(), - "azurerm_sql_database": resourceArmSqlDatabase(), - "azurerm_sql_elasticpool": resourceArmSqlElasticPool(), - "azurerm_sql_firewall_rule": resourceArmSqlFirewallRule(), - "azurerm_sql_server": resourceArmSqlServer(), - "azurerm_sql_virtual_network_rule": resourceArmSqlVirtualNetworkRule(), - "azurerm_storage_account": resourceArmStorageAccount(), - "azurerm_storage_blob": resourceArmStorageBlob(), - "azurerm_storage_container": resourceArmStorageContainer(), - "azurerm_storage_queue": resourceArmStorageQueue(), - "azurerm_storage_share": resourceArmStorageShare(), - "azurerm_storage_table": resourceArmStorageTable(), - "azurerm_subnet_network_security_group_association": resourceArmSubnetNetworkSecurityGroupAssociation(), - "azurerm_subnet_route_table_association": resourceArmSubnetRouteTableAssociation(), - "azurerm_subnet": resourceArmSubnet(), - "azurerm_template_deployment": resourceArmTemplateDeployment(), - "azurerm_traffic_manager_endpoint": resourceArmTrafficManagerEndpoint(), - "azurerm_traffic_manager_profile": resourceArmTrafficManagerProfile(), - "azurerm_user_assigned_identity": resourceArmUserAssignedIdentity(), - "azurerm_virtual_machine_data_disk_attachment": resourceArmVirtualMachineDataDiskAttachment(), - "azurerm_virtual_machine_extension": resourceArmVirtualMachineExtensions(), - "azurerm_virtual_machine_scale_set": resourceArmVirtualMachineScaleSet(), - "azurerm_virtual_machine": resourceArmVirtualMachine(), - "azurerm_virtual_network_gateway_connection": resourceArmVirtualNetworkGatewayConnection(), - "azurerm_virtual_network_gateway": resourceArmVirtualNetworkGateway(), - "azurerm_virtual_network_peering": resourceArmVirtualNetworkPeering(), - "azurerm_virtual_network": resourceArmVirtualNetwork(), - }, + DataSourcesMap: dataSources, + ResourcesMap: resources, } p.ConfigureFunc = providerConfigure(p) @@ -397,6 +555,9 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { SupportsClientSecretAuth: true, SupportsManagedServiceIdentity: d.Get("use_msi").(bool), SupportsAzureCliToken: true, + + // Doc Links + ClientSecretDocsLink: "https://www.terraform.io/docs/providers/azurerm/auth/service_principal_client_secret.html", } config, err := builder.Build() @@ -406,8 +567,9 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { partnerId := d.Get("partner_id").(string) skipProviderRegistration := d.Get("skip_provider_registration").(bool) - client, err := getArmClient(config, skipProviderRegistration, partnerId) + disableCorrelationRequestID := d.Get("disable_correlation_request_id").(bool) + client, err := getArmClient(config, skipProviderRegistration, partnerId, disableCorrelationRequestID) if err != nil { return nil, err } @@ -425,7 +587,7 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { // List all the available providers and their registration state to avoid unnecessary // requests. This also lets us check if the provider credentials are correct. ctx := client.StopContext - providerList, err := client.providersClient.List(ctx, nil, "") + providerList, err := client.resource.ProvidersClient.List(ctx, nil, "") if err != nil { return nil, fmt.Errorf("Unable to list provider registration status, it is possible that this is due to invalid "+ "credentials or the service principal does not have permission to use the Resource Manager API, Azure "+ @@ -436,7 +598,7 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { availableResourceProviders := providerList.Values() requiredResourceProviders := requiredResourceProviders() - err := ensureResourceProvidersAreRegistered(ctx, client.providersClient, availableResourceProviders, requiredResourceProviders) + err := ensureResourceProvidersAreRegistered(ctx, *client.resource.ProvidersClient, availableResourceProviders, requiredResourceProviders) if err != nil { return nil, fmt.Errorf("Error ensuring Resource Providers are registered: %s", err) } @@ -447,14 +609,6 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { } } -// armMutexKV is the instance of MutexKV for ARM resources -var armMutexKV = mutexkv.NewMutexKV() - -// Deprecated: use `suppress.CaseDifference` instead -func ignoreCaseDiffSuppressFunc(k, old, new string, d *schema.ResourceData) bool { - return suppress.CaseDifference(k, old, new, d) -} - // ignoreCaseStateFunc is a StateFunc from helper/schema that converts the // supplied value to lower before saving to state for consistency. func ignoreCaseStateFunc(val interface{}) string { diff --git a/azurerm/provider_test.go b/azurerm/provider_test.go index 2e736c418cb3..f5d2f3cecbf3 100644 --- a/azurerm/provider_test.go +++ b/azurerm/provider_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azuread/azuread" ) var testAccProviders map[string]terraform.ResourceProvider @@ -20,6 +21,7 @@ func init() { testAccProvider = Provider().(*schema.Provider) testAccProviders = map[string]terraform.ResourceProvider{ "azurerm": testAccProvider, + "azuread": azuread.Provider().(*schema.Provider), } } @@ -41,6 +43,7 @@ func testAccPreCheck(t *testing.T) { "ARM_TENANT_ID", "ARM_TEST_LOCATION", "ARM_TEST_LOCATION_ALT", + "ARM_TEST_LOCATION_ALT2", } for _, variable := range variables { @@ -59,6 +62,10 @@ func testAltLocation() string { return os.Getenv("ARM_TEST_LOCATION_ALT") } +func testAltLocation2() string { + return os.Getenv("ARM_TEST_LOCATION_ALT2") +} + func testArmEnvironmentName() string { envName, exists := os.LookupEnv("ARM_ENVIRONMENT") if !exists { diff --git a/azurerm/required_resource_providers.go b/azurerm/required_resource_providers.go index e159b46a887d..52a5e06061bf 100644 --- a/azurerm/required_resource_providers.go +++ b/azurerm/required_resource_providers.go @@ -37,11 +37,14 @@ func requiredResourceProviders() map[string]struct{} { "Microsoft.DocumentDB": {}, "Microsoft.EventGrid": {}, "Microsoft.EventHub": {}, + "Microsoft.HDInsight": {}, "Microsoft.KeyVault": {}, + "Microsoft.Kusto": {}, "microsoft.insights": {}, "Microsoft.Logic": {}, "Microsoft.ManagedIdentity": {}, "Microsoft.Management": {}, + "Microsoft.Maps": {}, "Microsoft.Media": {}, "Microsoft.Network": {}, "Microsoft.NotificationHubs": {}, @@ -57,6 +60,7 @@ func requiredResourceProviders() map[string]struct{} { "Microsoft.ServiceFabric": {}, "Microsoft.Sql": {}, "Microsoft.Storage": {}, + "Microsoft.StreamAnalytics": {}, "Microsoft.Web": {}, } } diff --git a/azurerm/required_resource_providers_test.go b/azurerm/required_resource_providers_test.go index f273243f7ae2..0850a25e8e52 100644 --- a/azurerm/required_resource_providers_test.go +++ b/azurerm/required_resource_providers_test.go @@ -14,12 +14,12 @@ func TestAccAzureRMEnsureRequiredResourceProvidersAreRegistered(t *testing.T) { } // this test intentionally checks all the RP's are registered - so this is intentional - armClient, err := getArmClient(config, true, "") + armClient, err := getArmClient(config, true, "", true) if err != nil { t.Fatalf("Error building ARM Client: %+v", err) } - client := armClient.providersClient + client := armClient.resource.ProvidersClient ctx := testAccProvider.StopContext() providerList, err := client.List(ctx, nil, "") if err != nil { @@ -30,7 +30,7 @@ func TestAccAzureRMEnsureRequiredResourceProvidersAreRegistered(t *testing.T) { availableResourceProviders := providerList.Values() requiredResourceProviders := requiredResourceProviders() - err = ensureResourceProvidersAreRegistered(ctx, client, availableResourceProviders, requiredResourceProviders) + err = ensureResourceProvidersAreRegistered(ctx, *client, availableResourceProviders, requiredResourceProviders) if err != nil { t.Fatalf("Error registering Resource Providers: %+v", err) } diff --git a/azurerm/resource_arm_analysis_services_server.go b/azurerm/resource_arm_analysis_services_server.go new file mode 100644 index 000000000000..1006977fcb41 --- /dev/null +++ b/azurerm/resource_arm_analysis_services_server.go @@ -0,0 +1,388 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/analysisservices/mgmt/2017-08-01/analysisservices" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmAnalysisServicesServer() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAnalysisServicesServerCreate, + Read: resourceArmAnalysisServicesServerRead, + Update: resourceArmAnalysisServicesServerUpdate, + Delete: resourceArmAnalysisServicesServerDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAnalysisServicesServerName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "sku": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "D1", + "B1", + "B2", + "S0", + "S1", + "S2", + "S4", + "S8", + "S9", + }, false), + }, + + "admin_users": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "enable_power_bi_service": { + Type: schema.TypeBool, + Optional: true, + }, + + "ipv4_firewall_rule": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "range_start": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.IPv4Address, + }, + "range_end": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.IPv4Address, + }, + }, + }, + }, + + "querypool_connection_mode": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validateQuerypoolConnectionMode(), + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmAnalysisServicesServerCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).analysisservices.ServerClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Azure ARM Analysis Services Server creation.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + server, err := client.GetDetails(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(server.Response) { + return fmt.Errorf("Error checking for presence of existing Analysis Services Server %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if server.ID != nil && *server.ID != "" { + return tf.ImportAsExistsError("azurerm_analysis_services_server", *server.ID) + } + } + + sku := d.Get("sku").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + + serverProperties := expandAnalysisServicesServerProperties(d) + + t := d.Get("tags").(map[string]interface{}) + + analysisServicesServer := analysisservices.Server{ + Name: &name, + Location: &location, + Sku: &analysisservices.ResourceSku{Name: &sku}, + ServerProperties: serverProperties, + Tags: tags.Expand(t), + } + + future, err := client.Create(ctx, resourceGroup, name, analysisServicesServer) + if err != nil { + return fmt.Errorf("Error creating Analysis Services Server %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Analysis Services Server %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + resp, getDetailsErr := client.GetDetails(ctx, resourceGroup, name) + if getDetailsErr != nil { + return fmt.Errorf("Error retrieving Analytics Services Server %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read ID for Analytics Services Server %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*resp.ID) + + return resourceArmAnalysisServicesServerRead(d, meta) +} + +func resourceArmAnalysisServicesServerRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).analysisservices.ServerClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["servers"] + + server, err := client.GetDetails(ctx, resourceGroup, name) + + if err != nil { + if utils.ResponseWasNotFound(server.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error retrieving Analytics Services Server %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + + if location := server.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if server.Sku != nil { + d.Set("sku", server.Sku.Name) + } + + if serverProps := server.ServerProperties; serverProps != nil { + if serverProps.AsAdministrators == nil || serverProps.AsAdministrators.Members == nil { + d.Set("admin_users", []string{}) + } else { + d.Set("admin_users", *serverProps.AsAdministrators.Members) + } + + enablePowerBi, fwRules := flattenAnalysisServicesServerFirewallSettings(serverProps) + d.Set("enable_power_bi_service", enablePowerBi) + if err := d.Set("ipv4_firewall_rule", fwRules); err != nil { + return fmt.Errorf("Error setting `ipv4_firewall_rule`: %s", err) + } + + d.Set("querypool_connection_mode", string(serverProps.QuerypoolConnectionMode)) + } + + return tags.FlattenAndSet(d, server.Tags) +} + +func resourceArmAnalysisServicesServerUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).analysisservices.ServerClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Azure ARM Analysis Services Server creation.") + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["servers"] + + serverProperties := expandAnalysisServicesServerMutableProperties(d) + sku := d.Get("sku").(string) + t := d.Get("tags").(map[string]interface{}) + + analysisServicesServer := analysisservices.ServerUpdateParameters{ + Sku: &analysisservices.ResourceSku{Name: &sku}, + Tags: tags.Expand(t), + ServerMutableProperties: serverProperties, + } + + future, err := client.Update(ctx, resourceGroup, name, analysisServicesServer) + if err != nil { + return fmt.Errorf("Error creating Analysis Services Server %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Analysis Services Server %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + return resourceArmAnalysisServicesServerRead(d, meta) +} + +func resourceArmAnalysisServicesServerDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).analysisservices.ServerClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["servers"] + + future, err := client.Delete(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error deleting Analysis Services Server %q (Resource Group %q): %+v", name, resGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of Analysis Services Server %q (Resource Group %q): %+v", name, resGroup, err) + } + + return nil +} + +func validateAnalysisServicesServerName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if !regexp.MustCompile(`^[a-z][0-9a-z]{2,62}$`).Match([]byte(value)) { + errors = append(errors, fmt.Errorf("%q must begin with a letter, be lowercase alphanumeric, and be between 3 and 63 characters in length", k)) + } + + return warnings, errors +} + +func validateQuerypoolConnectionMode() schema.SchemaValidateFunc { + connectionModes := make([]string, len(analysisservices.PossibleConnectionModeValues())) + for i, v := range analysisservices.PossibleConnectionModeValues() { + connectionModes[i] = string(v) + } + + return validation.StringInSlice(connectionModes, true) +} + +func expandAnalysisServicesServerProperties(d *schema.ResourceData) *analysisservices.ServerProperties { + adminUsers := expandAnalysisServicesServerAdminUsers(d) + + serverProperties := analysisservices.ServerProperties{AsAdministrators: adminUsers} + + serverProperties.IPV4FirewallSettings = expandAnalysisServicesServerFirewallSettings(d) + + if querypoolConnectionMode, ok := d.GetOk("querypool_connection_mode"); ok { + serverProperties.QuerypoolConnectionMode = analysisservices.ConnectionMode(querypoolConnectionMode.(string)) + } + + return &serverProperties +} + +func expandAnalysisServicesServerMutableProperties(d *schema.ResourceData) *analysisservices.ServerMutableProperties { + adminUsers := expandAnalysisServicesServerAdminUsers(d) + + serverProperties := analysisservices.ServerMutableProperties{AsAdministrators: adminUsers} + + serverProperties.IPV4FirewallSettings = expandAnalysisServicesServerFirewallSettings(d) + + serverProperties.QuerypoolConnectionMode = analysisservices.ConnectionMode(d.Get("querypool_connection_mode").(string)) + + return &serverProperties +} + +func expandAnalysisServicesServerAdminUsers(d *schema.ResourceData) *analysisservices.ServerAdministrators { + adminUsers := d.Get("admin_users").(*schema.Set) + members := make([]string, 0) + + for _, admin := range adminUsers.List() { + if adm, ok := admin.(string); ok { + members = append(members, adm) + } + } + + return &analysisservices.ServerAdministrators{Members: &members} +} + +func expandAnalysisServicesServerFirewallSettings(d *schema.ResourceData) *analysisservices.IPv4FirewallSettings { + firewallSettings := analysisservices.IPv4FirewallSettings{ + EnablePowerBIService: utils.Bool(d.Get("enable_power_bi_service").(bool)), + } + + firewallRules := d.Get("ipv4_firewall_rule").([]interface{}) + + fwRules := make([]analysisservices.IPv4FirewallRule, len(firewallRules)) + for i, v := range firewallRules { + fwRule := v.(map[string]interface{}) + fwRules[i] = analysisservices.IPv4FirewallRule{ + FirewallRuleName: utils.String(fwRule["name"].(string)), + RangeStart: utils.String(fwRule["range_start"].(string)), + RangeEnd: utils.String(fwRule["range_end"].(string)), + } + } + firewallSettings.FirewallRules = &fwRules + + return &firewallSettings +} + +func flattenAnalysisServicesServerFirewallSettings(serverProperties *analysisservices.ServerProperties) (enablePowerBi *bool, fwRules []interface{}) { + if serverProperties == nil || serverProperties.IPV4FirewallSettings == nil { + return utils.Bool(false), make([]interface{}, 0) + } + + firewallSettings := serverProperties.IPV4FirewallSettings + + enablePowerBi = utils.Bool(false) + if firewallSettings.EnablePowerBIService != nil { + enablePowerBi = firewallSettings.EnablePowerBIService + } + + fwRules = make([]interface{}, 0) + if firewallSettings.FirewallRules != nil { + for _, fwRule := range *firewallSettings.FirewallRules { + output := make(map[string]interface{}) + if fwRule.FirewallRuleName != nil { + output["name"] = *fwRule.FirewallRuleName + } + + if fwRule.RangeStart != nil { + output["range_start"] = *fwRule.RangeStart + } + + if fwRule.RangeEnd != nil { + output["range_end"] = *fwRule.RangeEnd + } + + fwRules = append(fwRules, output) + } + } + + return enablePowerBi, fwRules +} diff --git a/azurerm/resource_arm_analysis_services_server_test.go b/azurerm/resource_arm_analysis_services_server_test.go new file mode 100644 index 000000000000..8d1a9c902aa0 --- /dev/null +++ b/azurerm/resource_arm_analysis_services_server_test.go @@ -0,0 +1,409 @@ +package azurerm + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMAnalysisServicesServer_basic(t *testing.T) { + resourceName := "azurerm_analysis_services_server.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAnalysisServicesServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAnalysisServicesServer_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAnalysisServicesServerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAnalysisServicesServer_withTags(t *testing.T) { + resourceName := "azurerm_analysis_services_server.test" + ri := tf.AccRandTimeInt() + preConfig := testAccAzureRMAnalysisServicesServer_withTags(ri, testLocation()) + postConfig := testAccAzureRMAnalysisServicesServer_withTagsUpdate(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAnalysisServicesServerDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAnalysisServicesServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.label", "test"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAnalysisServicesServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.label", "test1"), + resource.TestCheckResourceAttr(resourceName, "tags.ENV", "prod"), + ), + }, + }, + }) +} + +func TestAccAzureRMAnalysisServicesServer_querypoolConnectionMode(t *testing.T) { + resourceName := "azurerm_analysis_services_server.test" + ri := tf.AccRandTimeInt() + preConfig := testAccAzureRMAnalysisServicesServer_querypoolConnectionMode(ri, testLocation(), "All") + postConfig := testAccAzureRMAnalysisServicesServer_querypoolConnectionMode(ri, testLocation(), "ReadOnly") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAnalysisServicesServerDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAnalysisServicesServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "querypool_connection_mode", "All"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAnalysisServicesServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "querypool_connection_mode", "ReadOnly"), + ), + }, + }, + }) +} + +func TestAccAzureRMAnalysisServicesServer_firewallSettings(t *testing.T) { + resourceName := "azurerm_analysis_services_server.test" + ri := tf.AccRandTimeInt() + + config1 := testAccAzureRMAnalysisServicesServer_firewallSettings1(ri, testLocation(), true) + + config2 := testAccAzureRMAnalysisServicesServer_firewallSettings2(ri, testLocation(), false) + + config3 := testAccAzureRMAnalysisServicesServer_firewallSettings3(ri, testLocation(), true) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAnalysisServicesServerDestroy, + Steps: []resource.TestStep{ + { + Config: config1, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAnalysisServicesServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enable_power_bi_service", "true"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.#", "0"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAnalysisServicesServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enable_power_bi_service", "false"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.#", "1"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.0.name", "test1"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.0.range_start", "92.123.234.11"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.0.range_end", "92.123.234.12"), + ), + }, + { + Config: config3, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAnalysisServicesServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enable_power_bi_service", "true"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.#", "2"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.0.name", "test1"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.0.range_start", "92.123.234.11"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.0.range_end", "92.123.234.13"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.1.name", "test2"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.1.range_start", "226.202.187.57"), + resource.TestCheckResourceAttr(resourceName, "ipv4_firewall_rule.1.range_end", "226.208.192.47"), + ), + }, + }, + }) +} + +// ARM_ACC_EMAIL1 and ARM_ACC_EMAIL2 must be set and existing emails in the tenant's AD to work properly +func TestAccAzureRMAnalysisServicesServer_adminUsers(t *testing.T) { + const ArmAccAdminEmail1 = "ARM_ACCTEST_ADMIN_EMAIL1" + const ArmAccAdminEmail2 = "ARM_ACCTEST_ADMIN_EMAIL2" + if os.Getenv(ArmAccAdminEmail1) == "" || os.Getenv(ArmAccAdminEmail2) == "" { + t.Skip(fmt.Sprintf("Acceptance test skipped unless env '%s' and '%s' set", ArmAccAdminEmail1, ArmAccAdminEmail2)) + return + } + + resourceName := "azurerm_analysis_services_server.test" + ri := tf.AccRandTimeInt() + email1 := os.Getenv(ArmAccAdminEmail1) + email2 := os.Getenv(ArmAccAdminEmail2) + preAdminUsers := []string{email1} + postAdminUsers := []string{email1, email2} + preConfig := testAccAzureRMAnalysisServicesServer_adminUsers(ri, testLocation(), preAdminUsers) + postConfig := testAccAzureRMAnalysisServicesServer_adminUsers(ri, testLocation(), postAdminUsers) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAnalysisServicesServerDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: postConfig, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMAnalysisServicesServer_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_analysis_services_server" "test" { + name = "acctestass%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "B1" +} +`, rInt, location, rInt) +} + +func testAccAzureRMAnalysisServicesServer_withTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_analysis_services_server" "test" { + name = "acctestass%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "B1" + + tags = { + label = "test" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMAnalysisServicesServer_withTagsUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_analysis_services_server" "test" { + name = "acctestass%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "B1" + + tags = { + label = "test1" + ENV = "prod" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMAnalysisServicesServer_querypoolConnectionMode(rInt int, location, connectionMode string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_analysis_services_server" "test" { + name = "acctestass%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "B1" + querypool_connection_mode = "%s" +} +`, rInt, location, rInt, connectionMode) +} + +func testAccAzureRMAnalysisServicesServer_firewallSettings1(rInt int, location string, enablePowerBIService bool) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_analysis_services_server" "test" { + name = "acctestass%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "B1" + enable_power_bi_service = %t +} +`, rInt, location, rInt, enablePowerBIService) +} + +func testAccAzureRMAnalysisServicesServer_firewallSettings2(rInt int, location string, enablePowerBIService bool) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_analysis_services_server" "test" { + name = "acctestass%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "B1" + enable_power_bi_service = %t + + ipv4_firewall_rule { + name = "test1" + range_start = "92.123.234.11" + range_end = "92.123.234.12" + } +} +`, rInt, location, rInt, enablePowerBIService) +} + +func testAccAzureRMAnalysisServicesServer_firewallSettings3(rInt int, location string, enablePowerBIService bool) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_analysis_services_server" "test" { + name = "acctestass%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "B1" + enable_power_bi_service = %t + + ipv4_firewall_rule { + name = "test1" + range_start = "92.123.234.11" + range_end = "92.123.234.13" + } + + ipv4_firewall_rule { + name = "test2" + range_start = "226.202.187.57" + range_end = "226.208.192.47" + } +} +`, rInt, location, rInt, enablePowerBIService) +} + +func testAccAzureRMAnalysisServicesServer_adminUsers(rInt int, location string, adminUsers []string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_analysis_services_server" "test" { + name = "acctestass%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "B1" + admin_users = ["%s"] +} +`, rInt, location, rInt, strings.Join(adminUsers, "\", \"")) +} + +func testCheckAzureRMAnalysisServicesServerDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).analysisservices.ServerClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_analysis_services_server" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.GetDetails(ctx, resourceGroup, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMAnalysisServicesServerExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + analysisServicesServerName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Analysis Services Server: %s", analysisServicesServerName) + } + + client := testAccProvider.Meta().(*ArmClient).analysisservices.ServerClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.GetDetails(ctx, resourceGroup, analysisServicesServerName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Analysis Services Server %q (resource group: %q) does not exist", analysisServicesServerName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on analysisServicesServerClient: %+v", err) + } + + return nil + } +} diff --git a/azurerm/resource_arm_api_management.go b/azurerm/resource_arm_api_management.go index 130b1fd23146..f655b20d5eb5 100644 --- a/azurerm/resource_arm_api_management.go +++ b/azurerm/resource_arm_api_management.go @@ -10,8 +10,11 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -21,7 +24,7 @@ var apimBackendProtocolTls11 = "Microsoft.WindowsAzure.ApiManagement.Gateway.Sec var apimFrontendProtocolSsl3 = "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Ssl30" var apimFrontendProtocolTls10 = "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls10" var apimFrontendProtocolTls11 = "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11" -var apimTripleDesChipers = "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TripleDes168" +var apimTripleDesCiphers = "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TripleDes168" func resourceArmApiManagementService() *schema.Resource { return &schema.Resource{ @@ -29,6 +32,7 @@ func resourceArmApiManagementService() *schema.Resource { Read: resourceArmApiManagementServiceRead, Update: resourceArmApiManagementServiceCreateUpdate, Delete: resourceArmApiManagementServiceDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -36,9 +40,9 @@ func resourceArmApiManagementService() *schema.Resource { Schema: map[string]*schema.Schema{ "name": azure.SchemaApiManagementName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "public_ip_addresses": { Type: schema.TypeList, @@ -119,10 +123,9 @@ func resourceArmApiManagementService() *schema.Resource { "additional_location": { Type: schema.TypeList, Optional: true, - MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "location": locationSchema(), + "location": azure.SchemaLocation(), "gateway_regional_url": { Type: schema.TypeString, @@ -173,7 +176,7 @@ func resourceArmApiManagementService() *schema.Resource { "security": { Type: schema.TypeList, Optional: true, - Computed: true, + Computed: true, // todo remove in 2.0 ? MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -193,9 +196,18 @@ func resourceArmApiManagementService() *schema.Resource { Default: false, }, "disable_triple_des_chipers": { + Type: schema.TypeBool, + Optional: true, + Computed: true, // todo remove in 2.0 + Deprecated: "This field has been deprecated in favour of the `disable_triple_des_ciphers` property to correct the spelling. it will be removed in version 2.0 of the provider", + ConflictsWith: []string{"security.0.disable_triple_des_ciphers"}, + }, + "disable_triple_des_ciphers": { Type: schema.TypeBool, Optional: true, - Default: false, + // Default: false, // todo remove in 2.0 + Computed: true, // todo remove in 2.0 + ConflictsWith: []string{"security.0.disable_triple_des_chipers"}, }, "disable_frontend_ssl30": { Type: schema.TypeBool, @@ -255,7 +267,84 @@ func resourceArmApiManagementService() *schema.Resource { }, }, - "tags": tagsSchema(), + "policy": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + ConfigMode: schema.SchemaConfigModeAttr, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "xml_content": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"policy.0.xml_link"}, + DiffSuppressFunc: suppress.XmlDiff, + }, + + "xml_link": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"policy.0.xml_content"}, + }, + }, + }, + }, + + "sign_in": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + }, + }, + }, + + "sign_up": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + + "terms_of_service": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + "consent_required": { + Type: schema.TypeBool, + Required: true, + }, + "text": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + }, + }, + }, + + "tags": tags.Schema(), "gateway_url": { Type: schema.TypeString, @@ -286,7 +375,7 @@ func resourceArmApiManagementService() *schema.Resource { } func resourceArmApiManagementServiceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementServiceClient + client := meta.(*ArmClient).apiManagement.ServiceClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for API Management Service creation.") @@ -294,7 +383,7 @@ func resourceArmApiManagementServiceCreateUpdate(d *schema.ResourceData, meta in name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -307,8 +396,8 @@ func resourceArmApiManagementServiceCreateUpdate(d *schema.ResourceData, meta in } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) sku := expandAzureRmApiManagementSku(d) @@ -329,7 +418,7 @@ func resourceArmApiManagementServiceCreateUpdate(d *schema.ResourceData, meta in Certificates: certificates, HostnameConfigurations: hostnameConfigurations, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), Sku: sku, } @@ -365,14 +454,51 @@ func resourceArmApiManagementServiceCreateUpdate(d *schema.ResourceData, meta in d.SetId(*read.ID) + signInSettingsRaw := d.Get("sign_in").([]interface{}) + signInSettings := expandApiManagementSignInSettings(signInSettingsRaw) + signInClient := meta.(*ArmClient).apiManagement.SignInClient + if _, err := signInClient.CreateOrUpdate(ctx, resourceGroup, name, signInSettings); err != nil { + return fmt.Errorf("Error setting Sign In settings for API Management Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + signUpSettingsRaw := d.Get("sign_up").([]interface{}) + signUpSettings := expandApiManagementSignUpSettings(signUpSettingsRaw) + signUpClient := meta.(*ArmClient).apiManagement.SignUpClient + if _, err := signUpClient.CreateOrUpdate(ctx, resourceGroup, name, signUpSettings); err != nil { + return fmt.Errorf("Error setting Sign Up settings for API Management Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + policyClient := meta.(*ArmClient).apiManagement.PolicyClient + policiesRaw := d.Get("policy").([]interface{}) + policy, err := expandApiManagementPolicies(policiesRaw) + if err != nil { + return err + } + + if d.HasChange("policy") { + // remove the existing policy + if resp, err := policyClient.Delete(ctx, resourceGroup, name, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error removing Policies from API Management Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + // then add the new one, if it exists + if policy != nil { + if _, err := policyClient.CreateOrUpdate(ctx, resourceGroup, name, *policy); err != nil { + return fmt.Errorf("Error setting Policies for API Management Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + } + return resourceArmApiManagementServiceRead(d, meta) } func resourceArmApiManagementServiceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementServiceClient + client := meta.(*ArmClient).apiManagement.ServiceClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -391,11 +517,31 @@ func resourceArmApiManagementServiceRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("Error making Read request on API Management Service %q (Resource Group %q): %+v", name, resourceGroup, err) } + signInClient := meta.(*ArmClient).apiManagement.SignInClient + signInSettings, err := signInClient.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving Sign In Settings for API Management Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + signUpClient := meta.(*ArmClient).apiManagement.SignUpClient + signUpSettings, err := signUpClient.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving Sign Up Settings for API Management Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + policyClient := meta.(*ArmClient).apiManagement.PolicyClient + policy, err := policyClient.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(policy.Response) { + return fmt.Errorf("Error retrieving Policy for API Management Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } identity := flattenAzureRmApiManagementMachineIdentity(resp.Identity) @@ -432,16 +578,26 @@ func resourceArmApiManagementServiceRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("Error setting `sku`: %+v", err) } - flattenAndSetTags(d, resp.Tags) + if err := d.Set("sign_in", flattenApiManagementSignInSettings(signInSettings)); err != nil { + return fmt.Errorf("Error setting `sign_in`: %+v", err) + } - return nil + if err := d.Set("sign_up", flattenApiManagementSignUpSettings(signUpSettings)); err != nil { + return fmt.Errorf("Error setting `sign_up`: %+v", err) + } + + if err := d.Set("policy", flattenApiManagementPolicies(d, policy)); err != nil { + return fmt.Errorf("Error setting `policy`: %+v", err) + } + + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmApiManagementServiceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementServiceClient + client := meta.(*ArmClient).apiManagement.ServiceClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -628,7 +784,7 @@ func expandAzureRmApiManagementAdditionalLocations(d *schema.ResourceData, sku * for _, v := range inputLocations { config := v.(map[string]interface{}) - location := azureRMNormalizeLocation(config["location"].(string)) + location := azure.NormalizeLocation(config["location"].(string)) additionalLocation := apimanagement.AdditionalLocation{ Location: utils.String(location), @@ -651,7 +807,7 @@ func flattenApiManagementAdditionalLocations(input *[]apimanagement.AdditionalLo output := make(map[string]interface{}) if prop.Location != nil { - output["location"] = azureRMNormalizeLocation(*prop.Location) + output["location"] = azure.NormalizeLocation(*prop.Location) } if prop.PublicIPAddresses != nil { @@ -744,7 +900,7 @@ func expandApiManagementCustomProperties(d *schema.ResourceData) map[string]*str frontendProtocolSsl3 := false frontendProtocolTls10 := false frontendProtocolTls11 := false - tripleDesChipers := false + tripleDesCiphers := false if len(vs) > 0 { v := vs[0].(map[string]interface{}) @@ -754,7 +910,13 @@ func expandApiManagementCustomProperties(d *schema.ResourceData) map[string]*str frontendProtocolSsl3 = v["disable_frontend_ssl30"].(bool) frontendProtocolTls10 = v["disable_frontend_tls10"].(bool) frontendProtocolTls11 = v["disable_frontend_tls11"].(bool) - tripleDesChipers = v["disable_triple_des_chipers"].(bool) + //tripleDesCiphers = v["disable_triple_des_ciphers"].(bool) //restore in 2.0 + } + + if c, ok := d.GetOkExists("security.0.disable_triple_des_ciphers"); ok { + tripleDesCiphers = c.(bool) + } else if c, ok := d.GetOkExists("security.0.disable_triple_des_chipers"); ok { + tripleDesCiphers = c.(bool) } return map[string]*string{ @@ -764,7 +926,7 @@ func expandApiManagementCustomProperties(d *schema.ResourceData) map[string]*str apimFrontendProtocolSsl3: utils.String(strconv.FormatBool(frontendProtocolSsl3)), apimFrontendProtocolTls10: utils.String(strconv.FormatBool(frontendProtocolTls10)), apimFrontendProtocolTls11: utils.String(strconv.FormatBool(frontendProtocolTls11)), - apimTripleDesChipers: utils.String(strconv.FormatBool(tripleDesChipers)), + apimTripleDesCiphers: utils.String(strconv.FormatBool(tripleDesCiphers)), } } @@ -777,7 +939,8 @@ func flattenApiManagementCustomProperties(input map[string]*string) []interface{ output["disable_frontend_ssl30"] = parseApiManagementNilableDictionary(input, apimFrontendProtocolSsl3) output["disable_frontend_tls10"] = parseApiManagementNilableDictionary(input, apimFrontendProtocolTls10) output["disable_frontend_tls11"] = parseApiManagementNilableDictionary(input, apimFrontendProtocolTls11) - output["disable_triple_des_chipers"] = parseApiManagementNilableDictionary(input, apimTripleDesChipers) + output["disable_triple_des_chipers"] = parseApiManagementNilableDictionary(input, apimTripleDesCiphers) // todo remove in 2.0 + output["disable_triple_des_ciphers"] = parseApiManagementNilableDictionary(input, apimTripleDesCiphers) return []interface{}{output} } @@ -857,3 +1020,166 @@ func parseApiManagementNilableDictionary(input map[string]*string, key string) b return val } + +func expandApiManagementSignInSettings(input []interface{}) apimanagement.PortalSigninSettings { + enabled := false + + if len(input) > 0 { + vs := input[0].(map[string]interface{}) + enabled = vs["enabled"].(bool) + } + + return apimanagement.PortalSigninSettings{ + PortalSigninSettingProperties: &apimanagement.PortalSigninSettingProperties{ + Enabled: utils.Bool(enabled), + }, + } +} + +func flattenApiManagementSignInSettings(input apimanagement.PortalSigninSettings) []interface{} { + enabled := false + + if props := input.PortalSigninSettingProperties; props != nil { + if props.Enabled != nil { + enabled = *props.Enabled + } + } + + return []interface{}{ + map[string]interface{}{ + "enabled": enabled, + }, + } +} + +func expandApiManagementSignUpSettings(input []interface{}) apimanagement.PortalSignupSettings { + if len(input) == 0 { + return apimanagement.PortalSignupSettings{ + PortalSignupSettingsProperties: &apimanagement.PortalSignupSettingsProperties{ + Enabled: utils.Bool(false), + TermsOfService: &apimanagement.TermsOfServiceProperties{ + ConsentRequired: utils.Bool(false), + Enabled: utils.Bool(false), + Text: utils.String(""), + }, + }, + } + } + + vs := input[0].(map[string]interface{}) + + props := apimanagement.PortalSignupSettingsProperties{ + Enabled: utils.Bool(vs["enabled"].(bool)), + } + + termsOfServiceRaw := vs["terms_of_service"].([]interface{}) + if len(termsOfServiceRaw) > 0 { + termsOfServiceVs := termsOfServiceRaw[0].(map[string]interface{}) + props.TermsOfService = &apimanagement.TermsOfServiceProperties{ + Enabled: utils.Bool(termsOfServiceVs["enabled"].(bool)), + ConsentRequired: utils.Bool(termsOfServiceVs["consent_required"].(bool)), + Text: utils.String(termsOfServiceVs["text"].(string)), + } + } + + return apimanagement.PortalSignupSettings{ + PortalSignupSettingsProperties: &props, + } +} + +func flattenApiManagementSignUpSettings(input apimanagement.PortalSignupSettings) []interface{} { + enabled := false + termsOfService := make([]interface{}, 0) + + if props := input.PortalSignupSettingsProperties; props != nil { + if props.Enabled != nil { + enabled = *props.Enabled + } + + if tos := props.TermsOfService; tos != nil { + output := make(map[string]interface{}) + + if tos.Enabled != nil { + output["enabled"] = *tos.Enabled + } + + if tos.ConsentRequired != nil { + output["consent_required"] = *tos.ConsentRequired + } + + if tos.Text != nil { + output["text"] = *tos.Text + } + + termsOfService = append(termsOfService, output) + } + } + + return []interface{}{ + map[string]interface{}{ + "enabled": enabled, + "terms_of_service": termsOfService, + }, + } +} + +func expandApiManagementPolicies(input []interface{}) (*apimanagement.PolicyContract, error) { + if len(input) == 0 { + return nil, nil + } + + vs := input[0].(map[string]interface{}) + xmlContent := vs["xml_content"].(string) + xmlLink := vs["xml_link"].(string) + + if xmlContent != "" { + return &apimanagement.PolicyContract{ + PolicyContractProperties: &apimanagement.PolicyContractProperties{ + ContentFormat: apimanagement.XML, + PolicyContent: utils.String(xmlContent), + }, + }, nil + } + + if xmlLink != "" { + return &apimanagement.PolicyContract{ + PolicyContractProperties: &apimanagement.PolicyContractProperties{ + ContentFormat: apimanagement.XMLLink, + PolicyContent: utils.String(xmlLink), + }, + }, nil + } + + return nil, fmt.Errorf("Either `xml_content` or `xml_link` should be set if the `policy` block is defined.") +} + +func flattenApiManagementPolicies(d *schema.ResourceData, input apimanagement.PolicyContract) []interface{} { + xmlContent := "" + if props := input.PolicyContractProperties; props != nil { + if props.PolicyContent != nil { + xmlContent = *props.PolicyContent + } + } + + // if there's no policy assigned, we set this to an empty list + if xmlContent == "" { + return []interface{}{} + } + + output := map[string]interface{}{ + "xml_content": xmlContent, + "xml_link": "", + } + + // when you submit an `xml_link` to the API, the API downloads this link and stores it as `xml_content` + // as such we need to retrieve this value from the state if it's present + if existing, ok := d.GetOk("policy"); ok { + existingVs := existing.([]interface{}) + if len(existingVs) > 0 { + existingV := existingVs[0].(map[string]interface{}) + output["xml_link"] = existingV["xml_link"].(string) + } + } + + return []interface{}{output} +} diff --git a/azurerm/resource_arm_api_management_api.go b/azurerm/resource_arm_api_management_api.go index d7a1347084b5..f17e0d779f58 100644 --- a/azurerm/resource_arm_api_management_api.go +++ b/azurerm/resource_arm_api_management_api.go @@ -11,6 +11,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -34,7 +35,7 @@ func resourceArmApiManagementApi() *schema.Resource { "api_management_name": azure.SchemaApiManagementName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "display_name": { Type: schema.TypeString, @@ -180,7 +181,7 @@ func resourceArmApiManagementApi() *schema.Resource { } func resourceArmApiManagementApiCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementApiClient + client := meta.(*ArmClient).apiManagement.ApiClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) @@ -190,7 +191,7 @@ func resourceArmApiManagementApiCreateUpdate(d *schema.ResourceData, meta interf path := d.Get("path").(string) apiId := fmt.Sprintf("%s;rev=%s", name, revision) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serviceName, apiId) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -285,9 +286,9 @@ func resourceArmApiManagementApiCreateUpdate(d *schema.ResourceData, meta interf func resourceArmApiManagementApiRead(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).apiManagementApiClient + client := meta.(*ArmClient).apiManagement.ApiClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -343,10 +344,10 @@ func resourceArmApiManagementApiRead(d *schema.ResourceData, meta interface{}) e } func resourceArmApiManagementApiDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementApiClient + client := meta.(*ArmClient).apiManagement.ApiClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_api_management_api_operation.go b/azurerm/resource_arm_api_management_api_operation.go new file mode 100644 index 000000000000..9c32f2a15d3b --- /dev/null +++ b/azurerm/resource_arm_api_management_api_operation.go @@ -0,0 +1,340 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementApiOperation() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementApiOperationCreateUpdate, + Read: resourceArmApiManagementApiOperationRead, + Update: resourceArmApiManagementApiOperationCreateUpdate, + Delete: resourceArmApiManagementApiOperationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "operation_id": azure.SchemaApiManagementChildName(), + + "api_name": azure.SchemaApiManagementChildName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "display_name": { + Type: schema.TypeString, + Required: true, + }, + + "method": { + Type: schema.TypeString, + Required: true, + }, + + "url_template": { + Type: schema.TypeString, + Required: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "request": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "header": azure.SchemaApiManagementOperationParameterContract(), + + "query_parameter": azure.SchemaApiManagementOperationParameterContract(), + + "representation": azure.SchemaApiManagementOperationRepresentation(), + }, + }, + }, + + "response": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "status_code": { + Type: schema.TypeInt, + Required: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "header": azure.SchemaApiManagementOperationParameterContract(), + + "representation": azure.SchemaApiManagementOperationRepresentation(), + }, + }, + }, + + "template_parameter": azure.SchemaApiManagementOperationParameterContract(), + }, + } +} + +func resourceArmApiManagementApiOperationCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiOperationsClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + apiId := d.Get("api_name").(string) + operationId := d.Get("operation_id").(string) + + description := d.Get("description").(string) + displayName := d.Get("display_name").(string) + method := d.Get("method").(string) + urlTemplate := d.Get("url_template").(string) + + requestContractRaw := d.Get("request").([]interface{}) + requestContract, err := expandApiManagementOperationRequestContract(requestContractRaw) + if err != nil { + return err + } + + responseContractsRaw := d.Get("response").([]interface{}) + responseContracts, err := expandApiManagementOperationResponseContract(responseContractsRaw) + if err != nil { + return err + } + + templateParametersRaw := d.Get("template_parameter").([]interface{}) + templateParameters := azure.ExpandApiManagementOperationParameterContract(templateParametersRaw) + + parameters := apimanagement.OperationContract{ + OperationContractProperties: &apimanagement.OperationContractProperties{ + Description: utils.String(description), + DisplayName: utils.String(displayName), + Method: utils.String(method), + Request: requestContract, + Responses: responseContracts, + TemplateParameters: templateParameters, + URLTemplate: utils.String(urlTemplate), + }, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, apiId, operationId, parameters, ""); err != nil { + return fmt.Errorf("Error creating/updating API Operation %q (API %q / API Management Service %q / Resource Group %q): %+v", operationId, apiId, serviceName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, apiId, operationId) + if err != nil { + return fmt.Errorf("Error retrieving API Operation %q (API %q / API Management Service %q / Resource Group %q): %+v", operationId, apiId, serviceName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmApiManagementApiOperationRead(d, meta) +} + +func resourceArmApiManagementApiOperationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiOperationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + apiId := id.Path["apis"] + operationId := id.Path["operations"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, apiId, operationId) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] API Operation %q (API %q / API Management Service %q / Resource Group %q) was not found - removing from state!", operationId, apiId, serviceName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving API Operation %q (API %q / API Management Service %q / Resource Group %q): %+v", operationId, apiId, serviceName, resourceGroup, err) + } + + d.Set("operation_id", operationId) + d.Set("api_name", apiId) + d.Set("api_management_name", serviceName) + d.Set("resource_group_name", resourceGroup) + + if props := resp.OperationContractProperties; props != nil { + d.Set("description", props.Description) + d.Set("display_name", props.DisplayName) + d.Set("method", props.Method) + d.Set("url_template", props.URLTemplate) + + flattenedRequest := flattenApiManagementOperationRequestContract(props.Request) + if err := d.Set("request", flattenedRequest); err != nil { + return fmt.Errorf("Error flattening `request`: %+v", err) + } + + flattenedResponse := flattenApiManagementOperationResponseContract(props.Responses) + if err := d.Set("response", flattenedResponse); err != nil { + return fmt.Errorf("Error flattening `response`: %+v", err) + } + + flattenedTemplateParams := azure.FlattenApiManagementOperationParameterContract(props.TemplateParameters) + if err := d.Set("template_parameter", flattenedTemplateParams); err != nil { + return fmt.Errorf("Error flattening `template_parameter`: %+v", err) + } + } + + return nil +} + +func resourceArmApiManagementApiOperationDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiOperationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + apiId := id.Path["apis"] + operationId := id.Path["operations"] + + resp, err := client.Delete(ctx, resourceGroup, serviceName, apiId, operationId, "") + if err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting API Operation %q (API %q / API Management Service %q / Resource Group %q): %+v", operationId, apiId, serviceName, resourceGroup, err) + } + } + + return nil +} + +func expandApiManagementOperationRequestContract(input []interface{}) (*apimanagement.RequestContract, error) { + if len(input) == 0 { + return nil, nil + } + + vs := input[0].(map[string]interface{}) + description := vs["description"].(string) + + headersRaw := vs["header"].([]interface{}) + headers := azure.ExpandApiManagementOperationParameterContract(headersRaw) + + queryParametersRaw := vs["query_parameter"].([]interface{}) + queryParameters := azure.ExpandApiManagementOperationParameterContract(queryParametersRaw) + + representationsRaw := vs["representation"].([]interface{}) + representations, err := azure.ExpandApiManagementOperationRepresentation(representationsRaw) + if err != nil { + return nil, err + } + + return &apimanagement.RequestContract{ + Description: utils.String(description), + Headers: headers, + QueryParameters: queryParameters, + Representations: representations, + }, nil +} + +func flattenApiManagementOperationRequestContract(input *apimanagement.RequestContract) []interface{} { + if input == nil { + return []interface{}{} + } + + output := make(map[string]interface{}) + + if input.Description != nil { + output["description"] = *input.Description + } + + output["header"] = azure.FlattenApiManagementOperationParameterContract(input.Headers) + output["query_parameter"] = azure.FlattenApiManagementOperationParameterContract(input.QueryParameters) + output["representation"] = azure.FlattenApiManagementOperationRepresentation(input.Representations) + + return []interface{}{output} +} + +func expandApiManagementOperationResponseContract(input []interface{}) (*[]apimanagement.ResponseContract, error) { + if len(input) == 0 { + return &[]apimanagement.ResponseContract{}, nil + } + + outputs := make([]apimanagement.ResponseContract, 0) + + for _, v := range input { + vs := v.(map[string]interface{}) + + description := vs["description"].(string) + statusCode := vs["status_code"].(int) + + headersRaw := vs["header"].([]interface{}) + headers := azure.ExpandApiManagementOperationParameterContract(headersRaw) + + representationsRaw := vs["representation"].([]interface{}) + representations, err := azure.ExpandApiManagementOperationRepresentation(representationsRaw) + if err != nil { + return nil, err + } + + output := apimanagement.ResponseContract{ + Description: utils.String(description), + Headers: headers, + Representations: representations, + StatusCode: utils.Int32(int32(statusCode)), + } + + outputs = append(outputs, output) + } + + return &outputs, nil +} + +func flattenApiManagementOperationResponseContract(input *[]apimanagement.ResponseContract) []interface{} { + if input == nil { + return []interface{}{} + } + + outputs := make([]interface{}, 0) + + for _, v := range *input { + output := make(map[string]interface{}) + + if v.Description != nil { + output["description"] = *v.Description + } + + if v.StatusCode != nil { + output["status_code"] = int(*v.StatusCode) + } + + output["header"] = azure.FlattenApiManagementOperationParameterContract(v.Headers) + output["representation"] = azure.FlattenApiManagementOperationRepresentation(v.Representations) + + outputs = append(outputs, output) + } + + return outputs +} diff --git a/azurerm/resource_arm_api_management_api_operation_policy.go b/azurerm/resource_arm_api_management_api_operation_policy.go new file mode 100644 index 000000000000..a1c1e896bbb8 --- /dev/null +++ b/azurerm/resource_arm_api_management_api_operation_policy.go @@ -0,0 +1,171 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementApiOperationPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementAPIOperationPolicyCreateUpdate, + Read: resourceArmApiManagementAPIOperationPolicyRead, + Update: resourceArmApiManagementAPIOperationPolicyCreateUpdate, + Delete: resourceArmApiManagementAPIOperationPolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "resource_group_name": azure.SchemaResourceGroupName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "api_name": azure.SchemaApiManagementChildName(), + + "operation_id": azure.SchemaApiManagementChildName(), + + "xml_content": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"xml_link"}, + DiffSuppressFunc: suppress.XmlDiff, + }, + + "xml_link": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"xml_content"}, + }, + }, + } +} + +func resourceArmApiManagementAPIOperationPolicyCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiOperationPoliciesClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + apiName := d.Get("api_name").(string) + operationID := d.Get("operation_id").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serviceName, apiName, operationID) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing API Operation Policy (API Management Service %q / API %q / Operation %q / Resource Group %q): %s", serviceName, apiName, operationID, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_api_operation_policy", *existing.ID) + } + } + + parameters := apimanagement.PolicyContract{} + + xmlContent := d.Get("xml_content").(string) + xmlLink := d.Get("xml_link").(string) + + if xmlContent != "" { + parameters.PolicyContractProperties = &apimanagement.PolicyContractProperties{ + ContentFormat: apimanagement.XML, + PolicyContent: utils.String(xmlContent), + } + } + + if xmlLink != "" { + parameters.PolicyContractProperties = &apimanagement.PolicyContractProperties{ + ContentFormat: apimanagement.XMLLink, + PolicyContent: utils.String(xmlLink), + } + } + + if parameters.PolicyContractProperties == nil { + return fmt.Errorf("Either `xml_content` or `xml_link` must be set") + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, apiName, operationID, parameters, ""); err != nil { + return fmt.Errorf("Error creating or updating API Operation Policy (Resource Group %q / API Management Service %q / API %q / Operation %q): %+v", resourceGroup, serviceName, apiName, operationID, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, apiName, operationID) + if err != nil { + return fmt.Errorf("Error retrieving API Operation Policy (Resource Group %q / API Management Service %q / API %q / Operation %q): %+v", resourceGroup, serviceName, apiName, operationID, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read ID for API Operation Policy (Resource Group %q / API Management Service %q / API %q / Operation %q): %+v", resourceGroup, serviceName, apiName, operationID, err) + } + d.SetId(*resp.ID) + + return resourceArmApiManagementAPIOperationPolicyRead(d, meta) +} + +func resourceArmApiManagementAPIOperationPolicyRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiOperationPoliciesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + apiName := id.Path["apis"] + operationID := id.Path["operations"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, apiName, operationID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] API Operation Policy (Resource Group %q / API Management Service %q / API %q / Operation %q) was not found - removing from state!", resourceGroup, serviceName, apiName, operationID) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request for API Operation Policy (Resource Group %q / API Management Service %q / API %q / Operation %q): %+v", resourceGroup, serviceName, apiName, operationID, err) + } + + d.Set("resource_group_name", resourceGroup) + d.Set("api_management_name", serviceName) + d.Set("api_name", apiName) + d.Set("operation_id", operationID) + + if properties := resp.PolicyContractProperties; properties != nil { + // when you submit an `xml_link` to the API, the API downloads this link and stores it as `xml_content` + // as such there is no way to set `xml_link` and we'll let Terraform handle it + d.Set("xml_content", properties.PolicyContent) + } + + return nil +} + +func resourceArmApiManagementAPIOperationPolicyDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiOperationPoliciesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + apiName := id.Path["apis"] + operationID := id.Path["operations"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, apiName, operationID, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting API Operation Policy (Resource Group %q / API Management Service %q / API %q / Operation %q): %+v", resourceGroup, serviceName, apiName, operationID, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_api_management_api_operation_policy_test.go b/azurerm/resource_arm_api_management_api_operation_policy_test.go new file mode 100644 index 000000000000..8957b3627e98 --- /dev/null +++ b/azurerm/resource_arm_api_management_api_operation_policy_test.go @@ -0,0 +1,209 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMApiManagementAPIOperationPolicy_basic(t *testing.T) { + resourceName := "azurerm_api_management_api_operation_policy.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementAPIOperationPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementAPIOperationPolicy_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementAPIOperationPolicyExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"xml_link"}, + }, + }, + }) +} + +func TestAccAzureRMApiManagementAPIOperationPolicy_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_api_operation_policy.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementAPIOperationPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementAPIOperationPolicy_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementAPIOperationPolicyExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementAPIOperationPolicy_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_api_policy"), + }, + }, + }) +} + +func TestAccAzureRMApiManagementAPIOperationPolicy_update(t *testing.T) { + resourceName := "azurerm_api_management_api_operation_policy.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementAPIOperationPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementAPIOperationPolicy_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementAPIOperationPolicyExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementAPIOperationPolicy_updated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementAPIOperationPolicyExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"xml_link"}, + }, + }, + }) +} + +func testCheckAzureRMApiManagementAPIOperationPolicyExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + apiName := rs.Primary.Attributes["api_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + operationID := rs.Primary.Attributes["operation_id"] + + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ApiOperationPoliciesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, serviceName, apiName, operationID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: API Policy (API Management Service %q / API %q / Operation %q / Resource Group %q) does not exist", serviceName, apiName, operationID, resourceGroup) + } + + return fmt.Errorf("Bad: Get on apiManagementAPIOperationPoliciesClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMApiManagementAPIOperationPolicyDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ApiOperationPoliciesClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_api_operation_policy" { + continue + } + + apiName := rs.Primary.Attributes["api_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + operationID := rs.Primary.Attributes["operation_id"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, serviceName, apiName, operationID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return nil + } + + return nil +} + +func testAccAzureRMApiManagementAPIOperationPolicy_basic(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_basic(rInt, location) + + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation_policy" "test" { + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + operation_id = "${azurerm_api_management_api_operation.test.operation_id}" + xml_link = "https://gist.githubusercontent.com/tombuildsstuff/4f58581599d2c9f64b236f505a361a67/raw/0d29dcb0167af1e5afe4bd52a6d7f69ba1e05e1f/example.xml" +} +`, template) +} + +func testAccAzureRMApiManagementAPIOperationPolicy_requiresImport(rInt int, location string) string { + template := testAccAzureRMApiManagementAPIOperationPolicy_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation_policy" "import" { + api_name = "${azurerm_api_management_api_policy.test.api_name}" + api_management_name = "${azurerm_api_management_api_policy.test.api_management_name}" + resource_group_name = "${azurerm_api_management_api_policy.test.resource_group_name}" + operation_id = "${azurerm_api_management_api_operation.test.operation_id}" + xml_link = "${azurerm_api_management_api_policy.test.xml_link}" +} +`, template) +} + +func testAccAzureRMApiManagementAPIOperationPolicy_updated(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation_policy" "test" { + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + operation_id = "${azurerm_api_management_api_operation.test.operation_id}" + + xml_content = < + + + + +XML +} +`, template) +} diff --git a/azurerm/resource_arm_api_management_api_operation_test.go b/azurerm/resource_arm_api_management_api_operation_test.go new file mode 100644 index 000000000000..b7d3483a8437 --- /dev/null +++ b/azurerm/resource_arm_api_management_api_operation_test.go @@ -0,0 +1,566 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMApiManagementApiOperation_basic(t *testing.T) { + resourceName := "azurerm_api_management_api_operation.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiOperationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiOperation_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiOperationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiOperation_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_api_operation.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiOperationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiOperation_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiOperationExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementApiOperation_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_api_operation"), + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiOperation_customMethod(t *testing.T) { + resourceName := "azurerm_api_management_api_operation.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiOperationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiOperation_customMethod(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiOperationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "method", "HAMMERTIME"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiOperation_headers(t *testing.T) { + resourceName := "azurerm_api_management_api_operation.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiOperationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiOperation_headers(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiOperationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiOperation_requestRepresentations(t *testing.T) { + resourceName := "azurerm_api_management_api_operation.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiOperationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiOperation_requestRepresentation(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiOperationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMApiManagementApiOperation_requestRepresentationUpdated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiOperationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiOperation_representations(t *testing.T) { + // TODO: once `azurerm_api_management_schema` is supported add `request.0.representation.0.schema_id` + resourceName := "azurerm_api_management_api_operation.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiOperationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiOperation_representation(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiOperationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMApiManagementApiOperation_representationUpdated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiOperationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMApiManagementApiOperationDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ApiOperationsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_api_operation" { + continue + } + + operationId := rs.Primary.Attributes["operation_id"] + apiName := rs.Primary.Attributes["api_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, serviceName, apiName, operationId) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMApiManagementApiOperationExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + operationId := rs.Primary.Attributes["operation_id"] + apiName := rs.Primary.Attributes["api_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ApiOperationsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, serviceName, apiName, operationId) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: API Operation %q (API %q / API Management Service %q / Resource Group: %q) does not exist", operationId, apiName, serviceName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on apiManagementApiOperationsClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMApiManagementApiOperation_basic(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation" "test" { + operation_id = "acctest-operation" + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "DELETE Resource" + method = "DELETE" + url_template = "/resource" +} +`, template) +} + +func testAccAzureRMApiManagementApiOperation_customMethod(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation" "test" { + operation_id = "acctest-operation" + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "HAMMERTIME Resource" + method = "HAMMERTIME" + url_template = "/resource" +} +`, template) +} + +func testAccAzureRMApiManagementApiOperation_requiresImport(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation" "import" { + operation_id = "${azurerm_api_management_api_operation.test.operation_id}" + api_name = "${azurerm_api_management_api_operation.test.api_name}" + api_management_name = "${azurerm_api_management_api_operation.test.api_management_name}" + resource_group_name = "${azurerm_api_management_api_operation.test.resource_group_name}" + display_name = "${azurerm_api_management_api_operation.test.display_name}" + method = "${azurerm_api_management_api_operation.test.method}" + url_template = "${azurerm_api_management_api_operation.test.url_template}" +} +`, template) +} + +func testAccAzureRMApiManagementApiOperation_requestRepresentation(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation" "test" { + operation_id = "acctest-operation" + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Acceptance Test Operation" + method = "DELETE" + url_template = "/user1" + description = "This can only be done by the logged in user." + + request { + description = "Created user object" + + representation { + content_type = "application/json" + type_name = "User" + } + } +} +`, template) +} + +func testAccAzureRMApiManagementApiOperation_requestRepresentationUpdated(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation" "test" { + operation_id = "acctest-operation" + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Acceptance Test Operation" + method = "DELETE" + url_template = "/user1" + description = "This can only be done by the logged in user." + + request { + description = "Created user object" + + representation { + content_type = "application/json" + type_name = "User" + } + } +} +`, template) +} + +func testAccAzureRMApiManagementApiOperation_headers(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation" "test" { + operation_id = "acctest-operation" + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Acceptance Test Operation" + method = "DELETE" + url_template = "/user1" + description = "This can only be done by the logged in user." + + request { + description = "Created user object" + + header { + name = "X-Test-Operation" + required = true + type = "string" + } + + representation { + content_type = "application/json" + type_name = "User" + } + } + + response { + status_code = 200 + description = "successful operation" + + header { + name = "X-Test-Operation" + required = true + type = "string" + } + + representation { + content_type = "application/xml" + + sample = < + + + + + + + +SAMPLE + } + } +} +`, template) +} + +func testAccAzureRMApiManagementApiOperation_representation(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation" "test" { + operation_id = "acctest-operation" + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Acceptance Test Operation" + method = "DELETE" + url_template = "/user1" + description = "This can only be done by the logged in user." + + request { + description = "Created user object" + + representation { + content_type = "application/json" + type_name = "User" + } + } + + response { + status_code = 200 + description = "successful operation" + + representation { + content_type = "application/xml" + + sample = < + + + + + + + +SAMPLE + } + } +} +`, template) +} + +func testAccAzureRMApiManagementApiOperation_representationUpdated(rInt int, location string) string { + template := testAccAzureRMApiManagementApiOperation_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation" "test" { + operation_id = "acctest-operation" + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Acceptance Test Operation" + method = "DELETE" + url_template = "/user1" + description = "This can only be done by the logged in user." + + request { + description = "Created user object" + + representation { + content_type = "application/json" + type_name = "User" + } + } + + response { + status_code = 200 + description = "successful operation" + + representation { + content_type = "application/xml" + + sample = < + + + + + + + +SAMPLE + } + + representation { + content_type = "application/json" + + sample = < + + + + +XML +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_api_management_api_schema.go b/azurerm/resource_arm_api_management_api_schema.go new file mode 100644 index 000000000000..68255089568f --- /dev/null +++ b/azurerm/resource_arm_api_management_api_schema.go @@ -0,0 +1,158 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementApiSchema() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementApiSchemaCreateUpdate, + Read: resourceArmApiManagementApiSchemaRead, + Update: resourceArmApiManagementApiSchemaCreateUpdate, + Delete: resourceArmApiManagementApiSchemaDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "schema_id": azure.SchemaApiManagementChildName(), + + "api_name": azure.SchemaApiManagementChildName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "content_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "value": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + } +} + +func resourceArmApiManagementApiSchemaCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiSchemasClient + ctx := meta.(*ArmClient).StopContext + + schemaID := d.Get("schema_id").(string) + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + apiName := d.Get("api_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serviceName, apiName, schemaID) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing API Schema %q (API Management Service %q / API %q / Resource Group %q): %s", schemaID, serviceName, apiName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_api_schema", *existing.ID) + } + } + + contentType := d.Get("content_type").(string) + value := d.Get("value").(string) + parameters := apimanagement.SchemaContract{ + SchemaContractProperties: &apimanagement.SchemaContractProperties{ + ContentType: &contentType, + SchemaDocumentProperties: &apimanagement.SchemaDocumentProperties{ + Value: &value, + }, + }, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, apiName, schemaID, parameters, ""); err != nil { + return fmt.Errorf("Error creating or updating API Schema %q (API Management Service %q / API %q / Resource Group %q): %s", schemaID, serviceName, apiName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, apiName, schemaID) + if err != nil { + return fmt.Errorf("Error retrieving API Schema %q (API Management Service %q / API %q / Resource Group %q): %s", schemaID, serviceName, apiName, resourceGroup, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read ID for API Schema %q (API Management Service %q / API %q / Resource Group %q): %s", schemaID, serviceName, apiName, resourceGroup, err) + } + d.SetId(*resp.ID) + + return resourceArmApiManagementApiSchemaRead(d, meta) +} + +func resourceArmApiManagementApiSchemaRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiSchemasClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + apiName := id.Path["apis"] + schemaID := id.Path["schemas"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, apiName, schemaID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] API Schema %q (API Management Service %q / API %q / Resource Group %q) was not found - removing from state!", schemaID, serviceName, apiName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request for API Schema %q (API Management Service %q / API %q / Resource Group %q): %s", schemaID, serviceName, apiName, resourceGroup, err) + } + + d.Set("resource_group_name", resourceGroup) + d.Set("api_management_name", serviceName) + d.Set("api_name", apiName) + d.Set("schema_id", schemaID) + + if properties := resp.SchemaContractProperties; properties != nil { + d.Set("content_type", properties.ContentType) + if documentProperties := properties.SchemaDocumentProperties; documentProperties != nil { + d.Set("value", documentProperties.Value) + } + } + + return nil +} + +func resourceArmApiManagementApiSchemaDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiSchemasClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + apiName := id.Path["apis"] + schemaID := id.Path["schemas"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, apiName, schemaID, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting API Schema %q (API Management Service %q / API %q / Resource Group %q): %s", schemaID, serviceName, apiName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_api_management_api_schema_test.go b/azurerm/resource_arm_api_management_api_schema_test.go new file mode 100644 index 000000000000..559715622fd5 --- /dev/null +++ b/azurerm/resource_arm_api_management_api_schema_test.go @@ -0,0 +1,188 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMApiManagementApiSchema_basic(t *testing.T) { + resourceName := "azurerm_api_management_api_schema.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiSchemaDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiSchema_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiSchemaExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiSchema_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_api_schema.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiSchemaDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiSchema_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiSchemaExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementApiSchema_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_api_schema"), + }, + }, + }) +} + +func testCheckAzureRMApiManagementApiSchemaDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ApiSchemasClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_api_schema" { + continue + } + + schemaID := rs.Primary.Attributes["schema_id"] + apiName := rs.Primary.Attributes["api_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, serviceName, apiName, schemaID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMApiManagementApiSchemaExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + schemaID := rs.Primary.Attributes["schema_id"] + apiName := rs.Primary.Attributes["api_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ApiSchemasClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, serviceName, apiName, schemaID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: API Schema %q (API %q / API Management Service %q / Resource Group: %q) does not exist", schemaID, apiName, serviceName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on apiManagementApiSchemasClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMApiManagementApiSchema_basic(rInt int, location string) string { + template := testAccAzureRMApiManagementApiSchema_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_schema" "test" { + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management_api.test.api_management_name}" + resource_group_name = "${azurerm_api_management_api.test.resource_group_name}" + schema_id = "acctestSchema%d" + content_type = "application/vnd.ms-azure-apim.xsd+xml" + value = "${file("testdata/api_management_api_schema.xml")}" +} +`, template, rInt) +} + +func testAccAzureRMApiManagementApiSchema_requiresImport(rInt int, location string) string { + template := testAccAzureRMApiManagementApiSchema_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_schema" "test" { + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + schema_id = "acctestSchema%d" + content_type = "application/vnd.ms-azure-apim.xsd+xml" + value = "${file("testdata/api_management_api_schema.xml")}" +} +`, template, rInt) +} + +func testAccAzureRMApiManagementApiSchema_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_api" "test" { + name = "acctestapi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + display_name = "api1" + path = "api1" + protocols = ["https"] + revision = "1" +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_api_management_api_test.go b/azurerm/resource_arm_api_management_api_test.go index 02072c3f670a..2b78826b0a7b 100644 --- a/azurerm/resource_arm_api_management_api_test.go +++ b/azurerm/resource_arm_api_management_api_test.go @@ -4,15 +4,16 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func TestAccAzureRMApiManagementApi_basic(t *testing.T) { resourceName := "azurerm_api_management_api.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -40,7 +41,7 @@ func TestAccAzureRMApiManagementApi_basic(t *testing.T) { func TestAccAzureRMApiManagementApi_wordRevision(t *testing.T) { resourceName := "azurerm_api_management_api.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -65,13 +66,13 @@ func TestAccAzureRMApiManagementApi_wordRevision(t *testing.T) { } func TestAccAzureRMApiManagementApi_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } resourceName := "azurerm_api_management_api.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -95,7 +96,7 @@ func TestAccAzureRMApiManagementApi_requiresImport(t *testing.T) { func TestAccAzureRMApiManagementApi_soapPassthrough(t *testing.T) { resourceName := "azurerm_api_management_api.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -120,7 +121,7 @@ func TestAccAzureRMApiManagementApi_soapPassthrough(t *testing.T) { func TestAccAzureRMApiManagementApi_importSwagger(t *testing.T) { resourceName := "azurerm_api_management_api.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -149,7 +150,7 @@ func TestAccAzureRMApiManagementApi_importSwagger(t *testing.T) { func TestAccAzureRMApiManagementApi_importWsdl(t *testing.T) { resourceName := "azurerm_api_management_api.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -178,7 +179,7 @@ func TestAccAzureRMApiManagementApi_importWsdl(t *testing.T) { func TestAccAzureRMApiManagementApi_importUpdate(t *testing.T) { resourceName := "azurerm_api_management_api.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -222,7 +223,7 @@ func TestAccAzureRMApiManagementApi_importUpdate(t *testing.T) { func TestAccAzureRMApiManagementApi_complete(t *testing.T) { resourceName := "azurerm_api_management_api.test" - ri := acctest.RandInt() + ri := tf.AccRandTimeInt() location := testLocation() resource.Test(t, resource.TestCase{ @@ -246,7 +247,7 @@ func TestAccAzureRMApiManagementApi_complete(t *testing.T) { } func testCheckAzureRMApiManagementApiDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).apiManagementApiClient + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ApiClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management_api" { @@ -288,7 +289,7 @@ func testCheckAzureRMApiManagementApiExists(name string) resource.TestCheckFunc resourceGroup := rs.Primary.Attributes["resource_group_name"] revision := rs.Primary.Attributes["revision"] - conn := testAccProvider.Meta().(*ArmClient).apiManagementApiClient + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ApiClient ctx := testAccProvider.Meta().(*ArmClient).StopContext apiId := fmt.Sprintf("%s;rev=%s", name, revision) @@ -450,7 +451,7 @@ resource "azurerm_api_management_api" "test" { func testAccAzureRMApiManagementApi_template(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%d" + name = "acctestRG-%d" location = "%s" } diff --git a/azurerm/resource_arm_api_management_api_version_set.go b/azurerm/resource_arm_api_management_api_version_set.go new file mode 100644 index 000000000000..fd87e0fcce5f --- /dev/null +++ b/azurerm/resource_arm_api_management_api_version_set.go @@ -0,0 +1,213 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/validation" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementApiVersionSet() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementApiVersionSetCreateUpdate, + Read: resourceArmApiManagementApiVersionSetRead, + Update: resourceArmApiManagementApiVersionSetCreateUpdate, + Delete: resourceArmApiManagementApiVersionSetDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaApiManagementChildName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "display_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "versioning_scheme": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(apimanagement.VersioningSchemeHeader), + string(apimanagement.VersioningSchemeQuery), + string(apimanagement.VersioningSchemeSegment), + }, false), + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "version_header_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + ConflictsWith: []string{"version_query_name"}, + }, + + "version_query_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + ConflictsWith: []string{"version_header_name"}, + }, + }, + } +} + +func resourceArmApiManagementApiVersionSetCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiVersionSetClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Api Version Set %q (Api Management Service %q / Resource Group %q): %s", name, serviceName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_api_version_set", *existing.ID) + } + } + + versioningScheme := apimanagement.VersioningScheme(d.Get("versioning_scheme").(string)) + parameters := apimanagement.APIVersionSetContract{ + APIVersionSetContractProperties: &apimanagement.APIVersionSetContractProperties{ + DisplayName: utils.String(d.Get("display_name").(string)), + VersioningScheme: versioningScheme, + Description: utils.String(d.Get("description").(string)), + }, + } + + var headerSet, querySet bool + if v, ok := d.GetOk("version_header_name"); ok { + headerSet = v.(string) != "" + parameters.APIVersionSetContractProperties.VersionHeaderName = utils.String(v.(string)) + } + if v, ok := d.GetOk("version_query_name"); ok { + querySet = v.(string) != "" + parameters.APIVersionSetContractProperties.VersionQueryName = utils.String(v.(string)) + } + + switch schema := versioningScheme; schema { + case apimanagement.VersioningSchemeHeader: + if !headerSet { + return fmt.Errorf("`version_header_name` must be set if `versioning_schema` is `Header`") + } + if querySet { + return fmt.Errorf("`version_query_name` can not be set if `versioning_schema` is `Header`") + } + + case apimanagement.VersioningSchemeQuery: + if headerSet { + return fmt.Errorf("`version_header_name` can not be set if `versioning_schema` is `Query`") + } + if !querySet { + return fmt.Errorf("`version_query_name` must be set if `versioning_schema` is `Query`") + } + + case apimanagement.VersioningSchemeSegment: + if headerSet { + return fmt.Errorf("`version_header_name` can not be set if `versioning_schema` is `Segment`") + } + if querySet { + return fmt.Errorf("`version_query_name` can not be set if `versioning_schema` is `Segment`") + } + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, name, parameters, ""); err != nil { + return fmt.Errorf("Error creating/updating Api Version Set %q (Resource Group %q / Api Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + return fmt.Errorf("Error retrieving Api Version Set %q (Resource Group %q / Api Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read ID for Api Version Set %q (Resource Group %q / Api Management Service %q)", name, resourceGroup, serviceName) + } + d.SetId(*resp.ID) + + return resourceArmApiManagementApiVersionSetRead(d, meta) +} + +func resourceArmApiManagementApiVersionSetRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiVersionSetClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["api-version-sets"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Api Version Set %q (Resource Group %q / Api Management Service %q) was not found - removing from state!", name, resourceGroup, serviceName) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request for Api Version Set %q (Resource Group %q / Api Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("api_management_name", serviceName) + + if props := resp.APIVersionSetContractProperties; props != nil { + d.Set("description", props.Description) + d.Set("display_name", props.DisplayName) + d.Set("versioning_scheme", string(props.VersioningScheme)) + d.Set("version_header_name", props.VersionHeaderName) + d.Set("version_query_name", props.VersionQueryName) + } + + return nil +} + +func resourceArmApiManagementApiVersionSetDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ApiVersionSetClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["api-version-sets"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, name, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting Api Version Set %q (Resource Group %q / Api Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_api_management_api_version_set_test.go b/azurerm/resource_arm_api_management_api_version_set_test.go new file mode 100644 index 000000000000..e7075f7ed0ef --- /dev/null +++ b/azurerm/resource_arm_api_management_api_version_set_test.go @@ -0,0 +1,305 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMApiManagementApiVersionSet_basic(t *testing.T) { + resourceName := "azurerm_api_management_api_version_set.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiVersionSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiVersionSet_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiVersionSetExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiVersionSet_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_api_version_set.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiVersionSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiVersionSet_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiVersionSetExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementApiVersionSet_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_api_version_set"), + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiVersionSet_header(t *testing.T) { + resourceName := "azurerm_api_management_api_version_set.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiVersionSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiVersionSet_header(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiVersionSetExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiVersionSet_query(t *testing.T) { + resourceName := "azurerm_api_management_api_version_set.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiVersionSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiVersionSet_query(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiVersionSetExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementApiVersionSet_update(t *testing.T) { + resourceName := "azurerm_api_management_api_version_set.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementApiVersionSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementApiVersionSet_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiVersionSetExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "TestDescription1"), + resource.TestCheckResourceAttr(resourceName, "display_name", fmt.Sprintf("TestApiVersionSet1%d", ri)), + ), + }, + { + Config: testAccAzureRMApiManagementApiVersionSet_update(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementApiVersionSetExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "TestDescription2"), + resource.TestCheckResourceAttr(resourceName, "display_name", fmt.Sprintf("TestApiVersionSet2%d", ri)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMApiManagementApiVersionSetDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).apiManagement.ApiVersionSetClient + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_api_version_set" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + return nil +} + +func testCheckAzureRMApiManagementApiVersionSetExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + client := testAccProvider.Meta().(*ArmClient).apiManagement.ApiVersionSetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Api Management Api Version Set %q (Resource Group %q / Api Management Service %q) does not exist", name, resourceGroup, serviceName) + } + return fmt.Errorf("Bad: Get on apiManagementApiVersionSetClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMApiManagementApiVersionSet_basic(rInt int, location string) string { + template := testAccAzureRMApiManagementApiVersionSet_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_version_set" "test" { + name = "acctestAMAVS-%d" + resource_group_name = "${azurerm_api_management.test.resource_group_name}" + api_management_name = "${azurerm_api_management.test.name}" + description = "TestDescription1" + display_name = "TestApiVersionSet1%d" + versioning_scheme = "Segment" +} +`, template, rInt, rInt) +} + +func testAccAzureRMApiManagementApiVersionSet_requiresImport(rInt int, location string) string { + template := testAccAzureRMApiManagementApiVersionSet_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_version_set" "import" { + name = "${azurerm_api_management_api_version_set.test.name}" + resource_group_name = "${azurerm_api_management_api_version_set.test.resource_group_name}" + api_management_name = "${azurerm_api_management_api_version_set.test.api_management_name}" + description = "${azurerm_api_management_api_version_set.test.description}" + display_name = "${azurerm_api_management_api_version_set.test.display_name}" + versioning_scheme = "${azurerm_api_management_api_version_set.test.versioning_scheme}" +} +`, template) +} + +func testAccAzureRMApiManagementApiVersionSet_header(rInt int, location string) string { + template := testAccAzureRMApiManagementApiVersionSet_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_version_set" "test" { + name = "acctestAMAVS-%d" + resource_group_name = "${azurerm_api_management.test.resource_group_name}" + api_management_name = "${azurerm_api_management.test.name}" + description = "TestDescription1" + display_name = "TestApiVersionSet1%d" + versioning_scheme = "Header" + version_header_name = "Header1" +} +`, template, rInt, rInt) +} + +func testAccAzureRMApiManagementApiVersionSet_query(rInt int, location string) string { + template := testAccAzureRMApiManagementApiVersionSet_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_version_set" "test" { + name = "acctestAMAVS-%d" + resource_group_name = "${azurerm_api_management.test.resource_group_name}" + api_management_name = "${azurerm_api_management.test.name}" + description = "TestDescription1" + display_name = "TestApiVersionSet1%d" + versioning_scheme = "Query" + version_query_name = "Query1" +} +`, template, rInt, rInt) +} + +func testAccAzureRMApiManagementApiVersionSet_update(rInt int, location string) string { + template := testAccAzureRMApiManagementApiVersionSet_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_version_set" "test" { + name = "acctestAMAVS-%d" + resource_group_name = "${azurerm_api_management.test.resource_group_name}" + api_management_name = "${azurerm_api_management.test.name}" + description = "TestDescription2" + display_name = "TestApiVersionSet2%d" + versioning_scheme = "Segment" +} +`, template, rInt, rInt) +} + +func testAccAzureRMApiManagementApiVersionSet_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_api_management_authorization_server.go b/azurerm/resource_arm_api_management_authorization_server.go new file mode 100644 index 000000000000..3e401a50b6b9 --- /dev/null +++ b/azurerm/resource_arm_api_management_authorization_server.go @@ -0,0 +1,493 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementAuthorizationServer() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementAuthorizationServerCreateUpdate, + Read: resourceArmApiManagementAuthorizationServerRead, + Update: resourceArmApiManagementAuthorizationServerCreateUpdate, + Delete: resourceArmApiManagementAuthorizationServerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaApiManagementChildName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "authorization_endpoint": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "authorization_methods": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(apimanagement.DELETE), + string(apimanagement.GET), + string(apimanagement.HEAD), + string(apimanagement.OPTIONS), + string(apimanagement.PATCH), + string(apimanagement.POST), + string(apimanagement.PUT), + string(apimanagement.TRACE), + }, false), + }, + Set: schema.HashString, + }, + + "client_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "client_registration_endpoint": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "display_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "grant_types": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(apimanagement.AuthorizationCode), + string(apimanagement.ClientCredentials), + string(apimanagement.Implicit), + string(apimanagement.ResourceOwnerPassword), + }, false), + }, + Set: schema.HashString, + }, + + // Optional + "bearer_token_sending_methods": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(apimanagement.AuthorizationHeader), + string(apimanagement.Query), + }, false), + }, + Set: schema.HashString, + }, + + "client_authentication_method": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(apimanagement.Basic), + string(apimanagement.Body), + }, false), + }, + Set: schema.HashString, + }, + + "client_secret": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + + "default_scope": { + Type: schema.TypeString, + Optional: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "resource_owner_username": { + Type: schema.TypeString, + Optional: true, + }, + + "resource_owner_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + + "support_state": { + Type: schema.TypeBool, + Optional: true, + }, + + "token_body_parameter": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "value": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + + "token_endpoint": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func resourceArmApiManagementAuthorizationServerCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.AuthorizationServersClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + name := d.Get("name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Authorization Server %q (API Management Service %q / Resource Group %q): %s", name, serviceName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_authorization_server", *existing.ID) + } + } + + authorizationEndpoint := d.Get("authorization_endpoint").(string) + clientId := d.Get("client_id").(string) + clientRegistrationEndpoint := d.Get("client_registration_endpoint").(string) + displayName := d.Get("display_name").(string) + grantTypesRaw := d.Get("grant_types").(*schema.Set).List() + grantTypes := expandApiManagementAuthorizationServerGrantTypes(grantTypesRaw) + + clientAuthenticationMethodsRaw := d.Get("client_authentication_method").(*schema.Set).List() + clientAuthenticationMethods := expandApiManagementAuthorizationServerClientAuthenticationMethods(clientAuthenticationMethodsRaw) + clientSecret := d.Get("client_secret").(string) + defaultScope := d.Get("default_scope").(string) + description := d.Get("description").(string) + resourceOwnerPassword := d.Get("resource_owner_password").(string) + resourceOwnerUsername := d.Get("resource_owner_username").(string) + supportState := d.Get("support_state").(bool) + tokenBodyParametersRaw := d.Get("token_body_parameter").([]interface{}) + tokenBodyParameters := expandApiManagementAuthorizationServerTokenBodyParameters(tokenBodyParametersRaw) + + params := apimanagement.AuthorizationServerContract{ + AuthorizationServerContractProperties: &apimanagement.AuthorizationServerContractProperties{ + // Required + AuthorizationEndpoint: utils.String(authorizationEndpoint), + ClientID: utils.String(clientId), + ClientRegistrationEndpoint: utils.String(clientRegistrationEndpoint), + DisplayName: utils.String(displayName), + GrantTypes: grantTypes, + + // Optional + ClientAuthenticationMethod: clientAuthenticationMethods, + ClientSecret: utils.String(clientSecret), + DefaultScope: utils.String(defaultScope), + Description: utils.String(description), + ResourceOwnerPassword: utils.String(resourceOwnerPassword), + ResourceOwnerUsername: utils.String(resourceOwnerUsername), + SupportState: utils.Bool(supportState), + TokenBodyParameters: tokenBodyParameters, + }, + } + + authorizationMethodsRaw := d.Get("authorization_methods").(*schema.Set).List() + if len(authorizationMethodsRaw) > 0 { + authorizationMethods := expandApiManagementAuthorizationServerAuthorizationMethods(authorizationMethodsRaw) + params.AuthorizationServerContractProperties.AuthorizationMethods = authorizationMethods + } + + bearerTokenSendingMethodsRaw := d.Get("bearer_token_sending_methods").(*schema.Set).List() + if len(bearerTokenSendingMethodsRaw) > 0 { + bearerTokenSendingMethods := expandApiManagementAuthorizationServerBearerTokenSendingMethods(bearerTokenSendingMethodsRaw) + params.AuthorizationServerContractProperties.BearerTokenSendingMethods = bearerTokenSendingMethods + } + + if tokenEndpoint := d.Get("token_endpoint").(string); tokenEndpoint != "" { + params.AuthorizationServerContractProperties.TokenEndpoint = utils.String(tokenEndpoint) + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, name, params, ""); err != nil { + return fmt.Errorf("Error creating/updating Authorization Server %q (API Management Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + return fmt.Errorf("Error retrieving Authorization Server %q (API Management Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read ID for Authorization Server %q (API Management Service %q / Resource Group %q)", name, serviceName, resourceGroup) + } + + d.SetId(*read.ID) + return resourceArmApiManagementAuthorizationServerRead(d, meta) +} + +func resourceArmApiManagementAuthorizationServerRead(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + client := meta.(*ArmClient).apiManagement.AuthorizationServersClient + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["authorizationServers"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Authorization Server %q (API Management Service %q / Resource Group %q) does not exist - removing from state!", name, serviceName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Authorization Server %q (API Management Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + d.Set("api_management_name", serviceName) + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + + if props := resp.AuthorizationServerContractProperties; props != nil { + d.Set("authorization_endpoint", props.AuthorizationEndpoint) + d.Set("client_id", props.ClientID) + d.Set("client_registration_endpoint", props.ClientRegistrationEndpoint) + d.Set("client_secret", props.ClientSecret) + d.Set("default_scope", props.DefaultScope) + d.Set("description", props.Description) + d.Set("display_name", props.DisplayName) + d.Set("resource_owner_password", props.ResourceOwnerPassword) + d.Set("resource_owner_username", props.ResourceOwnerUsername) + d.Set("support_state", props.SupportState) + d.Set("token_endpoint", props.TokenEndpoint) + + if err := d.Set("authorization_methods", flattenApiManagementAuthorizationServerAuthorizationMethods(props.AuthorizationMethods)); err != nil { + return fmt.Errorf("Error flattening `authorization_methods`: %+v", err) + } + + if err := d.Set("bearer_token_sending_methods", flattenApiManagementAuthorizationServerBearerTokenSendingMethods(props.BearerTokenSendingMethods)); err != nil { + return fmt.Errorf("Error flattening `bearer_token_sending_methods`: %+v", err) + } + + if err := d.Set("client_authentication_method", flattenApiManagementAuthorizationServerClientAuthenticationMethods(props.ClientAuthenticationMethod)); err != nil { + return fmt.Errorf("Error flattening `client_authentication_method`: %+v", err) + } + + if err := d.Set("grant_types", flattenApiManagementAuthorizationServerGrantTypes(props.GrantTypes)); err != nil { + return fmt.Errorf("Error flattening `grant_types`: %+v", err) + } + + if err := d.Set("token_body_parameter", flattenApiManagementAuthorizationServerTokenBodyParameters(props.TokenBodyParameters)); err != nil { + return fmt.Errorf("Error flattening `token_body_parameter`: %+v", err) + } + } + + return nil +} + +func resourceArmApiManagementAuthorizationServerDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.AuthorizationServersClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["authorizationServers"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, name, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting Authorization Server %q (API Management Service %q / Resource Group %q): %s", name, serviceName, resourceGroup, err) + } + } + + return nil +} + +func expandApiManagementAuthorizationServerGrantTypes(input []interface{}) *[]apimanagement.GrantType { + outputs := make([]apimanagement.GrantType, 0) + + for _, v := range input { + grantType := apimanagement.GrantType(v.(string)) + outputs = append(outputs, grantType) + } + + return &outputs +} + +func flattenApiManagementAuthorizationServerGrantTypes(input *[]apimanagement.GrantType) []interface{} { + outputs := make([]interface{}, 0) + if input == nil { + return outputs + } + + for _, v := range *input { + outputs = append(outputs, string(v)) + } + + return outputs +} + +func expandApiManagementAuthorizationServerAuthorizationMethods(input []interface{}) *[]apimanagement.AuthorizationMethod { + outputs := make([]apimanagement.AuthorizationMethod, 0) + + for _, v := range input { + grantType := apimanagement.AuthorizationMethod(v.(string)) + outputs = append(outputs, grantType) + } + + return &outputs +} + +func flattenApiManagementAuthorizationServerAuthorizationMethods(input *[]apimanagement.AuthorizationMethod) []interface{} { + outputs := make([]interface{}, 0) + if input == nil { + return outputs + } + + for _, v := range *input { + outputs = append(outputs, string(v)) + } + + return outputs +} + +func expandApiManagementAuthorizationServerBearerTokenSendingMethods(input []interface{}) *[]apimanagement.BearerTokenSendingMethod { + outputs := make([]apimanagement.BearerTokenSendingMethod, 0) + + for _, v := range input { + grantType := apimanagement.BearerTokenSendingMethod(v.(string)) + outputs = append(outputs, grantType) + } + + return &outputs +} + +func flattenApiManagementAuthorizationServerBearerTokenSendingMethods(input *[]apimanagement.BearerTokenSendingMethod) []interface{} { + outputs := make([]interface{}, 0) + if input == nil { + return outputs + } + + for _, v := range *input { + outputs = append(outputs, string(v)) + } + + return outputs +} + +func expandApiManagementAuthorizationServerClientAuthenticationMethods(input []interface{}) *[]apimanagement.ClientAuthenticationMethod { + outputs := make([]apimanagement.ClientAuthenticationMethod, 0) + + for _, v := range input { + grantType := apimanagement.ClientAuthenticationMethod(v.(string)) + outputs = append(outputs, grantType) + } + + return &outputs +} + +func flattenApiManagementAuthorizationServerClientAuthenticationMethods(input *[]apimanagement.ClientAuthenticationMethod) []interface{} { + outputs := make([]interface{}, 0) + if input == nil { + return outputs + } + + for _, v := range *input { + outputs = append(outputs, string(v)) + } + + return outputs +} + +func expandApiManagementAuthorizationServerTokenBodyParameters(input []interface{}) *[]apimanagement.TokenBodyParameterContract { + outputs := make([]apimanagement.TokenBodyParameterContract, 0) + + for _, v := range input { + vs := v.(map[string]interface{}) + name := vs["name"].(string) + value := vs["value"].(string) + + output := apimanagement.TokenBodyParameterContract{ + Name: utils.String(name), + Value: utils.String(value), + } + outputs = append(outputs, output) + } + + return &outputs +} + +func flattenApiManagementAuthorizationServerTokenBodyParameters(input *[]apimanagement.TokenBodyParameterContract) []interface{} { + outputs := make([]interface{}, 0) + if input == nil { + return outputs + } + + for _, v := range *input { + output := make(map[string]interface{}) + + if v.Name != nil { + output["name"] = *v.Name + } + + if v.Value != nil { + output["value"] = *v.Value + } + + outputs = append(outputs, output) + } + + return outputs +} diff --git a/azurerm/resource_arm_api_management_authorization_server_test.go b/azurerm/resource_arm_api_management_authorization_server_test.go new file mode 100644 index 000000000000..dac89f439cdd --- /dev/null +++ b/azurerm/resource_arm_api_management_authorization_server_test.go @@ -0,0 +1,247 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMAPIManagementAuthorizationServer_basic(t *testing.T) { + resourceName := "azurerm_api_management_authorization_server.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementAuthorizationServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementAuthorizationServer_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementAuthorizationServerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAPIManagementAuthorizationServer_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_authorization_server.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementAuthorizationServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementAuthorizationServer_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementAuthorizationServerExists(resourceName), + ), + }, + { + Config: testAccAzureRMAPIManagementAuthorizationServer_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_authorization_server"), + }, + }, + }) +} + +func TestAccAzureRMAPIManagementAuthorizationServer_complete(t *testing.T) { + resourceName := "azurerm_api_management_authorization_server.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementAuthorizationServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementAuthorizationServer_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementAuthorizationServerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMAPIManagementAuthorizationServerDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).apiManagement.AuthorizationServersClient + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_authorization_server" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + return nil +} + +func testCheckAzureRMAPIManagementAuthorizationServerExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + client := testAccProvider.Meta().(*ArmClient).apiManagement.AuthorizationServersClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Authorization Server %q (API Management Service %q / Resource Group %q) does not exist", name, serviceName, resourceGroup) + } + return fmt.Errorf("Bad: Get on apiManagementAuthorizationServersClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMAPIManagementAuthorizationServer_basic(rInt int, location string) string { + template := testAccAzureRMAPIManagementAuthorizationServer_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_authorization_server" "test" { + name = "acctestauthsrv-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + display_name = "Test Group" + authorization_endpoint = "https://azacctest.hashicorptest.com/client/authorize" + client_id = "42424242-4242-4242-4242-424242424242" + client_registration_endpoint = "https://azacctest.hashicorptest.com/client/register" + + grant_types = [ + "implicit", + ] + + authorization_methods = [ + "GET", + ] +} +`, template, rInt) +} + +func testAccAzureRMAPIManagementAuthorizationServer_requiresImport(rInt int, location string) string { + template := testAccAzureRMAPIManagementAuthorizationServer_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_authorization_server" "import" { + name = "${azurerm_api_management_authorization_server.test.name}" + resource_group_name = "${azurerm_api_management_authorization_server.test.resource_group_name}" + api_management_name = "${azurerm_api_management_authorization_server.test.api_management_name}" + display_name = "${azurerm_api_management_authorization_server.test.display_name}" + authorization_endpoint = "${azurerm_api_management_authorization_server.test.authorization_endpoint}" + client_id = "${azurerm_api_management_authorization_server.test.client_id}" + client_registration_endpoint = "${azurerm_api_management_authorization_server.test.client_registration_endpoint}" + grant_types = "${azurerm_api_management_authorization_server.test.grant_types}" + + authorization_methods = [ + "GET", + ] +} +`, template) +} + +func testAccAzureRMAPIManagementAuthorizationServer_complete(rInt int, location string) string { + template := testAccAzureRMAPIManagementAuthorizationServer_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_authorization_server" "test" { + name = "acctestauthsrv-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + display_name = "Test Group" + authorization_endpoint = "https://azacctest.hashicorptest.com/client/authorize" + client_id = "42424242-4242-4242-4242-424242424242" + client_registration_endpoint = "https://azacctest.hashicorptest.com/client/register" + + grant_types = [ + "authorizationCode", + ] + + authorization_methods = [ + "GET", + "POST", + ] + + bearer_token_sending_methods = [ + "authorizationHeader", + ] + + client_secret = "n1n3-m0re-s3a5on5-m0r1y" + default_scope = "read write" + token_endpoint = "https://azacctest.hashicorptest.com/client/token" + resource_owner_username = "rick" + resource_owner_password = "C-193P" + support_state = true +} +`, template, rInt) +} + +func testAccAzureRMAPIManagementAuthorizationServer_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_api_management_backend.go b/azurerm/resource_arm_api_management_backend.go new file mode 100644 index 000000000000..ba66aa70a98d --- /dev/null +++ b/azurerm/resource_arm_api_management_backend.go @@ -0,0 +1,615 @@ +package azurerm + +import ( + "fmt" + "log" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementBackend() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementBackendCreateUpdate, + Read: resourceArmApiManagementBackendRead, + Update: resourceArmApiManagementBackendCreateUpdate, + Delete: resourceArmApiManagementBackendDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.ApiManagementBackendName, + }, + + "api_management_name": azure.SchemaApiManagementName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "credentials": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorization": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "parameter": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "scheme": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + "certificate": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + "header": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + "query": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 2000), + }, + + "protocol": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(apimanagement.BackendProtocolHTTP), + string(apimanagement.BackendProtocolSoap), + }, false), + }, + + "proxy": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "url": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "username": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + + "resource_id": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 2000), + }, + + "service_fabric_cluster": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_certificate_thumbprint": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "management_endpoints": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + "max_partition_resolution_retries": { + Type: schema.TypeInt, + Required: true, + }, + "server_certificate_thumbprints": { + Type: schema.TypeSet, + Optional: true, + ConflictsWith: []string{"service_fabric_cluster.0.server_x509_name"}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + "server_x509_name": { + Type: schema.TypeSet, + Optional: true, + ConflictsWith: []string{"service_fabric_cluster.0.server_certificate_thumbprints"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "issuer_certificate_thumbprint": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + }, + }, + + "title": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 300), + }, + + "tls": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "validate_certificate_chain": { + Type: schema.TypeBool, + Optional: true, + }, + "validate_certificate_name": { + Type: schema.TypeBool, + Optional: true, + }, + }, + }, + }, + + "url": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + } +} + +func resourceArmApiManagementBackendCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.BackendClient + ctx := meta.(*ArmClient).StopContext + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + name := d.Get("name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing backend %q (API Management Service %q / Resource Group %q): %s", name, serviceName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_backend", *existing.ID) + } + } + + credentialsRaw := d.Get("credentials").([]interface{}) + credentials := expandApiManagementBackendCredentials(credentialsRaw) + protocol := d.Get("protocol").(string) + proxyRaw := d.Get("proxy").([]interface{}) + proxy := expandApiManagementBackendProxy(proxyRaw) + tlsRaw := d.Get("tls").([]interface{}) + tls := expandApiManagementBackendTls(tlsRaw) + url := d.Get("url").(string) + + backendContract := apimanagement.BackendContract{ + BackendContractProperties: &apimanagement.BackendContractProperties{ + Credentials: credentials, + Protocol: apimanagement.BackendProtocol(protocol), + Proxy: proxy, + TLS: tls, + URL: utils.String(url), + }, + } + if description, ok := d.GetOk("description"); ok { + backendContract.BackendContractProperties.Description = utils.String(description.(string)) + } + if resourceID, ok := d.GetOk("resource_id"); ok { + backendContract.BackendContractProperties.ResourceID = utils.String(resourceID.(string)) + } + if title, ok := d.GetOk("title"); ok { + backendContract.BackendContractProperties.Title = utils.String(title.(string)) + } + + if serviceFabricClusterRaw, ok := d.GetOk("service_fabric_cluster"); ok { + err, serviceFabricCluster := expandApiManagementBackendServiceFabricCluster(serviceFabricClusterRaw.([]interface{})) + if err != nil { + return err + } + backendContract.BackendContractProperties.Properties = &apimanagement.BackendProperties{ + ServiceFabricCluster: serviceFabricCluster, + } + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, name, backendContract, ""); err != nil { + return fmt.Errorf("Error creating/updating backend %q (API Management Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + return fmt.Errorf("Error retrieving backend %q (API Management Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read ID for backend %q (API Management Service %q / Resource Group %q)", name, serviceName, resourceGroup) + } + + d.SetId(*read.ID) + return resourceArmApiManagementBackendRead(d, meta) +} + +func resourceArmApiManagementBackendRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.BackendClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["backends"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] backend %q (API Management Service %q / Resource Group %q) does not exist - removing from state!", name, serviceName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving backend %q (API Management Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + d.Set("name", name) + d.Set("api_management_name", serviceName) + d.Set("resource_group_name", resourceGroup) + + if props := resp.BackendContractProperties; props != nil { + d.Set("description", props.Description) + d.Set("protocol", string(props.Protocol)) + d.Set("resource_id", props.ResourceID) + d.Set("title", props.Title) + d.Set("url", props.URL) + if err := d.Set("credentials", flattenApiManagementBackendCredentials(props.Credentials)); err != nil { + return fmt.Errorf("Error setting `credentials`: %s", err) + } + if err := d.Set("proxy", flattenApiManagementBackendProxy(props.Proxy)); err != nil { + return fmt.Errorf("Error setting `proxy`: %s", err) + } + if properties := props.Properties; properties != nil { + if err := d.Set("service_fabric_cluster", flattenApiManagementBackendServiceFabricCluster(properties.ServiceFabricCluster)); err != nil { + return fmt.Errorf("Error setting `service_fabric_cluster`: %s", err) + } + } + if err := d.Set("tls", flattenApiManagementBackendTls(props.TLS)); err != nil { + return fmt.Errorf("Error setting `tls`: %s", err) + } + } + + return nil +} + +func resourceArmApiManagementBackendDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.BackendClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["backends"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, name, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting backend %q (API Management Service %q / Resource Group %q): %s", name, serviceName, resourceGroup, err) + } + } + + return nil +} + +func expandApiManagementBackendCredentials(input []interface{}) *apimanagement.BackendCredentialsContract { + if len(input) == 0 { + return nil + } + v := input[0].(map[string]interface{}) + contract := apimanagement.BackendCredentialsContract{} + if authorizationRaw := v["authorization"]; authorizationRaw != nil { + authorization := expandApiManagementBackendCredentialsAuthorization(authorizationRaw.([]interface{})) + contract.Authorization = authorization + } + if certificate := v["certificate"]; certificate != nil { + certificates := utils.ExpandStringSlice(certificate.([]interface{})) + if certificates != nil && len(*certificates) > 0 { + contract.Certificate = certificates + } + } + if headerRaw := v["header"]; headerRaw != nil { + header := expandApiManagementBackendCredentialsObject(headerRaw.(map[string]interface{})) + contract.Header = *header + } + if queryRaw := v["query"]; queryRaw != nil { + query := expandApiManagementBackendCredentialsObject(queryRaw.(map[string]interface{})) + contract.Query = *query + } + return &contract +} + +func expandApiManagementBackendCredentialsAuthorization(input []interface{}) *apimanagement.BackendAuthorizationHeaderCredentials { + if len(input) == 0 { + return nil + } + v := input[0].(map[string]interface{}) + credentials := apimanagement.BackendAuthorizationHeaderCredentials{} + if parameter := v["parameter"]; parameter != nil { + credentials.Parameter = utils.String(parameter.(string)) + } + if scheme := v["scheme"]; scheme != nil { + credentials.Scheme = utils.String(scheme.(string)) + } + return &credentials +} + +func expandApiManagementBackendCredentialsObject(input map[string]interface{}) *map[string][]string { + output := make(map[string][]string) + for k, v := range input { + output[k] = strings.Split(v.(string), ",") + } + return &output +} + +func expandApiManagementBackendProxy(input []interface{}) *apimanagement.BackendProxyContract { + if len(input) == 0 { + return nil + } + v := input[0].(map[string]interface{}) + contract := apimanagement.BackendProxyContract{} + if password := v["password"]; password != nil { + contract.Password = utils.String(password.(string)) + } + if url := v["url"]; url != nil { + contract.URL = utils.String(url.(string)) + } + if username := v["username"]; username != nil { + contract.Username = utils.String(username.(string)) + } + return &contract +} + +func expandApiManagementBackendServiceFabricCluster(input []interface{}) (error, *apimanagement.BackendServiceFabricClusterProperties) { + if len(input) == 0 { + return nil, nil + } + v := input[0].(map[string]interface{}) + clientCertificatethumbprint := v["client_certificate_thumbprint"].(string) + managementEndpoints := v["management_endpoints"].(*schema.Set).List() + maxPartitionResolutionRetries := int32(v["max_partition_resolution_retries"].(int)) + properties := apimanagement.BackendServiceFabricClusterProperties{ + ClientCertificatethumbprint: utils.String(clientCertificatethumbprint), + ManagementEndpoints: utils.ExpandStringSlice(managementEndpoints), + MaxPartitionResolutionRetries: utils.Int32(maxPartitionResolutionRetries), + } + serverCertificateThumbprintsUnset := true + serverX509NamesUnset := true + if serverCertificateThumbprints := v["server_certificate_thumbprints"]; serverCertificateThumbprints != nil { + properties.ServerCertificateThumbprints = utils.ExpandStringSlice(serverCertificateThumbprints.(*schema.Set).List()) + serverCertificateThumbprintsUnset = false + } + if serverX509Names := v["server_x509_name"]; serverX509Names != nil { + properties.ServerX509Names = expandApiManagementBackendServiceFabricClusterServerX509Names(serverX509Names.(*schema.Set).List()) + serverX509NamesUnset = false + } + if serverCertificateThumbprintsUnset && serverX509NamesUnset { + return fmt.Errorf("One of `server_certificate_thumbprints` or `server_x509_name` must be set"), nil + } + return nil, &properties +} + +func expandApiManagementBackendServiceFabricClusterServerX509Names(input []interface{}) *[]apimanagement.X509CertificateName { + results := make([]apimanagement.X509CertificateName, 0) + for _, certificateName := range input { + v := certificateName.(map[string]interface{}) + result := apimanagement.X509CertificateName{ + IssuerCertificateThumbprint: utils.String(v["issuer_certificate_thumbprint"].(string)), + Name: utils.String(v["name"].(string)), + } + results = append(results, result) + } + return &results +} + +func expandApiManagementBackendTls(input []interface{}) *apimanagement.BackendTLSProperties { + if len(input) == 0 { + return nil + } + v := input[0].(map[string]interface{}) + properties := apimanagement.BackendTLSProperties{} + if validateCertificateChain := v["validate_certificate_chain"]; validateCertificateChain != nil { + properties.ValidateCertificateChain = utils.Bool(validateCertificateChain.(bool)) + } + if validateCertificateName := v["validate_certificate_name"]; validateCertificateName != nil { + properties.ValidateCertificateName = utils.Bool(validateCertificateName.(bool)) + } + return &properties +} + +func flattenApiManagementBackendCredentials(input *apimanagement.BackendCredentialsContract) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + result := make(map[string]interface{}) + result["authorization"] = flattenApiManagementBackendCredentialsAuthorization(input.Authorization) + if input.Certificate != nil { + result["certificate"] = *input.Certificate + } + result["header"] = flattenApiManagementBackendCredentialsObject(input.Header) + result["query"] = flattenApiManagementBackendCredentialsObject(input.Query) + return append(results, result) +} + +func flattenApiManagementBackendCredentialsObject(input map[string][]string) map[string]interface{} { + results := make(map[string]interface{}) + if input == nil { + return results + } + for k, v := range input { + results[k] = strings.Join(v, ",") + } + return results +} + +func flattenApiManagementBackendCredentialsAuthorization(input *apimanagement.BackendAuthorizationHeaderCredentials) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + result := make(map[string]interface{}) + if parameter := input.Parameter; parameter != nil { + result["parameter"] = *parameter + } + if scheme := input.Scheme; scheme != nil { + result["scheme"] = *scheme + } + return append(results, result) +} + +func flattenApiManagementBackendProxy(input *apimanagement.BackendProxyContract) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + result := make(map[string]interface{}) + if password := input.Password; password != nil { + result["password"] = *password + } + if url := input.URL; url != nil { + result["url"] = *url + } + if username := input.Username; username != nil { + result["username"] = *username + } + return append(results, result) +} + +func flattenApiManagementBackendServiceFabricCluster(input *apimanagement.BackendServiceFabricClusterProperties) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + result := make(map[string]interface{}) + if clientCertificatethumbprint := input.ClientCertificatethumbprint; clientCertificatethumbprint != nil { + result["client_certificate_thumbprint"] = *clientCertificatethumbprint + } + if managementEndpoints := input.ManagementEndpoints; managementEndpoints != nil { + result["management_endpoints"] = *managementEndpoints + } + if maxPartitionResolutionRetries := input.MaxPartitionResolutionRetries; maxPartitionResolutionRetries != nil { + result["max_partition_resolution_retries"] = int(*maxPartitionResolutionRetries) + } + if serverCertificateThumbprints := input.ServerCertificateThumbprints; serverCertificateThumbprints != nil { + result["server_certificate_thumbprints"] = *serverCertificateThumbprints + } + result["server_x509_name"] = flattenApiManagementBackendServiceFabricClusterServerX509Names(input.ServerX509Names) + return append(results, result) +} + +func flattenApiManagementBackendServiceFabricClusterServerX509Names(input *[]apimanagement.X509CertificateName) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + for _, certificateName := range *input { + result := make(map[string]interface{}) + if issuerCertificateThumbprint := certificateName.IssuerCertificateThumbprint; issuerCertificateThumbprint != nil { + result["issuer_certificate_thumbprint"] = *issuerCertificateThumbprint + } + if name := certificateName.Name; name != nil { + result["name"] = *name + } + results = append(results, result) + } + return results +} + +func flattenApiManagementBackendTls(input *apimanagement.BackendTLSProperties) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + result := make(map[string]interface{}) + if validateCertificateChain := input.ValidateCertificateChain; validateCertificateChain != nil { + result["validate_certificate_chain"] = *validateCertificateChain + } + if validateCertificateName := input.ValidateCertificateName; validateCertificateName != nil { + result["validate_certificate_name"] = *validateCertificateName + } + return append(results, result) +} diff --git a/azurerm/resource_arm_api_management_backend_test.go b/azurerm/resource_arm_api_management_backend_test.go new file mode 100644 index 000000000000..4f0fee31d754 --- /dev/null +++ b/azurerm/resource_arm_api_management_backend_test.go @@ -0,0 +1,534 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMApiManagementBackend_basic(t *testing.T) { + resourceName := "azurerm_api_management_backend.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementBackendDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementBackend_basic(ri, "basic", location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "url", "https://acctest"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementBackend_allProperties(t *testing.T) { + resourceName := "azurerm_api_management_backend.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementBackendDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementBackend_allProperties(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "url", "https://acctest"), + resource.TestCheckResourceAttr(resourceName, "description", "description"), + resource.TestCheckResourceAttr(resourceName, "resource_id", "https://resourceid"), + resource.TestCheckResourceAttr(resourceName, "title", "title"), + resource.TestCheckResourceAttr(resourceName, "credentials.#", "1"), + resource.TestCheckResourceAttr(resourceName, "credentials.0.authorization.0.parameter", "parameter"), + resource.TestCheckResourceAttr(resourceName, "credentials.0.authorization.0.scheme", "scheme"), + resource.TestCheckResourceAttrSet(resourceName, "credentials.0.certificate.0"), + resource.TestCheckResourceAttr(resourceName, "credentials.0.header.header1", "header1value1,header1value2"), + resource.TestCheckResourceAttr(resourceName, "credentials.0.header.header2", "header2value1,header2value2"), + resource.TestCheckResourceAttr(resourceName, "credentials.0.query.query1", "query1value1,query1value2"), + resource.TestCheckResourceAttr(resourceName, "credentials.0.query.query2", "query2value1,query2value2"), + resource.TestCheckResourceAttr(resourceName, "proxy.#", "1"), + resource.TestCheckResourceAttr(resourceName, "proxy.0.url", "http://192.168.1.1:8080"), + resource.TestCheckResourceAttr(resourceName, "proxy.0.username", "username"), + resource.TestCheckResourceAttr(resourceName, "proxy.0.password", "password"), + resource.TestCheckResourceAttr(resourceName, "tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "tls.0.validate_certificate_chain", "false"), + resource.TestCheckResourceAttr(resourceName, "tls.0.validate_certificate_name", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementBackend_credentialsNoCertificate(t *testing.T) { + resourceName := "azurerm_api_management_backend.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementBackendDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementBackend_credentialsNoCertificate(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementBackend_update(t *testing.T) { + resourceName := "azurerm_api_management_backend.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementBackendDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementBackend_basic(ri, "update", location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "url", "https://acctest"), + ), + }, + { + Config: testAccAzureRMApiManagementBackend_update(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "protocol", "soap"), + resource.TestCheckResourceAttr(resourceName, "url", "https://updatedacctest"), + resource.TestCheckResourceAttr(resourceName, "description", "description"), + resource.TestCheckResourceAttr(resourceName, "resource_id", "https://resourceid"), + resource.TestCheckResourceAttr(resourceName, "proxy.#", "1"), + resource.TestCheckResourceAttr(resourceName, "proxy.0.url", "http://192.168.1.1:8080"), + resource.TestCheckResourceAttr(resourceName, "proxy.0.username", "username"), + resource.TestCheckResourceAttr(resourceName, "proxy.0.password", "password"), + resource.TestCheckResourceAttr(resourceName, "tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "tls.0.validate_certificate_chain", "false"), + resource.TestCheckResourceAttr(resourceName, "tls.0.validate_certificate_name", "true"), + ), + }, + { + Config: testAccAzureRMApiManagementBackend_basic(ri, "update", location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "url", "https://acctest"), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "resource_id", ""), + resource.TestCheckResourceAttr(resourceName, "proxy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tls.#", "0"), + ), + }, + }, + }) +} + +func TestAccAzureRMApiManagementBackend_serviceFabric(t *testing.T) { + resourceName := "azurerm_api_management_backend.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementBackendDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementBackend_serviceFabric(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "url", "https://acctest"), + resource.TestCheckResourceAttr(resourceName, "service_fabric_cluster.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "service_fabric_cluster.0.client_certificate_thumbprint"), + resource.TestCheckResourceAttr(resourceName, "service_fabric_cluster.0.max_partition_resolution_retries", "5"), + resource.TestCheckResourceAttr(resourceName, "service_fabric_cluster.0.management_endpoints.#", "1"), + resource.TestCheckResourceAttr(resourceName, "service_fabric_cluster.0.server_certificate_thumbprints.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementBackend_disappears(t *testing.T) { + resourceName := "azurerm_api_management_backend.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementBackendDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementBackend_basic(ri, "disappears", location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + testCheckAzureRMApiManagementBackendDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementBackend_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_backend.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementBackendDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementBackend_basic(ri, "import", location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementBackendExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementBackend_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_backend"), + }, + }, + }) +} + +func testCheckAzureRMApiManagementBackendDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).apiManagement.BackendClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_backend" { + continue + } + + name := rs.Primary.Attributes["name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMApiManagementBackendExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).apiManagement.BackendClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Backend %q (API Management Service %q / Resource Group: %q) does not exist", name, serviceName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on BackendClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMApiManagementBackendDisappears(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for backend: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).apiManagement.BackendClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Delete(ctx, resourceGroup, serviceName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp) { + return nil + } + return fmt.Errorf("Bad: Delete on BackendClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMApiManagementBackend_basic(rInt int, testName string, location string) string { + template := testAccAzureRMApiManagementBackend_template(rInt, testName, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_backend" "test" { + name = "acctestapi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + protocol = "http" + url = "https://acctest" +} +`, template, rInt) +} + +func testAccAzureRMApiManagementBackend_update(rInt int, location string) string { + template := testAccAzureRMApiManagementBackend_template(rInt, "update", location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_backend" "test" { + name = "acctestapi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + protocol = "soap" + url = "https://updatedacctest" + description = "description" + resource_id = "https://resourceid" + proxy { + url = "http://192.168.1.1:8080" + username = "username" + password = "password" + } + tls { + validate_certificate_chain = false + validate_certificate_name = true + } +} +`, template, rInt) +} + +func testAccAzureRMApiManagementBackend_allProperties(rInt int, location string) string { + template := testAccAzureRMApiManagementBackend_template(rInt, "all", location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_certificate" "test" { + name = "example-cert" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + data = "${filebase64("testdata/keyvaultcert.pfx")}" + password = "" +} + +resource "azurerm_api_management_backend" "test" { + name = "acctestapi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + protocol = "http" + url = "https://acctest" + description = "description" + resource_id = "https://resourceid" + title = "title" + credentials { + authorization { + parameter = "parameter" + scheme = "scheme" + } + certificate = [ + "${azurerm_api_management_certificate.test.thumbprint}", + ] + header = { + header1 = "header1value1,header1value2" + header2 = "header2value1,header2value2" + } + query = { + query1 = "query1value1,query1value2" + query2 = "query2value1,query2value2" + } + } + proxy { + url = "http://192.168.1.1:8080" + username = "username" + password = "password" + } + tls { + validate_certificate_chain = false + validate_certificate_name = true + } +} +`, template, rInt) +} + +func testAccAzureRMApiManagementBackend_serviceFabric(rInt int, location string) string { + template := testAccAzureRMApiManagementBackend_template(rInt, "sf", location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_certificate" "test" { + name = "example-cert" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + data = "${filebase64("testdata/keyvaultcert.pfx")}" + password = "" +} + +resource "azurerm_api_management_backend" "test" { + name = "acctestapi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + protocol = "http" + url = "https://acctest" + service_fabric_cluster { + client_certificate_thumbprint = "${azurerm_api_management_certificate.test.thumbprint}" + management_endpoints = [ + "https://acctestsf.com", + ] + max_partition_resolution_retries = 5 + server_certificate_thumbprints = [ + "thumb1", + "thumb2", + ] + } +} +`, template, rInt) +} + +func testAccAzureRMApiManagementBackend_requiresImport(rInt int, location string) string { + template := testAccAzureRMApiManagementBackend_basic(rInt, "requiresimport", location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_backend" "import" { + name = "${azurerm_api_management_backend.test.name}" + resource_group_name = "${azurerm_api_management_backend.test.resource_group_name}" + api_management_name = "${azurerm_api_management_backend.test.api_management_name}" + protocol = "${azurerm_api_management_backend.test.protocol}" + url = "${azurerm_api_management_backend.test.url}" +} +`, template) +} + +func testAccAzureRMApiManagementBackend_template(rInt int, testName string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d-%s" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d-%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} +`, rInt, testName, location, rInt, testName) +} + +func testAccAzureRMApiManagementBackend_credentialsNoCertificate(rInt int, location string) string { + template := testAccAzureRMApiManagementBackend_template(rInt, "all", location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_backend" "test" { + name = "acctestapi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + protocol = "http" + url = "https://acctest" + description = "description" + resource_id = "https://resourceid" + title = "title" + credentials { + authorization { + parameter = "parameter" + scheme = "scheme" + } + header = { + header1 = "header1value1,header1value2" + header2 = "header2value1,header2value2" + } + query = { + query1 = "query1value1,query1value2" + query2 = "query2value1,query2value2" + } + } + proxy { + url = "http://192.168.1.1:8080" + username = "username" + password = "password" + } + tls { + validate_certificate_chain = false + validate_certificate_name = true + } +} +`, template, rInt) +} diff --git a/azurerm/resource_arm_api_management_certificate.go b/azurerm/resource_arm_api_management_certificate.go new file mode 100644 index 000000000000..8ae1a8255610 --- /dev/null +++ b/azurerm/resource_arm_api_management_certificate.go @@ -0,0 +1,171 @@ +package azurerm + +import ( + "fmt" + "log" + "time" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementCertificateCreateUpdate, + Read: resourceArmApiManagementCertificateRead, + Update: resourceArmApiManagementCertificateCreateUpdate, + Delete: resourceArmApiManagementCertificateDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaApiManagementChildName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "data": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.Base64String(), + }, + + "password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + + "expiration": { + Type: schema.TypeString, + Computed: true, + }, + + "subject": { + Type: schema.TypeString, + Computed: true, + }, + + "thumbprint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmApiManagementCertificateCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.CertificatesClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + data := d.Get("data").(string) + password := d.Get("password").(string) + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Certificate %q (API Management Service %q / Resource Group %q): %s", name, serviceName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_certificate", *existing.ID) + } + } + + parameters := apimanagement.CertificateCreateOrUpdateParameters{ + CertificateCreateOrUpdateProperties: &apimanagement.CertificateCreateOrUpdateProperties{ + Data: utils.String(data), + Password: utils.String(password), + }, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, name, parameters, ""); err != nil { + return fmt.Errorf("Error creating or updating Certificate %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + return fmt.Errorf("Error retrieving Certificate %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read ID for Certificate %q (Resource Group %q / API Management Service %q)", name, resourceGroup, serviceName) + } + d.SetId(*resp.ID) + + return resourceArmApiManagementCertificateRead(d, meta) +} + +func resourceArmApiManagementCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.CertificatesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["certificates"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Certificate %q (Resource Group %q / API Management Service %q) was not found - removing from state!", name, resourceGroup, serviceName) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request for Certificate %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("api_management_name", serviceName) + + if props := resp.CertificateContractProperties; props != nil { + + if expiration := props.ExpirationDate; expiration != nil { + formatted := expiration.Format(time.RFC3339) + d.Set("expiration", formatted) + } + + d.Set("subject", props.Thumbprint) + d.Set("thumbprint", props.Thumbprint) + } + + return nil +} + +func resourceArmApiManagementCertificateDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.CertificatesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["certificates"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, name, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting Certificate %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_api_management_certificate_test.go b/azurerm/resource_arm_api_management_certificate_test.go new file mode 100644 index 000000000000..a72a7e6ddf7d --- /dev/null +++ b/azurerm/resource_arm_api_management_certificate_test.go @@ -0,0 +1,169 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMAPIManagementCertificate_basic(t *testing.T) { + resourceName := "azurerm_api_management_certificate.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementCertificate_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementCertificateExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "expiration"), + resource.TestCheckResourceAttrSet(resourceName, "subject"), + resource.TestCheckResourceAttrSet(resourceName, "thumbprint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "data", + "password", + }, + }, + }, + }) +} + +func TestAccAzureRMAPIManagementCertificate_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_certificate.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementCertificate_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementCertificateExists(resourceName), + ), + }, + { + Config: testAccAzureRMAPIManagementCertificate_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_certificate"), + }, + }, + }) +} + +func testCheckAzureRMAPIManagementCertificateDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).apiManagement.CertificatesClient + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_certificate" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + return nil +} + +func testCheckAzureRMAPIManagementCertificateExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + client := testAccProvider.Meta().(*ArmClient).apiManagement.CertificatesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: API Management Certificate %q (Resource Group %q / API Management Service %q) does not exist", name, resourceGroup, serviceName) + } + return fmt.Errorf("Bad: Get on apiManagementCertificatesClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMAPIManagementCertificate_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_certificate" "test" { + name = "example-cert" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + data = "${filebase64("testdata/keyvaultcert.pfx")}" + password = "" +} +`, rInt, location, rInt) +} + +func testAccAzureRMAPIManagementCertificate_requiresImport(rInt int, location string) string { + template := testAccAzureRMAPIManagementCertificate_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_certificate" "import" { + name = "${azurerm_api_management_certificate.test.name}" + api_management_name = "${azurerm_api_management_certificate.test.api_management_name}" + resource_group_name = "${azurerm_api_management_certificate.test.resource_group_name}" + data = "${azurerm_api_management_certificate.test.data}" + password = "${azurerm_api_management_certificate.test.password}" +} +`, template) +} diff --git a/azurerm/resource_arm_api_management_group.go b/azurerm/resource_arm_api_management_group.go index b240956b3aa1..825572bd9566 100644 --- a/azurerm/resource_arm_api_management_group.go +++ b/azurerm/resource_arm_api_management_group.go @@ -10,6 +10,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -26,7 +27,7 @@ func resourceArmApiManagementGroup() *schema.Resource { Schema: map[string]*schema.Schema{ "name": azure.SchemaApiManagementChildName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "api_management_name": azure.SchemaApiManagementName(), @@ -62,7 +63,7 @@ func resourceArmApiManagementGroup() *schema.Resource { } func resourceArmApiManagementGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementGroupClient + client := meta.(*ArmClient).apiManagement.GroupClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -74,7 +75,7 @@ func resourceArmApiManagementGroupCreateUpdate(d *schema.ResourceData, meta inte externalID := d.Get("external_id").(string) groupType := d.Get("type").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serviceName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -113,10 +114,10 @@ func resourceArmApiManagementGroupCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmApiManagementGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementGroupClient + client := meta.(*ArmClient).apiManagement.GroupClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -150,10 +151,10 @@ func resourceArmApiManagementGroupRead(d *schema.ResourceData, meta interface{}) } func resourceArmApiManagementGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementGroupClient + client := meta.(*ArmClient).apiManagement.GroupClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_api_management_group_test.go b/azurerm/resource_arm_api_management_group_test.go index 4a3f8f336cb2..85a5f34f9900 100644 --- a/azurerm/resource_arm_api_management_group_test.go +++ b/azurerm/resource_arm_api_management_group_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +39,7 @@ func TestAccAzureRMAPIManagementGroup_basic(t *testing.T) { } func TestAccAzureRMAPIManagementGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -139,7 +140,7 @@ func TestAccAzureRMAPIManagementGroup_descriptionDisplayNameUpdate(t *testing.T) } func testCheckAzureRMAPIManagementGroupDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).apiManagementGroupClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.GroupClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management_group" { continue @@ -174,14 +175,14 @@ func testCheckAzureRMAPIManagementGroupExists(resourceName string) resource.Test resourceGroup := rs.Primary.Attributes["resource_group_name"] serviceName := rs.Primary.Attributes["api_management_name"] - client := testAccProvider.Meta().(*ArmClient).apiManagementGroupClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.GroupClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serviceName, name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { return fmt.Errorf("Bad: API Management Group %q (Resource Group %q / API Management Service %q) does not exist", name, resourceGroup, serviceName) } - return fmt.Errorf("Bad: Get on apiManagementGroupClient: %+v", err) + return fmt.Errorf("Bad: Get on apiManagement.GroupClient: %+v", err) } return nil diff --git a/azurerm/resource_arm_api_management_group_user.go b/azurerm/resource_arm_api_management_group_user.go index e509dd9ec369..07efdaca1bce 100644 --- a/azurerm/resource_arm_api_management_group_user.go +++ b/azurerm/resource_arm_api_management_group_user.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -24,7 +25,7 @@ func resourceArmApiManagementGroupUser() *schema.Resource { "group_name": azure.SchemaApiManagementChildName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "api_management_name": azure.SchemaApiManagementName(), }, @@ -32,7 +33,7 @@ func resourceArmApiManagementGroupUser() *schema.Resource { } func resourceArmApiManagementGroupUserCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementGroupUsersClient + client := meta.(*ArmClient).apiManagement.GroupUsersClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) @@ -40,7 +41,7 @@ func resourceArmApiManagementGroupUserCreate(d *schema.ResourceData, meta interf groupName := d.Get("group_name").(string) userId := d.Get("user_id").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { resp, err := client.CheckEntityExists(ctx, resourceGroup, serviceName, groupName, userId) if err != nil { if !utils.ResponseWasNotFound(resp) { @@ -67,10 +68,10 @@ func resourceArmApiManagementGroupUserCreate(d *schema.ResourceData, meta interf } func resourceArmApiManagementGroupUserRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementGroupUsersClient + client := meta.(*ArmClient).apiManagement.GroupUsersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -99,10 +100,10 @@ func resourceArmApiManagementGroupUserRead(d *schema.ResourceData, meta interfac } func resourceArmApiManagementGroupUserDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementGroupUsersClient + client := meta.(*ArmClient).apiManagement.GroupUsersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_api_management_group_user_test.go b/azurerm/resource_arm_api_management_group_user_test.go index 9209ad4a0831..8ae68b3734a6 100644 --- a/azurerm/resource_arm_api_management_group_user_test.go +++ b/azurerm/resource_arm_api_management_group_user_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMAPIManagementGroupUser_basic(t *testing.T) { } func TestAccAzureRMAPIManagementGroupUser_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -65,7 +66,7 @@ func TestAccAzureRMAPIManagementGroupUser_requiresImport(t *testing.T) { } func testCheckAzureRMAPIManagementGroupUserDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).apiManagementGroupUsersClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.GroupUsersClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management_group_user" { continue @@ -101,14 +102,14 @@ func testCheckAzureRMAPIManagementGroupUserExists(resourceName string) resource. resourceGroup := rs.Primary.Attributes["resource_group_name"] serviceName := rs.Primary.Attributes["api_management_name"] - client := testAccProvider.Meta().(*ArmClient).apiManagementGroupUsersClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.GroupUsersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.CheckEntityExists(ctx, resourceGroup, serviceName, groupName, userId) if err != nil { if utils.ResponseWasNotFound(resp) { return fmt.Errorf("Bad: User %q / Group %q (API Management Service %q / Resource Group %q) does not exist", userId, groupName, serviceName, resourceGroup) } - return fmt.Errorf("Bad: Get on apiManagementGroupUsersClient: %+v", err) + return fmt.Errorf("Bad: Get on apiManagement.GroupUsersClient: %+v", err) } return nil @@ -143,19 +144,19 @@ resource "azurerm_api_management_group" "test" { } resource "azurerm_api_management_user" "test" { - user_id = "acctestuser%d" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance" - last_name = "Test" - email = "azure-acctest%d@example.com" + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test" + email = "azure-acctest%d@example.com" } resource "azurerm_api_management_group_user" "test" { - user_id = "${azurerm_api_management_user.test.user_id}" - group_name = "${azurerm_api_management_group.test.name}" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" + user_id = "${azurerm_api_management_user.test.user_id}" + group_name = "${azurerm_api_management_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" } `, rInt, location, rInt, rInt, rInt, rInt) } @@ -166,10 +167,10 @@ func testAccAzureRMAPIManagementGroupUser_requiresImport(rInt int, location stri %s resource "azurerm_api_management_group_user" "import" { - user_id = "${azurerm_api_management_group_user.test.user_id}" - group_name = "${azurerm_api_management_group_user.test.group_name}" - api_management_name = "${azurerm_api_management_group_user.test.api_management_name}" - resource_group_name = "${azurerm_api_management_group_user.test.resource_group_name}" + user_id = "${azurerm_api_management_group_user.test.user_id}" + group_name = "${azurerm_api_management_group_user.test.group_name}" + api_management_name = "${azurerm_api_management_group_user.test.api_management_name}" + resource_group_name = "${azurerm_api_management_group_user.test.resource_group_name}" } `, template) } diff --git a/azurerm/resource_arm_api_management_logger.go b/azurerm/resource_arm_api_management_logger.go new file mode 100644 index 000000000000..481b9e363742 --- /dev/null +++ b/azurerm/resource_arm_api_management_logger.go @@ -0,0 +1,270 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementLogger() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementLoggerCreate, + Read: resourceArmApiManagementLoggerRead, + Update: resourceArmApiManagementLoggerUpdate, + Delete: resourceArmApiManagementLoggerDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaApiManagementChildName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "eventhub": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"application_insights"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateEventHubName(), + }, + + "connection_string": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + + "application_insights": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"eventhub"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "instrumentation_key": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + + "buffered": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func resourceArmApiManagementLoggerCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.LoggerClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + + eventHubRaw := d.Get("eventhub").([]interface{}) + appInsightsRaw := d.Get("application_insights").([]interface{}) + + if len(eventHubRaw) == 0 && len(appInsightsRaw) == 0 { + return fmt.Errorf("Either `eventhub` or `application_insights` is required") + } + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Logger %q (API Management Service %q / Resource Group %q): %s", name, serviceName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_logger", *existing.ID) + } + } + + parameters := apimanagement.LoggerContract{ + LoggerContractProperties: &apimanagement.LoggerContractProperties{ + IsBuffered: utils.Bool(d.Get("buffered").(bool)), + Description: utils.String(d.Get("description").(string)), + }, + } + + if len(eventHubRaw) > 0 { + parameters.LoggerType = apimanagement.AzureEventHub + parameters.Credentials = expandArmApiManagementLoggerEventHub(eventHubRaw) + } else if len(appInsightsRaw) > 0 { + parameters.LoggerType = apimanagement.ApplicationInsights + parameters.Credentials = expandArmApiManagementLoggerApplicationInsights(appInsightsRaw) + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, name, parameters, ""); err != nil { + return fmt.Errorf("Error creating Logger %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + return fmt.Errorf("Error retrieving Logger %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read Logger %q (Resource Group %q / API Management Service %q) ID", name, resourceGroup, serviceName) + } + d.SetId(*resp.ID) + + return resourceArmApiManagementLoggerRead(d, meta) +} + +func resourceArmApiManagementLoggerRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.LoggerClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["loggers"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Logger %q (API Management Service %q / Resource Group %q) was not found - removing from state", name, serviceName, resourceGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading Logger %q (API Management Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("api_management_name", serviceName) + + if properties := resp.LoggerContractProperties; properties != nil { + d.Set("buffered", properties.IsBuffered) + d.Set("description", properties.Description) + if err := d.Set("eventhub", flattenArmApiManagementLoggerEventHub(d, properties)); err != nil { + return fmt.Errorf("Error setting `eventhub`: %s", err) + } + } + + return nil +} + +func resourceArmApiManagementLoggerUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.LoggerClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + name := d.Get("name").(string) + + eventHubRaw, hasEventHub := d.GetOk("eventhub") + appInsightsRaw, hasAppInsights := d.GetOk("application_insights") + + parameters := apimanagement.LoggerUpdateContract{ + LoggerUpdateParameters: &apimanagement.LoggerUpdateParameters{ + IsBuffered: utils.Bool(d.Get("buffered").(bool)), + Description: utils.String(d.Get("description").(string)), + }, + } + + if hasEventHub { + parameters.LoggerType = apimanagement.AzureEventHub + parameters.Credentials = expandArmApiManagementLoggerEventHub(eventHubRaw.([]interface{})) + } else if hasAppInsights { + parameters.LoggerType = apimanagement.ApplicationInsights + parameters.Credentials = expandArmApiManagementLoggerApplicationInsights(appInsightsRaw.([]interface{})) + } + + if _, err := client.Update(ctx, resourceGroup, serviceName, name, parameters, ""); err != nil { + return fmt.Errorf("Error updating Logger %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + + return resourceArmApiManagementLoggerRead(d, meta) +} + +func resourceArmApiManagementLoggerDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.LoggerClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["loggers"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, name, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting Logger %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + } + + return nil +} + +func expandArmApiManagementLoggerEventHub(input []interface{}) map[string]*string { + credentials := make(map[string]*string) + eventHub := input[0].(map[string]interface{}) + credentials["name"] = utils.String(eventHub["name"].(string)) + credentials["connectionString"] = utils.String(eventHub["connection_string"].(string)) + return credentials +} + +func expandArmApiManagementLoggerApplicationInsights(input []interface{}) map[string]*string { + credentials := make(map[string]*string) + ai := input[0].(map[string]interface{}) + credentials["instrumentationKey"] = utils.String(ai["instrumentation_key"].(string)) + return credentials +} + +func flattenArmApiManagementLoggerEventHub(d *schema.ResourceData, properties *apimanagement.LoggerContractProperties) []interface{} { + result := make([]interface{}, 0) + if name := properties.Credentials["name"]; name != nil { + eventHub := make(map[string]interface{}) + eventHub["name"] = *name + if existing := d.Get("eventhub").([]interface{}); len(existing) > 0 { + existingEventHub := existing[0].(map[string]interface{}) + if conn, ok := existingEventHub["connection_string"]; ok { + eventHub["connection_string"] = conn.(string) + } + } + result = append(result, eventHub) + } + return result +} diff --git a/azurerm/resource_arm_api_management_logger_test.go b/azurerm/resource_arm_api_management_logger_test.go new file mode 100644 index 000000000000..43b2cbfa8a9a --- /dev/null +++ b/azurerm/resource_arm_api_management_logger_test.go @@ -0,0 +1,412 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMApiManagementLogger_basicEventHub(t *testing.T) { + resourceName := "azurerm_api_management_logger.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementLoggerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementLogger_basicEventHub(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "true"), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "eventhub.0.name"), + resource.TestCheckResourceAttrSet(resourceName, "eventhub.0.connection_string"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"eventhub.0.connection_string"}, + }, + }, + }) +} + +func TestAccAzureRMApiManagementLogger_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_logger.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementLoggerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementLogger_basicEventHub(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "true"), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "eventhub.0.name"), + resource.TestCheckResourceAttrSet(resourceName, "eventhub.0.connection_string"), + ), + }, + { + Config: testAccAzureRMApiManagementLogger_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_logger"), + }, + }, + }) +} + +func TestAccAzureRMApiManagementLogger_basicApplicationInsights(t *testing.T) { + resourceName := "azurerm_api_management_logger.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementLoggerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementLogger_basicApplicationInsights(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "true"), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "0"), + resource.TestCheckResourceAttr(resourceName, "application_insights.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "application_insights.0.instrumentation_key"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"application_insights.#", "application_insights.0.instrumentation_key"}, + }, + }, + }) +} + +func TestAccAzureRMApiManagementLogger_complete(t *testing.T) { + resourceName := "azurerm_api_management_logger.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementLoggerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementLogger_complete(ri, location, "Logger from Terraform test", "false"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "Logger from Terraform test"), + resource.TestCheckResourceAttr(resourceName, "buffered", "false"), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "0"), + resource.TestCheckResourceAttr(resourceName, "application_insights.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "application_insights.0.instrumentation_key"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"application_insights.#", "application_insights.0.instrumentation_key"}, + }, + }, + }) +} + +func TestAccAzureRMApiManagementLogger_update(t *testing.T) { + resourceName := "azurerm_api_management_logger.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementLoggerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementLogger_basicApplicationInsights(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "true"), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "0"), + resource.TestCheckResourceAttr(resourceName, "application_insights.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "application_insights.0.instrumentation_key"), + ), + }, + { + Config: testAccAzureRMApiManagementLogger_basicEventHub(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "true"), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "eventhub.0.name"), + resource.TestCheckResourceAttrSet(resourceName, "eventhub.0.connection_string"), + ), + }, + { + Config: testAccAzureRMApiManagementLogger_complete(ri, location, "Logger from Terraform test", "false"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "false"), + resource.TestCheckResourceAttr(resourceName, "description", "Logger from Terraform test"), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "0"), + resource.TestCheckResourceAttr(resourceName, "application_insights.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "application_insights.0.instrumentation_key"), + ), + }, + { + Config: testAccAzureRMApiManagementLogger_complete(ri, location, "Logger from Terraform update test", "true"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "true"), + resource.TestCheckResourceAttr(resourceName, "description", "Logger from Terraform update test"), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "0"), + resource.TestCheckResourceAttr(resourceName, "application_insights.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "application_insights.0.instrumentation_key"), + ), + }, + { + Config: testAccAzureRMApiManagementLogger_complete(ri, location, "Logger from Terraform test", "false"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "false"), + resource.TestCheckResourceAttr(resourceName, "description", "Logger from Terraform test"), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "0"), + resource.TestCheckResourceAttr(resourceName, "application_insights.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "application_insights.0.instrumentation_key"), + ), + }, + { + Config: testAccAzureRMApiManagementLogger_basicEventHub(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementLoggerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "buffered", "true"), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "eventhub.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "eventhub.0.name"), + resource.TestCheckResourceAttrSet(resourceName, "eventhub.0.connection_string"), + ), + }, + }, + }) +} + +func testCheckAzureRMApiManagementLoggerExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("API Management Logger not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + client := testAccProvider.Meta().(*ArmClient).apiManagement.LoggerClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + if resp, err := client.Get(ctx, resourceGroup, serviceName, name); err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Logger %q (Resource Group %q / API Management Service %q) does not exist", name, resourceGroup, serviceName) + } + return fmt.Errorf("Bad: Get on apiManagement.LoggerClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMApiManagementLoggerDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).apiManagement.LoggerClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_logger" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + if resp, err := client.Get(ctx, resourceGroup, serviceName, name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Get on apiManagement.LoggerClient: %+v", err) + } + } + + return nil + } + + return nil +} + +func testAccAzureRMApiManagementLogger_basicEventHub(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_eventhub_namespace" "test" { + name = "acctesteventhubnamespace-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Basic" +} + +resource "azurerm_eventhub" "test" { + name = "acctesteventhub-%d" + namespace_name = "${azurerm_eventhub_namespace.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + partition_count = 2 + message_retention = 1 +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_logger" "test" { + name = "acctestapimnglogger-%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + + eventhub { + name = "${azurerm_eventhub.test.name}" + connection_string = "${azurerm_eventhub_namespace.test.default_primary_connection_string}" + } +} +`, rInt, location, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMApiManagementLogger_requiresImport(rInt int, location string) string { + template := testAccAzureRMApiManagementLogger_basicEventHub(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_logger" "import" { + name = "${azurerm_api_management_logger.test.name}" + api_management_name = "${azurerm_api_management_logger.test.api_management_name}" + resource_group_name = "${azurerm_api_management_logger.test.resource_group_name}" + + eventhub { + name = "${azurerm_eventhub.test.name}" + connection_string = "${azurerm_eventhub_namespace.test.default_primary_connection_string}" + } +} +`, template) +} + +func testAccAzureRMApiManagementLogger_basicApplicationInsights(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestappinsights-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_type = "Other" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_logger" "test" { + name = "acctestapimnglogger-%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + + application_insights { + instrumentation_key = "${azurerm_application_insights.test.instrumentation_key}" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMApiManagementLogger_complete(rInt int, location string, description, buffered string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestappinsights-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_type = "Other" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_logger" "test" { + name = "acctestapimnglogger-%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + description = "%s" + buffered = %s + + application_insights { + instrumentation_key = "${azurerm_application_insights.test.instrumentation_key}" + } +} +`, rInt, location, rInt, rInt, rInt, description, buffered) +} diff --git a/azurerm/resource_arm_api_management_openid_connect_provider.go b/azurerm/resource_arm_api_management_openid_connect_provider.go new file mode 100644 index 000000000000..0c0f4f3a9a3c --- /dev/null +++ b/azurerm/resource_arm_api_management_openid_connect_provider.go @@ -0,0 +1,171 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementOpenIDConnectProvider() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementOpenIDConnectProviderCreateUpdate, + Read: resourceArmApiManagementOpenIDConnectProviderRead, + Update: resourceArmApiManagementOpenIDConnectProviderCreateUpdate, + Delete: resourceArmApiManagementOpenIDConnectProviderDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaApiManagementChildName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "client_id": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "client_secret": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "display_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "metadata_endpoint": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func resourceArmApiManagementOpenIDConnectProviderCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.OpenIdConnectClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing OpenID Connect Provider %q (API Management Service %q / Resource Group %q): %s", name, serviceName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_openid_connect_provider", *existing.ID) + } + } + + parameters := apimanagement.OpenidConnectProviderContract{ + OpenidConnectProviderContractProperties: &apimanagement.OpenidConnectProviderContractProperties{ + ClientID: utils.String(d.Get("client_id").(string)), + ClientSecret: utils.String(d.Get("client_secret").(string)), + Description: utils.String(d.Get("description").(string)), + DisplayName: utils.String(d.Get("display_name").(string)), + MetadataEndpoint: utils.String(d.Get("metadata_endpoint").(string)), + }, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, name, parameters, ""); err != nil { + return fmt.Errorf("Error creating OpenID Connect Provider %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + return fmt.Errorf("Error retrieving OpenID Connect Provider %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read OpenID Connect Provider %q (Resource Group %q / API Management Service %q) ID", name, resourceGroup, serviceName) + } + d.SetId(*resp.ID) + + return resourceArmApiManagementOpenIDConnectProviderRead(d, meta) +} + +func resourceArmApiManagementOpenIDConnectProviderRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.OpenIdConnectClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["openidConnectProviders"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] OpenID Connect Provider %q (API Management Service %q / Resource Group %q) was not found - removing from state", name, serviceName, resourceGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading OpenID Connect Provider %q (API Management Service %q / Resource Group %q): %+v", name, serviceName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("api_management_name", serviceName) + + if props := resp.OpenidConnectProviderContractProperties; props != nil { + d.Set("client_id", props.ClientID) + d.Set("client_secret", props.ClientSecret) + d.Set("description", props.Description) + d.Set("display_name", props.DisplayName) + d.Set("metadata_endpoint", props.MetadataEndpoint) + } + + return nil +} + +func resourceArmApiManagementOpenIDConnectProviderDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.OpenIdConnectClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + name := id.Path["openidConnectProviders"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, name, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting OpenID Connect Provider %q (Resource Group %q / API Management Service %q): %+v", name, resourceGroup, serviceName, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_api_management_openid_connect_provider_test.go b/azurerm/resource_arm_api_management_openid_connect_provider_test.go new file mode 100644 index 000000000000..8c9776d764fe --- /dev/null +++ b/azurerm/resource_arm_api_management_openid_connect_provider_test.go @@ -0,0 +1,221 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMApiManagementOpenIDConnectProvider_basic(t *testing.T) { + resourceName := "azurerm_api_management_openid_connect_provider.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementOpenIDConnectProviderDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementOpenIDConnectProvider_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementOpenIDConnectProviderExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagementOpenIDConnectProvider_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_openid_connect_provider.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementOpenIDConnectProviderDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementOpenIDConnectProvider_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementOpenIDConnectProviderExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementOpenIDConnectProvider_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_openid_connect_provider"), + }, + }, + }) +} + +func TestAccAzureRMApiManagementOpenIDConnectProvider_update(t *testing.T) { + resourceName := "azurerm_api_management_openid_connect_provider.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementOpenIDConnectProviderDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementOpenIDConnectProvider_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementOpenIDConnectProviderExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementOpenIDConnectProvider_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementOpenIDConnectProviderExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMApiManagementOpenIDConnectProviderExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("API Management OpenID Connect Provider not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + client := testAccProvider.Meta().(*ArmClient).apiManagement.OpenIdConnectClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + if resp, err := client.Get(ctx, resourceGroup, serviceName, name); err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: OpenID Connect Provider %q (Resource Group %q / API Management Service %q) does not exist", name, resourceGroup, serviceName) + } + return fmt.Errorf("Bad: Get on apiManagement.OpenIdConnectClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMApiManagementOpenIDConnectProviderDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).apiManagement.OpenIdConnectClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_openid_connect_provider" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + if resp, err := client.Get(ctx, resourceGroup, serviceName, name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Get on apiManagement.OpenIdConnectClient: %+v", err) + } + } + + return nil + } + + return nil +} + +func testAccAzureRMApiManagementOpenIDConnectProvider_basic(rInt int, location string) string { + template := testAccAzureRMApiManagementOpenIDConnectProvider_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_openid_connect_provider" "test" { + name = "acctest-%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + client_id = "00001111-2222-3333-%d" + client_secret = "%d-cwdavsxbacsaxZX-%d" + display_name = "Initial Name" + metadata_endpoint = "https://azacctest.hashicorptest.com/example/foo" +} +`, template, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMApiManagementOpenIDConnectProvider_requiresImport(rInt int, location string) string { + template := testAccAzureRMApiManagementOpenIDConnectProvider_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_openid_connect_provider" "import" { + name = "${azurerm_api_management_openid_connect_provider.test.name}" + api_management_name = "${azurerm_api_management_openid_connect_provider.test.api_management_name}" + resource_group_name = "${azurerm_api_management_openid_connect_provider.test.resource_group_name}" + client_id = "${azurerm_api_management_openid_connect_provider.test.client_id}" + client_secret = "${azurerm_api_management_openid_connect_provider.test.client_secret}" + display_name = "${azurerm_api_management_openid_connect_provider.test.display_name}" + metadata_endpoint = "${azurerm_api_management_openid_connect_provider.test.metadata_endpoint}" +} +`, template) +} + +func testAccAzureRMApiManagementOpenIDConnectProvider_complete(rInt int, location string) string { + template := testAccAzureRMApiManagementOpenIDConnectProvider_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_openid_connect_provider" "test" { + name = "acctest-%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + client_id = "00001111-3333-2222-%d" + client_secret = "%d-423egvwdcsjx-%d" + display_name = "Updated Name" + description = "Example description" + metadata_endpoint = "https://azacctest.hashicorptest.com/example/updated" +} +`, template, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMApiManagementOpenIDConnectProvider_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_api_management_product.go b/azurerm/resource_arm_api_management_product.go index 19b6faecca67..b3c94fbb175c 100644 --- a/azurerm/resource_arm_api_management_product.go +++ b/azurerm/resource_arm_api_management_product.go @@ -9,6 +9,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,7 +28,7 @@ func resourceArmApiManagementProduct() *schema.Resource { "api_management_name": azure.SchemaApiManagementName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "display_name": { Type: schema.TypeString, @@ -69,7 +70,7 @@ func resourceArmApiManagementProduct() *schema.Resource { } func resourceArmApiManagementProductCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductsClient + client := meta.(*ArmClient).apiManagement.ProductsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for API Management Product creation.") @@ -86,7 +87,7 @@ func resourceArmApiManagementProductCreateUpdate(d *schema.ResourceData, meta in subscriptionsLimit := d.Get("subscriptions_limit").(int) published := d.Get("published").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serviceName, productId) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -118,6 +119,8 @@ func resourceArmApiManagementProductCreateUpdate(d *schema.ResourceData, meta in if subscriptionRequired && subscriptionsLimit > 0 { properties.ProductContractProperties.ApprovalRequired = utils.Bool(approvalRequired) properties.ProductContractProperties.SubscriptionsLimit = utils.Int32(int32(subscriptionsLimit)) + } else if approvalRequired { + return fmt.Errorf("`subscription_required` must be true and `subscriptions_limit` must be greater than 0 to use `approval_required`") } if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, productId, properties, ""); err != nil { @@ -139,10 +142,10 @@ func resourceArmApiManagementProductCreateUpdate(d *schema.ResourceData, meta in } func resourceArmApiManagementProductRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductsClient + client := meta.(*ArmClient).apiManagement.ProductsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -180,10 +183,10 @@ func resourceArmApiManagementProductRead(d *schema.ResourceData, meta interface{ } func resourceArmApiManagementProductDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductsClient + client := meta.(*ArmClient).apiManagement.ProductsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_api_management_product_api.go b/azurerm/resource_arm_api_management_product_api.go index ebd57ab9ef78..2055e13c5c56 100644 --- a/azurerm/resource_arm_api_management_product_api.go +++ b/azurerm/resource_arm_api_management_product_api.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -24,7 +25,7 @@ func resourceArmApiManagementProductApi() *schema.Resource { "product_id": azure.SchemaApiManagementChildName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "api_management_name": azure.SchemaApiManagementName(), }, @@ -32,7 +33,7 @@ func resourceArmApiManagementProductApi() *schema.Resource { } func resourceArmApiManagementProductApiCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductApisClient + client := meta.(*ArmClient).apiManagement.ProductApisClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) @@ -40,7 +41,7 @@ func resourceArmApiManagementProductApiCreate(d *schema.ResourceData, meta inter apiName := d.Get("api_name").(string) productId := d.Get("product_id").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { resp, err := client.CheckEntityExists(ctx, resourceGroup, serviceName, productId, apiName) if err != nil { if !utils.ResponseWasNotFound(resp) { @@ -67,10 +68,10 @@ func resourceArmApiManagementProductApiCreate(d *schema.ResourceData, meta inter } func resourceArmApiManagementProductApiRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductApisClient + client := meta.(*ArmClient).apiManagement.ProductApisClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -99,10 +100,10 @@ func resourceArmApiManagementProductApiRead(d *schema.ResourceData, meta interfa } func resourceArmApiManagementProductApiDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductApisClient + client := meta.(*ArmClient).apiManagement.ProductApisClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_api_management_product_api_test.go b/azurerm/resource_arm_api_management_product_api_test.go index c88ecdde7732..57b651dd242d 100644 --- a/azurerm/resource_arm_api_management_product_api_test.go +++ b/azurerm/resource_arm_api_management_product_api_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMAPIManagementProductApi_basic(t *testing.T) { } func TestAccAzureRMAPIManagementProductApi_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -65,7 +66,7 @@ func TestAccAzureRMAPIManagementProductApi_requiresImport(t *testing.T) { } func testCheckAzureRMAPIManagementProductApiDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).apiManagementProductApisClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.ProductApisClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management_product_api" { continue @@ -101,14 +102,14 @@ func testCheckAzureRMAPIManagementProductApiExists(resourceName string) resource resourceGroup := rs.Primary.Attributes["resource_group_name"] serviceName := rs.Primary.Attributes["api_management_name"] - client := testAccProvider.Meta().(*ArmClient).apiManagementProductApisClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.ProductApisClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.CheckEntityExists(ctx, resourceGroup, serviceName, productId, apiName) if err != nil { if utils.ResponseWasNotFound(resp) { return fmt.Errorf("Bad: API %q / Product %q (API Management Service %q / Resource Group %q) does not exist", apiName, productId, serviceName, resourceGroup) } - return fmt.Errorf("Bad: Get on apiManagementProductApisClient: %+v", err) + return fmt.Errorf("Bad: Get on apiManagement.ProductApisClient: %+v", err) } return nil @@ -145,7 +146,6 @@ resource "azurerm_api_management_product" "test" { published = true } - resource "azurerm_api_management_api" "test" { name = "acctestapi-%d" resource_group_name = "${azurerm_resource_group.test.name}" @@ -157,10 +157,10 @@ resource "azurerm_api_management_api" "test" { } resource "azurerm_api_management_product_api" "test" { - product_id = "${azurerm_api_management_product.test.product_id}" - api_name = "${azurerm_api_management_api.test.name}" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" + product_id = "${azurerm_api_management_product.test.product_id}" + api_name = "${azurerm_api_management_api.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" } `, rInt, location, rInt, rInt) } diff --git a/azurerm/resource_arm_api_management_product_group.go b/azurerm/resource_arm_api_management_product_group.go index 13ad8e42c3a3..86a130dc5c27 100644 --- a/azurerm/resource_arm_api_management_product_group.go +++ b/azurerm/resource_arm_api_management_product_group.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -24,7 +25,7 @@ func resourceArmApiManagementProductGroup() *schema.Resource { "group_name": azure.SchemaApiManagementChildName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "api_management_name": azure.SchemaApiManagementName(), }, @@ -32,7 +33,7 @@ func resourceArmApiManagementProductGroup() *schema.Resource { } func resourceArmApiManagementProductGroupCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductGroupsClient + client := meta.(*ArmClient).apiManagement.ProductGroupsClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) @@ -40,7 +41,7 @@ func resourceArmApiManagementProductGroupCreate(d *schema.ResourceData, meta int groupName := d.Get("group_name").(string) productId := d.Get("product_id").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { resp, err := client.CheckEntityExists(ctx, resourceGroup, serviceName, productId, groupName) if err != nil { if !utils.ResponseWasNotFound(resp) { @@ -67,10 +68,10 @@ func resourceArmApiManagementProductGroupCreate(d *schema.ResourceData, meta int } func resourceArmApiManagementProductGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductGroupsClient + client := meta.(*ArmClient).apiManagement.ProductGroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -99,10 +100,10 @@ func resourceArmApiManagementProductGroupRead(d *schema.ResourceData, meta inter } func resourceArmApiManagementProductGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementProductGroupsClient + client := meta.(*ArmClient).apiManagement.ProductGroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_api_management_product_group_test.go b/azurerm/resource_arm_api_management_product_group_test.go index 6d8c9f02fc3d..b479d2ad7174 100644 --- a/azurerm/resource_arm_api_management_product_group_test.go +++ b/azurerm/resource_arm_api_management_product_group_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMAPIManagementProductGroup_basic(t *testing.T) { } func TestAccAzureRMAPIManagementProductGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -65,7 +66,7 @@ func TestAccAzureRMAPIManagementProductGroup_requiresImport(t *testing.T) { } func testCheckAzureRMAPIManagementProductGroupDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).apiManagementProductGroupsClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.ProductGroupsClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management_product_group" { continue @@ -101,14 +102,14 @@ func testCheckAzureRMAPIManagementProductGroupExists(resourceName string) resour resourceGroup := rs.Primary.Attributes["resource_group_name"] serviceName := rs.Primary.Attributes["api_management_name"] - client := testAccProvider.Meta().(*ArmClient).apiManagementProductGroupsClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.ProductGroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.CheckEntityExists(ctx, resourceGroup, serviceName, productId, groupName) if err != nil { if utils.ResponseWasNotFound(resp) { return fmt.Errorf("Bad: Product %q / Group %q (API Management Service %q / Resource Group %q) does not exist", productId, groupName, serviceName, resourceGroup) } - return fmt.Errorf("Bad: Get on apiManagementProductGroupsClient: %+v", err) + return fmt.Errorf("Bad: Get on apiManagement.ProductGroupsClient: %+v", err) } return nil @@ -153,10 +154,10 @@ resource "azurerm_api_management_group" "test" { } resource "azurerm_api_management_product_group" "test" { - product_id = "${azurerm_api_management_product.test.product_id}" - group_name = "${azurerm_api_management_group.test.name}" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" + product_id = "${azurerm_api_management_product.test.product_id}" + group_name = "${azurerm_api_management_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" } `, rInt, location, rInt, rInt) } @@ -167,10 +168,10 @@ func testAccAzureRMAPIManagementProductGroup_requiresImport(rInt int, location s %s resource "azurerm_api_management_product_group" "import" { - product_id = "${azurerm_api_management_product_group.test.product_id}" - group_name = "${azurerm_api_management_product_group.test.group_name}" - api_management_name = "${azurerm_api_management_product_group.test.api_management_name}" - resource_group_name = "${azurerm_api_management_product_group.test.resource_group_name}" + product_id = "${azurerm_api_management_product_group.test.product_id}" + group_name = "${azurerm_api_management_product_group.test.group_name}" + api_management_name = "${azurerm_api_management_product_group.test.api_management_name}" + resource_group_name = "${azurerm_api_management_product_group.test.resource_group_name}" } `, template) } diff --git a/azurerm/resource_arm_api_management_product_policy.go b/azurerm/resource_arm_api_management_product_policy.go new file mode 100644 index 000000000000..26267d8285d3 --- /dev/null +++ b/azurerm/resource_arm_api_management_product_policy.go @@ -0,0 +1,165 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementProductPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementProductPolicyCreateUpdate, + Read: resourceArmApiManagementProductPolicyRead, + Update: resourceArmApiManagementProductPolicyCreateUpdate, + Delete: resourceArmApiManagementProductPolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "resource_group_name": azure.SchemaResourceGroupName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "product_id": azure.SchemaApiManagementChildName(), + + "xml_content": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"xml_link"}, + DiffSuppressFunc: suppress.XmlDiff, + }, + + "xml_link": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"xml_content"}, + }, + }, + } +} + +func resourceArmApiManagementProductPolicyCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ProductPoliciesClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + productID := d.Get("product_id").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serviceName, productID) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Product Policy (API Management Service %q / Product %q / Resource Group %q): %s", serviceName, productID, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_api_management_product_policy", *existing.ID) + } + } + + parameters := apimanagement.PolicyContract{} + + xmlContent := d.Get("xml_content").(string) + xmlLink := d.Get("xml_link").(string) + + if xmlContent != "" { + parameters.PolicyContractProperties = &apimanagement.PolicyContractProperties{ + ContentFormat: apimanagement.XML, + PolicyContent: utils.String(xmlContent), + } + } + + if xmlLink != "" { + parameters.PolicyContractProperties = &apimanagement.PolicyContractProperties{ + ContentFormat: apimanagement.XMLLink, + PolicyContent: utils.String(xmlLink), + } + } + + if parameters.PolicyContractProperties == nil { + return fmt.Errorf("Either `xml_content` or `xml_link` must be set") + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, productID, parameters, ""); err != nil { + return fmt.Errorf("Error creating or updating Product Policy (Resource Group %q / API Management Service %q / Product %q): %+v", resourceGroup, serviceName, productID, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, productID) + if err != nil { + return fmt.Errorf("Error retrieving Product Policy (Resource Group %q / API Management Service %q / Product %q): %+v", resourceGroup, serviceName, productID, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read ID for Product Policy (Resource Group %q / API Management Service %q / Product %q): %+v", resourceGroup, serviceName, productID, err) + } + d.SetId(*resp.ID) + + return resourceArmApiManagementProductPolicyRead(d, meta) +} + +func resourceArmApiManagementProductPolicyRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ProductPoliciesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + productID := id.Path["products"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, productID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Product Policy (Resource Group %q / API Management Service %q / Product %q) was not found - removing from state!", resourceGroup, serviceName, productID) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request for Product Policy (Resource Group %q / API Management Service %q / Product %q): %+v", resourceGroup, serviceName, productID, err) + } + + d.Set("resource_group_name", resourceGroup) + d.Set("api_management_name", serviceName) + d.Set("product_id", productID) + + if properties := resp.PolicyContractProperties; properties != nil { + // when you submit an `xml_link` to the API, the API downloads this link and stores it as `xml_content` + // as such there is no way to set `xml_link` and we'll let Terraform handle it + d.Set("xml_content", properties.PolicyContent) + } + + return nil +} + +func resourceArmApiManagementProductPolicyDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.ProductPoliciesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + productID := id.Path["products"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, productID, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting Product Policy (Resource Group %q / API Management Service %q / Product %q): %+v", resourceGroup, serviceName, productID, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_api_management_product_policy_test.go b/azurerm/resource_arm_api_management_product_policy_test.go new file mode 100644 index 000000000000..0af7e1b6384c --- /dev/null +++ b/azurerm/resource_arm_api_management_product_policy_test.go @@ -0,0 +1,250 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMApiManagementProductPolicy_basic(t *testing.T) { + resourceName := "azurerm_api_management_product_policy.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementProductPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementProductPolicy_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementProductPolicyExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"xml_link"}, + }, + }, + }) +} + +func TestAccAzureRMApiManagementProductPolicy_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_product_policy.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementProductPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementProductPolicy_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementProductPolicyExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementProductPolicy_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_product"), + }, + }, + }) +} + +func TestAccAzureRMApiManagementProductPolicy_update(t *testing.T) { + resourceName := "azurerm_api_management_product_policy.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementProductPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementProductPolicy_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementProductPolicyExists(resourceName), + ), + }, + { + Config: testAccAzureRMApiManagementProductPolicy_updated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementProductPolicyExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"xml_link"}, + }, + }, + }) +} + +func testCheckAzureRMApiManagementProductPolicyExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + productID := rs.Primary.Attributes["product_id"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ProductPoliciesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, serviceName, productID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Product Policy (API Management Service %q / Product %q/ Resource Group %q) does not exist", serviceName, productID, resourceGroup) + } + + return fmt.Errorf("Bad: Get on apiManagement.ProductPoliciesClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMApiManagementProductPolicyDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ProductPoliciesClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_product_policy" { + continue + } + + productID := rs.Primary.Attributes["product_id"] + serviceName := rs.Primary.Attributes["api_management_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, serviceName, productID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return nil + } + + return nil +} + +func testAccAzureRMApiManagementProductPolicy_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_product" "test" { + product_id = "test-product" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Test Product" + subscription_required = false + published = false +} + +resource "azurerm_api_management_product_policy" "test" { + product_id = "${azurerm_api_management_product.test.product_id}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + xml_link = "https://gist.githubusercontent.com/tombuildsstuff/4f58581599d2c9f64b236f505a361a67/raw/0d29dcb0167af1e5afe4bd52a6d7f69ba1e05e1f/example.xml" +} +`, rInt, location, rInt) +} + +func testAccAzureRMApiManagementProductPolicy_requiresImport(rInt int, location string) string { + template := testAccAzureRMApiManagementProductPolicy_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_product_policy" "import" { + product_id = "${azurerm_api_management_product_policy.test.product_id}" + api_management_name = "${azurerm_api_management_product_policy.test.api_management_name}" + resource_group_name = "${azurerm_api_management_product_policy.test.resource_group_name}" + xml_link = "${azurerm_api_management_product_policy.test.xml_link}" +} +`, template) +} + +func testAccAzureRMApiManagementProductPolicy_updated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_product" "test" { + product_id = "test-product" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Test Product" + subscription_required = false + published = false +} + +resource "azurerm_api_management_product_policy" "test" { + product_id = "${azurerm_api_management_product.test.product_id}" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + + xml_content = < + + + + +XML +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_api_management_product_test.go b/azurerm/resource_arm_api_management_product_test.go index d69efc52b3fb..d97208c74b3d 100644 --- a/azurerm/resource_arm_api_management_product_test.go +++ b/azurerm/resource_arm_api_management_product_test.go @@ -2,11 +2,13 @@ package azurerm import ( "fmt" + "regexp" "testing" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -43,7 +45,7 @@ func TestAccAzureRMApiManagementProduct_basic(t *testing.T) { } func TestAccAzureRMApiManagementProduct_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -72,7 +74,7 @@ func TestAccAzureRMApiManagementProduct_requiresImport(t *testing.T) { } func testCheckAzureRMApiManagementProductDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).apiManagementProductsClient + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ProductsClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management_product" { @@ -148,7 +150,6 @@ func TestAccAzureRMApiManagementProduct_update(t *testing.T) { Config: testAccAzureRMApiManagementProduct_basic(ri, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMApiManagementProductExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "approval_required", "false"), resource.TestCheckResourceAttr(resourceName, "description", ""), resource.TestCheckResourceAttr(resourceName, "display_name", "Test Product"), resource.TestCheckResourceAttr(resourceName, "product_id", "test-product"), @@ -222,6 +223,26 @@ func TestAccAzureRMApiManagementProduct_complete(t *testing.T) { }) } +func TestAccAzureRMApiManagementProduct_approvalRequiredError(t *testing.T) { + resourceName := "azurerm_api_management_product.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementProductDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagementProduct_approvalRequiredError(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementProductExists(resourceName)), + ExpectError: regexp.MustCompile("`subscription_required` must be true and `subscriptions_limit` must be greater than 0 to use `approval_required`"), + }, + }, + }) +} + func testCheckAzureRMApiManagementProductExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -234,7 +255,7 @@ func testCheckAzureRMApiManagementProductExists(resourceName string) resource.Te serviceName := rs.Primary.Attributes["api_management_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - conn := testAccProvider.Meta().(*ArmClient).apiManagementProductsClient + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ProductsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, serviceName, productId) if err != nil { @@ -242,7 +263,7 @@ func testCheckAzureRMApiManagementProductExists(resourceName string) resource.Te return fmt.Errorf("Bad: Product %q (API Management Service %q / Resource Group %q) does not exist", productId, serviceName, resourceGroup) } - return fmt.Errorf("Bad: Get on apiManagementProductsClient: %+v", err) + return fmt.Errorf("Bad: Get on apiManagement.ProductsClient: %+v", err) } return nil @@ -324,6 +345,7 @@ resource "azurerm_api_management_product" "test" { display_name = "Test Updated Product" subscription_required = true approval_required = true + subscriptions_limit = 1 published = true } `, rInt, location, rInt) @@ -396,3 +418,37 @@ resource "azurerm_api_management_product" "test" { } `, rInt, location, rInt) } + +func testAccAzureRMApiManagementProduct_approvalRequiredError(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_product" "test" { + product_id = "test-product" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Test Product" + approval_required = true + subscription_required = false + published = true + description = "This is an example description" + terms = "These are some example terms and conditions" +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_api_management_property.go b/azurerm/resource_arm_api_management_property.go index 6730203d607c..f3167fdeaaeb 100644 --- a/azurerm/resource_arm_api_management_property.go +++ b/azurerm/resource_arm_api_management_property.go @@ -9,6 +9,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -25,7 +26,7 @@ func resourceArmApiManagementProperty() *schema.Resource { Schema: map[string]*schema.Schema{ "name": azure.SchemaApiManagementChildName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "api_management_name": azure.SchemaApiManagementName(), @@ -59,14 +60,14 @@ func resourceArmApiManagementProperty() *schema.Resource { } func resourceArmApiManagementPropertyCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementPropertyClient + client := meta.(*ArmClient).apiManagement.PropertyClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) serviceName := d.Get("api_management_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serviceName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -88,7 +89,7 @@ func resourceArmApiManagementPropertyCreateUpdate(d *schema.ResourceData, meta i } if tags, ok := d.GetOk("tags"); ok { - parameters.PropertyContractProperties.Tags = utils.ExpandStringArray(tags.([]interface{})) + parameters.PropertyContractProperties.Tags = utils.ExpandStringSlice(tags.([]interface{})) } if _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, name, parameters, ""); err != nil { @@ -108,10 +109,10 @@ func resourceArmApiManagementPropertyCreateUpdate(d *schema.ResourceData, meta i } func resourceArmApiManagementPropertyRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementPropertyClient + client := meta.(*ArmClient).apiManagement.PropertyClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -145,10 +146,10 @@ func resourceArmApiManagementPropertyRead(d *schema.ResourceData, meta interface } func resourceArmApiManagementPropertyDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementPropertyClient + client := meta.(*ArmClient).apiManagement.PropertyClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_api_management_property_test.go b/azurerm/resource_arm_api_management_property_test.go index b93d3aed3df4..80716d77d302 100644 --- a/azurerm/resource_arm_api_management_property_test.go +++ b/azurerm/resource_arm_api_management_property_test.go @@ -81,7 +81,7 @@ func TestAccAzureRMAPIManagementProperty_update(t *testing.T) { } func testCheckAzureRMAPIManagementPropertyDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).apiManagementPropertyClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.PropertyClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management_property" { continue @@ -116,14 +116,14 @@ func testCheckAzureRMAPIManagementPropertyExists(resourceName string) resource.T resourceGroup := rs.Primary.Attributes["resource_group_name"] serviceName := rs.Primary.Attributes["api_management_name"] - client := testAccProvider.Meta().(*ArmClient).apiManagementPropertyClient + client := testAccProvider.Meta().(*ArmClient).apiManagement.PropertyClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serviceName, name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { return fmt.Errorf("Bad: API Management Property %q (Resource Group %q / API Management Service %q) does not exist", name, resourceGroup, serviceName) } - return fmt.Errorf("Bad: Get on apiManagementPropertyClient: %+v", err) + return fmt.Errorf("Bad: Get on apiManagement.PropertyClient: %+v", err) } return nil @@ -181,7 +181,7 @@ resource "azurerm_api_management" "test" { sku { name = "Developer" - capacity = 1 + capacity = 1 } } diff --git a/azurerm/resource_arm_api_management_subscription.go b/azurerm/resource_arm_api_management_subscription.go new file mode 100644 index 000000000000..efd49fd7ca5c --- /dev/null +++ b/azurerm/resource_arm_api_management_subscription.go @@ -0,0 +1,202 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/satori/uuid" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApiManagementSubscription() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApiManagementSubscriptionCreateUpdate, + Read: resourceArmApiManagementSubscriptionRead, + Update: resourceArmApiManagementSubscriptionCreateUpdate, + Delete: resourceArmApiManagementSubscriptionDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "subscription_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validate.UUIDOrEmpty, + }, + + "user_id": azure.SchemaApiManagementChildID(), + + "product_id": azure.SchemaApiManagementChildID(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "api_management_name": azure.SchemaApiManagementName(), + + "display_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "state": { + Type: schema.TypeString, + Optional: true, + Default: string(apimanagement.Submitted), + ValidateFunc: validation.StringInSlice([]string{ + string(apimanagement.Active), + string(apimanagement.Cancelled), + string(apimanagement.Expired), + string(apimanagement.Rejected), + string(apimanagement.Submitted), + string(apimanagement.Suspended), + }, false), + }, + + "primary_key": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Sensitive: true, + }, + + "secondary_key": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Sensitive: true, + }, + }, + } +} + +func resourceArmApiManagementSubscriptionCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.SubscriptionsClient + ctx := meta.(*ArmClient).StopContext + + resourceGroup := d.Get("resource_group_name").(string) + serviceName := d.Get("api_management_name").(string) + subscriptionId := d.Get("subscription_id").(string) + if subscriptionId == "" { + subscriptionId = uuid.NewV4().String() + } + + if features.ShouldResourcesBeImported() { + resp, err := client.Get(ctx, resourceGroup, serviceName, subscriptionId) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Error checking for present of existing Subscription %q (API Management Service %q / Resource Group %q): %+v", subscriptionId, serviceName, resourceGroup, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return tf.ImportAsExistsError("azurerm_api_management_subscription", *resp.ID) + } + } + + displayName := d.Get("display_name").(string) + productId := d.Get("product_id").(string) + state := d.Get("state").(string) + userId := d.Get("user_id").(string) + + params := apimanagement.SubscriptionCreateParameters{ + SubscriptionCreateParameterProperties: &apimanagement.SubscriptionCreateParameterProperties{ + DisplayName: utils.String(displayName), + ProductID: utils.String(productId), + State: apimanagement.SubscriptionState(state), + UserID: utils.String(userId), + }, + } + + if v, ok := d.GetOk("primary_key"); ok { + params.SubscriptionCreateParameterProperties.PrimaryKey = utils.String(v.(string)) + } + + if v, ok := d.GetOk("secondary_key"); ok { + params.SubscriptionCreateParameterProperties.SecondaryKey = utils.String(v.(string)) + } + + sendEmail := utils.Bool(false) + _, err := client.CreateOrUpdate(ctx, resourceGroup, serviceName, subscriptionId, params, sendEmail, "") + if err != nil { + return fmt.Errorf("Error creating/updating Subscription %q (API Management Service %q / Resource Group %q): %+v", subscriptionId, serviceName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, serviceName, subscriptionId) + if err != nil { + return fmt.Errorf("Error retrieving Subscription %q (API Management Service %q / Resource Group %q): %+v", subscriptionId, serviceName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmApiManagementSubscriptionRead(d, meta) +} + +func resourceArmApiManagementSubscriptionRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.SubscriptionsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + subscriptionId := id.Path["subscriptions"] + + resp, err := client.Get(ctx, resourceGroup, serviceName, subscriptionId) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Subscription %q was not found in API Management Service %q / Resource Group %q - removing from state!", subscriptionId, serviceName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Subscription %q (API Management Service %q / Resource Group %q): %+v", subscriptionId, serviceName, resourceGroup, err) + } + + d.Set("subscription_id", subscriptionId) + d.Set("resource_group_name", resourceGroup) + d.Set("api_management_name", serviceName) + + if props := resp.SubscriptionContractProperties; props != nil { + d.Set("display_name", props.DisplayName) + d.Set("primary_key", props.PrimaryKey) + d.Set("secondary_key", props.SecondaryKey) + d.Set("state", string(props.State)) + d.Set("product_id", props.ProductID) + d.Set("user_id", props.UserID) + } + + return nil +} + +func resourceArmApiManagementSubscriptionDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).apiManagement.SubscriptionsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serviceName := id.Path["service"] + subscriptionId := id.Path["subscriptions"] + + if resp, err := client.Delete(ctx, resourceGroup, serviceName, subscriptionId, ""); err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error removing Subscription %q (API Management Service %q / Resource Group %q): %+v", subscriptionId, serviceName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_api_management_subscription_test.go b/azurerm/resource_arm_api_management_subscription_test.go new file mode 100644 index 000000000000..50cbeb667d5d --- /dev/null +++ b/azurerm/resource_arm_api_management_subscription_test.go @@ -0,0 +1,297 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMAPIManagementSubscription_basic(t *testing.T) { + resourceName := "azurerm_api_management_subscription.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementSubscriptionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementSubscription_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementSubscriptionExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "subscription_id"), + resource.TestCheckResourceAttrSet(resourceName, "primary_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_key"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAPIManagementSubscription_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_api_management_subscription.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementSubscriptionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementSubscription_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementSubscriptionExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "subscription_id"), + resource.TestCheckResourceAttrSet(resourceName, "primary_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_key"), + ), + }, + { + Config: testAccAzureRMAPIManagementSubscription_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_api_management_subscription"), + }, + }, + }) +} + +func TestAccAzureRMAPIManagementSubscription_update(t *testing.T) { + resourceName := "azurerm_api_management_subscription.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementSubscriptionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementSubscription_update(ri, location, "submitted"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementSubscriptionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "state", "submitted"), + resource.TestCheckResourceAttrSet(resourceName, "subscription_id"), + resource.TestCheckResourceAttrSet(resourceName, "primary_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_key"), + ), + }, + { + Config: testAccAzureRMAPIManagementSubscription_update(ri, location, "active"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementSubscriptionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "state", "active"), + ), + }, + { + Config: testAccAzureRMAPIManagementSubscription_update(ri, location, "suspended"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementSubscriptionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "state", "suspended"), + ), + }, + { + Config: testAccAzureRMAPIManagementSubscription_update(ri, location, "cancelled"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementSubscriptionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "state", "cancelled"), + ), + }, + }, + }) +} + +func TestAccAzureRMAPIManagementSubscription_complete(t *testing.T) { + resourceName := "azurerm_api_management_subscription.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAPIManagementSubscriptionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAPIManagementSubscription_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAPIManagementSubscriptionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "state", "active"), + resource.TestCheckResourceAttrSet(resourceName, "subscription_id"), + resource.TestCheckResourceAttrSet(resourceName, "primary_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_key"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMAPIManagementSubscriptionDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).apiManagement.SubscriptionsClient + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_api_management_subscription" { + continue + } + + subscriptionId := rs.Primary.Attributes["subscription_id"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, serviceName, subscriptionId) + + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + } + return nil +} + +func testCheckAzureRMAPIManagementSubscriptionExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + subscriptionId := rs.Primary.Attributes["subscription_id"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serviceName := rs.Primary.Attributes["api_management_name"] + + client := testAccProvider.Meta().(*ArmClient).apiManagement.SubscriptionsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, serviceName, subscriptionId) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Subscription %q (API Management Service %q / Resource Group %q) does not exist", subscriptionId, serviceName, resourceGroup) + } + return fmt.Errorf("Bad: Get on apiManagement.SubscriptionsClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMAPIManagementSubscription_basic(rInt int, location string) string { + template := testAccAzureRMAPIManagementSubscription_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_subscription" "test" { + resource_group_name = "${azurerm_api_management.test.resource_group_name}" + api_management_name = "${azurerm_api_management.test.name}" + user_id = "${azurerm_api_management_user.test.id}" + product_id = "${azurerm_api_management_product.test.id}" + display_name = "Butter Parser API Enterprise Edition" +} +`, template) +} + +func testAccAzureRMAPIManagementSubscription_requiresImport(rInt int, location string) string { + template := testAccAzureRMAPIManagementSubscription_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_subscription" "import" { + resource_group_name = "${azurerm_api_management_subscription.test.resource_group_name}" + api_management_name = "${azurerm_api_management_subscription.test.api_management_name}" + user_id = "${azurerm_api_management_subscription.test.user_id}" + product_id = "${azurerm_api_management_subscription.test.product_id}" + display_name = "${azurerm_api_management_subscription.test.display_name}" +} +`, template) +} + +func testAccAzureRMAPIManagementSubscription_update(rInt int, location, state string) string { + template := testAccAzureRMAPIManagementSubscription_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_subscription" "test" { + resource_group_name = "${azurerm_api_management.test.resource_group_name}" + api_management_name = "${azurerm_api_management.test.name}" + user_id = "${azurerm_api_management_user.test.id}" + product_id = "${azurerm_api_management_product.test.id}" + display_name = "Butter Parser API Enterprise Edition" + state = "%s" +} +`, template, state) +} + +func testAccAzureRMAPIManagementSubscription_complete(rInt int, location string) string { + template := testAccAzureRMAPIManagementSubscription_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_subscription" "test" { + resource_group_name = "${azurerm_api_management.test.resource_group_name}" + api_management_name = "${azurerm_api_management.test.name}" + user_id = "${azurerm_api_management_user.test.id}" + product_id = "${azurerm_api_management_product.test.id}" + display_name = "Butter Parser API Enterprise Edition" + state = "active" +} +`, template) +} + +func testAccAzureRMAPIManagementSubscription_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_product" "test" { + product_id = "test-product" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + display_name = "Test Product" + subscription_required = true + approval_required = false + published = true +} + +resource "azurerm_api_management_user" "test" { + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test" + email = "azure-acctest%d@example.com" +} +`, rInt, location, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_api_management_test.go b/azurerm/resource_arm_api_management_test.go index 7dd0a045eb68..8256b254c467 100644 --- a/azurerm/resource_arm_api_management_test.go +++ b/azurerm/resource_arm_api_management_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMApiManagement_basic(t *testing.T) { } func TestAccAzureRMApiManagement_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -92,7 +93,7 @@ func TestAccAzureRMApiManagement_customProps(t *testing.T) { func TestAccAzureRMApiManagement_complete(t *testing.T) { resourceName := "azurerm_api_management.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMApiManagement_complete(ri, testLocation(), testAltLocation()) + config := testAccAzureRMApiManagement_complete(ri, testLocation(), testAltLocation(), testAltLocation2()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -125,8 +126,81 @@ func TestAccAzureRMApiManagement_complete(t *testing.T) { }) } +func TestAccAzureRMApiManagement_signInSignUpSettings(t *testing.T) { + resourceName := "azurerm_api_management.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagement_signInSignUpSettings(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApiManagement_policy(t *testing.T) { + resourceName := "azurerm_api_management.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApiManagementDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApiManagement_policyXmlContent(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMApiManagement_policyXmlLink(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"policy.0.xml_link"}, + }, + { + Config: testAccAzureRMApiManagement_policyRemoved(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApiManagementExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMApiManagementDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).apiManagementServiceClient + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ServiceClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management" { @@ -166,7 +240,7 @@ func testCheckAzureRMApiManagementExists(resourceName string) resource.TestCheck return fmt.Errorf("Bad: no resource group found in state for Api Management: %s", apiMangementName) } - conn := testAccProvider.Meta().(*ArmClient).apiManagementServiceClient + conn := testAccProvider.Meta().(*ArmClient).apiManagement.ServiceClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, apiMangementName) if err != nil { @@ -203,6 +277,88 @@ resource "azurerm_api_management" "test" { `, rInt, location, rInt) } +func testAccAzureRMApiManagement_policyXmlContent(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } + + policy { + xml_content = < + + + + +XML + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMApiManagement_policyXmlLink(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } + + policy { + xml_link = "https://gist.githubusercontent.com/tombuildsstuff/4f58581599d2c9f64b236f505a361a67/raw/0d29dcb0167af1e5afe4bd52a6d7f69ba1e05e1f/example.xml" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMApiManagement_policyRemoved(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } + + policy = [] +} +`, rInt, location, rInt) +} + func testAccAzureRMApiManagement_requiresImport(rInt int, location string) string { template := testAccAzureRMApiManagement_basic(rInt, location) return fmt.Sprintf(` @@ -244,13 +400,49 @@ resource "azurerm_api_management" "test" { security { disable_frontend_tls10 = true - disable_triple_des_chipers = true + disable_triple_des_ciphers = true + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMApiManagement_signInSignUpSettings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } + + sign_in { + enabled = true + } + + sign_up { + enabled = true + + terms_of_service { + enabled = true + consent_required = false + text = "Lorem Ipsum Dolor Morty" + } } } `, rInt, location, rInt) } -func testAccAzureRMApiManagement_complete(rInt int, location string, altLocation string) string { +func testAccAzureRMApiManagement_complete(rInt int, location string, altLocation string, altLocation2 string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test1" { name = "acctestRG-%d" @@ -262,6 +454,11 @@ resource "azurerm_resource_group" "test2" { location = "%s" } +resource "azurerm_resource_group" "test3" { + name = "acctestRG3-%d" + location = "%s" +} + resource "azurerm_api_management" "test" { name = "acctestAM-%d" publisher_name = "pub1" @@ -272,26 +469,31 @@ resource "azurerm_api_management" "test" { location = "${azurerm_resource_group.test2.location}" } + additional_location { + location = "${azurerm_resource_group.test3.location}" + } + certificate { - encoded_certificate = "${base64encode(file("testdata/api_management_api_test.pfx"))}" + encoded_certificate = "${filebase64("testdata/api_management_api_test.pfx")}" certificate_password = "terraform" store_name = "CertificateAuthority" } certificate { - encoded_certificate = "${base64encode(file("testdata/api_management_api_test.pfx"))}" + encoded_certificate = "${filebase64("testdata/api_management_api_test.pfx")}" certificate_password = "terraform" store_name = "Root" } security { - disable_backend_tls11 = true + disable_backend_tls11 = true + disable_triple_des_ciphers = true } hostname_configuration { proxy { host_name = "api.terraform.io" - certificate = "${base64encode(file("testdata/api_management_api_test.pfx"))}" + certificate = "${filebase64("testdata/api_management_api_test.pfx")}" certificate_password = "terraform" default_ssl_binding = true negotiate_client_certificate = false @@ -299,14 +501,14 @@ resource "azurerm_api_management" "test" { proxy { host_name = "api2.terraform.io" - certificate = "${base64encode(file("testdata/api_management_api2_test.pfx"))}" + certificate = "${filebase64("testdata/api_management_api2_test.pfx")}" certificate_password = "terraform" negotiate_client_certificate = true } portal { host_name = "portal.terraform.io" - certificate = "${base64encode(file("testdata/api_management_portal_test.pfx"))}" + certificate = "${filebase64("testdata/api_management_portal_test.pfx")}" certificate_password = "terraform" } } @@ -323,5 +525,5 @@ resource "azurerm_api_management" "test" { location = "${azurerm_resource_group.test1.location}" resource_group_name = "${azurerm_resource_group.test1.name}" } -`, rInt, location, rInt, altLocation, rInt) +`, rInt, location, rInt, altLocation, rInt, altLocation2, rInt) } diff --git a/azurerm/resource_arm_api_management_user.go b/azurerm/resource_arm_api_management_user.go index 5fef2c29a93e..c416d4d3f00f 100644 --- a/azurerm/resource_arm_api_management_user.go +++ b/azurerm/resource_arm_api_management_user.go @@ -10,6 +10,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -28,7 +29,7 @@ func resourceArmApiManagementUser() *schema.Resource { "api_management_name": azure.SchemaApiManagementName(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "first_name": { Type: schema.TypeString, @@ -84,7 +85,7 @@ func resourceArmApiManagementUser() *schema.Resource { } func resourceArmApiManagementUserCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementUsersClient + client := meta.(*ArmClient).apiManagement.UsersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for API Management User creation.") @@ -100,7 +101,7 @@ func resourceArmApiManagementUserCreateUpdate(d *schema.ResourceData, meta inter note := d.Get("note").(string) password := d.Get("password").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serviceName, userId) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -154,10 +155,10 @@ func resourceArmApiManagementUserCreateUpdate(d *schema.ResourceData, meta inter } func resourceArmApiManagementUserRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementUsersClient + client := meta.(*ArmClient).apiManagement.UsersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -193,10 +194,10 @@ func resourceArmApiManagementUserRead(d *schema.ResourceData, meta interface{}) } func resourceArmApiManagementUserDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).apiManagementUsersClient + client := meta.(*ArmClient).apiManagement.UsersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_api_management_user_test.go b/azurerm/resource_arm_api_management_user_test.go index 6fa655c423f5..8327ae2e0f8e 100644 --- a/azurerm/resource_arm_api_management_user_test.go +++ b/azurerm/resource_arm_api_management_user_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +39,7 @@ func TestAccAzureRMApiManagementUser_basic(t *testing.T) { } func TestAccAzureRMApiManagementUser_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -226,7 +227,7 @@ func TestAccAzureRMApiManagementUser_complete(t *testing.T) { } func testCheckAzureRMApiManagementUserDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).apiManagementUsersClient + conn := testAccProvider.Meta().(*ArmClient).apiManagement.UsersClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_api_management_user" { @@ -264,7 +265,7 @@ func testCheckAzureRMApiManagementUserExists(resourceName string) resource.TestC serviceName := rs.Primary.Attributes["api_management_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - conn := testAccProvider.Meta().(*ArmClient).apiManagementUsersClient + conn := testAccProvider.Meta().(*ArmClient).apiManagement.UsersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, serviceName, userId) if err != nil { @@ -272,7 +273,7 @@ func testCheckAzureRMApiManagementUserExists(resourceName string) resource.TestC return fmt.Errorf("Bad: User %q (API Management Service %q / Resource Group %q) does not exist", userId, serviceName, resourceGroup) } - return fmt.Errorf("Bad: Get on apiManagementUsersClient: %+v", err) + return fmt.Errorf("Bad: Get on apiManagement.UsersClient: %+v", err) } return nil @@ -285,12 +286,12 @@ func testAccAzureRMApiManagementUser_basic(rInt int, location string) string { %s resource "azurerm_api_management_user" "test" { - user_id = "acctestuser%d" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance" - last_name = "Test" - email = "azure-acctest%d@example.com" + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test" + email = "azure-acctest%d@example.com" } `, template, rInt, rInt) } @@ -301,13 +302,13 @@ func testAccAzureRMApiManagementUser_requiresImport(rInt int, location string) s %s resource "azurerm_api_management_user" "import" { - user_id = "${azurerm_api_management_user.test.user_id}" - api_management_name = "${azurerm_api_management_user.test.api_management_name}" - resource_group_name = "${azurerm_api_management_user.test.resource_group_name}" - first_name = "${azurerm_api_management_user.test.first_name}" - last_name = "${azurerm_api_management_user.test.last_name}" - email = "${azurerm_api_management_user.test.email}" - state = "${azurerm_api_management_user.test.state}" + user_id = "${azurerm_api_management_user.test.user_id}" + api_management_name = "${azurerm_api_management_user.test.api_management_name}" + resource_group_name = "${azurerm_api_management_user.test.resource_group_name}" + first_name = "${azurerm_api_management_user.test.first_name}" + last_name = "${azurerm_api_management_user.test.last_name}" + email = "${azurerm_api_management_user.test.email}" + state = "${azurerm_api_management_user.test.state}" } `, template) } @@ -318,14 +319,14 @@ func testAccAzureRMApiManagementUser_password(rInt int, location string) string %s resource "azurerm_api_management_user" "test" { - user_id = "acctestuser%d" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance" - last_name = "Test" - email = "azure-acctest%d@example.com" - state = "active" - password = "3991bb15-282d-4b9b-9de3-3d5fc89eb530" + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test" + email = "azure-acctest%d@example.com" + state = "active" + password = "3991bb15-282d-4b9b-9de3-3d5fc89eb530" } `, template, rInt, rInt) } @@ -336,13 +337,13 @@ func testAccAzureRMApiManagementUser_updatedActive(rInt int, location string) st %s resource "azurerm_api_management_user" "test" { - user_id = "acctestuser%d" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance" - last_name = "Test" - email = "azure-acctest%d@example.com" - state = "active" + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test" + email = "azure-acctest%d@example.com" + state = "active" } `, template, rInt, rInt) } @@ -353,13 +354,13 @@ func testAccAzureRMApiManagementUser_updatedBlocked(rInt int, location string) s %s resource "azurerm_api_management_user" "test" { - user_id = "acctestuser%d" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance Updated" - last_name = "Test Updated" - email = "azure-acctest%d@example.com" - state = "blocked" + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance Updated" + last_name = "Test Updated" + email = "azure-acctest%d@example.com" + state = "blocked" } `, template, rInt, rInt) } @@ -370,14 +371,14 @@ func testAccAzureRMApiManagementUser_invited(rInt int, location string) string { %s resource "azurerm_api_management_user" "test" { - user_id = "acctestuser%d" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance" - last_name = "Test User" - email = "azure-acctest%d@example.com" - state = "blocked" - confirmation = "invite" + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test User" + email = "azure-acctest%d@example.com" + state = "blocked" + confirmation = "invite" } `, template, rInt, rInt) } @@ -388,14 +389,14 @@ func testAccAzureRMApiManagementUser_signUp(rInt int, location string) string { %s resource "azurerm_api_management_user" "test" { - user_id = "acctestuser%d" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance" - last_name = "Test User" - email = "azure-acctest%d@example.com" - state = "blocked" - confirmation = "signup" + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test User" + email = "azure-acctest%d@example.com" + state = "blocked" + confirmation = "signup" } `, template, rInt, rInt) } @@ -406,15 +407,15 @@ func testAccAzureRMApiManagementUser_complete(rInt int, location string) string %s resource "azurerm_api_management_user" "test" { - user_id = "acctestuser%d" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Acceptance" - last_name = "Test" - email = "azure-acctest%d@example.com" - state = "active" - confirmation = "signup" - note = "Used for testing in dimension C-137." + user_id = "acctestuser%d" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Acceptance" + last_name = "Test" + email = "azure-acctest%d@example.com" + state = "active" + confirmation = "signup" + note = "Used for testing in dimension C-137." } `, template, rInt, rInt) } diff --git a/azurerm/resource_arm_app_service.go b/azurerm/resource_arm_app_service.go index 9ce16fa39632..ce1c63edd56f 100644 --- a/azurerm/resource_arm_app_service.go +++ b/azurerm/resource_arm_app_service.go @@ -9,7 +9,10 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -31,36 +34,11 @@ func resourceArmAppService() *schema.Resource { ValidateFunc: validateAppServiceName, }, - "identity": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, - ValidateFunc: validation.StringInSlice([]string{ - "SystemAssigned", - }, true), - }, - "principal_id": { - Type: schema.TypeString, - Computed: true, - }, - "tenant_id": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, + "identity": azure.SchemaAppServiceIdentity(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "app_service_plan_id": { Type: schema.TypeString, @@ -69,6 +47,12 @@ func resourceArmAppService() *schema.Resource { "site_config": azure.SchemaAppServiceSiteConfig(), + "auth_settings": azure.SchemaAppServiceAuthSettings(), + + "logs": azure.SchemaAppServiceLogsConfig(), + + "backup": azure.SchemaAppServiceBackup(), + "client_affinity_enabled": { Type: schema.TypeBool, Optional: true, @@ -98,6 +82,8 @@ func resourceArmAppService() *schema.Resource { Computed: true, }, + "storage_account": azure.SchemaAppServiceStorageAccounts(), + "connection_string": { Type: schema.TypeSet, Optional: true, @@ -129,13 +115,13 @@ func resourceArmAppService() *schema.Resource { string(web.SQLAzure), string(web.SQLServer), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), "site_credential": { Type: schema.TypeList, @@ -191,7 +177,7 @@ func resourceArmAppService() *schema.Resource { } func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM App Service creation.") @@ -199,7 +185,7 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -225,27 +211,30 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("The name %q used for the App Service needs to be globally unique and isn't available: %s", name, *available.Message) } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) appServicePlanId := d.Get("app_service_plan_id").(string) enabled := d.Get("enabled").(bool) httpsOnly := d.Get("https_only").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + siteConfig, err := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + if err != nil { + return fmt.Errorf("Error expanding `site_config` for App Service %q (Resource Group %q): %s", name, resGroup, err) + } siteEnvelope := web.Site{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), SiteProperties: &web.SiteProperties{ ServerFarmID: utils.String(appServicePlanId), Enabled: utils.Bool(enabled), HTTPSOnly: utils.Bool(httpsOnly), - SiteConfig: &siteConfig, + SiteConfig: siteConfig, }, } if _, ok := d.GetOk("identity"); ok { - appServiceIdentity := expandAzureRmAppServiceIdentity(d) + appServiceIdentity := azure.ExpandAppServiceIdentity(d) siteEnvelope.Identity = appServiceIdentity } @@ -261,17 +250,17 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error createFuture, err := client.CreateOrUpdate(ctx, resGroup, name, siteEnvelope) if err != nil { - return err + return fmt.Errorf("Error creating App Service %q (Resource Group %q): %s", name, resGroup, err) } err = createFuture.WaitForCompletionRef(ctx, client.Client) if err != nil { - return err + return fmt.Errorf("Error waiting for App Service %q (Resource Group %q) to be created: %s", name, resGroup, err) } read, err := client.Get(ctx, resGroup, name) if err != nil { - return err + return fmt.Errorf("Error retrieving App Service %q (Resource Group %q): %s", name, resGroup, err) } if read.ID == nil { return fmt.Errorf("Cannot read App Service %q (resource group %q) ID", name, resGroup) @@ -279,14 +268,43 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error d.SetId(*read.ID) + authSettingsRaw := d.Get("auth_settings").([]interface{}) + authSettings := azure.ExpandAppServiceAuthSettings(authSettingsRaw) + + auth := web.SiteAuthSettings{ + ID: read.ID, + SiteAuthSettingsProperties: &authSettings} + + if _, err := client.UpdateAuthSettings(ctx, resGroup, name, auth); err != nil { + return fmt.Errorf("Error updating auth settings for App Service %q (Resource Group %q): %+s", name, resGroup, err) + } + + logsConfig := azure.ExpandAppServiceLogs(d.Get("logs")) + + logs := web.SiteLogsConfig{ + ID: read.ID, + SiteLogsConfigProperties: &logsConfig} + + if _, err := client.UpdateDiagnosticLogsConfig(ctx, resGroup, name, logs); err != nil { + return fmt.Errorf("Error updating diagnostic logs config for App Service %q (Resource Group %q): %+s", name, resGroup, err) + } + + backupRaw := d.Get("backup").([]interface{}) + if backup := azure.ExpandAppServiceBackup(backupRaw); backup != nil { + _, err = client.UpdateBackupConfiguration(ctx, resGroup, name, *backup) + if err != nil { + return fmt.Errorf("Error updating Backup Settings for App Service %q (Resource Group %q): %s", name, resGroup, err) + } + } + return resourceArmAppServiceUpdate(d, meta) } func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -294,21 +312,26 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error resGroup := id.ResourceGroup name := id.Path["sites"] - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) + appServicePlanId := d.Get("app_service_plan_id").(string) enabled := d.Get("enabled").(bool) httpsOnly := d.Get("https_only").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) + + siteConfig, err := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + if err != nil { + return fmt.Errorf("Error expanding `site_config` for App Service %q (Resource Group %q): %s", name, resGroup, err) + } - siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) siteEnvelope := web.Site{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), SiteProperties: &web.SiteProperties{ ServerFarmID: utils.String(appServicePlanId), Enabled: utils.Bool(enabled), HTTPSOnly: utils.Bool(httpsOnly), - SiteConfig: &siteConfig, + SiteConfig: siteConfig, }, } @@ -328,9 +351,12 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error if d.HasChange("site_config") { // update the main configuration - siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + siteConfig, err := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + if err != nil { + return fmt.Errorf("Error expanding `site_config` for App Service %q (Resource Group %q): %s", name, resGroup, err) + } siteConfigResource := web.SiteConfigResource{ - SiteConfig: &siteConfig, + SiteConfig: siteConfig, } if _, err := client.CreateOrUpdateConfiguration(ctx, resGroup, name, siteConfigResource); err != nil { @@ -338,6 +364,48 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error } } + if d.HasChange("auth_settings") { + authSettingsRaw := d.Get("auth_settings").([]interface{}) + authSettingsProperties := azure.ExpandAppServiceAuthSettings(authSettingsRaw) + id := d.Id() + authSettings := web.SiteAuthSettings{ + ID: &id, + SiteAuthSettingsProperties: &authSettingsProperties, + } + + if _, err := client.UpdateAuthSettings(ctx, resGroup, name, authSettings); err != nil { + return fmt.Errorf("Error updating Authentication Settings for App Service %q: %+v", name, err) + } + } + + if d.HasChange("logs") { + logs := azure.ExpandAppServiceLogs(d.Get("logs")) + id := d.Id() + logsResource := web.SiteLogsConfig{ + ID: &id, + SiteLogsConfigProperties: &logs, + } + + if _, err := client.UpdateDiagnosticLogsConfig(ctx, resGroup, name, logsResource); err != nil { + return fmt.Errorf("Error updating Diagnostics Logs for App Service %q: %+v", name, err) + } + } + + if d.HasChange("backup") { + backupRaw := d.Get("backup").([]interface{}) + if backup := azure.ExpandAppServiceBackup(backupRaw); backup != nil { + _, err = client.UpdateBackupConfiguration(ctx, resGroup, name, *backup) + if err != nil { + return fmt.Errorf("Error updating Backup Settings for App Service %q (Resource Group %q): %s", name, resGroup, err) + } + } else { + _, err = client.DeleteBackupConfiguration(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error removing Backup Settings for App Service %q (Resource Group %q): %s", name, resGroup, err) + } + } + } + if d.HasChange("client_affinity_enabled") { affinity := d.Get("client_affinity_enabled").(bool) @@ -366,6 +434,17 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error } } + if d.HasChange("storage_account") { + storageAccounts := azure.ExpandAppServiceStorageAccounts(d) + properties := web.AzureStoragePropertyDictionaryResource{ + Properties: storageAccounts, + } + + if _, err := client.UpdateAzureStorageAccounts(ctx, resGroup, name, properties); err != nil { + return fmt.Errorf("Error updating Storage Accounts for App Service %q: %+v", name, err) + } + } + if d.HasChange("connection_string") { // update the ConnectionStrings connectionStrings := expandAppServiceConnectionStrings(d) @@ -384,7 +463,7 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error getting configuration for App Service %q: %+v", name, err) } - appServiceIdentity := expandAzureRmAppServiceIdentity(d) + appServiceIdentity := azure.ExpandAppServiceIdentity(d) site.Identity = appServiceIdentity future, err := client.CreateOrUpdate(ctx, resGroup, name, site) @@ -402,9 +481,9 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error } func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -425,14 +504,46 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { configResp, err := client.GetConfiguration(ctx, resGroup, name) if err != nil { + if utils.ResponseWasNotFound(configResp.Response) { + log.Printf("[DEBUG] Configuration of App Service %q (resource group %q) was not found", name, resGroup) + d.SetId("") + return nil + } return fmt.Errorf("Error making Read request on AzureRM App Service Configuration %q: %+v", name, err) } + authResp, err := client.GetAuthSettings(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving the AuthSettings for App Service %q (Resource Group %q): %+v", name, resGroup, err) + } + + backupResp, err := client.GetBackupConfiguration(ctx, resGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(backupResp.Response) { + return fmt.Errorf("Error retrieving the BackupConfiguration for App Service %q (Resource Group %q): %+v", name, resGroup, err) + } + } + + logsResp, err := client.GetDiagnosticLogsConfiguration(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving the DiagnosticsLogsConfiguration for App Service %q (Resource Group %q): %+v", name, resGroup, err) + } + appSettingsResp, err := client.ListApplicationSettings(ctx, resGroup, name) if err != nil { + if utils.ResponseWasNotFound(appSettingsResp.Response) { + log.Printf("[DEBUG] Application Settings of App Service %q (resource group %q) were not found", name, resGroup) + d.SetId("") + return nil + } return fmt.Errorf("Error making Read request on AzureRM App Service AppSettings %q: %+v", name, err) } + storageAccountsResp, err := client.ListAzureStorageAccounts(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error making Read request on AzureRM App Service Storage Accounts %q: %+v", name, err) + } + connectionStringsResp, err := client.ListConnectionStrings(ctx, resGroup, name) if err != nil { return fmt.Errorf("Error making Read request on AzureRM App Service ConnectionStrings %q: %+v", name, err) @@ -451,7 +562,7 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { if err != nil { return err } - siteCredResp, err := siteCredFuture.Result(client) + siteCredResp, err := siteCredFuture.Result(*client) if err != nil { return fmt.Errorf("Error making Read request on AzureRM App Service Site Credential %q: %+v", name, err) } @@ -459,7 +570,7 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.SiteProperties; props != nil { @@ -473,12 +584,26 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { d.Set("possible_outbound_ip_addresses", props.PossibleOutboundIPAddresses) } - if err := d.Set("app_settings", flattenAppServiceAppSettings(appSettingsResp.Properties)); err != nil { - return err + appSettings := flattenAppServiceAppSettings(appSettingsResp.Properties) + + // remove DIAGNOSTICS* settings - Azure will sync these, so just maintain the logs block equivalents in the state + delete(appSettings, "DIAGNOSTICS_AZUREBLOBCONTAINERSASURL") + delete(appSettings, "DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS") + + if err := d.Set("app_settings", appSettings); err != nil { + return fmt.Errorf("Error setting `app_settings`: %s", err) + } + + if err := d.Set("backup", azure.FlattenAppServiceBackup(backupResp.BackupRequestProperties)); err != nil { + return fmt.Errorf("Error setting `backup`: %s", err) + } + + if err := d.Set("storage_account", azure.FlattenAppServiceStorageAccounts(storageAccountsResp.Properties)); err != nil { + return fmt.Errorf("Error setting `storage_account`: %s", err) } if err := d.Set("connection_string", flattenAppServiceConnectionStrings(connectionStringsResp.Properties)); err != nil { - return err + return fmt.Errorf("Error setting `connection_string`: %s", err) } siteConfig := azure.FlattenAppServiceSiteConfig(configResp.SiteConfig) @@ -486,30 +611,38 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error { return err } + authSettings := azure.FlattenAppServiceAuthSettings(authResp.SiteAuthSettingsProperties) + if err := d.Set("auth_settings", authSettings); err != nil { + return fmt.Errorf("Error setting `auth_settings`: %s", err) + } + + logs := azure.FlattenAppServiceLogs(logsResp.SiteLogsConfigProperties) + if err := d.Set("logs", logs); err != nil { + return fmt.Errorf("Error setting `logs`: %s", err) + } + scm := flattenAppServiceSourceControl(scmResp.SiteSourceControlProperties) if err := d.Set("source_control", scm); err != nil { - return err + return fmt.Errorf("Error setting `source_control`: %s", err) } siteCred := flattenAppServiceSiteCredential(siteCredResp.UserProperties) if err := d.Set("site_credential", siteCred); err != nil { - return err + return fmt.Errorf("Error setting `site_credential`: %s", err) } - identity := flattenAzureRmAppServiceMachineIdentity(resp.Identity) + identity := azure.FlattenAppServiceIdentity(resp.Identity) if err := d.Set("identity", identity); err != nil { - return err + return fmt.Errorf("Error setting `identity`: %s", err) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmAppServiceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -608,33 +741,6 @@ func flattenAppServiceAppSettings(input map[string]*string) map[string]string { return output } -func expandAzureRmAppServiceIdentity(d *schema.ResourceData) *web.ManagedServiceIdentity { - identities := d.Get("identity").([]interface{}) - identity := identities[0].(map[string]interface{}) - identityType := identity["type"].(string) - return &web.ManagedServiceIdentity{ - Type: web.ManagedServiceIdentityType(identityType), - } -} - -func flattenAzureRmAppServiceMachineIdentity(identity *web.ManagedServiceIdentity) []interface{} { - if identity == nil { - return make([]interface{}, 0) - } - - result := make(map[string]interface{}) - result["type"] = string(identity.Type) - - if identity.PrincipalID != nil { - result["principal_id"] = *identity.PrincipalID - } - if identity.TenantID != nil { - result["tenant_id"] = *identity.TenantID - } - - return []interface{}{result} -} - func validateAppServiceName(v interface{}, k string) (warnings []string, errors []error) { value := v.(string) diff --git a/azurerm/resource_arm_app_service_active_slot.go b/azurerm/resource_arm_app_service_active_slot.go index 18621a8aaa3b..0d080fe18068 100644 --- a/azurerm/resource_arm_app_service_active_slot.go +++ b/azurerm/resource_arm_app_service_active_slot.go @@ -6,6 +6,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -20,7 +21,7 @@ func resourceArmAppServiceActiveSlot() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "app_service_name": { Type: schema.TypeString, @@ -37,7 +38,7 @@ func resourceArmAppServiceActiveSlot() *schema.Resource { } func resourceArmAppServiceActiveSlotCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext appServiceName := d.Get("app_service_name").(string) @@ -78,10 +79,10 @@ func resourceArmAppServiceActiveSlotCreateUpdate(d *schema.ResourceData, meta in } func resourceArmAppServiceActiveSlotRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_app_service_certificate.go b/azurerm/resource_arm_app_service_certificate.go new file mode 100644 index 000000000000..320f7e625fa0 --- /dev/null +++ b/azurerm/resource_arm_app_service_certificate.go @@ -0,0 +1,258 @@ +package azurerm + +import ( + "encoding/base64" + "fmt" + "log" + "time" + + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmAppServiceCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAppServiceCertificateCreateUpdate, + Read: resourceArmAppServiceCertificateRead, + Update: resourceArmAppServiceCertificateCreateUpdate, + Delete: resourceArmAppServiceCertificateDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "location": azure.SchemaLocation(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "pfx_blob": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ForceNew: true, + ValidateFunc: validate.Base64String(), + }, + + "password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ForceNew: true, + ValidateFunc: validation.NoZeroValues, + }, + + "key_vault_secret_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: azure.ValidateKeyVaultChildId, + ConflictsWith: []string{"pfx_blob", "password"}, + }, + + "friendly_name": { + Type: schema.TypeString, + Computed: true, + }, + + "subject_name": { + Type: schema.TypeString, + Computed: true, + }, + + "host_names": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "issuer": { + Type: schema.TypeString, + Computed: true, + }, + + "issue_date": { + Type: schema.TypeString, + Computed: true, + }, + + "expiration_date": { + Type: schema.TypeString, + Computed: true, + }, + + "thumbprint": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmAppServiceCertificateCreateUpdate(d *schema.ResourceData, meta interface{}) error { + vaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).web.CertificatesClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for App Service Certificate creation.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + pfxBlob := d.Get("pfx_blob").(string) + password := d.Get("password").(string) + keyVaultSecretId := d.Get("key_vault_secret_id").(string) + t := d.Get("tags").(map[string]interface{}) + + if pfxBlob == "" && keyVaultSecretId == "" { + return fmt.Errorf("Either `pfx_blob` or `key_vault_secret_id` must be set") + } + + if requireResourcesToBeImported && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing App Service Certificate %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_app_service_certificate", *existing.ID) + } + } + + certificate := web.Certificate{ + CertificateProperties: &web.CertificateProperties{ + Password: utils.String(password), + }, + Location: utils.String(location), + Tags: tags.Expand(t), + } + + if pfxBlob != "" { + decodedPfxBlob, err := base64.StdEncoding.DecodeString(pfxBlob) + if err != nil { + return fmt.Errorf("Could not decode PFX blob: %+v", err) + } + certificate.CertificateProperties.PfxBlob = &decodedPfxBlob + } + + if keyVaultSecretId != "" { + parsedSecretId, err := azure.ParseKeyVaultChildID(keyVaultSecretId) + if err != nil { + return err + } + + keyVaultBaseUrl := parsedSecretId.KeyVaultBaseUrl + + keyVaultId, err := azure.GetKeyVaultIDFromBaseUrl(ctx, vaultClient, keyVaultBaseUrl) + if err != nil { + return fmt.Errorf("Error retrieving the Resource ID for the Key Vault at URL %q: %s", keyVaultBaseUrl, err) + } + if keyVaultId == nil { + return fmt.Errorf("Unable to determine the Resource ID for the Key Vault at URL %q", keyVaultBaseUrl) + } + + certificate.CertificateProperties.KeyVaultID = keyVaultId + certificate.CertificateProperties.KeyVaultSecretName = utils.String(parsedSecretId.Name) + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, name, certificate); err != nil { + return fmt.Errorf("Error creating/updating App Service Certificate %q (Resource Group %q): %s", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving App Service Certificate %q (Resource Group %q): %s", name, resourceGroup, err) + } + if read.ID == nil { + return fmt.Errorf("Cannot read App Service Certificate %q (Resource Group %q) ID", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmAppServiceCertificateRead(d, meta) +} + +func resourceArmAppServiceCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).web.CertificatesClient + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["certificates"] + + ctx := meta.(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] App Service Certificate %q (Resource Group %q) was not found - removing from state", name, resourceGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on App Service Certificate %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.CertificateProperties; props != nil { + d.Set("friendly_name", props.FriendlyName) + d.Set("subject_name", props.SubjectName) + d.Set("host_names", props.HostNames) + d.Set("issuer", props.Issuer) + d.Set("issue_date", props.IssueDate.Format(time.RFC3339)) + d.Set("expiration_date", props.ExpirationDate.Format(time.RFC3339)) + d.Set("thumbprint", props.Thumbprint) + } + + flattenAndSetTags(d, resp.Tags) + + return nil +} + +func resourceArmAppServiceCertificateDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).web.CertificatesClient + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["certificates"] + + log.Printf("[DEBUG] Deleting App Service Certificate %q (Resource Group %q)", name, resourceGroup) + + ctx := meta.(*ArmClient).StopContext + resp, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Error deleting App Service Certificate %q (Resource Group %q): %s)", name, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_app_service_certificate_test.go b/azurerm/resource_arm_app_service_certificate_test.go new file mode 100644 index 000000000000..d28e419a4bb6 --- /dev/null +++ b/azurerm/resource_arm_app_service_certificate_test.go @@ -0,0 +1,227 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMAppServiceCertificate_Pfx(t *testing.T) { + resourceName := "azurerm_app_service_certificate.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + config := testAccAzureRMAppServiceCertificatePfx(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "password", "terraform"), + resource.TestCheckResourceAttr(resourceName, "thumbprint", "7B985BF42467791F23E52B364A3E8DEBAB9C606E"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"pfx_blob", "password"}, + }, + }, + }) +} + +func TestAccAzureRMAppServiceCertificate_PfxNoPassword(t *testing.T) { + resourceName := "azurerm_app_service_certificate.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + config := testAccAzureRMAppServiceCertificatePfxNoPassword(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "thumbprint", "7B985BF42467791F23E52B364A3E8DEBAB9C606E"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"pfx_blob"}, + }, + }, + }) +} + +func TestAccAzureRMAppServiceCertificate_KeyVault(t *testing.T) { + resourceName := "azurerm_app_service_certificate.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + config := testAccAzureRMAppServiceCertificateKeyVault(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "thumbprint", "7B985BF42467791F23E52B364A3E8DEBAB9C606E"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"key_vault_secret_id"}, + }, + }, + }) +} + +func testAccAzureRMAppServiceCertificatePfx(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestwebcert%d" + location = "%s" +} + +resource "azurerm_app_service_certificate" "test" { + name = "acctest%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + pfx_blob = filebase64("testdata/app_service_certificate.pfx") + password = "terraform" +} +`, rInt, location, rInt) +} + +func testAccAzureRMAppServiceCertificatePfxNoPassword(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestwebcert%d" + location = "%s" +} + +resource "azurerm_app_service_certificate" "test" { + name = "acctest%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + pfx_blob = filebase64("testdata/app_service_certificate_nopassword.pfx") +} +`, rInt, location, rInt) +} + +func testAccAzureRMAppServiceCertificateKeyVault(rInt int, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "test" {} + +data "azuread_service_principal" "test" { + display_name = "Microsoft Azure App Service" +} + +resource "azurerm_resource_group" "test" { + name = "acctestwebcert%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "acct%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + tenant_id = data.azurerm_client_config.test.tenant_id + + sku_name = "standard" + + access_policy { + tenant_id = data.azurerm_client_config.test.tenant_id + object_id = data.azurerm_client_config.test.service_principal_object_id + secret_permissions = ["delete", "get", "set"] + certificate_permissions = ["create", "delete", "get", "import"] + } + + access_policy { + tenant_id = data.azurerm_client_config.test.tenant_id + object_id = data.azuread_service_principal.test.object_id + secret_permissions = ["get"] + certificate_permissions = ["get"] + } +} + +resource "azurerm_key_vault_certificate" "test" { + name = "acctest%d" + key_vault_id = azurerm_key_vault.test.id + + certificate { + contents = filebase64("testdata/app_service_certificate.pfx") + password = "terraform" + } + + certificate_policy { + issuer_parameters { + name = "Self" + } + + key_properties { + exportable = true + key_size = 2048 + key_type = "RSA" + reuse_key = false + } + + secret_properties { + content_type = "application/x-pkcs12" + } + } +} + +resource "azurerm_app_service_certificate" "test" { + name = "acctest%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + key_vault_secret_id = azurerm_key_vault_certificate.test.id +} +`, rInt, location, rInt, rInt, rInt) +} + +func testCheckAzureRMAppServiceCertificateDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).web.CertificatesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_app_service_certificate" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + + return nil +} diff --git a/azurerm/resource_arm_app_service_custom_hostname_binding.go b/azurerm/resource_arm_app_service_custom_hostname_binding.go index 49860761bfbd..88a7ae437180 100644 --- a/azurerm/resource_arm_app_service_custom_hostname_binding.go +++ b/azurerm/resource_arm_app_service_custom_hostname_binding.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -28,7 +31,7 @@ func resourceArmAppServiceCustomHostnameBinding() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "app_service_name": { Type: schema.TypeString, @@ -40,7 +43,7 @@ func resourceArmAppServiceCustomHostnameBinding() *schema.Resource { } func resourceArmAppServiceCustomHostnameBindingCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for App Service Hostname Binding creation.") @@ -49,10 +52,10 @@ func resourceArmAppServiceCustomHostnameBindingCreate(d *schema.ResourceData, me appServiceName := d.Get("app_service_name").(string) hostname := d.Get("hostname").(string) - azureRMLockByName(appServiceName, appServiceCustomHostnameBindingResourceName) - defer azureRMUnlockByName(appServiceName, appServiceCustomHostnameBindingResourceName) + locks.ByName(appServiceName, appServiceCustomHostnameBindingResourceName) + defer locks.UnlockByName(appServiceName, appServiceCustomHostnameBindingResourceName) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.GetHostNameBinding(ctx, resourceGroup, appServiceName, hostname) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -89,9 +92,9 @@ func resourceArmAppServiceCustomHostnameBindingCreate(d *schema.ResourceData, me } func resourceArmAppServiceCustomHostnameBindingRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -119,9 +122,9 @@ func resourceArmAppServiceCustomHostnameBindingRead(d *schema.ResourceData, meta } func resourceArmAppServiceCustomHostnameBindingDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -129,8 +132,8 @@ func resourceArmAppServiceCustomHostnameBindingDelete(d *schema.ResourceData, me appServiceName := id.Path["sites"] hostname := id.Path["hostNameBindings"] - azureRMLockByName(appServiceName, appServiceCustomHostnameBindingResourceName) - defer azureRMUnlockByName(appServiceName, appServiceCustomHostnameBindingResourceName) + locks.ByName(appServiceName, appServiceCustomHostnameBindingResourceName) + defer locks.UnlockByName(appServiceName, appServiceCustomHostnameBindingResourceName) log.Printf("[DEBUG] Deleting App Service Hostname Binding %q (App Service %q / Resource Group %q)", hostname, appServiceName, resGroup) diff --git a/azurerm/resource_arm_app_service_custom_hostname_binding_test.go b/azurerm/resource_arm_app_service_custom_hostname_binding_test.go index aa6444e5a2ef..23420d387f51 100644 --- a/azurerm/resource_arm_app_service_custom_hostname_binding_test.go +++ b/azurerm/resource_arm_app_service_custom_hostname_binding_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -75,7 +76,7 @@ func testAccAzureRMAppServiceCustomHostnameBinding_basic(t *testing.T, appServic } func testAccAzureRMAppServiceCustomHostnameBinding_requiresImport(t *testing.T, appServiceEnv, domainEnv string) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -131,7 +132,7 @@ func testAccAzureRMAppServiceCustomHostnameBinding_multiple(t *testing.T, appSer } func testCheckAzureRMAppServiceCustomHostnameBindingDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).appServicesClient + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_app_service_custom_hostname_binding" { @@ -170,7 +171,7 @@ func testCheckAzureRMAppServiceCustomHostnameBindingExists(resourceName string) appServiceName := rs.Primary.Attributes["app_service_name"] hostname := rs.Primary.Attributes["hostname"] - client := testAccProvider.Meta().(*ArmClient).appServicesClient + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.GetHostNameBinding(ctx, resourceGroup, appServiceName, hostname) if err != nil { diff --git a/azurerm/resource_arm_app_service_plan.go b/azurerm/resource_arm_app_service_plan.go index d9c4304dc591..afef016b002a 100644 --- a/azurerm/resource_arm_app_service_plan.go +++ b/azurerm/resource_arm_app_service_plan.go @@ -4,9 +4,13 @@ import ( "fmt" "log" "regexp" + "strings" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" "github.com/hashicorp/terraform/helper/schema" @@ -33,9 +37,9 @@ func resourceArmAppServicePlan() *schema.Resource { ValidateFunc: validateAppServicePlanName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "kind": { Type: schema.TypeString, @@ -45,10 +49,14 @@ func resourceArmAppServicePlan() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{ // @tombuildsstuff: I believe `app` is the older representation of `Windows` // thus we need to support it to be able to import resources without recreating them. + // @jcorioland: new SKU and kind 'xenon' have been added for Windows Containers support + // https://azure.microsoft.com/en-us/blog/announcing-the-public-preview-of-windows-container-support-in-azure-app-service/ "App", + "elastic", "FunctionApp", "Linux", "Windows", + "xenon", }, true), DiffSuppressFunc: suppress.CaseDifference, }, @@ -112,6 +120,7 @@ func resourceArmAppServicePlan() *schema.Resource { }, }, + /// AppServicePlanProperties "app_service_environment_id": { Type: schema.TypeString, Optional: true, @@ -134,18 +143,30 @@ func resourceArmAppServicePlan() *schema.Resource { ConflictsWith: []string{"properties.0.reserved"}, }, + "maximum_elastic_worker_count": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntAtLeast(0), + }, + "maximum_number_of_workers": { Type: schema.TypeInt, Computed: true, }, - "tags": tagsSchema(), + "is_xenon": { + Type: schema.TypeBool, + Optional: true, + }, + + "tags": tags.Schema(), }, } } func resourceArmAppServicePlanCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicePlansClient + client := meta.(*ArmClient).web.AppServicePlansClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM App Service Plan creation.") @@ -153,7 +174,7 @@ func resourceArmAppServicePlanCreateUpdate(d *schema.ResourceData, meta interfac resGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -166,18 +187,25 @@ func resourceArmAppServicePlanCreateUpdate(d *schema.ResourceData, meta interfac } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) kind := d.Get("kind").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) sku := expandAzureRmAppServicePlanSku(d) properties := expandAppServicePlanProperties(d) + isXenon := d.Get("is_xenon").(bool) + properties.IsXenon = &isXenon + + if kind == "xenon" && !isXenon { + return fmt.Errorf("Creating or updating App Service Plan %q (Resource Group %q): when kind is set to xenon, is_xenon property should be set to true", name, resGroup) + } + appServicePlan := web.AppServicePlan{ Location: &location, Kind: &kind, Sku: &sku, - Tags: expandTags(tags), + Tags: tags.Expand(t), AppServicePlanProperties: properties, } @@ -191,8 +219,19 @@ func resourceArmAppServicePlanCreateUpdate(d *schema.ResourceData, meta interfac appServicePlan.AppServicePlanProperties.PerSiteScaling = utils.Bool(v.(bool)) } - if v, exists := d.GetOkExists("reserved"); exists { - appServicePlan.AppServicePlanProperties.Reserved = utils.Bool(v.(bool)) + reserved, reservedExists := d.GetOkExists("reserved") + if strings.EqualFold(kind, "Linux") { + if !reserved.(bool) || !reservedExists { + return fmt.Errorf("Reserved has to be set to true when using kind Linux") + } + } + + if v, exists := d.GetOkExists("maximum_elastic_worker_count"); exists { + appServicePlan.AppServicePlanProperties.MaximumElasticWorkerCount = utils.Int32(int32(v.(int))) + } + + if reservedExists { + appServicePlan.AppServicePlanProperties.Reserved = utils.Bool(reserved.(bool)) } future, err := client.CreateOrUpdate(ctx, resGroup, name, appServicePlan) @@ -218,9 +257,9 @@ func resourceArmAppServicePlanCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmAppServicePlanRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicePlansClient + client := meta.(*ArmClient).web.AppServicePlansClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -242,10 +281,18 @@ func resourceArmAppServicePlanRead(d *schema.ResourceData, meta interface{}) err return fmt.Errorf("Error making Read request on App Service Plan %q (Resource Group %q): %+v", name, resourceGroup, err) } + // A 404 doesn't error from the app service plan sdk so we'll add this check here to catch resource not found responses + // TODO This block can be removed if https://github.com/Azure/azure-sdk-for-go/issues/5407 gets addressed. + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] App Service Plan %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("kind", resp.Kind) @@ -262,24 +309,27 @@ func resourceArmAppServicePlanRead(d *schema.ResourceData, meta interface{}) err d.Set("maximum_number_of_workers", int(*props.MaximumNumberOfWorkers)) } + if props.MaximumElasticWorkerCount != nil { + d.Set("maximum_elastic_worker_count", int(*props.MaximumElasticWorkerCount)) + } + d.Set("per_site_scaling", props.PerSiteScaling) d.Set("reserved", props.Reserved) + d.Set("is_xenon", props.IsXenon) } if err := d.Set("sku", flattenAppServicePlanSku(resp.Sku)); err != nil { return fmt.Errorf("Error setting `sku`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmAppServicePlanDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicePlansClient + client := meta.(*ArmClient).web.AppServicePlansClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_app_service_plan_test.go b/azurerm/resource_arm_app_service_plan_test.go index 24e32a261aad..a05dc5c6ce59 100644 --- a/azurerm/resource_arm_app_service_plan_test.go +++ b/azurerm/resource_arm_app_service_plan_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -109,7 +110,7 @@ func TestAccAzureRMAppServicePlan_basicLinux(t *testing.T) { } func TestAccAzureRMAppServicePlan_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -273,8 +274,58 @@ func TestAccAzureRMAppServicePlan_consumptionPlan(t *testing.T) { }) } +func TestAccAzureRMAppServicePlan_premiumConsumptionPlan(t *testing.T) { + resourceName := "azurerm_app_service_plan.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServicePlanDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAppServicePlan_premiumConsumptionPlan(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServicePlanExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "ElasticPremium"), + resource.TestCheckResourceAttr(resourceName, "sku.0.size", "EP1"), + resource.TestCheckResourceAttr(resourceName, "maximum_elastic_worker_count", "20"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServicePlan_basicWindowsContainer(t *testing.T) { + resourceName := "azurerm_app_service_plan.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServicePlanDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAppServicePlan_basicWindowsContainer(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServicePlanExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "kind", "xenon"), + resource.TestCheckResourceAttr(resourceName, "is_xenon", "true"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "PremiumContainer"), + resource.TestCheckResourceAttr(resourceName, "sku.0.size", "PC2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMAppServicePlanDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).appServicePlansClient + conn := testAccProvider.Meta().(*ArmClient).web.AppServicePlansClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_app_service_plan" { @@ -314,7 +365,7 @@ func testCheckAzureRMAppServicePlanExists(resourceName string) resource.TestChec return fmt.Errorf("Bad: no resource group found in state for App Service Plan: %s", appServicePlanName) } - conn := testAccProvider.Meta().(*ArmClient).appServicePlansClient + conn := testAccProvider.Meta().(*ArmClient).web.AppServicePlansClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, appServicePlanName) if err != nil { @@ -367,9 +418,7 @@ resource "azurerm_app_service_plan" "test" { size = "B1" } - properties { - reserved = true - } + reserved = true } `, rInt, location, rInt) } @@ -390,9 +439,7 @@ resource "azurerm_app_service_plan" "import" { size = "B1" } - properties { - reserved = true - } + reserved = true } `, template) } @@ -499,10 +546,8 @@ resource "azurerm_app_service_plan" "test" { size = "S1" } - properties { - per_site_scaling = true - reserved = false - } + per_site_scaling = true + reserved = false tags = { environment = "Test" @@ -559,3 +604,48 @@ resource "azurerm_app_service_plan" "test" { } `, rInt, location, rInt) } + +func testAccAzureRMAppServicePlan_premiumConsumptionPlan(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + kind = "elastic" + + maximum_elastic_worker_count = 20 + + sku { + tier = "ElasticPremium" + size = "EP1" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMAppServicePlan_basicWindowsContainer(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + kind = "xenon" + is_xenon = true + + sku { + tier = "PremiumContainer" + size = "PC2" + } +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_app_service_slot.go b/azurerm/resource_arm_app_service_slot.go index 803400bd56de..96d06f303ddf 100644 --- a/azurerm/resource_arm_app_service_slot.go +++ b/azurerm/resource_arm_app_service_slot.go @@ -8,7 +8,10 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -16,7 +19,7 @@ func resourceArmAppServiceSlot() *schema.Resource { return &schema.Resource{ Create: resourceArmAppServiceSlotCreate, Read: resourceArmAppServiceSlotRead, - Update: resourceArmAppServiceSlotUpdate, + Update: resourceArmAppServiceSlotCreate, Delete: resourceArmAppServiceSlotDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -30,36 +33,11 @@ func resourceArmAppServiceSlot() *schema.Resource { ValidateFunc: validateAppServiceName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), - "identity": { - Type: schema.TypeList, - Optional: true, - ForceNew: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, - ValidateFunc: validation.StringInSlice([]string{ - "SystemAssigned", - }, true), - }, - "principal_id": { - Type: schema.TypeString, - Computed: true, - }, - "tenant_id": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, + "identity": azure.SchemaAppServiceIdentity(), "app_service_name": { Type: schema.TypeString, @@ -75,6 +53,8 @@ func resourceArmAppServiceSlot() *schema.Resource { "site_config": azure.SchemaAppServiceSiteConfig(), + "auth_settings": azure.SchemaAppServiceAuthSettings(), + "client_affinity_enabled": { Type: schema.TypeBool, Optional: true, @@ -130,13 +110,32 @@ func resourceArmAppServiceSlot() *schema.Resource { string(web.SQLAzure), string(web.SQLServer), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), + + "site_credential": { + Type: schema.TypeList, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, + }, + }, "default_site_hostname": { Type: schema.TypeString, @@ -147,20 +146,18 @@ func resourceArmAppServiceSlot() *schema.Resource { } func resourceArmAppServiceSlotCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext - log.Printf("[INFO] preparing arguments for AzureRM App Service Slot creation.") - slot := d.Get("name").(string) - resGroup := d.Get("resource_group_name").(string) + resourceGroup := d.Get("resource_group_name").(string) appServiceName := d.Get("app_service_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { - existing, err := client.GetSlot(ctx, resGroup, appServiceName, slot) + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of existing Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resGroup, err) + return fmt.Errorf("Error checking for presence of existing Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } } @@ -169,59 +166,51 @@ func resourceArmAppServiceSlotCreate(d *schema.ResourceData, meta interface{}) e } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) appServicePlanId := d.Get("app_service_plan_id").(string) enabled := d.Get("enabled").(bool) httpsOnly := d.Get("https_only").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) + affinity := d.Get("client_affinity_enabled").(bool) - siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + siteConfig, err := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + if err != nil { + return fmt.Errorf("Error expanding `site_config` for App Service Slot %q (Resource Group %q): %s", slot, resourceGroup, err) + } siteEnvelope := web.Site{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), SiteProperties: &web.SiteProperties{ - ServerFarmID: utils.String(appServicePlanId), - Enabled: utils.Bool(enabled), - HTTPSOnly: utils.Bool(httpsOnly), - SiteConfig: &siteConfig, + ServerFarmID: utils.String(appServicePlanId), + Enabled: utils.Bool(enabled), + HTTPSOnly: utils.Bool(httpsOnly), + SiteConfig: siteConfig, + ClientAffinityEnabled: &affinity, }, } if _, ok := d.GetOk("identity"); ok { - appServiceIdentity := expandAzureRmAppServiceIdentity(d) + appServiceIdentity := azure.ExpandAppServiceIdentity(d) siteEnvelope.Identity = appServiceIdentity } - if v, ok := d.GetOk("client_affinity_enabled"); ok { - enabled := v.(bool) - siteEnvelope.SiteProperties.ClientAffinityEnabled = utils.Bool(enabled) - } - - resp, err := client.Get(ctx, resGroup, appServiceName) + createFuture, err := client.CreateOrUpdateSlot(ctx, resourceGroup, appServiceName, siteEnvelope, slot) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("[DEBUG] App Service %q (resource group %q) was not found.", appServiceName, resGroup) - } - return fmt.Errorf("Error making Read request on AzureRM App Service %q: %+v", appServiceName, err) - } - - createFuture, err := client.CreateOrUpdateSlot(ctx, resGroup, appServiceName, siteEnvelope, slot) - if err != nil { - return err + return fmt.Errorf("Error creating Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } err = createFuture.WaitForCompletionRef(ctx, client.Client) if err != nil { - return err + return fmt.Errorf("Error waiting for creation of Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - read, err := client.GetSlot(ctx, resGroup, appServiceName, slot) + read, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { - return err + return fmt.Errorf("Error retrieving Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } if read.ID == nil { - return fmt.Errorf("Cannot read App Service Slot %q/%q (resource group %q) ID", appServiceName, slot, resGroup) + return fmt.Errorf("Cannot read ID for Slot %q (App Service %q / Resource Group %q) ID", slot, appServiceName, resourceGroup) } d.SetId(*read.ID) @@ -230,68 +219,77 @@ func resourceArmAppServiceSlotCreate(d *schema.ResourceData, meta interface{}) e } func resourceArmAppServiceSlotUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup appServiceName := id.Path["sites"] - location := azureRMNormalizeLocation(d.Get("location").(string)) - appServicePlanId := d.Get("app_service_plan_id").(string) slot := id.Path["slots"] - siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + + location := azure.NormalizeLocation(d.Get("location").(string)) + appServicePlanId := d.Get("app_service_plan_id").(string) + siteConfig, err := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + if err != nil { + return fmt.Errorf("Error expanding `site_config` for App Service Slot %q (Resource Group %q): %s", slot, resourceGroup, err) + } enabled := d.Get("enabled").(bool) httpsOnly := d.Get("https_only").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) + siteEnvelope := web.Site{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), SiteProperties: &web.SiteProperties{ ServerFarmID: utils.String(appServicePlanId), Enabled: utils.Bool(enabled), HTTPSOnly: utils.Bool(httpsOnly), - SiteConfig: &siteConfig, + SiteConfig: siteConfig, }, } if v, ok := d.GetOk("client_affinity_enabled"); ok { enabled := v.(bool) siteEnvelope.SiteProperties.ClientAffinityEnabled = utils.Bool(enabled) } - createFuture, err := client.CreateOrUpdateSlot(ctx, resGroup, appServiceName, siteEnvelope, slot) + createFuture, err := client.CreateOrUpdateSlot(ctx, resourceGroup, appServiceName, siteEnvelope, slot) if err != nil { - return err + return fmt.Errorf("Error updating Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } err = createFuture.WaitForCompletionRef(ctx, client.Client) if err != nil { - return err + return fmt.Errorf("Error waiting for update of Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } + if d.HasChange("site_config") { // update the main configuration - siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + siteConfig, err := azure.ExpandAppServiceSiteConfig(d.Get("site_config")) + if err != nil { + return fmt.Errorf("Error expanding `site_config` for App Service Slot %q (Resource Group %q): %s", slot, resourceGroup, err) + } siteConfigResource := web.SiteConfigResource{ - SiteConfig: &siteConfig, + SiteConfig: siteConfig, } - if _, err := client.CreateOrUpdateConfigurationSlot(ctx, resGroup, appServiceName, siteConfigResource, slot); err != nil { + if _, err := client.CreateOrUpdateConfigurationSlot(ctx, resourceGroup, appServiceName, siteConfigResource, slot); err != nil { return fmt.Errorf("Error updating Configuration for App Service Slot %q/%q: %+v", appServiceName, slot, err) } } - if d.HasChange("client_affinity_enabled") { - affinity := d.Get("client_affinity_enabled").(bool) - sitePatchResource := web.SitePatchResource{ - ID: utils.String(d.Id()), - SitePatchResourceProperties: &web.SitePatchResourceProperties{ - ClientAffinityEnabled: &affinity, - }, + if d.HasChange("auth_settings") { + authSettingsRaw := d.Get("auth_settings").([]interface{}) + authSettingsProperties := azure.ExpandAppServiceAuthSettings(authSettingsRaw) + id := d.Id() + authSettings := web.SiteAuthSettings{ + ID: &id, + SiteAuthSettingsProperties: &authSettingsProperties, } - _, err := client.UpdateSlot(ctx, resGroup, appServiceName, sitePatchResource, slot) - if err != nil { - return fmt.Errorf("Error updating App Service ARR Affinity setting %q: %+v", slot, err) + + if _, err := client.UpdateAuthSettingsSlot(ctx, resourceGroup, appServiceName, authSettings, slot); err != nil { + return fmt.Errorf("Error updating Authentication Settings for App Service %q: %+v", appServiceName, err) } } @@ -302,7 +300,7 @@ func resourceArmAppServiceSlotUpdate(d *schema.ResourceData, meta interface{}) e Properties: appSettings, } - if _, err := client.UpdateApplicationSettingsSlot(ctx, resGroup, appServiceName, settings, slot); err != nil { + if _, err := client.UpdateApplicationSettingsSlot(ctx, resourceGroup, appServiceName, settings, slot); err != nil { return fmt.Errorf("Error updating Application Settings for App Service Slot %q/%q: %+v", appServiceName, slot, err) } } @@ -314,109 +312,160 @@ func resourceArmAppServiceSlotUpdate(d *schema.ResourceData, meta interface{}) e Properties: connectionStrings, } - if _, err := client.UpdateConnectionStringsSlot(ctx, resGroup, appServiceName, properties, slot); err != nil { + if _, err := client.UpdateConnectionStringsSlot(ctx, resourceGroup, appServiceName, properties, slot); err != nil { return fmt.Errorf("Error updating Connection Strings for App Service Slot %q/%q: %+v", appServiceName, slot, err) } } + if d.HasChange("identity") { + identity := azure.ExpandAppServiceIdentity(d) + sitePatchResource := web.SitePatchResource{ + ID: utils.String(d.Id()), + Identity: identity, + } + _, err := client.UpdateSlot(ctx, resourceGroup, appServiceName, sitePatchResource, slot) + if err != nil { + return fmt.Errorf("Error updating Managed Service Identity for App Service Slot %q/%q: %+v", appServiceName, slot, err) + } + } + return resourceArmAppServiceSlotRead(d, meta) } func resourceArmAppServiceSlotRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup appServiceName := id.Path["sites"] slot := id.Path["slots"] ctx := meta.(*ArmClient).StopContext - resp, err := client.GetSlot(ctx, resGroup, appServiceName, slot) + resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[DEBUG] App Service Slot %q/%q (resource group %q) was not found - removing from state", appServiceName, slot, resGroup) + log.Printf("[DEBUG] Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) + } + + configResp, err := client.GetConfigurationSlot(ctx, resourceGroup, appServiceName, slot) + if err != nil { + if utils.ResponseWasNotFound(configResp.Response) { + log.Printf("[DEBUG] Configuration for Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error making Read request on AzureRM App Service Slot %q/%q: %+v", appServiceName, slot, err) + + return fmt.Errorf("Error reading Configuration for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - configResp, err := client.GetConfigurationSlot(ctx, resGroup, appServiceName, slot) + authResp, err := client.GetAuthSettingsSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { - return fmt.Errorf("Error making Read request on AzureRM App Service Slot Configuration %q/%q: %+v", appServiceName, slot, err) + return fmt.Errorf("Error reading Auth Settings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) + } + + appSettingsResp, err := client.ListApplicationSettingsSlot(ctx, resourceGroup, appServiceName, slot) + if err != nil { + if utils.ResponseWasNotFound(appSettingsResp.Response) { + log.Printf("[DEBUG] App Settings for Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading App Settings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - appSettingsResp, err := client.ListApplicationSettingsSlot(ctx, resGroup, appServiceName, slot) + connectionStringsResp, err := client.ListConnectionStringsSlot(ctx, resourceGroup, appServiceName, slot) if err != nil { - return fmt.Errorf("Error making Read request on AzureRM App Service Slot AppSettings %q/%q: %+v", appServiceName, slot, err) + return fmt.Errorf("Error listing Connection Strings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } - connectionStringsResp, err := client.ListConnectionStringsSlot(ctx, resGroup, appServiceName, slot) + siteCredFuture, err := client.ListPublishingCredentialsSlot(ctx, resourceGroup, appServiceName, slot) + if err != nil { + return fmt.Errorf("Error retrieving publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) + } + err = siteCredFuture.WaitForCompletionRef(ctx, client.Client) if err != nil { - return fmt.Errorf("Error making Read request on AzureRM App Service Slot ConnectionStrings %q/%q: %+v", appServiceName, slot, err) + return fmt.Errorf("Error waiting for publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) + } + siteCredResp, err := siteCredFuture.Result(*client) + if err != nil { + return fmt.Errorf("Error reading publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } d.Set("name", slot) d.Set("app_service_name", appServiceName) - d.Set("resource_group_name", resGroup) + d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.SiteProperties; props != nil { d.Set("app_service_plan_id", props.ServerFarmID) d.Set("client_affinity_enabled", props.ClientAffinityEnabled) + d.Set("default_site_hostname", props.DefaultHostName) d.Set("enabled", props.Enabled) d.Set("https_only", props.HTTPSOnly) - d.Set("default_site_hostname", props.DefaultHostName) } if err := d.Set("app_settings", flattenAppServiceAppSettings(appSettingsResp.Properties)); err != nil { - return err + return fmt.Errorf("Error setting `app_settings`: %s", err) } if err := d.Set("connection_string", flattenAppServiceConnectionStrings(connectionStringsResp.Properties)); err != nil { - return err + return fmt.Errorf("Error setting `connection_string`: %s", err) } - siteConfig := azure.FlattenAppServiceSiteConfig(configResp.SiteConfig) - if err := d.Set("site_config", siteConfig); err != nil { - return err + authSettings := azure.FlattenAppServiceAuthSettings(authResp.SiteAuthSettingsProperties) + if err := d.Set("auth_settings", authSettings); err != nil { + return fmt.Errorf("Error setting `auth_settings`: %s", err) } - identity := flattenAzureRmAppServiceMachineIdentity(resp.Identity) + identity := azure.FlattenAppServiceIdentity(resp.Identity) if err := d.Set("identity", identity); err != nil { - return err + return fmt.Errorf("Error setting `identity`: %s", err) } - flattenAndSetTags(d, resp.Tags) + siteCred := flattenAppServiceSiteCredential(siteCredResp.UserProperties) + if err := d.Set("site_credential", siteCred); err != nil { + return fmt.Errorf("Error setting `site_credential`: %s", err) + } - return nil + siteConfig := azure.FlattenAppServiceSiteConfig(configResp.SiteConfig) + if err := d.Set("site_config", siteConfig); err != nil { + return fmt.Errorf("Error setting `site_config`: %s", err) + } + + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmAppServiceSlotDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup appServiceName := id.Path["sites"] slot := id.Path["slots"] - log.Printf("[DEBUG] Deleting App Service Slot %q/%q (resource group %q)", appServiceName, slot, resGroup) + log.Printf("[DEBUG] Deleting Slot %q (App Service %q / Resource Group %q)", slot, appServiceName, resourceGroup) deleteMetrics := true deleteEmptyServerFarm := false ctx := meta.(*ArmClient).StopContext - resp, err := client.DeleteSlot(ctx, resGroup, appServiceName, slot, &deleteMetrics, &deleteEmptyServerFarm) + resp, err := client.DeleteSlot(ctx, resourceGroup, appServiceName, slot, &deleteMetrics, &deleteEmptyServerFarm) if err != nil { if !utils.ResponseWasNotFound(resp) { - return err + return fmt.Errorf("Error deleting Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err) } } diff --git a/azurerm/resource_arm_app_service_slot_test.go b/azurerm/resource_arm_app_service_slot_test.go index e358e0f7d5e7..359255dbdc67 100644 --- a/azurerm/resource_arm_app_service_slot_test.go +++ b/azurerm/resource_arm_app_service_slot_test.go @@ -2,13 +2,15 @@ package azurerm import ( "fmt" + "os" "testing" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" - + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +40,7 @@ func TestAccAzureRMAppServiceSlot_basic(t *testing.T) { } func TestAccAzureRMAppServiceSlot_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -258,10 +260,10 @@ func TestAccAzureRMAppServiceSlot_connectionStrings(t *testing.T) { }) } -func TestAccAzureRMAppServiceSlot_defaultDocuments(t *testing.T) { - resourceName := "azurerm_app_service_slot.test" +func TestAccAzureRMAppServiceSlot_corsSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_defaultDocuments(ri, testLocation()) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -269,22 +271,24 @@ func TestAccAzureRMAppServiceSlot_defaultDocuments(t *testing.T) { CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMAppServiceSlot_corsSettings(ri, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.0", "first.html"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.1", "second.jsp"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.2", "third.aspx"), - ), + testCheckAzureRMAppServiceExists(resourceName), + )}, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMAppServiceSlot_enabled(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsAdditionalLoginParams(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), false) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsAdditionalLoginParams(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -295,18 +299,28 @@ func TestAccAzureRMAppServiceSlot_enabled(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.additional_login_params.test_key", "test_value"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_enabledUpdate(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsAdditionalAllowedExternalRedirectUrls(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), false) - updatedConfig := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), true) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsAdditionalAllowedExternalRedirectUrls(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -317,24 +331,29 @@ func TestAccAzureRMAppServiceSlot_enabledUpdate(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.allowed_external_redirect_urls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.allowed_external_redirect_urls.0", "https://terra.form"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, { - Config: updatedConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "enabled", "true"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMAppServiceSlot_httpsOnly(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsRuntimeVersion(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), true) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsRuntimeVersion(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -345,18 +364,28 @@ func TestAccAzureRMAppServiceSlot_httpsOnly(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "https_only", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.runtime_version", "1.0"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_httpsOnlyUpdate(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsTokenRefreshExtensionHours(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), true) - updatedConfig := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), false) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsTokenRefreshExtensionHours(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -367,24 +396,28 @@ func TestAccAzureRMAppServiceSlot_httpsOnlyUpdate(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "https_only", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.token_refresh_extension_hours", "75"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, { - Config: updatedConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "https_only", "false"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMAppServiceSlot_http2Enabled(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsUnauthenticatedClientAction(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_http2Enabled(ri, testLocation()) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsUnauthenticatedClientAction(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -395,17 +428,28 @@ func TestAccAzureRMAppServiceSlot_http2Enabled(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.http2_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.unauthenticated_client_action", "RedirectToLoginPage"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_oneIpRestriction(t *testing.T) { +func TestAccAzureRMAppServiceSlot_authSettingsTokenStoreEnabled(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_oneIpRestriction(ri, testLocation()) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_authSettingsTokenStoreEnabled(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -416,18 +460,28 @@ func TestAccAzureRMAppServiceSlot_oneIpRestriction(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.ip_address", "10.10.10.10"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.subnet_mask", "255.255.255.255"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.token_store_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_manyIpRestrictions(t *testing.T) { +func TestAccAzureRMAppServiceSlot_aadAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_manyIpRestrictions(ri, testLocation()) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppServiceSlot_aadAuthSettings(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -438,24 +492,26 @@ func TestAccAzureRMAppServiceSlot_manyIpRestrictions(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.ip_address", "10.10.10.10"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.subnet_mask", "255.255.255.255"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.1.ip_address", "20.20.20.0"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.1.subnet_mask", "255.255.255.0"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.2.ip_address", "30.30.0.0"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.2.subnet_mask", "255.255.0.0"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.3.ip_address", "192.168.1.2"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.3.subnet_mask", "255.255.255.0"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_localMySql(t *testing.T) { +func TestAccAzureRMAppServiceSlot_facebookAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_localMySql(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_facebookAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -466,17 +522,25 @@ func TestAccAzureRMAppServiceSlot_localMySql(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.local_mysql_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.app_id", "facebookappid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.app_secret", "facebookappsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.oauth_scopes.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_managedPipelineMode(t *testing.T) { +func TestAccAzureRMAppServiceSlot_googleAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_managedPipelineMode(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_googleAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -487,18 +551,25 @@ func TestAccAzureRMAppServiceSlot_managedPipelineMode(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.managed_pipeline_mode", "Classic"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.client_id", "googleclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.client_secret", "googleclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.oauth_scopes.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_tagsUpdate(t *testing.T) { +func TestAccAzureRMAppServiceSlot_microsoftAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_tags(ri, testLocation()) - updatedConfig := testAccAzureRMAppServiceSlot_tagsUpdated(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_microsoftAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -509,27 +580,25 @@ func TestAccAzureRMAppServiceSlot_tagsUpdate(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.Hello", "World"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_id", "microsoftclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_secret", "microsoftclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.oauth_scopes.#", "1"), ), }, { - Config: updatedConfig, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), - resource.TestCheckResourceAttr(resourceName, "tags.Hello", "World"), - resource.TestCheckResourceAttr(resourceName, "tags.Terraform", "AcceptanceTests"), - ), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) } -func TestAccAzureRMAppServiceSlot_remoteDebugging(t *testing.T) { +func TestAccAzureRMAppServiceSlot_twitterAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_remoteDebugging(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_twitterAuthSettings(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -540,18 +609,26 @@ func TestAccAzureRMAppServiceSlot_remoteDebugging(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_enabled", "true"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_version", "VS2015"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.twitter.0.consumer_key", "twitterconsumerkey"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.twitter.0.consumer_secret", "twitterconsumersecret"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_virtualNetwork(t *testing.T) { +func TestAccAzureRMAppServiceSlot_multiAuthSettings(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - location := testLocation() + tenantID := os.Getenv("ARM_TENANT_ID") + config1 := testAccAzureRMAppServiceSlot_aadAuthSettings(ri, testLocation(), tenantID) + config2 := testAccAzureRMAppServiceSlot_aadMicrosoftAuthSettings(ri, testLocation(), tenantID) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -559,27 +636,48 @@ func TestAccAzureRMAppServiceSlot_virtualNetwork(t *testing.T) { CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMAppServiceSlot_virtualNetwork(ri, location), + Config: config1, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn-%d", ri)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), ), }, { - Config: testAccAzureRMAppServiceSlot_virtualNetworkUpdated(ri, location), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: config2, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn2-%d", ri)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_id", "microsoftclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_secret", "microsoftclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.oauth_scopes.#", "1"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsDotNet2(t *testing.T) { +func TestAccAzureRMAppServiceSlot_defaultDocuments(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") + config := testAccAzureRMAppServiceSlot_defaultDocuments(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -590,17 +688,19 @@ func TestAccAzureRMAppServiceSlot_windowsDotNet2(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v2.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.0", "first.html"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.1", "second.jsp"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.default_documents.2", "third.aspx"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsDotNet4(t *testing.T) { +func TestAccAzureRMAppServiceSlot_enabled(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") + config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), false) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -611,18 +711,18 @@ func TestAccAzureRMAppServiceSlot_windowsDotNet4(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v4.0"), + resource.TestCheckResourceAttr(resourceName, "enabled", "false"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsDotNetUpdate(t *testing.T) { +func TestAccAzureRMAppServiceSlot_enabledUpdate(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") - updatedConfig := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") + config := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), false) + updatedConfig := testAccAzureRMAppServiceSlot_enabled(ri, testLocation(), true) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -633,24 +733,24 @@ func TestAccAzureRMAppServiceSlot_windowsDotNetUpdate(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v2.0"), + resource.TestCheckResourceAttr(resourceName, "enabled", "false"), ), }, { Config: updatedConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v4.0"), + resource.TestCheckResourceAttr(resourceName, "enabled", "true"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava7Jetty(t *testing.T) { +func TestAccAzureRMAppServiceSlot_httpsOnly(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "JETTY", "9.3") + config := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), true) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -661,19 +761,18 @@ func TestAccAzureRMAppServiceSlot_windowsJava7Jetty(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.7"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + resource.TestCheckResourceAttr(resourceName, "https_only", "true"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava8Jetty(t *testing.T) { +func TestAccAzureRMAppServiceSlot_httpsOnlyUpdate(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "JETTY", "9.3") + config := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), true) + updatedConfig := testAccAzureRMAppServiceSlot_httpsOnly(ri, testLocation(), false) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -684,18 +783,24 @@ func TestAccAzureRMAppServiceSlot_windowsJava8Jetty(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.8"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + resource.TestCheckResourceAttr(resourceName, "https_only", "true"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "https_only", "false"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava7Tomcat(t *testing.T) { + +func TestAccAzureRMAppServiceSlot_http2Enabled(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "TOMCAT", "9.0") + config := testAccAzureRMAppServiceSlot_http2Enabled(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -706,19 +811,17 @@ func TestAccAzureRMAppServiceSlot_windowsJava7Tomcat(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.7"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.http2_enabled", "true"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsJava8Tomcat(t *testing.T) { +func TestAccAzureRMAppServiceSlot_oneIpRestriction(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "TOMCAT", "9.0") + config := testAccAzureRMAppServiceSlot_oneIpRestriction(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -729,19 +832,18 @@ func TestAccAzureRMAppServiceSlot_windowsJava8Tomcat(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.8"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), - resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.ip_address", "10.10.10.10"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.subnet_mask", "255.255.255.255"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsPHP7(t *testing.T) { +func TestAccAzureRMAppServiceSlot_oneVNetSubnetIpRestriction(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsPHP(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_oneVNetSubnetIpRestriction(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -752,17 +854,23 @@ func TestAccAzureRMAppServiceSlot_windowsPHP7(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.php_version", "7.2"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAzureRMAppServiceSlot_windowsPython(t *testing.T) { +func TestAccAzureRMAppServiceSlot_zeroedIpRestriction(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_windowsPython(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_oneIpRestriction(ri, testLocation()) + noBlocksConfig := testAccAzureRMAppServiceSlot_basic(ri, testLocation()) + blocksEmptyConfig := testAccAzureRMAppServiceSlot_zeroedIpRestriction(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -770,20 +878,37 @@ func TestAccAzureRMAppServiceSlot_windowsPython(t *testing.T) { CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, Steps: []resource.TestStep{ { + // This configuration includes a single explicit ip_restriction Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.python_version", "3.4"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "1"), + ), + }, + { + // This configuration has no site_config blocks at all. + Config: noBlocksConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "1"), + ), + }, + { + // This configuration explicitly sets ip_restriction to [] using attribute syntax. + Config: blocksEmptyConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "0"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_webSockets(t *testing.T) { +func TestAccAzureRMAppServiceSlot_manyIpRestrictions(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_webSockets(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_manyIpRestrictions(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -794,17 +919,24 @@ func TestAccAzureRMAppServiceSlot_webSockets(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.websockets_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.ip_address", "10.10.10.10"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.0.subnet_mask", "255.255.255.255"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.1.ip_address", "20.20.20.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.1.subnet_mask", "255.255.255.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.2.ip_address", "30.30.0.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.2.subnet_mask", "255.255.0.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.3.ip_address", "192.168.1.2"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.3.subnet_mask", "255.255.255.0"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_enableManageServiceIdentity(t *testing.T) { +func TestAccAzureRMAppServiceSlot_localMySql(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_enableManageServiceIdentity(ri, testLocation()) + config := testAccAzureRMAppServiceSlot_localMySql(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -815,20 +947,17 @@ func TestAccAzureRMAppServiceSlot_enableManageServiceIdentity(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned"), - resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), - resource.TestMatchResourceAttr(resourceName, "identity.0.tenant_id", validate.UUIDRegExp), + resource.TestCheckResourceAttr(resourceName, "site_config.0.local_mysql_enabled", "true"), ), }, }, }) } -func TestAccAzureRMAppServiceSlot_minTls(t *testing.T) { +func TestAccAzureRMAppServiceSlot_managedPipelineMode(t *testing.T) { resourceName := "azurerm_app_service_slot.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppServiceSlot_minTls(ri, testLocation(), "1.0") - updatedConfig := testAccAzureRMAppServiceSlot_minTls(ri, testLocation(), "1.1") + config := testAccAzureRMAppServiceSlot_managedPipelineMode(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -839,83 +968,1281 @@ func TestAccAzureRMAppServiceSlot_minTls(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMAppServiceSlotExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.min_tls_version", "1.0"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.managed_pipeline_mode", "Classic"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_tagsUpdate(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_tags(ri, testLocation()) + updatedConfig := testAccAzureRMAppServiceSlot_tagsUpdated(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Hello", "World"), ), }, { Config: updatedConfig, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMAppServiceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "site_config.0.min_tls_version", "1.1"), + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.Hello", "World"), + resource.TestCheckResourceAttr(resourceName, "tags.Terraform", "AcceptanceTests"), ), }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_remoteDebugging(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_remoteDebugging(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.remote_debugging_version", "VS2015"), + ), }, }, }) } -func testCheckAzureRMAppServiceSlotDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).appServicesClient +func TestAccAzureRMAppServiceSlot_virtualNetwork(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + location := testLocation() - for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_app_service_slot" { - continue - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAppServiceSlot_virtualNetwork(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn-%d", ri)), + ), + }, + { + Config: testAccAzureRMAppServiceSlot_virtualNetworkUpdated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", fmt.Sprintf("acctestvn2-%d", ri)), + ), + }, + }, + }) +} - slot := rs.Primary.Attributes["name"] - appServiceName := rs.Primary.Attributes["app_service_name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] +func TestAccAzureRMAppServiceSlot_windowsDotNet2(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v2.0"), + ), + }, + }, + }) +} - if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return nil - } - return err - } +func TestAccAzureRMAppServiceSlot_updateManageServiceIdentity(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() - return nil - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAppServiceSlot_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + ), + }, + { + Config: testAccAzureRMAppServiceSlot_enableManageServiceIdentity(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned"), + resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(resourceName, "identity.0.tenant_id", validate.UUIDRegExp), + ), + }, + }, + }) +} - return nil +func TestAccAzureRMAppServiceSlot_windowsDotNet4(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v4.0"), + ), + }, + }, + }) } -func testCheckAzureRMAppServiceSlotExists(slot string) resource.TestCheckFunc { - return func(s *terraform.State) error { - // Ensure we have enough information in state to look up in API - rs, ok := s.RootModule().Resources[slot] - if !ok { - return fmt.Errorf("Slot Not found: %q", slot) - } +func TestAccAzureRMAppServiceSlot_userAssignedIdentity(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_userAssignedIdentity(ri, testLocation()) - appServiceName := rs.Primary.Attributes["app_service_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for App Service Slot: %q/%q", appServiceName, slot) - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "UserAssigned"), + resource.TestCheckResourceAttr(resourceName, "identity.0.identity_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "identity.0.principal_id", ""), + resource.TestCheckResourceAttr(resourceName, "identity.0.tenant_id", ""), + ), + }, + }, + }) +} - client := testAccProvider.Meta().(*ArmClient).appServicesClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) - if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Bad: App Service slot %q/%q (resource group: %q) does not exist", appServiceName, slot, resourceGroup) - } +func TestAccAzureRMAppServiceSlot_multipleAssignedIdentities(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_multipleAssignedIdentities(ri, testLocation()) - return fmt.Errorf("Bad: Get on appServicesClient: %+v", err) - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned, UserAssigned"), + resource.TestCheckResourceAttr(resourceName, "identity.0.identity_ids.#", "1"), + resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(resourceName, "identity.0.tenant_id", validate.UUIDRegExp), + ), + }, + }, + }) +} - return nil - } +func TestAccAzureRMAppServiceSlot_windowsDotNetUpdate(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v2.0") + updatedConfig := testAccAzureRMAppServiceSlot_windowsDotNet(ri, testLocation(), "v4.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v2.0"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.dotnet_framework_version", "v4.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava7Jetty(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "JETTY", "9.3") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.7"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava8Jetty(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "JETTY", "9.3") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.8"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + ), + }, + }, + }) +} +func TestAccAzureRMAppServiceSlot_windowsJava11Jetty(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "11", "JETTY", "9.3") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "11"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava7Tomcat(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.7", "TOMCAT", "9.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.7"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava8Tomcat(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "1.8", "TOMCAT", "9.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "1.8"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsJava11Tomcat(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsJava(ri, testLocation(), "11", "TOMCAT", "9.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "11"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsPHP7(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsPHP(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.php_version", "7.2"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_windowsPython(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_windowsPython(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.python_version", "3.4"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_webSockets(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_webSockets(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.websockets_enabled", "true"), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_enableManageServiceIdentity(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_enableManageServiceIdentity(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned"), + resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(resourceName, "identity.0.tenant_id", validate.UUIDRegExp), + ), + }, + }, + }) +} + +func TestAccAzureRMAppServiceSlot_minTls(t *testing.T) { + resourceName := "azurerm_app_service_slot.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppServiceSlot_minTls(ri, testLocation(), "1.0") + updatedConfig := testAccAzureRMAppServiceSlot_minTls(ri, testLocation(), "1.1") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceSlotExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.min_tls_version", "1.0"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.min_tls_version", "1.1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMAppServiceSlotDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_app_service_slot" { + continue + } + + slot := rs.Primary.Attributes["name"] + appServiceName := rs.Primary.Attributes["app_service_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMAppServiceSlotExists(slot string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[slot] + if !ok { + return fmt.Errorf("Slot Not found: %q", slot) + } + + appServiceName := rs.Primary.Attributes["app_service_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for App Service Slot: %q/%q", appServiceName, slot) + } + + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: App Service slot %q/%q (resource group: %q) does not exist", appServiceName, slot, resourceGroup) + } + + return fmt.Errorf("Bad: Get on appServicesClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMAppServiceSlot_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_requiresImport(rInt int, location string) string { + template := testAccAzureRMAppServiceSlot_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_app_service_slot" "import" { + name = "${azurerm_app_service_slot.test.name}" + location = "${azurerm_app_service_slot.test.location}" + resource_group_name = "${azurerm_app_service_slot.test.resource_group_name}" + app_service_plan_id = "${azurerm_app_service_slot.test.app_service_plan_id}" + app_service_name = "${azurerm_app_service_slot.test.app_service_name}" +} +`, template) +} + +func testAccAzureRMAppServiceSlot_32Bit(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + use_32_bit_worker_process = true + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_alwaysOn(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + always_on = true + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_appCommandLine(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + app_command_line = "/sbin/myservice -b 0.0.0.0" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_appSettings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + app_settings = { + "foo" = "bar" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_clientAffinityEnabled(rInt int, location string, clientAffinityEnabled bool) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + client_affinity_enabled = %t +} +`, rInt, location, rInt, rInt, rInt, clientAffinityEnabled) +} + +func testAccAzureRMAppServiceSlot_connectionStrings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + connection_string { + name = "First" + value = "first-connection-string" + type = "Custom" + } + + connection_string { + name = "Second" + value = "some-postgresql-connection-string" + type = "PostgreSQL" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_connectionStringsUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + connection_string { + name = "Second" + value = "some-postgresql-connection-string" + type = "PostgreSQL" + } + + connection_string { + name = "First" + value = "first-connection-string" + type = "Custom" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_corsSettings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + cors { + allowed_origins = [ + "http://www.contoso.com", + "www.contoso.com", + "contoso.com" + ] + support_credentials = true + } + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_authSettingsAdditionalLoginParams(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + additional_login_params = { + test_key = "test_value" + } + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, rInt, tenantID) +} + +func testAccAzureRMAppServiceSlot_authSettingsAdditionalAllowedExternalRedirectUrls(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + allowed_external_redirect_urls = [ + "https://terra.form" + ] + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, rInt, tenantID) +} + +func testAccAzureRMAppServiceSlot_authSettingsRuntimeVersion(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + runtime_version = "1.0" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, rInt, tenantID) +} + +func testAccAzureRMAppServiceSlot_authSettingsTokenRefreshExtensionHours(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + token_refresh_extension_hours = 75 + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, rInt, tenantID) +} + +func testAccAzureRMAppServiceSlot_authSettingsTokenStoreEnabled(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + token_store_enabled = true + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, rInt, tenantID) +} + +func testAccAzureRMAppServiceSlot_authSettingsUnauthenticatedClientAction(rInt int, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestRG-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + unauthenticated_client_action = "RedirectToLoginPage" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, rInt, rInt, rInt, tenantID) } -func testAccAzureRMAppServiceSlot_basic(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_aadAuthSettings(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -923,9 +2250,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -934,7 +2263,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" @@ -946,26 +2275,28 @@ resource "azurerm_app_service_slot" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" -} -`, rInt, location, rInt, rInt, rInt) -} -func testAccAzureRMAppServiceSlot_requiresImport(rInt int, location string) string { - template := testAccAzureRMAppServiceSlot_basic(rInt, location) - return fmt.Sprintf(` -%s + site_config { + always_on = true + } -resource "azurerm_app_service_slot" "import" { - name = "${azurerm_app_service_slot.test.name}" - location = "${azurerm_app_service_slot.test.location}" - resource_group_name = "${azurerm_app_service_slot.test.resource_group_name}" - app_service_plan_id = "${azurerm_app_service_slot.test.app_service_plan_id}" - app_service_name = "${azurerm_app_service_slot.test.app_service_name}" + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } } -`, template) +`, rInt, location, rInt, rInt, rInt, tenantID) } -func testAccAzureRMAppServiceSlot_32Bit(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_facebookAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -973,9 +2304,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -984,7 +2317,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" @@ -998,13 +2331,25 @@ resource "azurerm_app_service_slot" "test" { app_service_name = "${azurerm_app_service.test.name}" site_config { - use_32_bit_worker_process = true + always_on = true + } + + auth_settings { + enabled = true + facebook { + app_id = "facebookappid" + app_secret = "facebookappsecret" + + oauth_scopes = [ + "facebookscope", + ] + } } } `, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_alwaysOn(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_googleAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1012,9 +2357,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1023,7 +2370,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" @@ -1036,14 +2383,27 @@ resource "azurerm_app_service_slot" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" + site_config { always_on = true } + + auth_settings { + enabled = true + google { + client_id = "googleclientid" + client_secret = "googleclientsecret" + + oauth_scopes = [ + "googlescope", + ] + } + } } `, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_appCommandLine(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_microsoftAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1051,18 +2411,19 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } } - resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" @@ -1076,13 +2437,25 @@ resource "azurerm_app_service_slot" "test" { app_service_name = "${azurerm_app_service.test.name}" site_config { - app_command_line = "/sbin/myservice -b 0.0.0.0" + always_on = true + } + + auth_settings { + enabled = true + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "microsoftscope", + ] + } } } `, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_appSettings(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_twitterAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1090,9 +2463,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1101,7 +2476,7 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" @@ -1114,14 +2489,22 @@ resource "azurerm_app_service_slot" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - app_settings = { - "foo" = "bar" + site_config { + always_on = true + } + + auth_settings { + enabled = true + twitter { + consumer_key = "twitterconsumerkey" + consumer_secret = "twitterconsumersecret" + } } } `, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_clientAffinityEnabled(rInt int, location string, clientAffinityEnabled bool) string { +func testAccAzureRMAppServiceSlot_aadMicrosoftAuthSettings(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1129,9 +2512,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -1140,24 +2525,51 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" } resource "azurerm_app_service_slot" "test" { - name = "acctestASSlot-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - app_service_plan_id = "${azurerm_app_service_plan.test.id}" - app_service_name = "${azurerm_app_service.test.name}" - client_affinity_enabled = %t + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + default_provider = "%s" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "microsoftscope", + ] + } + } } -`, rInt, location, rInt, rInt, rInt, clientAffinityEnabled) +`, rInt, location, rInt, rInt, rInt, tenantID, web.AzureActiveDirectory) } -func testAccAzureRMAppServiceSlot_connectionStrings(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_defaultDocuments(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1189,22 +2601,18 @@ resource "azurerm_app_service_slot" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - connection_string { - name = "First" - value = "first-connection-string" - type = "Custom" - } - - connection_string { - name = "Second" - value = "some-postgresql-connection-string" - type = "PostgreSQL" + site_config { + default_documents = [ + "first.html", + "second.jsp", + "third.aspx", + ] } } `, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_connectionStringsUpdated(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_enabled(rInt int, location string, enabled bool) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1235,23 +2643,12 @@ resource "azurerm_app_service_slot" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - - connection_string { - name = "Second" - value = "some-postgresql-connection-string" - type = "PostgreSQL" - } - - connection_string { - name = "First" - value = "first-connection-string" - type = "Custom" - } + enabled = %t } -`, rInt, location, rInt, rInt, rInt) +`, rInt, location, rInt, rInt, rInt, enabled) } -func testAccAzureRMAppServiceSlot_defaultDocuments(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_httpsOnly(rInt int, location string, httpsOnly bool) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1282,19 +2679,12 @@ resource "azurerm_app_service_slot" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - - site_config { - default_documents = [ - "first.html", - "second.jsp", - "third.aspx", - ] - } + https_only = %t } -`, rInt, location, rInt, rInt, rInt) +`, rInt, location, rInt, rInt, rInt, httpsOnly) } -func testAccAzureRMAppServiceSlot_enabled(rInt int, location string, enabled bool) string { +func testAccAzureRMAppServiceSlot_http2Enabled(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1325,12 +2715,15 @@ resource "azurerm_app_service_slot" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - enabled = %t + + site_config { + http2_enabled = true + } } -`, rInt, location, rInt, rInt, rInt, enabled) +`, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_httpsOnly(rInt int, location string, httpsOnly bool) string { +func testAccAzureRMAppServiceSlot_oneIpRestriction(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1361,18 +2754,37 @@ resource "azurerm_app_service_slot" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" app_service_name = "${azurerm_app_service.test.name}" - https_only = %t + + site_config { + ip_restriction { + ip_address = "10.10.10.10" + } + } } -`, rInt, location, rInt, rInt, rInt, httpsOnly) +`, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_http2Enabled(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_oneVNetSubnetIpRestriction(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + resource "azurerm_app_service_plan" "test" { name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" @@ -1399,13 +2811,15 @@ resource "azurerm_app_service_slot" "test" { app_service_name = "${azurerm_app_service.test.name}" site_config { - http2_enabled = true + ip_restriction { + virtual_network_subnet_id = "${azurerm_subnet.test.id}" + } } } -`, rInt, location, rInt, rInt, rInt) +`, rInt, location, rInt, rInt, rInt, rInt, rInt) } -func testAccAzureRMAppServiceSlot_oneIpRestriction(rInt int, location string) string { +func testAccAzureRMAppServiceSlot_zeroedIpRestriction(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1438,9 +2852,7 @@ resource "azurerm_app_service_slot" "test" { app_service_name = "${azurerm_app_service.test.name}" site_config { - ip_restriction { - ip_address = "10.10.10.10" - } + ip_restriction = [] } } `, rInt, location, rInt, rInt, rInt) @@ -1613,7 +3025,7 @@ resource "azurerm_app_service_slot" "test" { app_service_name = "${azurerm_app_service.test.name}" tags = { - "Hello" = "World" + Hello = "World" } } `, rInt, location, rInt, rInt, rInt) @@ -1697,7 +3109,7 @@ resource "azurerm_app_service_slot" "test" { } tags = { - "Hello" = "World" + Hello = "World" } } `, rInt, location, rInt, rInt, rInt) @@ -2053,6 +3465,98 @@ resource "azurerm_app_service_slot" "test" { `, rInt, location, rInt, rInt, rInt) } +func testAccAzureRMAppServiceSlot_userAssignedIdentity(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_user_assigned_identity" "test" { + name = "acct-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + identity { + type = "UserAssigned" + identity_ids = ["${azurerm_user_assigned_identity.test.id}"] + } +} +`, rInt, location, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMAppServiceSlot_multipleAssignedIdentities(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_user_assigned_identity" "test" { + name = "acct-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} + +resource "azurerm_app_service_slot" "test" { + name = "acctestASSlot-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + app_service_name = "${azurerm_app_service.test.name}" + + identity { + type = "SystemAssigned, UserAssigned" + identity_ids = ["${azurerm_user_assigned_identity.test.id}"] + } +} +`, rInt, location, rInt, rInt, rInt, rInt) +} + func testAccAzureRMAppServiceSlot_minTls(rInt int, location string, tlsVersion string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/azurerm/resource_arm_app_service_test.go b/azurerm/resource_arm_app_service_test.go index 8aec9e76f477..55caca416f16 100644 --- a/azurerm/resource_arm_app_service_test.go +++ b/azurerm/resource_arm_app_service_test.go @@ -2,13 +2,17 @@ package azurerm import ( "fmt" + "os" "testing" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -80,7 +84,7 @@ func TestAccAzureRMAppService_basic(t *testing.T) { } func TestAccAzureRMAppService_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -210,6 +214,69 @@ func TestAccAzureRMAppService_32Bit(t *testing.T) { }) } +func TestAccAzureRMAppService_backup(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(5) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAppService_backup(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMAppService_backupUpdated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + // Enabled + Config: testAccAzureRMAppService_backup(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + // Disabled + Config: testAccAzureRMAppService_backupDisabled(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + // remove it + Config: testAccAzureRMAppService_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMAppService_http2Enabled(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() @@ -516,6 +583,56 @@ func TestAccAzureRMAppService_updateResourceByEnablingManageServiceIdentity(t *t }) } +func TestAccAzureRMAppService_userAssignedIdentity(t *testing.T) { + + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_userAssignedIdentity(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "UserAssigned"), + resource.TestCheckResourceAttr(resourceName, "identity.0.identity_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "identity.0.principal_id", ""), + resource.TestCheckResourceAttr(resourceName, "identity.0.tenant_id", ""), + ), + }, + }, + }) +} + +func TestAccAzureRMAppService_multipleAssignedIdentities(t *testing.T) { + + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_multipleAssignedIdentities(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned, UserAssigned"), + resource.TestCheckResourceAttr(resourceName, "identity.0.identity_ids.#", "1"), + resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(resourceName, "identity.0.tenant_id", validate.UUIDRegExp), + ), + }, + }, + }) +} + func TestAccAzureRMAppService_clientAffinityUpdate(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() @@ -598,6 +715,39 @@ func TestAccAzureRMAppService_connectionStrings(t *testing.T) { }) } +func TestAccAzureRMAppService_storageAccounts(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAppService_storageAccounts(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "storage_account.#", "1"), + ), + }, + { + Config: testAccAzureRMAppService_storageAccountsUpdated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "storage_account.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMAppService_oneIpRestriction(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() @@ -625,6 +775,71 @@ func TestAccAzureRMAppService_oneIpRestriction(t *testing.T) { }) } +func TestAccAzureRMAppService_oneVNetSubnetIpRestriction(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_oneVNetSubnetIpRestriction(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_zeroedIpRestriction(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_oneIpRestriction(ri, testLocation()) + noBlocksConfig := testAccAzureRMAppService_basic(ri, testLocation()) + blocksEmptyConfig := testAccAzureRMAppService_zeroedIpRestriction(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceSlotDestroy, + Steps: []resource.TestStep{ + { + // This configuration includes a single explicit ip_restriction + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "1"), + ), + }, + { + // This configuration has no site_config blocks at all. + Config: noBlocksConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "1"), + ), + }, + { + // This configuration explicitly sets ip_restriction to [] using attribute syntax. + Config: blocksEmptyConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.ip_restriction.#", "0"), + ), + }, + }, + }) +} + func TestAccAzureRMAppService_manyIpRestrictions(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() @@ -738,6 +953,97 @@ func TestAccAzureRMAppService_localMySql(t *testing.T) { }) } +func TestAccAzureRMAppService_applicationBlobStorageLogs(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_applicationBlobStorageLogs(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "logs.0.application_logs.0.azure_blob_storage.0.level", "Information"), + resource.TestCheckResourceAttr(resourceName, "logs.0.application_logs.0.azure_blob_storage.0.sas_url", "http://x.com/"), + resource.TestCheckResourceAttr(resourceName, "logs.0.application_logs.0.azure_blob_storage.0.retention_in_days", "3"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_httpFileSystemLogs(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_httpFileSystemLogs(ri, testLocation()) + config2 := testAccAzureRMAppService_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_httpFileSystemAndStorageBlobLogs(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(5) + config := testAccAzureRMAppService_httpFileSystemAndStorageBlobLogs(ri, rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMAppService_managedPipelineMode(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() @@ -959,10 +1265,37 @@ func TestAccAzureRMAppService_windowsJava8Jetty(t *testing.T) { }, }) } -func TestAccAzureRMAppService_windowsJava7Tomcat(t *testing.T) { +func TestAccAzureRMAppService_windowsJava11Jetty(t *testing.T) { resourceName := "azurerm_app_service.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMAppService_windowsJava(ri, testLocation(), "1.7", "TOMCAT", "9.0") + config := testAccAzureRMAppService_windowsJava(ri, testLocation(), "11", "JETTY", "9.3") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "11"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "JETTY"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.3"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccAzureRMAppService_windowsJava7Tomcat(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_windowsJava(ri, testLocation(), "1.7", "TOMCAT", "9.0") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -1014,6 +1347,33 @@ func TestAccAzureRMAppService_windowsJava8Tomcat(t *testing.T) { }, }) } +func TestAccAzureRMAppService_windowsJava11Tomcat(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_windowsJava(ri, testLocation(), "11", "TOMCAT", "9.0") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_version", "11"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container", "TOMCAT"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.java_container_version", "9.0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} func TestAccAzureRMAppService_windowsPHP7(t *testing.T) { resourceName := "azurerm_app_service.test" @@ -1208,63 +1568,1392 @@ func TestAccAzureRMAppService_minTls(t *testing.T) { }) } -func testCheckAzureRMAppServiceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).appServicesClient +func TestAccAzureRMAppService_corsSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_corsSettings(ri, testLocation()) - for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_app_service" { - continue - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.#", "1"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.0.support_credentials", "true"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.0.allowed_origins.#", "3"), + )}, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} - name := rs.Primary.Attributes["name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] +func TestAccAzureRMAppService_authSettingsAdditionalLoginParams(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsAdditionalLoginParams(ri, testLocation(), tenantID) - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := client.Get(ctx, resourceGroup, name) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.additional_login_params.test_key", "test_value"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} - if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return nil - } - return err - } +func TestAccAzureRMAppService_authSettingsAdditionalAllowedExternalRedirectUrls(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsAdditionalAllowedExternalRedirectUrls(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.allowed_external_redirect_urls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.allowed_external_redirect_urls.0", "https://terra.form"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_authSettingsRuntimeVersion(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsRuntimeVersion(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.runtime_version", "1.0"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_authSettingsTokenRefreshExtensionHours(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsTokenRefreshExtensionHours(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.token_refresh_extension_hours", "75"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_authSettingsUnauthenticatedClientAction(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsUnauthenticatedClientAction(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.unauthenticated_client_action", "RedirectToLoginPage"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_authSettingsTokenStoreEnabled(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_authSettingsTokenStoreEnabled(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.token_store_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_aadAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMAppService_aadAuthSettings(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_facebookAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_facebookAuthSettings(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.app_id", "facebookappid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.app_secret", "facebookappsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.facebook.0.oauth_scopes.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_googleAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_googleAuthSettings(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.client_id", "googleclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.client_secret", "googleclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.google.0.oauth_scopes.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_microsoftAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_microsoftAuthSettings(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_id", "microsoftclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_secret", "microsoftclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.oauth_scopes.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_twitterAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_twitterAuthSettings(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.twitter.0.consumer_key", "twitterconsumerkey"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.twitter.0.consumer_secret", "twitterconsumersecret"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_multiAuthSettings(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + tenantID := os.Getenv("ARM_TENANT_ID") + config1 := testAccAzureRMAppService_aadAuthSettings(ri, testLocation(), tenantID) + config2 := testAccAzureRMAppService_aadMicrosoftAuthSettings(ri, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config1, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_id", "microsoftclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.client_secret", "microsoftclientsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.microsoft.0.oauth_scopes.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAppService_basicWindowsContainer(t *testing.T) { + resourceName := "azurerm_app_service.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMAppService_basicWindowsContainer(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAppServiceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.windows_fx_version", "DOCKER|mcr.microsoft.com/azure-app-service/samples/aspnethelloworld:latest"), + resource.TestCheckResourceAttr(resourceName, "app_settings.DOCKER_REGISTRY_SERVER_URL", "https://mcr.microsoft.com"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMAppServiceDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_app_service" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMAppServiceExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + appServiceName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for App Service: %s", appServiceName) + } + + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, appServiceName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: App Service %q (resource group: %q) does not exist", appServiceName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on appServicesClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMAppService_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_requiresImport(rInt int, location string) string { + template := testAccAzureRMAppService_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_app_service" "import" { + name = "${azurerm_app_service.test.name}" + location = "${azurerm_app_service.test.location}" + resource_group_name = "${azurerm_app_service.test.resource_group_name}" + app_service_plan_id = "${azurerm_app_service.test.app_service_plan_id}" +} +`, template) +} + +func testAccAzureRMAppService_freeTier(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Free" + size = "F1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + use_32_bit_worker_process = true + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_moved(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service_plan" "other" { + name = "acctestASP2-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.other.id}" +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppService_sharedTier(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Free" + size = "F1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + use_32_bit_worker_process = true + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_alwaysOn(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + always_on = true + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_appCommandLine(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + app_command_line = "/sbin/myserver -b 0.0.0.0" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_httpsOnly(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + https_only = true +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_clientCertEnabled(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + client_cert_enabled = true +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_clientCertEnabledNotSet(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_32Bit(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + use_32_bit_worker_process = true + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_backup(rInt int, rString, location string) string { + template := testAccAzureRMAppService_backupTemplate(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + backup { + name = "acctest" + storage_account_url = "https://${azurerm_storage_account.test.name}.blob.core.windows.net/${azurerm_storage_container.test.name}${data.azurerm_storage_account_sas.test.sas}&sr=b" + schedule { + frequency_interval = 1 + frequency_unit = "Day" + } + } +} +`, template, rInt) +} + +func testAccAzureRMAppService_backupDisabled(rInt int, rString, location string) string { + template := testAccAzureRMAppService_backupTemplate(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + backup { + name = "acctest" + storage_account_url = "https://${azurerm_storage_account.test.name}.blob.core.windows.net/${azurerm_storage_container.test.name}${data.azurerm_storage_account_sas.test.sas}&sr=b" + enabled = false + schedule { + frequency_interval = 1 + frequency_unit = "Day" + } + } +} +`, template, rInt) +} + +func testAccAzureRMAppService_backupUpdated(rInt int, rString, location string) string { + template := testAccAzureRMAppService_backupTemplate(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + backup { + name = "acctest" + storage_account_url = "https://${azurerm_storage_account.test.name}.blob.core.windows.net/${azurerm_storage_container.test.name}${data.azurerm_storage_account_sas.test.sas}&sr=b" + schedule { + frequency_interval = 2 + frequency_unit = "Hour" + } + } +} +`, template, rInt) +} + +func testAccAzureRMAppService_backupTemplate(rInt int, rString, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "example" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} + +data "azurerm_storage_account_sas" "test" { + connection_string = "${azurerm_storage_account.test.primary_connection_string}" + https_only = true + + resource_types { + service = false + container = false + object = true + } + + services { + blob = true + queue = false + table = false + file = false + } + + start = "2019-03-21" + expiry = "2022-03-21" + + permissions { + read = false + write = true + delete = false + list = false + add = false + create = false + update = false + process = false + } +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} +`, rInt, location, rString, rInt) +} + +func testAccAzureRMAppService_http2Enabled(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + http2_enabled = true + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_appSettings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + app_settings = { + "foo" = "bar" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_clientAffinityEnabled(rInt int, location string) string { + return testAccAzureRMAppService_clientAffinity(rInt, location, true) +} + +func testAccAzureRMAppService_clientAffinityDisabled(rInt int, location string) string { + return testAccAzureRMAppService_clientAffinity(rInt, location, false) +} + +func testAccAzureRMAppService_clientAffinity(rInt int, location string, clientAffinity bool) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + client_affinity_enabled = %t +} +`, rInt, location, rInt, rInt, clientAffinity) +} + +func testAccAzureRMAppService_virtualNetwork(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvn-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "10.0.1.0/24" + } +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + virtual_network_name = "${azurerm_virtual_network.test.name}" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppService_virtualNetworkUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvn-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "10.0.1.0/24" + } +} + +resource "azurerm_virtual_network" "second" { + name = "acctestvn2-%d" + address_space = ["172.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + name = "internal" + address_prefix = "172.0.1.0/24" + } +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + virtual_network_name = "${azurerm_virtual_network.second.name}" + } +} +`, rInt, location, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMAppService_mangedServiceIdentity(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + identity { + type = "SystemAssigned" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_userAssignedIdentity(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_user_assigned_identity" "test" { + name = "acct-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + identity { + type = "UserAssigned" + identity_ids = ["${azurerm_user_assigned_identity.test.id}"] + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppService_multipleAssignedIdentities(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_user_assigned_identity" "test" { + name = "acct-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + identity { + type = "SystemAssigned, UserAssigned" + identity_ids = ["${azurerm_user_assigned_identity.test.id}"] + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMAppService_connectionStrings(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + connection_string { + name = "First" + value = "first-connection-string" + type = "Custom" + } + + connection_string { + name = "Second" + value = "some-postgresql-connection-string" + type = "PostgreSQL" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAppService_connectionStringsUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + connection_string { + name = "Second" + value = "some-postgresql-connection-string" + type = "PostgreSQL" + } + + connection_string { + name = "First" + value = "first-connection-string" + type = "Custom" + } +} +`, rInt, location, rInt, rInt) +} - return nil - } +func testAccAzureRMAppService_storageAccounts(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} - return nil +resource "azurerm_storage_account" "test" { + name = "acct%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + account_tier = "Standard" + account_replication_type = "LRS" } -func testCheckAzureRMAppServiceExists(resourceName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - // Ensure we have enough information in state to look up in API - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("Not found: %s", resourceName) - } +resource "azurerm_storage_container" "test" { + name = "acctestcontainer" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} - appServiceName := rs.Primary.Attributes["name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for App Service: %s", appServiceName) - } +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" - client := testAccProvider.Meta().(*ArmClient).appServicesClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := client.Get(ctx, resourceGroup, appServiceName) - if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Bad: App Service %q (resource group: %q) does not exist", appServiceName, resourceGroup) - } + sku { + tier = "Standard" + size = "S1" + } +} - return fmt.Errorf("Bad: Get on appServicesClient: %+v", err) - } +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" - return nil - } + storage_account { + name = "blobs" + type = "AzureBlob" + account_name = "${azurerm_storage_account.test.name}" + share_name = "${azurerm_storage_container.test.name}" + access_key = "${azurerm_storage_account.test.primary_access_key}" + mount_path = "/blobs" + } +} +`, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppService_basic(rInt int, location string) string { +func testAccAzureRMAppService_storageAccountsUpdated(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1282,30 +2971,54 @@ resource "azurerm_app_service_plan" "test" { } } +resource "azurerm_storage_account" "test" { + name = "acct%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctestcontainer" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} + +resource "azurerm_storage_share" "test" { + name = "acctestshare" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} + resource "azurerm_app_service" "test" { name = "acctestAS-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" -} -`, rInt, location, rInt, rInt) -} -func testAccAzureRMAppService_requiresImport(rInt int, location string) string { - template := testAccAzureRMAppService_basic(rInt, location) - return fmt.Sprintf(` -%s + storage_account { + name = "blobs" + type = "AzureBlob" + account_name = "${azurerm_storage_account.test.name}" + share_name = "${azurerm_storage_container.test.name}" + access_key = "${azurerm_storage_account.test.primary_access_key}" + mount_path = "/blobs" + } -resource "azurerm_app_service" "import" { - name = "${azurerm_app_service.test.name}" - location = "${azurerm_app_service.test.location}" - resource_group_name = "${azurerm_app_service.test.resource_group_name}" - app_service_plan_id = "${azurerm_app_service.test.app_service_plan_id}" + storage_account { + name = "files" + type = "AzureFiles" + account_name = "${azurerm_storage_account.test.name}" + share_name = "${azurerm_storage_share.test.name}" + access_key = "${azurerm_storage_account.test.primary_access_key}" + mount_path = "/files" + } } -`, template) +`, rInt, location, rInt, rInt, rInt) } -func testAccAzureRMAppService_freeTier(rInt int, location string) string { +func testAccAzureRMAppService_oneIpRestriction(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1318,8 +3031,8 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - tier = "Free" - size = "F1" + tier = "Standard" + size = "S1" } } @@ -1330,32 +3043,37 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - use_32_bit_worker_process = true + ip_restriction { + ip_address = "10.10.10.10" + } } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_moved(rInt int, location string) string { +func testAccAzureRMAppService_oneVNetSubnetIpRestriction(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } -resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" +} - sku { - tier = "Standard" - size = "S1" - } +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" } -resource "azurerm_app_service_plan" "other" { - name = "acctestASP2-%d" +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" @@ -1369,12 +3087,18 @@ resource "azurerm_app_service" "test" { name = "acctestAS-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - app_service_plan_id = "${azurerm_app_service_plan.other.id}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + site_config { + ip_restriction { + virtual_network_subnet_id = "${azurerm_subnet.test.id}" + } + } } -`, rInt, location, rInt, rInt, rInt) +`, rInt, location, rInt, rInt, rInt, rInt) } -func testAccAzureRMAppService_sharedTier(rInt int, location string) string { +func testAccAzureRMAppService_manyIpRestrictions(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1387,8 +3111,8 @@ resource "azurerm_app_service_plan" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - tier = "Free" - size = "F1" + tier = "Standard" + size = "S1" } } @@ -1399,13 +3123,30 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - use_32_bit_worker_process = true + ip_restriction { + ip_address = "10.10.10.10" + } + + ip_restriction { + ip_address = "20.20.20.0" + subnet_mask = "255.255.255.0" + } + + ip_restriction { + ip_address = "30.30.0.0" + subnet_mask = "255.255.0.0" + } + + ip_restriction { + ip_address = "192.168.1.2" + subnet_mask = "255.255.255.0" + } } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_alwaysOn(rInt int, location string) string { +func testAccAzureRMAppService_zeroedIpRestriction(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1430,13 +3171,13 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - always_on = true + ip_restriction = [] } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_appCommandLine(rInt int, location string) string { +func testAccAzureRMAppService_defaultDocuments(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1461,13 +3202,17 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - app_command_line = "/sbin/myserver -b 0.0.0.0" + default_documents = [ + "first.html", + "second.jsp", + "third.aspx", + ] } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_httpsOnly(rInt int, location string) string { +func testAccAzureRMAppService_enabled(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1490,12 +3235,12 @@ resource "azurerm_app_service" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - https_only = true + enabled = false } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_clientCertEnabled(rInt int, location string) string { +func testAccAzureRMAppService_localMySql(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1518,12 +3263,15 @@ resource "azurerm_app_service" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - client_cert_enabled = true + + site_config { + local_mysql_enabled = true + } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_clientCertEnabledNotSet(rInt int, location string) string { +func testAccAzureRMAppService_applicationBlobStorageLogs(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1546,11 +3294,21 @@ resource "azurerm_app_service" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + logs { + application_logs { + azure_blob_storage { + level = "Information" + sas_url = "http://x.com/" + retention_in_days = 3 + } + } + } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_32Bit(rInt int, location string) string { +func testAccAzureRMAppService_httpFileSystemLogs(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1574,14 +3332,49 @@ resource "azurerm_app_service" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - site_config { - use_32_bit_worker_process = true + logs { + http_logs { + file_system { + retention_in_days = 4 + retention_in_mb = 25 + } + } } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_http2Enabled(rInt int, location string) string { +func testAccAzureRMAppService_httpFileSystemAndStorageBlobLogs(rInt int, rString string, location string) string { + template := testAccAzureRMAppService_backupTemplate(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + logs { + application_logs { + azure_blob_storage { + level = "Information" + sas_url = "https://${azurerm_storage_account.test.name}.blob.core.windows.net/${azurerm_storage_container.test.name}${data.azurerm_storage_account_sas.test.sas}&sr=b" + retention_in_days = 3 + } + } + http_logs { + file_system { + retention_in_days = 4 + retention_in_mb = 25 + } + } + } +} +`, template, rInt) +} + +func testAccAzureRMAppService_managedPipelineMode(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1606,13 +3399,13 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - http2_enabled = true + managed_pipeline_mode = "Classic" } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_appSettings(rInt int, location string) string { +func testAccAzureRMAppService_remoteDebugging(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1636,22 +3429,19 @@ resource "azurerm_app_service" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - app_settings = { - "foo" = "bar" + site_config { + remote_debugging_enabled = true + remote_debugging_version = "VS2015" } -} -`, rInt, location, rInt, rInt) -} -func testAccAzureRMAppService_clientAffinityEnabled(rInt int, location string) string { - return testAccAzureRMAppService_clientAffinity(rInt, location, true) + tags = { + Hello = "World" + } } - -func testAccAzureRMAppService_clientAffinityDisabled(rInt int, location string) string { - return testAccAzureRMAppService_clientAffinity(rInt, location, false) +`, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_clientAffinity(rInt int, location string, clientAffinity bool) string { +func testAccAzureRMAppService_tags(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1670,34 +3460,25 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - app_service_plan_id = "${azurerm_app_service_plan.test.id}" - client_affinity_enabled = %t + name = "acctestAS-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + + tags = { + Hello = "World" + } } -`, rInt, location, rInt, rInt, clientAffinity) +`, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_virtualNetwork(rInt int, location string) string { +func testAccAzureRMAppService_tagsUpdated(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } -resource "azurerm_virtual_network" "test" { - name = "acctestvn-%d" - address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - - subnet { - name = "internal" - address_prefix = "10.0.1.0/24" - } -} - resource "azurerm_app_service_plan" "test" { name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" @@ -1715,43 +3496,51 @@ resource "azurerm_app_service" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - site_config { - virtual_network_name = "${azurerm_virtual_network.test.name}" + tags = { + "Hello" = "World" + "Terraform" = "AcceptanceTests" } } -`, rInt, location, rInt, rInt, rInt) +`, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_virtualNetworkUpdated(rInt int, location string) string { +func testAccAzureRMAppService_windowsDotNet(rInt int, location, version string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } -resource "azurerm_virtual_network" "test" { - name = "acctestvn-%d" - address_space = ["10.0.0.0/16"] +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - subnet { - name = "internal" - address_prefix = "10.0.1.0/24" + sku { + tier = "Standard" + size = "S1" } } -resource "azurerm_virtual_network" "second" { - name = "acctestvn2-%d" - address_space = ["172.0.0.0/16"] +resource "azurerm_app_service" "test" { + name = "acctestAS-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" - subnet { - name = "internal" - address_prefix = "172.0.1.0/24" + site_config { + dotnet_framework_version = "%s" } } +`, rInt, location, rInt, rInt, version) +} + +func testAccAzureRMAppService_windowsJava(rInt int, location, javaVersion, container, containerVersion string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} resource "azurerm_app_service_plan" "test" { name = "acctestASP-%d" @@ -1771,13 +3560,15 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - virtual_network_name = "${azurerm_virtual_network.second.name}" + java_version = "%s" + java_container = "%s" + java_container_version = "%s" } } -`, rInt, location, rInt, rInt, rInt, rInt) +`, rInt, location, rInt, rInt, javaVersion, container, containerVersion) } -func testAccAzureRMAppService_mangedServiceIdentity(rInt int, location string) string { +func testAccAzureRMAppService_windowsPHP(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1801,14 +3592,14 @@ resource "azurerm_app_service" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - identity { - type = "SystemAssigned" + site_config { + php_version = "7.2" } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_connectionStrings(rInt int, location string) string { +func testAccAzureRMAppService_windowsPython(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1832,22 +3623,14 @@ resource "azurerm_app_service" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - connection_string { - name = "First" - value = "first-connection-string" - type = "Custom" - } - - connection_string { - name = "Second" - value = "some-postgresql-connection-string" - type = "PostgreSQL" + site_config { + python_version = "3.4" } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_connectionStringsUpdated(rInt int, location string) string { +func testAccAzureRMAppService_webSockets(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1871,22 +3654,14 @@ resource "azurerm_app_service" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - connection_string { - name = "Second" - value = "some-postgresql-connection-string" - type = "PostgreSQL" - } - - connection_string { - name = "First" - value = "first-connection-string" - type = "Custom" + site_config { + websockets_enabled = true } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_oneIpRestriction(rInt int, location string) string { +func testAccAzureRMAppService_scmType(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1911,15 +3686,13 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - ip_restriction { - ip_address = "10.10.10.10" - } + scm_type = "LocalGit" } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_manyIpRestrictions(rInt int, location string) string { +func testAccAzureRMAppService_ftpsState(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1944,30 +3717,13 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - ip_restriction { - ip_address = "10.10.10.10" - } - - ip_restriction { - ip_address = "20.20.20.0" - subnet_mask = "255.255.255.0" - } - - ip_restriction { - ip_address = "30.30.0.0" - subnet_mask = "255.255.0.0" - } - - ip_restriction { - ip_address = "192.168.1.2" - subnet_mask = "255.255.255.0" - } + ftps_state = "AllAllowed" } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_defaultDocuments(rInt int, location string) string { +func testAccAzureRMAppService_linuxFxVersion(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -1992,17 +3748,18 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - default_documents = [ - "first.html", - "second.jsp", - "third.aspx", - ] + always_on = true + linux_fx_version = "DOCKER|(golang:latest)" + } + + app_settings = { + "WEBSITES_ENABLE_APP_SERVICE_STORAGE" = "false" } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_enabled(rInt int, location string) string { +func testAccAzureRMAppService_minTls(rInt int, location string, tlsVersion string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2025,12 +3782,15 @@ resource "azurerm_app_service" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - enabled = false + + site_config { + min_tls_version = "%s" + } } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt, rInt, tlsVersion) } -func testAccAzureRMAppService_localMySql(rInt int, location string) string { +func testAccAzureRMAppService_corsSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2055,13 +3815,21 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - local_mysql_enabled = true + cors { + allowed_origins = [ + "http://www.contoso.com", + "www.contoso.com", + "contoso.com", + ] + + support_credentials = true + } } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_managedPipelineMode(rInt int, location string) string { +func testAccAzureRMAppService_authSettingsAdditionalLoginParams(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2069,9 +3837,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2080,19 +3850,37 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - managed_pipeline_mode = "Classic" + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + additional_login_params = { + test_key = "test_value" + } + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } } } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt, rInt, tenantID) } -func testAccAzureRMAppService_remoteDebugging(rInt int, location string) string { +func testAccAzureRMAppService_authSettingsAdditionalAllowedExternalRedirectUrls(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2100,9 +3888,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2111,24 +3901,37 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - remote_debugging_enabled = true - remote_debugging_version = "VS2015" + always_on = true } - tags = { - "Hello" = "World" + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + allowed_external_redirect_urls = [ + "https://terra.form", + ] + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } } } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt, rInt, tenantID) } -func testAccAzureRMAppService_tags(rInt int, location string) string { +func testAccAzureRMAppService_authSettingsRuntimeVersion(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2136,9 +3939,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2147,19 +3952,34 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - tags = { - "Hello" = "World" + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + runtime_version = "1.0" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } } } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt, rInt, tenantID) } -func testAccAzureRMAppService_tagsUpdated(rInt int, location string) string { +func testAccAzureRMAppService_authSettingsTokenRefreshExtensionHours(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2167,9 +3987,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2178,20 +4000,34 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" - tags = { - "Hello" = "World" - "Terraform" = "AcceptanceTests" + site_config { + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + token_refresh_extension_hours = 75 + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } } } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt, rInt, tenantID) } -func testAccAzureRMAppService_windowsDotNet(rInt int, location, version string) string { +func testAccAzureRMAppService_authSettingsTokenStoreEnabled(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2199,9 +4035,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2210,19 +4048,34 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - dotnet_framework_version = "%s" + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + token_store_enabled = true + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } } } -`, rInt, location, rInt, rInt, version) +`, rInt, location, rInt, rInt, tenantID) } -func testAccAzureRMAppService_windowsJava(rInt int, location, javaVersion, container, containerVersion string) string { +func testAccAzureRMAppService_authSettingsUnauthenticatedClientAction(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2230,9 +4083,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2241,21 +4096,34 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - java_version = "%s" - java_container = "%s" - java_container_version = "%s" + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + unauthenticated_client_action = "RedirectToLoginPage" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } } } -`, rInt, location, rInt, rInt, javaVersion, container, containerVersion) +`, rInt, location, rInt, rInt, tenantID) } -func testAccAzureRMAppService_windowsPHP(rInt int, location string) string { +func testAccAzureRMAppService_aadAuthSettings(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2263,9 +4131,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2274,19 +4144,33 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - php_version = "7.2" + always_on = true + } + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } } } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt, rInt, tenantID) } -func testAccAzureRMAppService_windowsPython(rInt int, location string) string { +func testAccAzureRMAppService_facebookAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2294,9 +4178,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2305,19 +4191,32 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - python_version = "3.4" + always_on = true + } + + auth_settings { + enabled = true + + facebook { + app_id = "facebookappid" + app_secret = "facebookappsecret" + + oauth_scopes = [ + "facebookscope", + ] + } } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_webSockets(rInt int, location string) string { +func testAccAzureRMAppService_googleAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2325,9 +4224,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2336,19 +4237,32 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - websockets_enabled = true + always_on = true + } + + auth_settings { + enabled = true + + google { + client_id = "googleclientid" + client_secret = "googleclientsecret" + + oauth_scopes = [ + "googlescope", + ] + } } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_scmType(rInt int, location string) string { +func testAccAzureRMAppService_microsoftAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2356,9 +4270,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2367,19 +4283,32 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - scm_type = "LocalGit" + always_on = true + } + + auth_settings { + enabled = true + + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "microsoftscope", + ] + } } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_ftpsState(rInt int, location string) string { +func testAccAzureRMAppService_twitterAuthSettings(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2387,9 +4316,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2398,19 +4329,28 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - ftps_state = "AllAllowed" + always_on = true + } + + auth_settings { + enabled = true + + twitter { + consumer_key = "twitterconsumerkey" + consumer_secret = "twitterconsumersecret" + } } } `, rInt, location, rInt, rInt) } -func testAccAzureRMAppService_linuxFxVersion(rInt int, location string) string { +func testAccAzureRMAppService_aadMicrosoftAuthSettings(rInt int, location string, tenantID string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2418,9 +4358,11 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_app_service_plan" "test" { - name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + name = "acctestRG-%d" + kind = "Linux" + reserved = true sku { tier = "Standard" @@ -2429,24 +4371,43 @@ resource "azurerm_app_service_plan" "test" { } resource "azurerm_app_service" "test" { - name = "acctestAS-%d" + name = "acctestRG-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - always_on = true - linux_fx_version = "DOCKER|(golang:latest)" + always_on = true } - app_settings = { - "WEBSITES_ENABLE_APP_SERVICE_STORAGE" = "false" + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%s" + default_provider = "%s" + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + + microsoft { + client_id = "microsoftclientid" + client_secret = "microsoftclientsecret" + + oauth_scopes = [ + "microsoftscope", + ] + } } } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt, rInt, tenantID, web.AzureActiveDirectory) } -func testAccAzureRMAppService_minTls(rInt int, location string, tlsVersion string) string { +func testAccAzureRMAppService_basicWindowsContainer(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -2457,10 +4418,12 @@ resource "azurerm_app_service_plan" "test" { name = "acctestASP-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + is_xenon = true + kind = "xenon" sku { - tier = "Standard" - size = "S1" + tier = "PremiumContainer" + size = "PC2" } } @@ -2471,8 +4434,14 @@ resource "azurerm_app_service" "test" { app_service_plan_id = "${azurerm_app_service_plan.test.id}" site_config { - min_tls_version = "%s" + windows_fx_version = "DOCKER|mcr.microsoft.com/azure-app-service/samples/aspnethelloworld:latest" + } + + app_settings = { + "DOCKER_REGISTRY_SERVER_URL" = "https://mcr.microsoft.com" + "DOCKER_REGISTRY_SERVER_USERNAME" = "" + "DOCKER_REGISTRY_SERVER_PASSWORD" = "" } } -`, rInt, location, rInt, rInt, tlsVersion) +`, rInt, location, rInt, rInt) } diff --git a/azurerm/resource_arm_application_gateway.go b/azurerm/resource_arm_application_gateway.go index 49a343f045ed..a8e0c2a1ce95 100644 --- a/azurerm/resource_arm_application_gateway.go +++ b/azurerm/resource_arm_application_gateway.go @@ -4,16 +4,27 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +// See https://github.com/Azure/azure-sdk-for-go/blob/master/services/network/mgmt/2018-04-01/network/models.go +func possibleArmApplicationGatewaySslCipherSuiteValues() []string { + cipherSuites := make([]string, 0) + for _, cipherSuite := range network.PossibleApplicationGatewaySslCipherSuiteValues() { + cipherSuites = append(cipherSuites, string(cipherSuite)) + } + return cipherSuites +} + func resourceArmApplicationGateway() *schema.Resource { return &schema.Resource{ Create: resourceArmApplicationGatewayCreateUpdate, @@ -31,13 +42,43 @@ func resourceArmApplicationGateway() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), + + "zones": azure.SchemaZones(), "resource_group_name": { Type: schema.TypeString, Required: true, ForceNew: true, }, + "identity": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Optional: true, + Default: string(network.ResourceIdentityTypeUserAssigned), + ValidateFunc: validation.StringInSlice([]string{ + string(network.ResourceIdentityTypeUserAssigned), + }, false), + }, + "identity_ids": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.NoZeroValues, + }, + }, + }, + }, + }, // Required "backend_address_pool": { @@ -146,6 +187,17 @@ func resourceArmApplicationGateway() *schema.Resource { }, true), }, + "affinity_cookie_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "host_name": { + Type: schema.TypeString, + Optional: true, + }, + "pick_host_name_from_backend_address": { Type: schema.TypeBool, Optional: true, @@ -289,6 +341,7 @@ func resourceArmApplicationGateway() *schema.Resource { "gateway_ip_configuration": { Type: schema.TypeList, Required: true, + MaxItems: 2, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { @@ -445,6 +498,18 @@ func resourceArmApplicationGateway() *schema.Resource { Optional: true, }, + "redirect_configuration_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "rewrite_rule_set_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "backend_address_pool_id": { Type: schema.TypeString, Computed: true, @@ -469,10 +534,97 @@ func resourceArmApplicationGateway() *schema.Resource { Type: schema.TypeString, Computed: true, }, + + "redirect_configuration_id": { + Type: schema.TypeString, + Computed: true, + }, + + "rewrite_rule_set_id": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, + "redirect_configuration": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "redirect_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.Permanent), + string(network.Temporary), + string(network.Found), + string(network.SeeOther), + }, false), + }, + + "target_listener_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "target_url": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "include_path": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "include_query_string": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "id": { + Type: schema.TypeString, + Computed: true, + }, + + "target_listener_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "autoscale_configuration": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min_capacity": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(2, 10), + }, + "max_capacity": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(2, 100), + }, + }, + }, + }, "sku": { Type: schema.TypeList, Required: true, @@ -508,8 +660,8 @@ func resourceArmApplicationGateway() *schema.Resource { "capacity": { Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(1, 10), + Optional: true, + ValidateFunc: validation.IntBetween(1, 32), }, }, }, @@ -540,10 +692,12 @@ func resourceArmApplicationGateway() *schema.Resource { }, }, - // TODO: @tombuildsstuff deprecate this in favour of a full `ssl_protocol` block in the future + // TODO: remove in 2.0 "disabled_ssl_protocols": { - Type: schema.TypeList, - Optional: true, + Type: schema.TypeList, + Optional: true, + Computed: true, + Deprecated: "has been replaced by `ssl_policy`.`disabled_protocols`", Elem: &schema.Schema{ Type: schema.TypeString, DiffSuppressFunc: suppress.CaseDifference, @@ -555,6 +709,65 @@ func resourceArmApplicationGateway() *schema.Resource { }, }, + "ssl_policy": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disabled_protocols": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(network.TLSv10), + string(network.TLSv11), + string(network.TLSv12), + }, false), + }, + }, + + "policy_type": { + Type: schema.TypeString, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(network.Custom), + string(network.Predefined), + }, false), + }, + }, + + "policy_name": { + Type: schema.TypeString, + Optional: true, + }, + + "cipher_suites": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(possibleArmApplicationGatewaySslCipherSuiteValues(), false), + }, + }, + + "min_protocol_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.TLSv10), + string(network.TLSv11), + string(network.TLSv12), + }, false), + }, + }, + }, + }, + "enable_http2": { Type: schema.TypeBool, Optional: true, @@ -649,6 +862,106 @@ func resourceArmApplicationGateway() *schema.Resource { }, }, + "rewrite_rule_set": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "rewrite_rule": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "rule_sequence": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 1000), + }, + + "condition": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "variable": { + Type: schema.TypeString, + Required: true, + }, + "pattern": { + Type: schema.TypeString, + Required: true, + }, + "ignore_case": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "negate": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + }, + }, + }, + + "request_header_configuration": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "header_name": { + Type: schema.TypeString, + Required: true, + }, + "header_value": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "response_header_configuration": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "header_name": { + Type: schema.TypeString, + Required: true, + }, + "header_value": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + }, + }, + + "id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "ssl_certificate": { // TODO: should this become a Set? Type: schema.TypeList, @@ -698,12 +1011,24 @@ func resourceArmApplicationGateway() *schema.Resource { "default_backend_address_pool_name": { Type: schema.TypeString, - Required: true, + Optional: true, }, "default_backend_http_settings_name": { Type: schema.TypeString, - Required: true, + Optional: true, + }, + + "default_redirect_configuration_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "default_rewrite_rule_set_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, }, "path_rule": { @@ -726,12 +1051,24 @@ func resourceArmApplicationGateway() *schema.Resource { "backend_address_pool_name": { Type: schema.TypeString, - Required: true, + Optional: true, }, "backend_http_settings_name": { Type: schema.TypeString, - Required: true, + Optional: true, + }, + + "redirect_configuration_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "rewrite_rule_set_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, }, "backend_address_pool_id": { @@ -744,6 +1081,16 @@ func resourceArmApplicationGateway() *schema.Resource { Computed: true, }, + "redirect_configuration_id": { + Type: schema.TypeString, + Computed: true, + }, + + "rewrite_rule_set_id": { + Type: schema.TypeString, + Computed: true, + }, + "id": { Type: schema.TypeString, Computed: true, @@ -762,6 +1109,16 @@ func resourceArmApplicationGateway() *schema.Resource { Computed: true, }, + "default_redirect_configuration_id": { + Type: schema.TypeString, + Computed: true, + }, + + "default_rewrite_rule_set_id": { + Type: schema.TypeString, + Computed: true, + }, + "id": { Type: schema.TypeString, Computed: true, @@ -811,27 +1168,116 @@ func resourceArmApplicationGateway() *schema.Resource { ValidateFunc: validation.IntBetween(1, 500), Default: 100, }, - }, - }, - }, - - "custom_error_configuration": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "status_code": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - string(network.HTTPStatus403), - string(network.HTTPStatus502), - }, false), + "request_body_check": { + Type: schema.TypeBool, + Optional: true, + Default: true, }, - - "custom_error_page_url": { - Type: schema.TypeString, - Required: true, + "max_request_body_size_kb": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 128), + Default: 128, + }, + "disabled_rule_group": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "rule_group_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "crs_20_protocol_violations", + "crs_21_protocol_anomalies", + "crs_23_request_limits", + "crs_30_http_policy", + "crs_35_bad_robots", + "crs_40_generic_attacks", + "crs_41_sql_injection_attacks", + "crs_41_xss_attacks", + "crs_42_tight_security", + "crs_45_trojans", + "General", + "REQUEST-911-METHOD-ENFORCEMENT", + "REQUEST-913-SCANNER-DETECTION", + "REQUEST-920-PROTOCOL-ENFORCEMENT", + "REQUEST-921-PROTOCOL-ATTACK", + "REQUEST-930-APPLICATION-ATTACK-LFI", + "REQUEST-931-APPLICATION-ATTACK-RFI", + "REQUEST-932-APPLICATION-ATTACK-RCE", + "REQUEST-933-APPLICATION-ATTACK-PHP", + "REQUEST-941-APPLICATION-ATTACK-XSS", + "REQUEST-942-APPLICATION-ATTACK-SQLI", + "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION", + }, false), + }, + + "rules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + ValidateFunc: validation.IntAtLeast(1), + }, + }, + }, + }, + }, + "exclusion": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "match_variable": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "RequestHeaderNames", + "RequestArgNames", + "RequestCookieNames", + }, false), + }, + + "selector_match_operator": { + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + "Equals", + "StartsWith", + "EndsWith", + "Contains", + }, false), + Optional: true, + }, + "selector": { + ValidateFunc: validate.NoEmptyStrings, + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + }, + }, + }, + + "custom_error_configuration": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "status_code": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.HTTPStatus403), + string(network.HTTPStatus502), + }, false), + }, + + "custom_error_page_url": { + Type: schema.TypeString, + Required: true, }, "id": { @@ -842,14 +1288,14 @@ func resourceArmApplicationGateway() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta interface{}) error { armClient := meta.(*ArmClient) - client := armClient.applicationGatewayClient + client := armClient.network.ApplicationGatewaysClient ctx := armClient.StopContext log.Printf("[INFO] preparing arguments for Application Gateway creation.") @@ -857,7 +1303,7 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -870,9 +1316,9 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) enablehttp2 := d.Get("enable_http2").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) // Gateway ID is needed to link sub-resources together in expand functions gatewayIDFmt := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/applicationGateways/%s" @@ -883,20 +1329,37 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte backendHTTPSettingsCollection := expandApplicationGatewayBackendHTTPSettings(d, gatewayID) frontendIPConfigurations := expandApplicationGatewayFrontendIPConfigurations(d) frontendPorts := expandApplicationGatewayFrontendPorts(d) - gatewayIPConfigurations := expandApplicationGatewayIPConfigurations(d) + gatewayIPConfigurations, stopApplicationGateway := expandApplicationGatewayIPConfigurations(d) httpListeners := expandApplicationGatewayHTTPListeners(d, gatewayID) probes := expandApplicationGatewayProbes(d) - requestRoutingRules := expandApplicationGatewayRequestRoutingRules(d, gatewayID) sku := expandApplicationGatewaySku(d) + autoscaleConfiguration := expandApplicationGatewayAutoscaleConfiguration(d) sslCertificates := expandApplicationGatewaySslCertificates(d) sslPolicy := expandApplicationGatewaySslPolicy(d) customErrorConfigurations := expandApplicationGatewayCustomErrorConfigurations(d.Get("custom_error_configuration").([]interface{})) - urlPathMaps := expandApplicationGatewayURLPathMaps(d, gatewayID) + rewriteRuleSets := expandApplicationGatewayRewriteRuleSets(d) + zones := azure.ExpandZones(d.Get("zones").([]interface{})) + + requestRoutingRules, err := expandApplicationGatewayRequestRoutingRules(d, gatewayID) + if err != nil { + return fmt.Errorf("Error expanding `request_routing_rule`: %+v", err) + } + + urlPathMaps, err := expandApplicationGatewayURLPathMaps(d, gatewayID) + if err != nil { + return fmt.Errorf("Error expanding `url_path_map`: %+v", err) + } + + redirectConfigurations, err := expandApplicationGatewayRedirectConfigurations(d, gatewayID) + if err != nil { + return fmt.Errorf("Error expanding `redirect_configuration`: %+v", err) + } gateway := network.ApplicationGateway{ Location: utils.String(location), + Zones: zones, - Tags: expandTags(tags), + Tags: tags.Expand(t), ApplicationGatewayPropertiesFormat: &network.ApplicationGatewayPropertiesFormat{ AuthenticationCertificates: authenticationCertificates, BackendAddressPools: backendAddressPools, @@ -908,25 +1371,46 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte HTTPListeners: httpListeners, Probes: probes, RequestRoutingRules: requestRoutingRules, + RedirectConfigurations: redirectConfigurations, Sku: sku, SslCertificates: sslCertificates, SslPolicy: sslPolicy, CustomErrorConfigurations: customErrorConfigurations, + RewriteRuleSets: rewriteRuleSets, URLPathMaps: urlPathMaps, + AutoscaleConfiguration: autoscaleConfiguration, }, } - for _, probe := range *probes { - probeProperties := *probe.ApplicationGatewayProbePropertiesFormat - host := *probeProperties.Host - pick := *probeProperties.PickHostNameFromBackendHTTPSettings + if _, ok := d.GetOk("identity"); ok { + gateway.Identity = expandAzureRmApplicationGatewayIdentity(d) + } - if host == "" && !pick { - return fmt.Errorf("One of `host` or `pick_host_name_from_backend_http_settings` must be set") + for _, backendHttpSettings := range *backendHTTPSettingsCollection { + if props := backendHttpSettings.ApplicationGatewayBackendHTTPSettingsPropertiesFormat; props != nil { + if props.HostName == nil || props.PickHostNameFromBackendAddress == nil { + continue + } + + if *props.HostName != "" && *props.PickHostNameFromBackendAddress { + return fmt.Errorf("Only one of `host_name` or `pick_host_name_from_backend_address` can be set") + } } + } - if host != "" && pick { - return fmt.Errorf("Only one of `host` or `pick_host_name_from_backend_http_settings` can be set") + for _, probe := range *probes { + if props := probe.ApplicationGatewayProbePropertiesFormat; props != nil { + if props.Host == nil || props.PickHostNameFromBackendHTTPSettings == nil { + continue + } + + if *props.Host == "" && !*props.PickHostNameFromBackendHTTPSettings { + return fmt.Errorf("One of `host` or `pick_host_name_from_backend_http_settings` must be set") + } + + if *props.Host != "" && *props.PickHostNameFromBackendHTTPSettings { + return fmt.Errorf("Only one of `host` or `pick_host_name_from_backend_http_settings` can be set") + } } } @@ -934,6 +1418,17 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte gateway.ApplicationGatewayPropertiesFormat.WebApplicationFirewallConfiguration = expandApplicationGatewayWafConfig(d) } + if stopApplicationGateway { + future, err := client.Stop(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error Stopping Application Gateway %q (Resource Group %q): %+v", name, resGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for the Application Gateway %q (Resource Group %q) to stop: %+v", name, resGroup, err) + } + } + future, err := client.CreateOrUpdate(ctx, resGroup, name, gateway) if err != nil { return fmt.Errorf("Error Creating/Updating Application Gateway %q (Resource Group %q): %+v", name, resGroup, err) @@ -943,6 +1438,17 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte return fmt.Errorf("Error waiting for the create/update of Application Gateway %q (Resource Group %q): %+v", name, resGroup, err) } + if stopApplicationGateway { + future, err := client.Start(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error Starting Application Gateway %q (Resource Group %q): %+v", name, resGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for the Application Gateway %q (Resource Group %q) to start: %+v", name, resGroup, err) + } + } + read, err := client.Get(ctx, resGroup, name) if err != nil { return fmt.Errorf("Error retrieving Application Gateway %q (Resource Group %q): %+v", name, resGroup, err) @@ -957,10 +1463,10 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmApplicationGatewayRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationGatewayClient + client := meta.(*ArmClient).network.ApplicationGatewaysClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -981,7 +1487,13 @@ func resourceArmApplicationGatewayRead(d *schema.ResourceData, meta interface{}) d.Set("name", applicationGateway.Name) d.Set("resource_group_name", id.ResourceGroup) if location := applicationGateway.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) + } + d.Set("zones", applicationGateway.Zones) + + identity := flattenRmApplicationGatewayIdentity(applicationGateway.Identity) + if err := d.Set("identity", identity); err != nil { + return err } if props := applicationGateway.ApplicationGatewayPropertiesFormat; props != nil { @@ -1006,6 +1518,10 @@ func resourceArmApplicationGatewayRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error setting `disabled_ssl_protocols`: %+v", setErr) } + if setErr := d.Set("ssl_policy", flattenApplicationGatewaySslPolicy(props.SslPolicy)); setErr != nil { + return fmt.Errorf("Error setting `ssl_policy`: %+v", setErr) + } + d.Set("enable_http2", props.EnableHTTP2) httpListeners, err := flattenApplicationGatewayHTTPListeners(props.HTTPListeners) @@ -1040,10 +1556,27 @@ func resourceArmApplicationGatewayRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error setting `request_routing_rule`: %+v", setErr) } + redirectConfigurations, err := flattenApplicationGatewayRedirectConfigurations(props.RedirectConfigurations) + if err != nil { + return fmt.Errorf("Error flattening `redirect configuration`: %+v", err) + } + if setErr := d.Set("redirect_configuration", redirectConfigurations); setErr != nil { + return fmt.Errorf("Error setting `redirect configuration`: %+v", setErr) + } + + rewriteRuleSets := flattenApplicationGatewayRewriteRuleSets(props.RewriteRuleSets) + if setErr := d.Set("rewrite_rule_set", rewriteRuleSets); setErr != nil { + return fmt.Errorf("Error setting `rewrite_rule_set`: %+v", setErr) + } + if setErr := d.Set("sku", flattenApplicationGatewaySku(props.Sku)); setErr != nil { return fmt.Errorf("Error setting `sku`: %+v", setErr) } + if setErr := d.Set("autoscale_configuration", flattenApplicationGatewayAutoscaleConfiguration(props.AutoscaleConfiguration)); setErr != nil { + return fmt.Errorf("Error setting `autoscale_configuration`: %+v", setErr) + } + if setErr := d.Set("ssl_certificate", flattenApplicationGatewaySslCertificates(props.SslCertificates, d)); setErr != nil { return fmt.Errorf("Error setting `ssl_certificate`: %+v", setErr) } @@ -1065,16 +1598,14 @@ func resourceArmApplicationGatewayRead(d *schema.ResourceData, meta interface{}) } } - flattenAndSetTags(d, applicationGateway.Tags) - - return nil + return tags.FlattenAndSet(d, applicationGateway.Tags) } func resourceArmApplicationGatewayDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationGatewayClient + client := meta.(*ArmClient).network.ApplicationGatewaysClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -1093,6 +1624,50 @@ func resourceArmApplicationGatewayDelete(d *schema.ResourceData, meta interface{ return nil } +func expandAzureRmApplicationGatewayIdentity(d *schema.ResourceData) *network.ManagedServiceIdentity { + v := d.Get("identity") + identities := v.([]interface{}) + identity := identities[0].(map[string]interface{}) + identityType := network.ResourceIdentityType(identity["type"].(string)) + + identityIds := make(map[string]*network.ManagedServiceIdentityUserAssignedIdentitiesValue) + for _, id := range identity["identity_ids"].([]interface{}) { + identityIds[id.(string)] = &network.ManagedServiceIdentityUserAssignedIdentitiesValue{} + } + + appGatewayIdentity := network.ManagedServiceIdentity{ + Type: identityType, + } + + if identityType == network.ResourceIdentityTypeUserAssigned { + appGatewayIdentity.UserAssignedIdentities = identityIds + } + + return &appGatewayIdentity +} + +func flattenRmApplicationGatewayIdentity(identity *network.ManagedServiceIdentity) []interface{} { + if identity == nil { + return make([]interface{}, 0) + } + + result := make(map[string]interface{}) + result["type"] = string(identity.Type) + if result["type"] == "userAssigned" { + result["type"] = "UserAssigned" + } + + identityIds := make([]string, 0) + if identity.UserAssignedIdentities != nil { + for key := range identity.UserAssignedIdentities { + identityIds = append(identityIds, key) + } + } + result["identity_ids"] = identityIds + + return []interface{}{result} +} + func expandApplicationGatewayAuthenticationCertificates(d *schema.ResourceData) *[]network.ApplicationGatewayAuthenticationCertificate { vs := d.Get("authentication_certificate").([]interface{}) results := make([]network.ApplicationGatewayAuthenticationCertificate, 0) @@ -1139,7 +1714,7 @@ func flattenApplicationGatewayAuthenticationCertificates(input *[]network.Applic // since the certificate data isn't returned we have to load it from the same index if existing, ok := d.GetOk("authentication_certificate"); ok && existing != nil { existingVals := existing.([]interface{}) - if len(existingVals) >= i { + if len(existingVals) > i { existingCerts := existingVals[i].(map[string]interface{}) if data := existingCerts["data"]; data != nil { output["data"] = data.(string) @@ -1172,17 +1747,19 @@ func expandApplicationGatewayBackendAddressPools(d *schema.ResourceData) *[]netw }) } - // TODO: remove in 2.0 - for _, ip := range v["ip_address_list"].([]interface{}) { - backendAddresses = append(backendAddresses, network.ApplicationGatewayBackendAddress{ - IPAddress: utils.String(ip.(string)), - }) - } - // TODO: remove in 2.0 - for _, ip := range v["fqdn_list"].([]interface{}) { - backendAddresses = append(backendAddresses, network.ApplicationGatewayBackendAddress{ - Fqdn: utils.String(ip.(string)), - }) + if len(backendAddresses) == 0 { + // TODO: remove in 2.0 + for _, ip := range v["ip_address_list"].([]interface{}) { + backendAddresses = append(backendAddresses, network.ApplicationGatewayBackendAddress{ + IPAddress: utils.String(ip.(string)), + }) + } + // TODO: remove in 2.0 + for _, ip := range v["fqdn_list"].([]interface{}) { + backendAddresses = append(backendAddresses, network.ApplicationGatewayBackendAddress{ + Fqdn: utils.String(ip.(string)), + }) + } } name := v["name"].(string) @@ -1272,6 +1849,16 @@ func expandApplicationGatewayBackendHTTPSettings(d *schema.ResourceData, gateway }, } + hostName := v["host_name"].(string) + if hostName != "" { + setting.ApplicationGatewayBackendHTTPSettingsPropertiesFormat.HostName = utils.String(hostName) + } + + affinityCookieName := v["affinity_cookie_name"].(string) + if affinityCookieName != "" { + setting.AffinityCookieName = utils.String(affinityCookieName) + } + if v["authentication_certificate"] != nil { authCerts := v["authentication_certificate"].([]interface{}) authCertSubResources := make([]network.SubResource, 0) @@ -1324,6 +1911,10 @@ func flattenApplicationGatewayBackendHTTPSettings(input *[]network.ApplicationGa if props := v.ApplicationGatewayBackendHTTPSettingsPropertiesFormat; props != nil { output["cookie_based_affinity"] = string(props.CookieBasedAffinity) + if affinityCookieName := props.AffinityCookieName; affinityCookieName != nil { + output["affinity_cookie_name"] = affinityCookieName + } + if path := props.Path; path != nil { output["path"] = *path } @@ -1333,6 +1924,10 @@ func flattenApplicationGatewayBackendHTTPSettings(input *[]network.ApplicationGa output["port"] = int(*port) } + if hostName := props.HostName; hostName != nil { + output["host_name"] = *hostName + } + if pickHostNameFromBackendAddress := props.PickHostNameFromBackendAddress; pickHostNameFromBackendAddress != nil { output["pick_host_name_from_backend_address"] = *pickHostNameFromBackendAddress } @@ -1350,7 +1945,7 @@ func flattenApplicationGatewayBackendHTTPSettings(input *[]network.ApplicationGa continue } - certId, err := parseAzureResourceID(*cert.ID) + certId, err := azure.ParseAzureResourceID(*cert.ID) if err != nil { return nil, err } @@ -1367,7 +1962,7 @@ func flattenApplicationGatewayBackendHTTPSettings(input *[]network.ApplicationGa if probe := props.Probe; probe != nil { if probe.ID != nil { - id, err := parseAzureResourceID(*probe.ID) + id, err := azure.ParseAzureResourceID(*probe.ID) if err != nil { return results, err } @@ -1416,16 +2011,94 @@ func flattenApplicationGatewayConnectionDraining(input *network.ApplicationGatew } func expandApplicationGatewaySslPolicy(d *schema.ResourceData) *network.ApplicationGatewaySslPolicy { - vs := d.Get("disabled_ssl_protocols").([]interface{}) - results := make([]network.ApplicationGatewaySslProtocol, 0) + policy := network.ApplicationGatewaySslPolicy{} + disabledSSLPolicies := make([]network.ApplicationGatewaySslProtocol, 0) - for _, v := range vs { - results = append(results, network.ApplicationGatewaySslProtocol(v.(string))) + vs := d.Get("ssl_policy").([]interface{}) + vsdsp := d.Get("disabled_ssl_protocols").([]interface{}) + + if len(vsdsp) == 0 && len(vs) == 0 { + policy = network.ApplicationGatewaySslPolicy{ + DisabledSslProtocols: &disabledSSLPolicies, + } } - return &network.ApplicationGatewaySslPolicy{ - DisabledSslProtocols: &results, + for _, policy := range vsdsp { + disabledSSLPolicies = append(disabledSSLPolicies, network.ApplicationGatewaySslProtocol(policy.(string))) } + + if len(vs) > 0 { + v := vs[0].(map[string]interface{}) + policyType := network.ApplicationGatewaySslPolicyType(v["policy_type"].(string)) + + // reset disabledSSLPolicies here to always use the new disabled_protocols block in favor of disabled_ssl_protocols + disabledSSLPolicies = disabledSSLPolicies[:0] + + for _, policy := range v["disabled_protocols"].([]interface{}) { + disabledSSLPolicies = append(disabledSSLPolicies, network.ApplicationGatewaySslProtocol(policy.(string))) + } + + if policyType == network.Predefined { + policyName := network.ApplicationGatewaySslPolicyName(v["policy_name"].(string)) + policy = network.ApplicationGatewaySslPolicy{ + PolicyType: policyType, + PolicyName: policyName, + } + } else if policyType == network.Custom { + minProtocolVersion := network.ApplicationGatewaySslProtocol(v["min_protocol_version"].(string)) + cipherSuites := make([]network.ApplicationGatewaySslCipherSuite, 0) + + for _, cipherSuite := range v["cipher_suites"].([]interface{}) { + cipherSuites = append(cipherSuites, network.ApplicationGatewaySslCipherSuite(cipherSuite.(string))) + } + + policy = network.ApplicationGatewaySslPolicy{ + PolicyType: policyType, + MinProtocolVersion: minProtocolVersion, + CipherSuites: &cipherSuites, + } + } + } + + if len(disabledSSLPolicies) > 0 { + policy = network.ApplicationGatewaySslPolicy{ + DisabledSslProtocols: &disabledSSLPolicies, + } + } + + return &policy +} + +func flattenApplicationGatewaySslPolicy(input *network.ApplicationGatewaySslPolicy) []interface{} { + results := make([]interface{}, 0) + + if input == nil { + return results + } + + output := map[string]interface{}{} + output["policy_name"] = input.PolicyName + output["policy_type"] = input.PolicyType + output["min_protocol_version"] = input.MinProtocolVersion + + cipherSuites := make([]interface{}, 0) + if input.CipherSuites != nil { + for _, v := range *input.CipherSuites { + cipherSuites = append(cipherSuites, string(v)) + } + } + output["cipher_suites"] = cipherSuites + + disabledSslProtocols := make([]interface{}, 0) + if input.DisabledSslProtocols != nil { + for _, v := range *input.DisabledSslProtocols { + disabledSslProtocols = append(disabledSslProtocols, string(v)) + } + } + output["disabled_protocols"] = disabledSslProtocols + + results = append(results, output) + return results } func flattenApplicationGatewayDisabledSSLProtocols(input *network.ApplicationGatewaySslPolicy) []interface{} { @@ -1511,7 +2184,7 @@ func flattenApplicationGatewayHTTPListeners(input *[]network.ApplicationGatewayH if props := v.ApplicationGatewayHTTPListenerPropertiesFormat; props != nil { if port := props.FrontendPort; port != nil { if port.ID != nil { - portId, err := parseAzureResourceID(*port.ID) + portId, err := azure.ParseAzureResourceID(*port.ID) if err != nil { return nil, err } @@ -1523,7 +2196,7 @@ func flattenApplicationGatewayHTTPListeners(input *[]network.ApplicationGatewayH if feConfig := props.FrontendIPConfiguration; feConfig != nil { if feConfig.ID != nil { - feConfigId, err := parseAzureResourceID(*feConfig.ID) + feConfigId, err := azure.ParseAzureResourceID(*feConfig.ID) if err != nil { return nil, err } @@ -1541,7 +2214,7 @@ func flattenApplicationGatewayHTTPListeners(input *[]network.ApplicationGatewayH if cert := props.SslCertificate; cert != nil { if cert.ID != nil { - certId, err := parseAzureResourceID(*cert.ID) + certId, err := azure.ParseAzureResourceID(*cert.ID) if err != nil { return nil, err } @@ -1565,9 +2238,10 @@ func flattenApplicationGatewayHTTPListeners(input *[]network.ApplicationGatewayH return results, nil } -func expandApplicationGatewayIPConfigurations(d *schema.ResourceData) *[]network.ApplicationGatewayIPConfiguration { +func expandApplicationGatewayIPConfigurations(d *schema.ResourceData) (*[]network.ApplicationGatewayIPConfiguration, bool) { vs := d.Get("gateway_ip_configuration").([]interface{}) results := make([]network.ApplicationGatewayIPConfiguration, 0) + stopApplicationGateway := false for _, configRaw := range vs { data := configRaw.(map[string]interface{}) @@ -1586,7 +2260,35 @@ func expandApplicationGatewayIPConfigurations(d *schema.ResourceData) *[]network results = append(results, output) } - return &results + if d.HasChange("gateway_ip_configuration") { + oldRaw, newRaw := d.GetChange("gateway_ip_configuration") + oldVS := oldRaw.([]interface{}) + newVS := newRaw.([]interface{}) + + // If we're creating the application gateway return the current gateway ip configuration. + if len(oldVS) == 0 { + return &results, false + } + + // The application gateway needs to be stopped if a gateway ip configuration is added or removed + if len(oldVS) != len(newVS) { + stopApplicationGateway = true + } + + for i, configRaw := range newVS { + newData := configRaw.(map[string]interface{}) + oldData := oldVS[i].(map[string]interface{}) + + newSubnetID := newData["subnet_id"].(string) + oldSubnetID := oldData["subnet_id"].(string) + // The application gateway needs to be shutdown if the subnet ids don't match + if newSubnetID != oldSubnetID { + stopApplicationGateway = true + } + } + } + + return &results, stopApplicationGateway } func flattenApplicationGatewayIPConfigurations(input *[]network.ApplicationGatewayIPConfiguration) []interface{} { @@ -1876,7 +2578,7 @@ func flattenApplicationGatewayProbes(input *[]network.ApplicationGatewayProbe) [ return results } -func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gatewayID string) *[]network.ApplicationGatewayRequestRoutingRule { +func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gatewayID string) (*[]network.ApplicationGatewayRequestRoutingRule, error) { vs := d.Get("request_routing_rule").([]interface{}) results := make([]network.ApplicationGatewayRequestRoutingRule, 0) @@ -1887,6 +2589,9 @@ func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gateway ruleType := v["rule_type"].(string) httpListenerName := v["http_listener_name"].(string) httpListenerID := fmt.Sprintf("%s/httpListeners/%s", gatewayID, httpListenerName) + backendAddressPoolName := v["backend_address_pool_name"].(string) + backendHTTPSettingsName := v["backend_http_settings_name"].(string) + redirectConfigName := v["redirect_configuration_name"].(string) rule := network.ApplicationGatewayRequestRoutingRule{ Name: utils.String(name), @@ -1898,20 +2603,35 @@ func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gateway }, } - if backendAddressPoolName := v["backend_address_pool_name"].(string); backendAddressPoolName != "" { + if backendAddressPoolName != "" && redirectConfigName != "" { + return nil, fmt.Errorf("Conflict between `backend_address_pool_name` and `redirect_configuration_name` (back-end pool not applicable when redirection specified)") + } + + if backendHTTPSettingsName != "" && redirectConfigName != "" { + return nil, fmt.Errorf("Conflict between `backend_http_settings_name` and `redirect_configuration_name` (back-end settings not applicable when redirection specified)") + } + + if backendAddressPoolName != "" { backendAddressPoolID := fmt.Sprintf("%s/backendAddressPools/%s", gatewayID, backendAddressPoolName) rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.BackendAddressPool = &network.SubResource{ ID: utils.String(backendAddressPoolID), } } - if backendHTTPSettingsName := v["backend_http_settings_name"].(string); backendHTTPSettingsName != "" { + if backendHTTPSettingsName != "" { backendHTTPSettingsID := fmt.Sprintf("%s/backendHttpSettingsCollection/%s", gatewayID, backendHTTPSettingsName) rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.BackendHTTPSettings = &network.SubResource{ ID: utils.String(backendHTTPSettingsID), } } + if redirectConfigName != "" { + redirectConfigID := fmt.Sprintf("%s/redirectConfigurations/%s", gatewayID, redirectConfigName) + rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.RedirectConfiguration = &network.SubResource{ + ID: utils.String(redirectConfigID), + } + } + if urlPathMapName := v["url_path_map_name"].(string); urlPathMapName != "" { urlPathMapID := fmt.Sprintf("%s/urlPathMaps/%s", gatewayID, urlPathMapName) rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.URLPathMap = &network.SubResource{ @@ -1919,10 +2639,17 @@ func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gateway } } + if rewriteRuleSetName := v["rewrite_rule_set_name"].(string); rewriteRuleSetName != "" { + rewriteRuleSetID := fmt.Sprintf("%s/rewriteRuleSets/%s", gatewayID, rewriteRuleSetName) + rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.RewriteRuleSet = &network.SubResource{ + ID: utils.String(rewriteRuleSetID), + } + } + results = append(results, rule) } - return &results + return &results, nil } func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGatewayRequestRoutingRule) ([]interface{}, error) { @@ -1948,7 +2675,7 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa if pool := props.BackendAddressPool; pool != nil { if pool.ID != nil { - poolId, err := parseAzureResourceID(*pool.ID) + poolId, err := azure.ParseAzureResourceID(*pool.ID) if err != nil { return nil, err } @@ -1960,7 +2687,7 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa if settings := props.BackendHTTPSettings; settings != nil { if settings.ID != nil { - settingsId, err := parseAzureResourceID(*settings.ID) + settingsId, err := azure.ParseAzureResourceID(*settings.ID) if err != nil { return nil, err } @@ -1972,7 +2699,7 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa if listener := props.HTTPListener; listener != nil { if listener.ID != nil { - listenerId, err := parseAzureResourceID(*listener.ID) + listenerId, err := azure.ParseAzureResourceID(*listener.ID) if err != nil { return nil, err } @@ -1984,7 +2711,7 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa if pathMap := props.URLPathMap; pathMap != nil { if pathMap.ID != nil { - pathMapId, err := parseAzureResourceID(*pathMap.ID) + pathMapId, err := azure.ParseAzureResourceID(*pathMap.ID) if err != nil { return nil, err } @@ -1994,6 +2721,30 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa } } + if redirect := props.RedirectConfiguration; redirect != nil { + if redirect.ID != nil { + redirectId, err := azure.ParseAzureResourceID(*redirect.ID) + if err != nil { + return nil, err + } + redirectName := redirectId.Path["redirectConfigurations"] + output["redirect_configuration_name"] = redirectName + output["redirect_configuration_id"] = *redirect.ID + } + } + + if rewrite := props.RewriteRuleSet; rewrite != nil { + if rewrite.ID != nil { + rewriteId, err := azure.ParseAzureResourceID(*rewrite.ID) + if err != nil { + return nil, err + } + rewriteName := rewriteId.Path["rewriteRuleSets"] + output["rewrite_rule_set_name"] = rewriteName + output["rewrite_rule_set_id"] = *rewrite.ID + } + } + results = append(results, output) } } @@ -2001,6 +2752,328 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa return results, nil } +func expandApplicationGatewayRewriteRuleSets(d *schema.ResourceData) *[]network.ApplicationGatewayRewriteRuleSet { + vs := d.Get("rewrite_rule_set").([]interface{}) + ruleSets := make([]network.ApplicationGatewayRewriteRuleSet, 0) + + for _, raw := range vs { + v := raw.(map[string]interface{}) + rules := make([]network.ApplicationGatewayRewriteRule, 0) + + name := v["name"].(string) + + for _, ruleConfig := range v["rewrite_rule"].([]interface{}) { + r := ruleConfig.(map[string]interface{}) + conditions := make([]network.ApplicationGatewayRewriteRuleCondition, 0) + requestConfigurations := make([]network.ApplicationGatewayHeaderConfiguration, 0) + responseConfigurations := make([]network.ApplicationGatewayHeaderConfiguration, 0) + + rule := network.ApplicationGatewayRewriteRule{ + Name: utils.String(r["name"].(string)), + RuleSequence: utils.Int32(int32(r["rule_sequence"].(int))), + } + + for _, rawCondition := range r["condition"].([]interface{}) { + c := rawCondition.(map[string]interface{}) + condition := network.ApplicationGatewayRewriteRuleCondition{ + Variable: utils.String(c["variable"].(string)), + Pattern: utils.String(c["pattern"].(string)), + IgnoreCase: utils.Bool(c["ignore_case"].(bool)), + Negate: utils.Bool(c["negate"].(bool)), + } + conditions = append(conditions, condition) + } + rule.Conditions = &conditions + + for _, rawConfig := range r["request_header_configuration"].([]interface{}) { + c := rawConfig.(map[string]interface{}) + config := network.ApplicationGatewayHeaderConfiguration{ + HeaderName: utils.String(c["header_name"].(string)), + HeaderValue: utils.String(c["header_value"].(string)), + } + requestConfigurations = append(requestConfigurations, config) + } + + for _, rawConfig := range r["response_header_configuration"].([]interface{}) { + c := rawConfig.(map[string]interface{}) + config := network.ApplicationGatewayHeaderConfiguration{ + HeaderName: utils.String(c["header_name"].(string)), + HeaderValue: utils.String(c["header_value"].(string)), + } + responseConfigurations = append(responseConfigurations, config) + } + + rule.ActionSet = &network.ApplicationGatewayRewriteRuleActionSet{ + RequestHeaderConfigurations: &requestConfigurations, + ResponseHeaderConfigurations: &responseConfigurations, + } + rules = append(rules, rule) + } + + ruleSet := network.ApplicationGatewayRewriteRuleSet{ + Name: utils.String(name), + ApplicationGatewayRewriteRuleSetPropertiesFormat: &network.ApplicationGatewayRewriteRuleSetPropertiesFormat{ + RewriteRules: &rules, + }, + } + + ruleSets = append(ruleSets, ruleSet) + } + + return &ruleSets +} + +func flattenApplicationGatewayRewriteRuleSets(input *[]network.ApplicationGatewayRewriteRuleSet) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + for _, config := range *input { + if props := config.ApplicationGatewayRewriteRuleSetPropertiesFormat; props != nil { + + output := map[string]interface{}{} + + if config.ID != nil { + output["id"] = *config.ID + } + + if config.Name != nil { + output["name"] = *config.Name + } + + if rulesConfig := props.RewriteRules; rulesConfig != nil { + rules := make([]interface{}, 0) + for _, rule := range *rulesConfig { + + ruleOutput := map[string]interface{}{} + + if rule.Name != nil { + ruleOutput["name"] = *rule.Name + } + + if rule.RuleSequence != nil { + ruleOutput["rule_sequence"] = *rule.RuleSequence + } + + conditions := make([]interface{}, 0) + if rule.Conditions != nil { + for _, config := range *rule.Conditions { + condition := map[string]interface{}{} + + if config.Variable != nil { + condition["variable"] = *config.Variable + } + + if config.Pattern != nil { + condition["pattern"] = *config.Pattern + } + + if config.IgnoreCase != nil { + condition["ignore_case"] = *config.IgnoreCase + } + + if config.Negate != nil { + condition["negate"] = *config.Negate + } + + conditions = append(conditions, condition) + } + } + ruleOutput["condition"] = conditions + + requestConfigs := make([]interface{}, 0) + responseConfigs := make([]interface{}, 0) + if rule.ActionSet != nil { + actionSet := *rule.ActionSet + + if actionSet.RequestHeaderConfigurations != nil { + for _, config := range *actionSet.RequestHeaderConfigurations { + requestConfig := map[string]interface{}{} + + if config.HeaderName != nil { + requestConfig["header_name"] = *config.HeaderName + } + + if config.HeaderValue != nil { + requestConfig["header_value"] = *config.HeaderValue + } + + requestConfigs = append(requestConfigs, requestConfig) + } + } + + if actionSet.ResponseHeaderConfigurations != nil { + for _, config := range *actionSet.ResponseHeaderConfigurations { + responseConfig := map[string]interface{}{} + + if config.HeaderName != nil { + responseConfig["header_name"] = *config.HeaderName + } + + if config.HeaderValue != nil { + responseConfig["header_value"] = *config.HeaderValue + } + + responseConfigs = append(responseConfigs, responseConfig) + } + } + } + ruleOutput["request_header_configuration"] = requestConfigs + ruleOutput["response_header_configuration"] = responseConfigs + + rules = append(rules, ruleOutput) + } + output["rewrite_rule"] = rules + } + results = append(results, output) + } + } + + return results +} + +func expandApplicationGatewayRedirectConfigurations(d *schema.ResourceData, gatewayID string) (*[]network.ApplicationGatewayRedirectConfiguration, error) { + + vs := d.Get("redirect_configuration").([]interface{}) + results := make([]network.ApplicationGatewayRedirectConfiguration, 0) + + for _, raw := range vs { + v := raw.(map[string]interface{}) + + name := v["name"].(string) + redirectType := v["redirect_type"].(string) + targetListenerName := v["target_listener_name"].(string) + targetUrl := v["target_url"].(string) + includePath := v["include_path"].(bool) + includeQueryString := v["include_query_string"].(bool) + + output := network.ApplicationGatewayRedirectConfiguration{ + Name: utils.String(name), + ApplicationGatewayRedirectConfigurationPropertiesFormat: &network.ApplicationGatewayRedirectConfigurationPropertiesFormat{ + RedirectType: network.ApplicationGatewayRedirectType(redirectType), + IncludeQueryString: utils.Bool(includeQueryString), + }, + } + + if targetListenerName == "" && targetUrl == "" { + return nil, fmt.Errorf("Set either `target_listener_name` or `target_url`") + } + + if targetListenerName != "" && targetUrl != "" { + return nil, fmt.Errorf("Conflict between `target_listener_name` and `target_url` (redirection is either to URL or target listener)") + } + + if targetUrl != "" && includePath { + return nil, fmt.Errorf("`include_path` is not a valid option when `target_url` is set") + } + + if targetListenerName != "" { + targetListenerID := fmt.Sprintf("%s/httpListeners/%s", gatewayID, targetListenerName) + output.ApplicationGatewayRedirectConfigurationPropertiesFormat.TargetListener = &network.SubResource{ + ID: utils.String(targetListenerID), + } + output.ApplicationGatewayRedirectConfigurationPropertiesFormat.IncludePath = utils.Bool(includePath) + } + + if targetUrl != "" { + output.ApplicationGatewayRedirectConfigurationPropertiesFormat.TargetURL = utils.String(targetUrl) + } + + results = append(results, output) + } + + return &results, nil +} + +func flattenApplicationGatewayRedirectConfigurations(input *[]network.ApplicationGatewayRedirectConfiguration) ([]interface{}, error) { + results := make([]interface{}, 0) + if input == nil { + return results, nil + } + + for _, config := range *input { + if props := config.ApplicationGatewayRedirectConfigurationPropertiesFormat; props != nil { + + output := map[string]interface{}{ + "redirect_type": string(props.RedirectType), + } + + if config.ID != nil { + output["id"] = *config.ID + } + + if config.Name != nil { + output["name"] = *config.Name + } + + if listener := props.TargetListener; listener != nil { + if listener.ID != nil { + listenerId, err := azure.ParseAzureResourceID(*listener.ID) + if err != nil { + return nil, err + } + targetListenerName := listenerId.Path["httpListeners"] + output["target_listener_name"] = targetListenerName + output["target_listener_id"] = *listener.ID + } + } + + if config.TargetURL != nil { + output["target_url"] = *config.TargetURL + } + + if config.IncludePath != nil { + output["include_path"] = *config.IncludePath + } + + if config.IncludeQueryString != nil { + output["include_query_string"] = *config.IncludeQueryString + } + + results = append(results, output) + } + } + + return results, nil +} + +func expandApplicationGatewayAutoscaleConfiguration(d *schema.ResourceData) *network.ApplicationGatewayAutoscaleConfiguration { + vs := d.Get("autoscale_configuration").([]interface{}) + if len(vs) == 0 { + return nil + } + v := vs[0].(map[string]interface{}) + + minCapacity := int32(v["min_capacity"].(int)) + maxCapacity := int32(v["max_capacity"].(int)) + + configuration := network.ApplicationGatewayAutoscaleConfiguration{ + MinCapacity: utils.Int32(minCapacity), + } + + if maxCapacity != 0 { + configuration.MaxCapacity = utils.Int32(maxCapacity) + } + + return &configuration +} + +func flattenApplicationGatewayAutoscaleConfiguration(input *network.ApplicationGatewayAutoscaleConfiguration) []interface{} { + result := make(map[string]interface{}) + if input == nil { + return []interface{}{} + } + if v := input.MinCapacity; v != nil { + result["min_capacity"] = *v + } + if input.MaxCapacity != nil { + result["max_capacity"] = *input.MaxCapacity + } + + return []interface{}{result} +} + func expandApplicationGatewaySku(d *schema.ResourceData) *network.ApplicationGatewaySku { vs := d.Get("sku").([]interface{}) v := vs[0].(map[string]interface{}) @@ -2009,11 +3082,16 @@ func expandApplicationGatewaySku(d *schema.ResourceData) *network.ApplicationGat tier := v["tier"].(string) capacity := int32(v["capacity"].(int)) - return &network.ApplicationGatewaySku{ - Name: network.ApplicationGatewaySkuName(name), - Tier: network.ApplicationGatewayTier(tier), - Capacity: utils.Int32(capacity), + sku := network.ApplicationGatewaySku{ + Name: network.ApplicationGatewaySkuName(name), + Tier: network.ApplicationGatewayTier(tier), + } + + if capacity != 0 { + sku.Capacity = utils.Int32(capacity) } + + return &sku } func flattenApplicationGatewaySku(input *network.ApplicationGatewaySku) []interface{} { @@ -2108,7 +3186,7 @@ func flattenApplicationGatewaySslCertificates(input *[]network.ApplicationGatewa return results } -func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID string) *[]network.ApplicationGatewayURLPathMap { +func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID string) (*[]network.ApplicationGatewayURLPathMap, error) { vs := d.Get("url_path_map").([]interface{}) results := make([]network.ApplicationGatewayURLPathMap, 0) @@ -2116,17 +3194,15 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin v := raw.(map[string]interface{}) name := v["name"].(string) - defaultBackendAddressPoolName := v["default_backend_address_pool_name"].(string) - defaultBackendHTTPSettingsName := v["default_backend_http_settings_name"].(string) - - defaultBackendAddressPoolID := fmt.Sprintf("%s/backendAddressPools/%s", gatewayID, defaultBackendAddressPoolName) - defaultBackendHTTPSettingsID := fmt.Sprintf("%s/backendHttpSettingsCollection/%s", gatewayID, defaultBackendHTTPSettingsName) pathRules := make([]network.ApplicationGatewayPathRule, 0) for _, ruleConfig := range v["path_rule"].([]interface{}) { ruleConfigMap := ruleConfig.(map[string]interface{}) ruleName := ruleConfigMap["name"].(string) + backendAddressPoolName := ruleConfigMap["backend_address_pool_name"].(string) + backendHTTPSettingsName := ruleConfigMap["backend_http_settings_name"].(string) + redirectConfigurationName := ruleConfigMap["redirect_configuration_name"].(string) rulePaths := make([]string, 0) for _, rulePath := range ruleConfigMap["paths"].([]interface{}) { @@ -2140,40 +3216,96 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin }, } - if backendAddressPoolName := ruleConfigMap["backend_address_pool_name"].(string); backendAddressPoolName != "" { + if backendAddressPoolName != "" && redirectConfigurationName != "" { + return nil, fmt.Errorf("Conflict between `backend_address_pool_name` and `redirect_configuration_name` (back-end pool not applicable when redirection specified)") + } + + if backendHTTPSettingsName != "" && redirectConfigurationName != "" { + return nil, fmt.Errorf("Conflict between `backend_http_settings_name` and `redirect_configuration_name` (back-end settings not applicable when redirection specified)") + } + + if backendAddressPoolName != "" { backendAddressPoolID := fmt.Sprintf("%s/backendAddressPools/%s", gatewayID, backendAddressPoolName) rule.ApplicationGatewayPathRulePropertiesFormat.BackendAddressPool = &network.SubResource{ ID: utils.String(backendAddressPoolID), } } - if backendHTTPSettingsName := ruleConfigMap["backend_http_settings_name"].(string); backendHTTPSettingsName != "" { + if backendHTTPSettingsName != "" { backendHTTPSettingsID := fmt.Sprintf("%s/backendHttpSettingsCollection/%s", gatewayID, backendHTTPSettingsName) rule.ApplicationGatewayPathRulePropertiesFormat.BackendHTTPSettings = &network.SubResource{ ID: utils.String(backendHTTPSettingsID), } } + if redirectConfigurationName != "" { + redirectConfigurationID := fmt.Sprintf("%s/redirectConfigurations/%s", gatewayID, redirectConfigurationName) + rule.ApplicationGatewayPathRulePropertiesFormat.RedirectConfiguration = &network.SubResource{ + ID: utils.String(redirectConfigurationID), + } + } + + if rewriteRuleSetName := ruleConfigMap["rewrite_rule_set_name"].(string); rewriteRuleSetName != "" { + rewriteRuleSetID := fmt.Sprintf("%s/rewriteRuleSets/%s", gatewayID, rewriteRuleSetName) + rule.ApplicationGatewayPathRulePropertiesFormat.RewriteRuleSet = &network.SubResource{ + ID: utils.String(rewriteRuleSetID), + } + } + pathRules = append(pathRules, rule) } output := network.ApplicationGatewayURLPathMap{ Name: utils.String(name), ApplicationGatewayURLPathMapPropertiesFormat: &network.ApplicationGatewayURLPathMapPropertiesFormat{ - DefaultBackendAddressPool: &network.SubResource{ - ID: utils.String(defaultBackendAddressPoolID), - }, - DefaultBackendHTTPSettings: &network.SubResource{ - ID: utils.String(defaultBackendHTTPSettingsID), - }, PathRules: &pathRules, }, } + defaultBackendAddressPoolName := v["default_backend_address_pool_name"].(string) + defaultBackendHTTPSettingsName := v["default_backend_http_settings_name"].(string) + defaultRedirectConfigurationName := v["default_redirect_configuration_name"].(string) + + if defaultBackendAddressPoolName != "" && defaultRedirectConfigurationName != "" { + return nil, fmt.Errorf("Conflict between `default_backend_address_pool_name` and `default_redirect_configuration_name` (back-end pool not applicable when redirection specified)") + } + + if defaultBackendHTTPSettingsName != "" && defaultRedirectConfigurationName != "" { + return nil, fmt.Errorf("Conflict between `default_backend_http_settings_name` and `default_redirect_configuration_name` (back-end settings not applicable when redirection specified)") + } + + if defaultBackendAddressPoolName != "" { + defaultBackendAddressPoolID := fmt.Sprintf("%s/backendAddressPools/%s", gatewayID, defaultBackendAddressPoolName) + output.ApplicationGatewayURLPathMapPropertiesFormat.DefaultBackendAddressPool = &network.SubResource{ + ID: utils.String(defaultBackendAddressPoolID), + } + } + + if defaultBackendHTTPSettingsName != "" { + defaultBackendHTTPSettingsID := fmt.Sprintf("%s/backendHttpSettingsCollection/%s", gatewayID, defaultBackendHTTPSettingsName) + output.ApplicationGatewayURLPathMapPropertiesFormat.DefaultBackendHTTPSettings = &network.SubResource{ + ID: utils.String(defaultBackendHTTPSettingsID), + } + } + + if defaultRedirectConfigurationName != "" { + defaultRedirectConfigurationID := fmt.Sprintf("%s/redirectConfigurations/%s", gatewayID, defaultRedirectConfigurationName) + output.ApplicationGatewayURLPathMapPropertiesFormat.DefaultRedirectConfiguration = &network.SubResource{ + ID: utils.String(defaultRedirectConfigurationID), + } + } + + if defaultRewriteRuleSetName := v["default_rewrite_rule_set_name"].(string); defaultRewriteRuleSetName != "" { + defaultRewriteRuleSetID := fmt.Sprintf("%s/rewriteRuleSets/%s", gatewayID, defaultRewriteRuleSetName) + output.ApplicationGatewayURLPathMapPropertiesFormat.DefaultRewriteRuleSet = &network.SubResource{ + ID: utils.String(defaultRewriteRuleSetID), + } + } + results = append(results, output) } - return &results + return &results, nil } func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURLPathMap) ([]interface{}, error) { @@ -2195,7 +3327,7 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL if props := v.ApplicationGatewayURLPathMapPropertiesFormat; props != nil { if backendPool := props.DefaultBackendAddressPool; backendPool != nil && backendPool.ID != nil { - poolId, err := parseAzureResourceID(*backendPool.ID) + poolId, err := azure.ParseAzureResourceID(*backendPool.ID) if err != nil { return nil, err } @@ -2205,7 +3337,7 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL } if settings := props.DefaultBackendHTTPSettings; settings != nil && settings.ID != nil { - settingsId, err := parseAzureResourceID(*settings.ID) + settingsId, err := azure.ParseAzureResourceID(*settings.ID) if err != nil { return nil, err } @@ -2214,6 +3346,26 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL output["default_backend_http_settings_id"] = *settings.ID } + if redirect := props.DefaultRedirectConfiguration; redirect != nil && redirect.ID != nil { + settingsId, err := azure.ParseAzureResourceID(*redirect.ID) + if err != nil { + return nil, err + } + redirectConfigurationName := settingsId.Path["redirectConfigurations"] + output["default_redirect_configuration_name"] = redirectConfigurationName + output["default_redirect_configuration_id"] = *redirect.ID + } + + if rewrite := props.DefaultRewriteRuleSet; rewrite != nil && rewrite.ID != nil { + settingsId, err := azure.ParseAzureResourceID(*rewrite.ID) + if err != nil { + return nil, err + } + defaultRewriteRuleSetName := settingsId.Path["rewriteRuleSets"] + output["default_rewrite_rule_set_name"] = defaultRewriteRuleSetName + output["default_rewrite_rule_set_id"] = *rewrite.ID + } + pathRules := make([]interface{}, 0) if rules := props.PathRules; rules != nil { for _, rule := range *rules { @@ -2229,7 +3381,7 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL if ruleProps := rule.ApplicationGatewayPathRulePropertiesFormat; ruleProps != nil { if pool := ruleProps.BackendAddressPool; pool != nil && pool.ID != nil { - poolId, err := parseAzureResourceID(*pool.ID) + poolId, err := azure.ParseAzureResourceID(*pool.ID) if err != nil { return nil, err } @@ -2239,7 +3391,7 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL } if backend := ruleProps.BackendHTTPSettings; backend != nil && backend.ID != nil { - backendId, err := parseAzureResourceID(*backend.ID) + backendId, err := azure.ParseAzureResourceID(*backend.ID) if err != nil { return nil, err } @@ -2248,6 +3400,26 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL ruleOutput["backend_http_settings_id"] = *backend.ID } + if redirect := ruleProps.RedirectConfiguration; redirect != nil && redirect.ID != nil { + redirectId, err := azure.ParseAzureResourceID(*redirect.ID) + if err != nil { + return nil, err + } + redirectConfigurationName2 := redirectId.Path["redirectConfigurations"] + ruleOutput["redirect_configuration_name"] = redirectConfigurationName2 + ruleOutput["redirect_configuration_id"] = *redirect.ID + } + + if rewrite := ruleProps.RewriteRuleSet; rewrite != nil && rewrite.ID != nil { + rewriteId, err := azure.ParseAzureResourceID(*rewrite.ID) + if err != nil { + return nil, err + } + rewriteRuleSet := rewriteId.Path["rewriteRuleSets"] + ruleOutput["rewrite_rule_set_name"] = rewriteRuleSet + ruleOutput["rewrite_rule_set_id"] = *rewrite.ID + } + pathOutputs := make([]interface{}, 0) if paths := ruleProps.Paths; paths != nil { for _, rulePath := range *paths { @@ -2278,13 +3450,19 @@ func expandApplicationGatewayWafConfig(d *schema.ResourceData) *network.Applicat ruleSetType := v["rule_set_type"].(string) ruleSetVersion := v["rule_set_version"].(string) fileUploadLimitInMb := v["file_upload_limit_mb"].(int) + requestBodyCheck := v["request_body_check"].(bool) + maxRequestBodySizeInKb := v["max_request_body_size_kb"].(int) return &network.ApplicationGatewayWebApplicationFirewallConfiguration{ - Enabled: utils.Bool(enabled), - FirewallMode: network.ApplicationGatewayFirewallMode(mode), - RuleSetType: utils.String(ruleSetType), - RuleSetVersion: utils.String(ruleSetVersion), - FileUploadLimitInMb: utils.Int32(int32(fileUploadLimitInMb)), + Enabled: utils.Bool(enabled), + FirewallMode: network.ApplicationGatewayFirewallMode(mode), + RuleSetType: utils.String(ruleSetType), + RuleSetVersion: utils.String(ruleSetVersion), + FileUploadLimitInMb: utils.Int32(int32(fileUploadLimitInMb)), + RequestBodyCheck: utils.Bool(requestBodyCheck), + MaxRequestBodySizeInKb: utils.Int32(int32(maxRequestBodySizeInKb)), + DisabledRuleGroups: expandApplicationGatewayFirewallDisabledRuleGroup(v["disabled_rule_group"].([]interface{})), + Exclusions: expandApplicationGatewayFirewallExclusion(v["exclusion"].([]interface{})), } } @@ -2310,15 +3488,129 @@ func flattenApplicationGatewayWafConfig(input *network.ApplicationGatewayWebAppl output["rule_set_version"] = *input.RuleSetVersion } + if input.DisabledRuleGroups != nil { + output["disabled_rule_group"] = flattenApplicationGateWayDisabledRuleGroups(input.DisabledRuleGroups) + } + if input.FileUploadLimitInMb != nil { output["file_upload_limit_mb"] = int(*input.FileUploadLimitInMb) } + if input.RequestBodyCheck != nil { + output["request_body_check"] = *input.RequestBodyCheck + } + + if input.MaxRequestBodySizeInKb != nil { + output["max_request_body_size_kb"] = int(*input.MaxRequestBodySizeInKb) + } + + if input.Exclusions != nil { + output["exclusion"] = flattenApplicationGatewayFirewallExclusion(input.Exclusions) + } results = append(results, output) return results } +func expandApplicationGatewayFirewallDisabledRuleGroup(d []interface{}) *[]network.ApplicationGatewayFirewallDisabledRuleGroup { + if len(d) == 0 { + return nil + } + + disabledRuleGroups := make([]network.ApplicationGatewayFirewallDisabledRuleGroup, 0) + for _, disabledRuleGroup := range d { + disabledRuleGroupMap := disabledRuleGroup.(map[string]interface{}) + + ruleGroupName := disabledRuleGroupMap["rule_group_name"].(string) + + ruleGroup := network.ApplicationGatewayFirewallDisabledRuleGroup{ + RuleGroupName: utils.String(ruleGroupName), + } + + rules := make([]int32, 0) + for _, rule := range disabledRuleGroupMap["rules"].([]interface{}) { + rules = append(rules, int32(rule.(int))) + } + + if len(rules) > 0 { + ruleGroup.Rules = &rules + } + + disabledRuleGroups = append(disabledRuleGroups, ruleGroup) + } + return &disabledRuleGroups +} + +func flattenApplicationGateWayDisabledRuleGroups(input *[]network.ApplicationGatewayFirewallDisabledRuleGroup) []interface{} { + ruleGroups := make([]interface{}, 0) + for _, ruleGroup := range *input { + ruleGroupOutput := map[string]interface{}{} + + if ruleGroup.RuleGroupName != nil { + ruleGroupOutput["rule_group_name"] = *ruleGroup.RuleGroupName + } + + ruleOutputs := make([]interface{}, 0) + if rules := ruleGroup.Rules; rules != nil { + for _, rule := range *rules { + ruleOutputs = append(ruleOutputs, rule) + } + } + ruleGroupOutput["rules"] = ruleOutputs + + ruleGroups = append(ruleGroups, ruleGroupOutput) + + } + return ruleGroups +} + +func expandApplicationGatewayFirewallExclusion(d []interface{}) *[]network.ApplicationGatewayFirewallExclusion { + if len(d) == 0 { + return nil + } + + exclusions := make([]network.ApplicationGatewayFirewallExclusion, 0) + for _, exclusion := range d { + exclusionMap := exclusion.(map[string]interface{}) + + matchVariable := exclusionMap["match_variable"].(string) + selectorMatchOperator := exclusionMap["selector_match_operator"].(string) + selector := exclusionMap["selector"].(string) + + exclusionList := network.ApplicationGatewayFirewallExclusion{ + MatchVariable: utils.String(matchVariable), + SelectorMatchOperator: utils.String(selectorMatchOperator), + Selector: utils.String(selector), + } + + exclusions = append(exclusions, exclusionList) + } + + return &exclusions +} + +func flattenApplicationGatewayFirewallExclusion(input *[]network.ApplicationGatewayFirewallExclusion) []interface{} { + exclusionLists := make([]interface{}, 0) + for _, exclusionList := range *input { + exclusionListOutput := map[string]interface{}{} + + if exclusionList.MatchVariable != nil { + exclusionListOutput["match_variable"] = *exclusionList.MatchVariable + } + + if exclusionList.SelectorMatchOperator != nil { + exclusionListOutput["selector_match_operator"] = *exclusionList.SelectorMatchOperator + } + + if exclusionList.Selector != nil { + exclusionListOutput["selector"] = *exclusionList.Selector + } + exclusionLists = append(exclusionLists, exclusionListOutput) + + } + return exclusionLists +} + func expandApplicationGatewayCustomErrorConfigurations(vs []interface{}) *[]network.ApplicationGatewayCustomError { results := make([]network.ApplicationGatewayCustomError, 0) diff --git a/azurerm/resource_arm_application_gateway_test.go b/azurerm/resource_arm_application_gateway_test.go index 60ede482b143..70de9e17c017 100644 --- a/azurerm/resource_arm_application_gateway_test.go +++ b/azurerm/resource_arm_application_gateway_test.go @@ -2,11 +2,14 @@ package azurerm import ( "fmt" + "regexp" "testing" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,6 +41,103 @@ func TestAccAzureRMApplicationGateway_basic(t *testing.T) { }) } +func TestAccAzureRMApplicationGateway_autoscaleConfiguration(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_autoscaleConfiguration(ri, testLocation(), 2, 10), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Standard_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Standard_v2"), + resource.TestCheckResourceAttr(resourceName, "autoscale_configuration.0.min_capacity", "2"), + resource.TestCheckResourceAttr(resourceName, "autoscale_configuration.0.max_capacity", "10"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.#", "0"), + ), + }, + { + Config: testAccAzureRMApplicationGateway_autoscaleConfiguration(ri, testLocation(), 4, 12), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Standard_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Standard_v2"), + resource.TestCheckResourceAttr(resourceName, "autoscale_configuration.0.min_capacity", "4"), + resource.TestCheckResourceAttr(resourceName, "autoscale_configuration.0.max_capacity", "12"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_autoscaleConfigurationNoMaxCapacity(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_autoscaleConfigurationNoMaxCapacity(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Standard_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Standard_v2"), + resource.TestCheckResourceAttr(resourceName, "autoscale_configuration.0.min_capacity", "2"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_zones(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_zones(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Standard_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Standard_v2"), + resource.TestCheckResourceAttr(resourceName, "zones.#", "2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "2"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMApplicationGateway_overridePath(t *testing.T) { resourceName := "azurerm_application_gateway.test" ri := tf.AccRandTimeInt() @@ -89,7 +189,7 @@ func TestAccAzureRMApplicationGateway_http2(t *testing.T) { } func TestAccAzureRMApplicationGateway_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -187,6 +287,84 @@ func TestAccAzureRMApplicationGateway_pathBasedRouting(t *testing.T) { }) } +func TestAccAzureRMApplicationGateway_routingRedirect_httpListener(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_routingRedirect_httpListener(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "redirect_configuration.0.name"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.0.redirect_type", "Temporary"), + resource.TestCheckResourceAttrSet(resourceName, "redirect_configuration.0.target_listener_name"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.0.include_path", "true"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.0.include_query_string", "false"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_routingRedirect_httpListenerError(t *testing.T) { + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_routingRedirect_httpListenerError(ri, testLocation()), + ExpectError: regexp.MustCompile("Conflict between `backend_address_pool_name` and `redirect_configuration_name`"), + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_routingRedirect_pathBased(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_routingRedirect_pathBased(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "redirect_configuration.0.name"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.0.redirect_type", "Found"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.0.target_url", "http://www.example.com"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.0.include_query_string", "true"), + resource.TestCheckResourceAttrSet(resourceName, "redirect_configuration.1.name"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.1.redirect_type", "Permanent"), + resource.TestCheckResourceAttrSet(resourceName, "redirect_configuration.1.target_listener_name"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.1.include_path", "false"), + resource.TestCheckResourceAttr(resourceName, "redirect_configuration.1.include_query_string", "false"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMApplicationGateway_customErrorConfigurations(t *testing.T) { resourceName := "azurerm_application_gateway.test" ri := tf.AccRandTimeInt() @@ -211,6 +389,56 @@ func TestAccAzureRMApplicationGateway_customErrorConfigurations(t *testing.T) { }) } +func TestAccAzureRMApplicationGateway_rewriteRuleSets_backend(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_rewriteRuleSets_backend(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "rewrite_rule_set.0.name"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_rewriteRuleSets_redirect(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_rewriteRuleSets_redirect(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "rewrite_rule_set.0.name"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMApplicationGateway_probes(t *testing.T) { resourceName := "azurerm_application_gateway.test" ri := tf.AccRandTimeInt() @@ -260,6 +488,49 @@ func TestAccAzureRMApplicationGateway_probesPickHostNameFromBackendHTTPSettings( }) } +func TestAccAzureRMApplicationGateway_backendHttpSettingsHostName(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + hostName := "example.com" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_backendHttpSettingsHostName(ri, testLocation(), hostName, false), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "backend_http_settings.0.host_name", hostName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_backendHttpSettingsHostNameAndPick(t *testing.T) { + ri := tf.AccRandTimeInt() + hostName := "example.com" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_backendHttpSettingsHostName(ri, testLocation(), hostName, true), + ExpectError: regexp.MustCompile("Only one of `host_name` or `pick_host_name_from_backend_address` can be set"), + }, + }, + }) +} + func TestAccAzureRMApplicationGateway_settingsPickHostNameFromBackendAddress(t *testing.T) { resourceName := "azurerm_application_gateway.test" ri := tf.AccRandTimeInt() @@ -351,6 +622,8 @@ func TestAccAzureRMApplicationGateway_webApplicationFirewall(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_type", "OWASP"), resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_version", "3.0"), resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.file_upload_limit_mb", "100"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.request_body_check", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.max_request_body_size_kb", "100"), ), }, }, @@ -399,21 +672,320 @@ func TestAccAzureRMApplicationGateway_connectionDraining(t *testing.T) { }) } -func testCheckAzureRMApplicationGatewayExists(resourceName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("Not found: %q", resourceName) - } +func TestAccAzureRMApplicationGateway_webApplicationFirewall_disabledRuleGroups(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() - gatewayName := rs.Primary.Attributes["name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for Application Gateway: %q", gatewayName) - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_webApplicationFirewall_disabledRuleGroups(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "WAF_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "WAF_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "1"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.firewall_mode", "Detection"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_type", "OWASP"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_version", "3.0"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.request_body_check", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.max_request_body_size_kb", "128"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.file_upload_limit_mb", "100"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.0.rule_group_name", "REQUEST-921-PROTOCOL-ATTACK"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.0.rules.0", "921110"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.0.rules.1", "921151"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.0.rules.2", "921180"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.1.rule_group_name", "REQUEST-930-APPLICATION-ATTACK-LFI"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.1.rules.0", "930120"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.1.rules.1", "930130"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.2.rule_group_name", "REQUEST-942-APPLICATION-ATTACK-SQLI"), + ), + }, + { + Config: testAccAzureRMApplicationGateway_webApplicationFirewall_disabledRuleGroups_enabled_some_rules(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "WAF_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "WAF_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "1"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.firewall_mode", "Detection"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_type", "OWASP"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_version", "3.0"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.request_body_check", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.max_request_body_size_kb", "128"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.file_upload_limit_mb", "100"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.0.rule_group_name", "REQUEST-921-PROTOCOL-ATTACK"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.0.rules.0", "921110"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.0.rules.1", "921151"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.0.rules.2", "921180"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.disabled_rule_group.1.rule_group_name", "REQUEST-942-APPLICATION-ATTACK-SQLI"), + ), + }, + }, + }) +} - client := testAccProvider.Meta().(*ArmClient).applicationGatewayClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext +func TestAccAzureRMApplicationGateway_webApplicationFirewall_exclusions(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_webApplicationFirewall_exclusions_many(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "WAF_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "WAF_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "1"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.firewall_mode", "Detection"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_type", "OWASP"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_version", "3.0"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.request_body_check", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.max_request_body_size_kb", "128"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.file_upload_limit_mb", "100"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.0.match_variable", "RequestArgNames"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.0.selector_match_operator", "Equals"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.0.selector", "displayNameHtml"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.1.match_variable", "RequestCookieNames"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.1.selector_match_operator", "EndsWith"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.1.selector", "username"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.2.match_variable", "RequestHeaderNames"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.2.selector_match_operator", "StartsWith"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.2.selector", "ORIGIN"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.3.match_variable", "RequestHeaderNames"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.3.selector_match_operator", "Contains"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.3.selector", "ORIGIN"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.4.match_variable", "RequestHeaderNames"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.4.selector_match_operator", ""), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.4.selector", ""), + ), + }, + { + Config: testAccAzureRMApplicationGateway_webApplicationFirewall_exclusions_one(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "WAF_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "WAF_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "1"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.firewall_mode", "Detection"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_type", "OWASP"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.rule_set_version", "3.0"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.request_body_check", "true"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.max_request_body_size_kb", "128"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.file_upload_limit_mb", "100"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.0.match_variable", "RequestArgNames"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.0.selector_match_operator", "Equals"), + resource.TestCheckResourceAttr(resourceName, "waf_configuration.0.exclusion.0.selector", "displayNameHtml"), + ), + }, + }, + }) +} +func TestAccAzureRMApplicationGateway_sslPolicy_policyType_predefined(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_sslPolicy_policyType_predefined(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.policy_type", "Predefined"), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.policy_name", "AppGwSslPolicy20170401S"), + ), + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_sslPolicy_policyType_custom(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_sslPolicy_policyType_custom(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.policy_type", "Custom"), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.min_protocol_version", "TLSv1_1"), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.cipher_suites.0", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.cipher_suites.1", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.cipher_suites.2", "TLS_RSA_WITH_AES_128_GCM_SHA256"), + ), + }, + }, + }) +} +func TestAccAzureRMApplicationGateway_sslPolicy_disabledProtocols(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_sslPolicy_disabledProtocols(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.disabled_protocols.0", "TLSv1_0"), + resource.TestCheckResourceAttr(resourceName, "ssl_policy.0.disabled_protocols.1", "TLSv1_1"), + ), + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_disabledSslProtocols(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_disabledSslProtocols(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "disabled_ssl_protocols.0", "TLSv1_0"), + resource.TestCheckResourceAttr(resourceName, "disabled_ssl_protocols.1", "TLSv1_1"), + ), + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_cookieAffinity(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_cookieAffinity(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "backend_http_settings.0.affinity_cookie_name", "testCookieName"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMApplicationGateway_cookieAffinityUpdated(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "backend_http_settings.0.affinity_cookie_name", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApplicationGateway_gatewayIP(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMApplicationGateway_gatewayIPUpdated(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccAzureRMApplicationGateway_UserAssignedIdentity(t *testing.T) { + resourceName := "azurerm_application_gateway.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(14) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationGatewayDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationGateway_UserDefinedIdentity(ri, testLocation(), rs), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationGatewayExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "UserAssigned"), + resource.TestCheckResourceAttr(resourceName, "identity.0.identity_ids.#", "1"), + ), + }, + }, + }) +} + +func testCheckAzureRMApplicationGatewayExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %q", resourceName) + } + + gatewayName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Application Gateway: %q", gatewayName) + } + + client := testAccProvider.Meta().(*ArmClient).network.ApplicationGatewaysClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, gatewayName) if err != nil { @@ -429,7 +1001,7 @@ func testCheckAzureRMApplicationGatewayExists(resourceName string) resource.Test } func testCheckAzureRMApplicationGatewayDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).applicationGatewayClient + client := testAccProvider.Meta().(*ArmClient).network.ApplicationGatewaysClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -450,13 +1022,1769 @@ func testCheckAzureRMApplicationGatewayDestroy(s *terraform.State) error { return err } - return fmt.Errorf("Application Gateway still exists:\n%#v", resp.ApplicationGatewayPropertiesFormat) - } + return fmt.Errorf("Application Gateway still exists:\n%#v", resp.ApplicationGatewayPropertiesFormat) + } + + return nil +} + +func testAccAzureRMApplicationGateway_basic(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_UserDefinedIdentity(rInt int, location string, rString string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_user_assigned_identity" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + name = "acctest%s" +} + +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_v2" + tier = "Standard_v2" + capacity = 1 + } + + identity { + identity_ids = ["${azurerm_user_assigned_identity.test.id}"] + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rString, rInt, rInt) +} + +func testAccAzureRMApplicationGateway_zones(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + zones = ["1", "2"] + + sku { + name = "Standard_v2" + tier = "Standard_v2" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt, rInt) +} + +func testAccAzureRMApplicationGateway_autoscaleConfiguration(rInt int, location string, minCapacity int, maxCapacity int) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_v2" + tier = "Standard_v2" + } + + autoscale_configuration { + min_capacity = %d + max_capacity = %d + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt, rInt, minCapacity, maxCapacity) +} + +func testAccAzureRMApplicationGateway_autoscaleConfigurationNoMaxCapacity(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_v2" + tier = "Standard_v2" + } + + autoscale_configuration { + min_capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt, rInt) +} + +func testAccAzureRMApplicationGateway_overridePath(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + path = "/path1/" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_http2(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + enable_http2 = true + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_requiresImport(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_application_gateway" "import" { + name = "${azurerm_application_gateway.test.name}" + resource_group_name = "${azurerm_application_gateway.test.resource_group_name}" + location = "${azurerm_application_gateway.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template) +} + +func testAccAzureRMApplicationGateway_authCertificate(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + auth_cert_name = "${azurerm_virtual_network.test.name}-auth" + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 443 + protocol = "Https" + request_timeout = 1 + + authentication_certificate { + name = "${local.auth_cert_name}" + } + } + + authentication_certificate { + name = "${local.auth_cert_name}" + data = "${file("testdata/application_gateway_test.cer")}" + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_authCertificateUpdated(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + auth_cert_name = "${azurerm_virtual_network.test.name}-auth2" + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 443 + protocol = "Https" + request_timeout = 1 + + authentication_certificate { + name = "${local.auth_cert_name}" + } + } + + authentication_certificate { + name = "${local.auth_cert_name}" + data = "${file("testdata/application_gateway_test_2.crt")}" + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_pathBasedRouting(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + path_rule_name = "${azurerm_virtual_network.test.name}-pathrule1" + url_path_map_name = "${azurerm_virtual_network.test.name}-urlpath1" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "PathBasedRouting" + url_path_map_name = "${local.url_path_map_name}" + http_listener_name = "${local.listener_name}" + } + + url_path_map { + name = "${local.url_path_map_name}" + default_backend_address_pool_name = "${local.backend_address_pool_name}" + default_backend_http_settings_name = "${local.http_setting_name}" + + path_rule { + name = "${local.path_rule_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + + paths = [ + "/test", + ] + } + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_routingRedirect_httpListener(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_port_name2 = "${azurerm_virtual_network.test.name}-feport2" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + target_listener_name = "${azurerm_virtual_network.test.name}-trgthttplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + path_rule_name = "${azurerm_virtual_network.test.name}-pathrule1" + url_path_map_name = "${azurerm_virtual_network.test.name}-urlpath1" + redirect_configuration_name = "${azurerm_virtual_network.test.name}-Port80To8888Redirect" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_port { + name = "${local.frontend_port_name2}" + port = 8888 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + http_listener { + name = "${local.target_listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name2}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + redirect_configuration_name = "${local.redirect_configuration_name}" + } + + redirect_configuration { + name = "${local.redirect_configuration_name}" + redirect_type = "Temporary" + target_listener_name = "${local.target_listener_name}" + include_path = true + include_query_string = false + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_routingRedirect_httpListenerError(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_port_name2 = "${azurerm_virtual_network.test.name}-feport2" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + target_listener_name = "${azurerm_virtual_network.test.name}-trgthttplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + path_rule_name = "${azurerm_virtual_network.test.name}-pathrule1" + url_path_map_name = "${azurerm_virtual_network.test.name}-urlpath1" + redirect_configuration_name = "${azurerm_virtual_network.test.name}-Port80To8888Redirect" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_port { + name = "${local.frontend_port_name2}" + port = 8888 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + http_listener { + name = "${local.target_listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name2}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + redirect_configuration_name = "${local.redirect_configuration_name}" + } + + redirect_configuration { + name = "${local.redirect_configuration_name}" + redirect_type = "Temporary" + target_listener_name = "${local.target_listener_name}" + include_path = true + include_query_string = false + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_routingRedirect_pathBased(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_port_name2 = "${azurerm_virtual_network.test.name}-feport2" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + target_listener_name = "${azurerm_virtual_network.test.name}-trgthttplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + path_rule_name = "${azurerm_virtual_network.test.name}-pathrule1" + path_rule_name2 = "${azurerm_virtual_network.test.name}-pathrule2" + url_path_map_name = "${azurerm_virtual_network.test.name}-urlpath1" + redirect_configuration_name = "${azurerm_virtual_network.test.name}-PathRedirect" + redirect_configuration_name2 = "${azurerm_virtual_network.test.name}-PathRedirect2" + target_url = "http://www.example.com" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_port { + name = "${local.frontend_port_name2}" + port = 8888 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + http_listener { + name = "${local.target_listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name2}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "PathBasedRouting" + url_path_map_name = "${local.url_path_map_name}" + http_listener_name = "${local.listener_name}" + } + + url_path_map { + name = "${local.url_path_map_name}" + default_backend_address_pool_name = "${local.backend_address_pool_name}" + default_backend_http_settings_name = "${local.http_setting_name}" + + path_rule { + name = "${local.path_rule_name}" + redirect_configuration_name = "${local.redirect_configuration_name}" + + paths = [ + "/test", + ] + } + + path_rule { + name = "${local.path_rule_name2}" + redirect_configuration_name = "${local.redirect_configuration_name2}" + + paths = [ + "/test2", + ] + } + } + + redirect_configuration { + name = "${local.redirect_configuration_name}" + redirect_type = "Found" + target_url = "${local.target_url}" + include_query_string = true + } + + redirect_configuration { + name = "${local.redirect_configuration_name2}" + redirect_type = "Permanent" + target_listener_name = "${local.target_listener_name}" + include_path = false + include_query_string = false + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_probes(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + probe1_name = "${azurerm_virtual_network.test.name}-probe1" + probe2_name = "${azurerm_virtual_network.test.name}-probe2" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + probe_name = "${local.probe1_name}" + protocol = "Http" + request_timeout = 1 + } + + backend_http_settings { + name = "${local.http_setting_name}-2" + cookie_based_affinity = "Disabled" + port = 8080 + probe_name = "${local.probe2_name}" + protocol = "Http" + request_timeout = 1 + } + + probe { + name = "${local.probe1_name}" + protocol = "Http" + path = "/test" + host = "azure.com" + timeout = 120 + interval = 300 + unhealthy_threshold = 8 + } + + probe { + name = "${local.probe2_name}" + protocol = "Http" + path = "/other" + host = "azure.com" + timeout = 120 + interval = 300 + unhealthy_threshold = 8 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_probesPickHostNameFromBackendHTTPSettings(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + probe_name = "${azurerm_virtual_network.test.name}-probe" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + pick_host_name_from_backend_address = true + port = 80 + probe_name = "${local.probe_name}" + protocol = "Http" + request_timeout = 1 + } + + probe { + name = "${local.probe_name}" + protocol = "Http" + path = "/test" + timeout = 120 + interval = 300 + unhealthy_threshold = 8 + pick_host_name_from_backend_http_settings = true + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_backendHttpSettingsHostName(rInt int, location string, hostName string, pick bool) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + host_name = "%s" + port = 80 + protocol = "Http" + request_timeout = 1 + pick_host_name_from_backend_address = %t + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt, hostName, pick) +} + +func testAccAzureRMApplicationGateway_settingsPickHostNameFromBackendAddress(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + pick_host_name_from_backend_address = true + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_sslCertificate(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + ssl_certificate_name = "${azurerm_virtual_network.test.name}-ssl1" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 443 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Https" + ssl_certificate_name = "${local.ssl_certificate_name}" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } + + ssl_certificate { + name = "${local.ssl_certificate_name}" + data = "${filebase64("testdata/application_gateway_test.pfx")}" + password = "terraform" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_sslCertificateUpdated(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + ssl_certificate_name = "${azurerm_virtual_network.test.name}-ssl2" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "Standard_Small" + tier = "Standard" + capacity = 2 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 443 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Https" + ssl_certificate_name = "${local.ssl_certificate_name}" + } + + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } + + ssl_certificate { + name = "${local.ssl_certificate_name}" + data = "${filebase64("testdata/application_gateway_test_2.pfx")}" + password = "hello-world" + } +} +`, template, rInt) +} + +func testAccAzureRMApplicationGateway_webApplicationFirewall(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) + return fmt.Sprintf(` +%s + +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "WAF_Medium" + tier = "WAF" + capacity = 1 + } + + disabled_ssl_protocols = [ + "TLSv1_0", + ] + + waf_configuration { + enabled = true + firewall_mode = "Detection" + rule_set_type = "OWASP" + rule_set_version = "3.0" + file_upload_limit_mb = 100 + request_body_check = true + max_request_body_size_kb = 100 + } + + gateway_ip_configuration { + name = "my-gateway-ip-configuration" + subnet_id = "${azurerm_subnet.test.id}" + } + + frontend_port { + name = "${local.frontend_port_name}" + port = 80 + } + + frontend_ip_configuration { + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } + + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = "${local.listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name}" + protocol = "Http" + } - return nil + request_routing_rule { + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" + } +} +`, template, rInt) } -func testAccAzureRMApplicationGateway_basic(rInt int, location string) string { +func testAccAzureRMApplicationGateway_connectionDraining(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -475,6 +2803,7 @@ resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" + enable_http2 = true sku { name = "Standard_Small" @@ -507,6 +2836,11 @@ resource "azurerm_application_gateway" "test" { port = 80 protocol = "Http" request_timeout = 1 + + connection_draining { + enabled = true + drain_timeout_sec = 1984 + } } http_listener { @@ -526,8 +2860,7 @@ resource "azurerm_application_gateway" "test" { } `, template, rInt) } - -func testAccAzureRMApplicationGateway_overridePath(rInt int, location string) string { +func testAccAzureRMApplicationGateway_webApplicationFirewall_disabledRuleGroups(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -542,15 +2875,47 @@ locals { request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" - capacity = 2 + name = "WAF_v2" + tier = "WAF_v2" + capacity = 1 + } + + waf_configuration { + enabled = true + firewall_mode = "Detection" + rule_set_type = "OWASP" + rule_set_version = "3.0" + request_body_check = true + max_request_body_size_kb = 128 + file_upload_limit_mb = 100 + + disabled_rule_group { + rule_group_name = "REQUEST-921-PROTOCOL-ATTACK" + rules = [921110, 921151, 921180] + } + + disabled_rule_group { + rule_group_name = "REQUEST-930-APPLICATION-ATTACK-LFI" + rules = [930120, 930130] + } + + disabled_rule_group { + rule_group_name = "REQUEST-942-APPLICATION-ATTACK-SQLI" + } } gateway_ip_configuration { @@ -565,7 +2930,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -575,7 +2940,6 @@ resource "azurerm_application_gateway" "test" { backend_http_settings { name = "${local.http_setting_name}" cookie_based_affinity = "Disabled" - path = "/path1/" port = 80 protocol = "Http" request_timeout = 1 @@ -596,10 +2960,10 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_http2(rInt int, location string) string { +func testAccAzureRMApplicationGateway_webApplicationFirewall_disabledRuleGroups_enabled_some_rules(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -614,16 +2978,42 @@ locals { request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" - enable_http2 = true sku { - name = "Standard_Small" - tier = "Standard" - capacity = 2 + name = "WAF_v2" + tier = "WAF_v2" + capacity = 1 + } + + waf_configuration { + enabled = true + firewall_mode = "Detection" + rule_set_type = "OWASP" + rule_set_version = "3.0" + request_body_check = true + max_request_body_size_kb = 128 + file_upload_limit_mb = 100 + + disabled_rule_group { + rule_group_name = "REQUEST-921-PROTOCOL-ATTACK" + rules = [921110, 921151, 921180] + } + + disabled_rule_group { + rule_group_name = "REQUEST-942-APPLICATION-ATTACK-SQLI" + } } gateway_ip_configuration { @@ -638,7 +3028,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -668,23 +3058,79 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_requiresImport(rInt int, location string) string { - template := testAccAzureRMApplicationGateway_basic(rInt, location) +func testAccAzureRMApplicationGateway_webApplicationFirewall_exclusions_many(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s -resource "azurerm_application_gateway" "import" { - name = "${azurerm_application_gateway.test.name}" - resource_group_name = "${azurerm_application_gateway.test.resource_group_name}" - location = "${azurerm_application_gateway.test.location}" +# since these variables are re-used - a locals block makes this more maintainable +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" +} + +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + +resource "azurerm_application_gateway" "test" { + name = "acctestag-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" - capacity = 2 + name = "WAF_v2" + tier = "WAF_v2" + capacity = 1 + } + + waf_configuration { + enabled = true + firewall_mode = "Detection" + rule_set_type = "OWASP" + rule_set_version = "3.0" + request_body_check = true + max_request_body_size_kb = 128 + file_upload_limit_mb = 100 + + exclusion { + match_variable = "RequestArgNames" + selector_match_operator = "Equals" + selector = "displayNameHtml" + } + + exclusion { + match_variable = "RequestCookieNames" + selector_match_operator = "EndsWith" + selector = "username" + } + + exclusion { + match_variable = "RequestHeaderNames" + selector_match_operator = "StartsWith" + selector = "ORIGIN" + } + + exclusion { + match_variable = "RequestHeaderNames" + selector_match_operator = "Contains" + selector = "ORIGIN" + } + + exclusion { + match_variable = "RequestHeaderNames" + } } gateway_ip_configuration { @@ -699,7 +3145,7 @@ resource "azurerm_application_gateway" "import" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -729,17 +3175,15 @@ resource "azurerm_application_gateway" "import" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template) +`, template, rInt, rInt) } - -func testAccAzureRMApplicationGateway_authCertificate(rInt int, location string) string { +func testAccAzureRMApplicationGateway_webApplicationFirewall_exclusions_one(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s # since these variables are re-used - a locals block makes this more maintainable locals { - auth_cert_name = "${azurerm_virtual_network.test.name}-auth" backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" frontend_port_name = "${azurerm_virtual_network.test.name}-feport" frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" @@ -748,15 +3192,39 @@ locals { request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" - capacity = 2 + name = "WAF_v2" + tier = "WAF_v2" + capacity = 1 + } + + waf_configuration { + enabled = true + firewall_mode = "Detection" + rule_set_type = "OWASP" + rule_set_version = "3.0" + request_body_check = true + max_request_body_size_kb = 128 + file_upload_limit_mb = 100 + + exclusion { + match_variable = "RequestArgNames" + selector_match_operator = "Equals" + selector = "displayNameHtml" + } } gateway_ip_configuration { @@ -771,7 +3239,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -781,18 +3249,9 @@ resource "azurerm_application_gateway" "test" { backend_http_settings { name = "${local.http_setting_name}" cookie_based_affinity = "Disabled" - port = 443 - protocol = "Https" + port = 80 + protocol = "Http" request_timeout = 1 - - authentication_certificate { - name = "${local.auth_cert_name}" - } - } - - authentication_certificate { - name = "${local.auth_cert_name}" - data = "${file("testdata/application_gateway_test.cer")}" } http_listener { @@ -810,17 +3269,15 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_authCertificateUpdated(rInt int, location string) string { +func testAccAzureRMApplicationGateway_sslPolicy_policyType_predefined(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s - -# since these variables are re-used - a locals block makes this more maintainable +# since these variables are re-used - a locals block makes this more maintainable locals { - auth_cert_name = "${azurerm_virtual_network.test.name}-auth2" backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" frontend_port_name = "${azurerm_virtual_network.test.name}-feport" frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" @@ -829,15 +3286,28 @@ locals { request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" - capacity = 2 + name = "Standard_v2" + tier = "Standard_v2" + capacity = 1 + } + + ssl_policy { + policy_name = "AppGwSslPolicy20170401S" + policy_type = "Predefined" } gateway_ip_configuration { @@ -852,7 +3322,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -862,18 +3332,9 @@ resource "azurerm_application_gateway" "test" { backend_http_settings { name = "${local.http_setting_name}" cookie_based_affinity = "Disabled" - port = 443 - protocol = "Https" + port = 80 + protocol = "Http" request_timeout = 1 - - authentication_certificate { - name = "${local.auth_cert_name}" - } - } - - authentication_certificate { - name = "${local.auth_cert_name}" - data = "${file("testdata/application_gateway_test_2.crt")}" } http_listener { @@ -891,15 +3352,14 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_pathBasedRouting(rInt int, location string) string { +func testAccAzureRMApplicationGateway_sslPolicy_policyType_custom(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s - -# since these variables are re-used - a locals block makes this more maintainable +# since these variables are re-used - a locals block makes this more maintainable locals { backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" frontend_port_name = "${azurerm_virtual_network.test.name}-feport" @@ -907,8 +3367,14 @@ locals { http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" - path_rule_name = "${azurerm_virtual_network.test.name}-pathrule1" - url_path_map_name = "${azurerm_virtual_network.test.name}-urlpath1" +} + +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" } resource "azurerm_application_gateway" "test" { @@ -917,9 +3383,15 @@ resource "azurerm_application_gateway" "test" { location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" - capacity = 2 + name = "Standard_v2" + tier = "Standard_v2" + capacity = 1 + } + + ssl_policy { + policy_type = "Custom" + min_protocol_version = "TLSv1_1" + cipher_suites = ["TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"] } gateway_ip_configuration { @@ -934,7 +3406,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -957,57 +3429,51 @@ resource "azurerm_application_gateway" "test" { } request_routing_rule { - name = "${local.request_routing_rule_name}" - rule_type = "PathBasedRouting" - url_path_map_name = "${local.url_path_map_name}" - http_listener_name = "${local.listener_name}" - } - - url_path_map { - name = "${local.url_path_map_name}" - default_backend_address_pool_name = "${local.backend_address_pool_name}" - default_backend_http_settings_name = "${local.http_setting_name}" - - path_rule { - name = "${local.path_rule_name}" - backend_address_pool_name = "${local.backend_address_pool_name}" - backend_http_settings_name = "${local.http_setting_name}" - - paths = [ - "/test", - ] - } + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + backend_address_pool_name = "${local.backend_address_pool_name}" + backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_probes(rInt int, location string) string { +func testAccAzureRMApplicationGateway_sslPolicy_disabledProtocols(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s - -# since these variables are re-used - a locals block makes this more maintainable +# since these variables are re-used - a locals block makes this more maintainable locals { backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" frontend_port_name = "${azurerm_virtual_network.test.name}-feport" frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" - probe1_name = "${azurerm_virtual_network.test.name}-probe1" - probe2_name = "${azurerm_virtual_network.test.name}-probe2" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" - capacity = 2 + name = "Standard_v2" + tier = "Standard_v2" + capacity = 1 + } + + ssl_policy { + disabled_protocols = ["TLSv1_0", "TLSv1_1"] } gateway_ip_configuration { @@ -1021,50 +3487,20 @@ resource "azurerm_application_gateway" "test" { } frontend_ip_configuration { - name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" - } - - backend_address_pool { - name = "${local.backend_address_pool_name}" - } - - backend_http_settings { - name = "${local.http_setting_name}" - cookie_based_affinity = "Disabled" - port = 80 - probe_name = "${local.probe1_name}" - protocol = "Http" - request_timeout = 1 - } - - backend_http_settings { - name = "${local.http_setting_name}-2" - cookie_based_affinity = "Disabled" - port = 8080 - probe_name = "${local.probe2_name}" - protocol = "Http" - request_timeout = 1 - } - - probe { - name = "${local.probe1_name}" - protocol = "Http" - path = "/test" - host = "azure.com" - timeout = 120 - interval = 300 - unhealthy_threshold = 8 + name = "${local.frontend_ip_configuration_name}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } - probe { - name = "${local.probe2_name}" - protocol = "Http" - path = "/other" - host = "azure.com" - timeout = 120 - interval = 300 - unhealthy_threshold = 8 + backend_address_pool { + name = "${local.backend_address_pool_name}" + } + + backend_http_settings { + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 } http_listener { @@ -1082,36 +3518,44 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_probesPickHostNameFromBackendHTTPSettings(rInt int, location string) string { +func testAccAzureRMApplicationGateway_disabledSslProtocols(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s - -# since these variables are re-used - a locals block makes this more maintainable +# since these variables are re-used - a locals block makes this more maintainable locals { backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" frontend_port_name = "${azurerm_virtual_network.test.name}-feport" frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" - probe_name = "${azurerm_virtual_network.test.name}-probe" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" } +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" +} + resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" - capacity = 2 + name = "Standard_v2" + tier = "Standard_v2" + capacity = 1 } + disabled_ssl_protocols = ["TLSv1_0", "TLSv1_1"] + gateway_ip_configuration { name = "my-gateway-ip-configuration" subnet_id = "${azurerm_subnet.test.id}" @@ -1124,7 +3568,7 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -1132,23 +3576,11 @@ resource "azurerm_application_gateway" "test" { } backend_http_settings { - name = "${local.http_setting_name}" - cookie_based_affinity = "Disabled" - pick_host_name_from_backend_address = true - port = 80 - probe_name = "${local.probe_name}" - protocol = "Http" - request_timeout = 1 - } - - probe { - name = "${local.probe_name}" - protocol = "Http" - path = "/test" - timeout = 120 - interval = 300 - unhealthy_threshold = 8 - pick_host_name_from_backend_http_settings = true + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 } http_listener { @@ -1166,10 +3598,40 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_settingsPickHostNameFromBackendAddress(rInt int, location string) string { +func testAccAzureRMApplicationGateway_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctest-vnet-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" +} + +resource "azurerm_subnet" "test" { + name = "subnet-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.0.0/24" +} + +resource "azurerm_public_ip" "test" { + name = "acctest-pubip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Dynamic" +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMApplicationGateway_customErrorConfigurations(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -1182,6 +3644,8 @@ locals { http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + path_rule_name = "${azurerm_virtual_network.test.name}-pathrule1" + url_path_map_name = "${azurerm_virtual_network.test.name}-urlpath1" } resource "azurerm_application_gateway" "test" { @@ -1215,12 +3679,11 @@ resource "azurerm_application_gateway" "test" { } backend_http_settings { - name = "${local.http_setting_name}" - cookie_based_affinity = "Disabled" - pick_host_name_from_backend_address = true - port = 80 - protocol = "Http" - request_timeout = 1 + name = "${local.http_setting_name}" + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 } http_listener { @@ -1228,6 +3691,26 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" frontend_port_name = "${local.frontend_port_name}" protocol = "Http" + + custom_error_configuration { + status_code = "HttpStatus403" + custom_error_page_url = "http://azure.com/error403_listener.html" + } + + custom_error_configuration { + status_code = "HttpStatus502" + custom_error_page_url = "http://azure.com/error502_listener.html" + } + } + + custom_error_configuration { + status_code = "HttpStatus403" + custom_error_page_url = "http://azure.com/error.html" + } + + custom_error_configuration { + status_code = "HttpStatus502" + custom_error_page_url = "http://azure.com/error.html" } request_routing_rule { @@ -1241,7 +3724,7 @@ resource "azurerm_application_gateway" "test" { `, template, rInt) } -func testAccAzureRMApplicationGateway_sslCertificate(rInt int, location string) string { +func testAccAzureRMApplicationGateway_rewriteRuleSets_backend(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -1254,7 +3737,16 @@ locals { http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" - ssl_certificate_name = "${azurerm_virtual_network.test.name}-ssl1" + rewrite_rule_set_name = "${azurerm_virtual_network.test.name}-rwset" + rewrite_rule_name = "${azurerm_virtual_network.test.name}-rwrule" +} + +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" } resource "azurerm_application_gateway" "test" { @@ -1263,8 +3755,8 @@ resource "azurerm_application_gateway" "test" { location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" + name = "Standard_v2" + tier = "Standard_v2" capacity = 2 } @@ -1275,12 +3767,12 @@ resource "azurerm_application_gateway" "test" { frontend_port { name = "${local.frontend_port_name}" - port = 443 + port = 80 } frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -1299,8 +3791,7 @@ resource "azurerm_application_gateway" "test" { name = "${local.listener_name}" frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" frontend_port_name = "${local.frontend_port_name}" - protocol = "Https" - ssl_certificate_name = "${local.ssl_certificate_name}" + protocol = "Http" } request_routing_rule { @@ -1309,18 +3800,32 @@ resource "azurerm_application_gateway" "test" { http_listener_name = "${local.listener_name}" backend_address_pool_name = "${local.backend_address_pool_name}" backend_http_settings_name = "${local.http_setting_name}" + rewrite_rule_set_name = "${local.rewrite_rule_set_name}" } - ssl_certificate { - name = "${local.ssl_certificate_name}" - data = "${file("testdata/application_gateway_test.pfx")}" - password = "terraform" + rewrite_rule_set { + name = "${local.rewrite_rule_set_name}" + + rewrite_rule { + name = "${local.rewrite_rule_name}" + rule_sequence = 1 + + condition { + variable = "var_http_status" + pattern = "502" + } + + request_header_configuration { + header_name = "X-custom" + header_value = "customvalue" + } + } } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_sslCertificateUpdated(rInt int, location string) string { +func testAccAzureRMApplicationGateway_rewriteRuleSets_redirect(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -1329,11 +3834,23 @@ func testAccAzureRMApplicationGateway_sslCertificateUpdated(rInt int, location s locals { backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_port_name2 = "${azurerm_virtual_network.test.name}-feport2" frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" + target_listener_name = "${azurerm_virtual_network.test.name}-trgthttplstn" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" - ssl_certificate_name = "${azurerm_virtual_network.test.name}-ssl2" + redirect_configuration_name = "${azurerm_virtual_network.test.name}-Port80To8888Redirect" + rewrite_rule_set_name = "${azurerm_virtual_network.test.name}-rwset" + rewrite_rule_name = "${azurerm_virtual_network.test.name}-rwrule" +} + +resource "azurerm_public_ip" "test_standard" { + name = "acctest-pubip-%d-standard" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + allocation_method = "Static" } resource "azurerm_application_gateway" "test" { @@ -1342,8 +3859,8 @@ resource "azurerm_application_gateway" "test" { location = "${azurerm_resource_group.test.location}" sku { - name = "Standard_Small" - tier = "Standard" + name = "Standard_v2" + tier = "Standard_v2" capacity = 2 } @@ -1354,12 +3871,17 @@ resource "azurerm_application_gateway" "test" { frontend_port { name = "${local.frontend_port_name}" - port = 443 + port = 80 + } + + frontend_port { + name = "${local.frontend_port_name2}" + port = 8888 } frontend_ip_configuration { name = "${local.frontend_ip_configuration_name}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + public_ip_address_id = "${azurerm_public_ip.test_standard.id}" } backend_address_pool { @@ -1378,28 +3900,55 @@ resource "azurerm_application_gateway" "test" { name = "${local.listener_name}" frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" frontend_port_name = "${local.frontend_port_name}" - protocol = "Https" - ssl_certificate_name = "${local.ssl_certificate_name}" + protocol = "Http" + } + + http_listener { + name = "${local.target_listener_name}" + frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" + frontend_port_name = "${local.frontend_port_name2}" + protocol = "Http" } request_routing_rule { - name = "${local.request_routing_rule_name}" - rule_type = "Basic" - http_listener_name = "${local.listener_name}" - backend_address_pool_name = "${local.backend_address_pool_name}" - backend_http_settings_name = "${local.http_setting_name}" + name = "${local.request_routing_rule_name}" + rule_type = "Basic" + http_listener_name = "${local.listener_name}" + redirect_configuration_name = "${local.redirect_configuration_name}" + rewrite_rule_set_name = "${local.rewrite_rule_set_name}" } - ssl_certificate { - name = "${local.ssl_certificate_name}" - data = "${file("testdata/application_gateway_test_2.pfx")}" - password = "hello-world" + rewrite_rule_set { + name = "${local.rewrite_rule_set_name}" + + rewrite_rule { + name = "${local.rewrite_rule_name}" + rule_sequence = 1 + + condition { + variable = "var_http_status" + pattern = "502" + } + + request_header_configuration { + header_name = "X-custom" + header_value = "customvalue" + } + } + } + + redirect_configuration { + name = "${local.redirect_configuration_name}" + redirect_type = "Temporary" + target_listener_name = "${local.target_listener_name}" + include_path = true + include_query_string = false } } -`, template, rInt) +`, template, rInt, rInt) } -func testAccAzureRMApplicationGateway_webApplicationFirewall(rInt int, location string) string { +func testAccAzureRMApplicationGateway_cookieAffinity(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -1420,21 +3969,9 @@ resource "azurerm_application_gateway" "test" { location = "${azurerm_resource_group.test.location}" sku { - name = "WAF_Medium" - tier = "WAF" - capacity = 1 - } - - disabled_ssl_protocols = [ - "TLSv1_0", - ] - - waf_configuration { - enabled = true - firewall_mode = "Detection" - rule_set_type = "OWASP" - rule_set_version = "3.0" - file_upload_limit_mb = 100 + name = "Standard_Small" + tier = "Standard" + capacity = 2 } gateway_ip_configuration { @@ -1458,7 +3995,8 @@ resource "azurerm_application_gateway" "test" { backend_http_settings { name = "${local.http_setting_name}" - cookie_based_affinity = "Disabled" + cookie_based_affinity = "Enabled" + affinity_cookie_name = "testCookieName" port = 80 protocol = "Http" request_timeout = 1 @@ -1482,7 +4020,7 @@ resource "azurerm_application_gateway" "test" { `, template, rInt) } -func testAccAzureRMApplicationGateway_connectionDraining(rInt int, location string) string { +func testAccAzureRMApplicationGateway_cookieAffinityUpdated(rInt int, location string) string { template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` %s @@ -1501,7 +4039,6 @@ resource "azurerm_application_gateway" "test" { name = "acctestag-%d" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" - enable_http2 = true sku { name = "Standard_Small" @@ -1530,15 +4067,10 @@ resource "azurerm_application_gateway" "test" { backend_http_settings { name = "${local.http_setting_name}" - cookie_based_affinity = "Disabled" + cookie_based_affinity = "Enabled" port = 80 protocol = "Http" request_timeout = 1 - - connection_draining { - enabled = true - drain_timeout_sec = 1984 - } } http_listener { @@ -1559,41 +4091,18 @@ resource "azurerm_application_gateway" "test" { `, template, rInt) } -func testAccAzureRMApplicationGateway_template(rInt int, location string) string { +func testAccAzureRMApplicationGateway_gatewayIPUpdated(rInt int, location string) string { + template := testAccAzureRMApplicationGateway_template(rInt, location) return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_virtual_network" "test" { - name = "acctest-vnet-%d" - resource_group_name = "${azurerm_resource_group.test.name}" - address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.test.location}" -} +%s -resource "azurerm_subnet" "test" { - name = "subnet-%d" +resource "azurerm_subnet" "test1" { + name = "subnet1-%d" resource_group_name = "${azurerm_resource_group.test.name}" virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.0.0.0/24" -} - -resource "azurerm_public_ip" "test" { - name = "acctest-pubip-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - allocation_method = "Dynamic" -} -`, rInt, location, rInt, rInt, rInt) + address_prefix = "10.0.1.0/24" } -func testAccAzureRMApplicationGateway_customErrorConfigurations(rInt int, location string) string { - template := testAccAzureRMApplicationGateway_template(rInt, location) - return fmt.Sprintf(` -%s - # since these variables are re-used - a locals block makes this more maintainable locals { backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" @@ -1602,8 +4111,6 @@ locals { http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" - path_rule_name = "${azurerm_virtual_network.test.name}-pathrule1" - url_path_map_name = "${azurerm_virtual_network.test.name}-urlpath1" } resource "azurerm_application_gateway" "test" { @@ -1619,7 +4126,7 @@ resource "azurerm_application_gateway" "test" { gateway_ip_configuration { name = "my-gateway-ip-configuration" - subnet_id = "${azurerm_subnet.test.id}" + subnet_id = "${azurerm_subnet.test1.id}" } frontend_port { @@ -1649,24 +4156,6 @@ resource "azurerm_application_gateway" "test" { frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}" frontend_port_name = "${local.frontend_port_name}" protocol = "Http" - custom_error_configuration { - status_code = "HttpStatus403" - custom_error_page_url = "http://azure.com/error403_listener.html" - } - custom_error_configuration { - status_code = "HttpStatus502" - custom_error_page_url = "http://azure.com/error502_listener.html" - } - } - - custom_error_configuration { - status_code = "HttpStatus403" - custom_error_page_url = "http://azure.com/error.html" - } - - custom_error_configuration { - status_code = "HttpStatus502" - custom_error_page_url = "http://azure.com/error.html" } request_routing_rule { @@ -1677,5 +4166,5 @@ resource "azurerm_application_gateway" "test" { backend_http_settings_name = "${local.http_setting_name}" } } -`, template, rInt) +`, template, rInt, rInt) } diff --git a/azurerm/resource_arm_application_insights.go b/azurerm/resource_arm_application_insights.go index 1a7141caacbd..19703628df6e 100644 --- a/azurerm/resource_arm_application_insights.go +++ b/azurerm/resource_arm_application_insights.go @@ -5,8 +5,11 @@ import ( "log" "net/http" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights" "github.com/hashicorp/terraform/helper/schema" @@ -31,9 +34,9 @@ func resourceArmApplicationInsights() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "application_type": { Type: schema.TypeString, @@ -52,7 +55,7 @@ func resourceArmApplicationInsights() *schema.Resource { }, true), }, - "tags": tagsSchema(), + "tags": tags.Schema(), "app_id": { Type: schema.TypeString, @@ -69,7 +72,7 @@ func resourceArmApplicationInsights() *schema.Resource { } func resourceArmApplicationInsightsCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appInsightsClient + client := meta.(*ArmClient).appInsights.ComponentsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Application Insights creation.") @@ -77,7 +80,7 @@ func resourceArmApplicationInsightsCreateUpdate(d *schema.ResourceData, meta int name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -91,8 +94,8 @@ func resourceArmApplicationInsightsCreateUpdate(d *schema.ResourceData, meta int } applicationType := d.Get("application_type").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) applicationInsightsComponentProperties := insights.ApplicationInsightsComponentProperties{ ApplicationID: &name, @@ -104,7 +107,7 @@ func resourceArmApplicationInsightsCreateUpdate(d *schema.ResourceData, meta int Location: &location, Kind: &applicationType, ApplicationInsightsComponentProperties: &applicationInsightsComponentProperties, - Tags: expandTags(tags), + Tags: tags.Expand(t), } resp, err := client.CreateOrUpdate(ctx, resGroup, name, insightProperties) @@ -131,10 +134,10 @@ func resourceArmApplicationInsightsCreateUpdate(d *schema.ResourceData, meta int } func resourceArmApplicationInsightsRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appInsightsClient + client := meta.(*ArmClient).appInsights.ComponentsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -156,7 +159,7 @@ func resourceArmApplicationInsightsRead(d *schema.ResourceData, meta interface{} d.Set("name", name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.ApplicationInsightsComponentProperties; props != nil { @@ -165,16 +168,14 @@ func resourceArmApplicationInsightsRead(d *schema.ResourceData, meta interface{} d.Set("instrumentation_key", props.InstrumentationKey) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmApplicationInsightsDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appInsightsClient + client := meta.(*ArmClient).appInsights.ComponentsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_application_insights_api_key.go b/azurerm/resource_arm_application_insights_api_key.go index 53810d7e05e2..3426acfed6cd 100644 --- a/azurerm/resource_arm_application_insights_api_key.go +++ b/azurerm/resource_arm_application_insights_api_key.go @@ -6,6 +6,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights" "github.com/hashicorp/terraform/helper/schema" @@ -69,7 +70,7 @@ func resourceArmApplicationInsightsAPIKey() *schema.Resource { } func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appInsightsAPIKeyClient + client := meta.(*ArmClient).appInsights.APIKeyClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Application Insights API key creation.") @@ -77,7 +78,7 @@ func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta int name := d.Get("name").(string) appInsightsID := d.Get("application_insights_id").(string) - id, err := parseAzureResourceID(appInsightsID) + id, err := azure.ParseAzureResourceID(appInsightsID) if err != nil { return err } @@ -85,7 +86,7 @@ func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta int resGroup := id.ResourceGroup appInsightsName := id.Path["components"] - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { var existing insights.ApplicationInsightsComponentAPIKey existing, err = client.Get(ctx, resGroup, appInsightsName, name) if err != nil { @@ -123,10 +124,10 @@ func resourceArmApplicationInsightsAPIKeyCreate(d *schema.ResourceData, meta int } func resourceArmApplicationInsightsAPIKeyRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appInsightsAPIKeyClient + client := meta.(*ArmClient).appInsights.APIKeyClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -163,10 +164,10 @@ func resourceArmApplicationInsightsAPIKeyRead(d *schema.ResourceData, meta inter } func resourceArmApplicationInsightsAPIKeyDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appInsightsAPIKeyClient + client := meta.(*ArmClient).appInsights.APIKeyClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_application_insights_api_key_test.go b/azurerm/resource_arm_application_insights_api_key_test.go index 1cb6a16f048a..0e9bfe075af0 100644 --- a/azurerm/resource_arm_application_insights_api_key_test.go +++ b/azurerm/resource_arm_application_insights_api_key_test.go @@ -8,7 +8,9 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMApplicationInsightsAPIKey_no_permission(t *testing.T) { @@ -29,7 +31,7 @@ func TestAccAzureRMApplicationInsightsAPIKey_no_permission(t *testing.T) { } func TestAccAzureRMApplicationInsightsAPIKey_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -182,7 +184,7 @@ func TestAccAzureRMApplicationInsightsAPIKey_full_permissions(t *testing.T) { } func testCheckAzureRMApplicationInsightsAPIKeyDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).appInsightsAPIKeyClient + conn := testAccProvider.Meta().(*ArmClient).appInsights.APIKeyClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -191,7 +193,7 @@ func testCheckAzureRMApplicationInsightsAPIKeyDestroy(s *terraform.State) error } name := rs.Primary.Attributes["name"] - id, err := parseAzureResourceID(rs.Primary.Attributes["id"]) + id, err := azure.ParseAzureResourceID(rs.Primary.Attributes["id"]) if err != nil { return err } @@ -220,7 +222,7 @@ func testCheckAzureRMApplicationInsightsAPIKeyExists(resourceName string) resour return fmt.Errorf("Not found: %s", resourceName) } - id, err := parseAzureResourceID(rs.Primary.Attributes["id"]) + id, err := azure.ParseAzureResourceID(rs.Primary.Attributes["id"]) if err != nil { return err } @@ -228,7 +230,7 @@ func testCheckAzureRMApplicationInsightsAPIKeyExists(resourceName string) resour resGroup := id.ResourceGroup appInsightsName := id.Path["components"] - conn := testAccProvider.Meta().(*ArmClient).appInsightsAPIKeyClient + conn := testAccProvider.Meta().(*ArmClient).appInsights.APIKeyClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resGroup, appInsightsName, keyID) diff --git a/azurerm/resource_arm_application_insights_test.go b/azurerm/resource_arm_application_insights_test.go index 9067eb57ed7b..4f01b21b5b3e 100644 --- a/azurerm/resource_arm_application_insights_test.go +++ b/azurerm/resource_arm_application_insights_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMApplicationInsights_basicWeb(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMApplicationInsights_basicWeb(t *testing.T) { } func TestAccAzureRMApplicationInsights_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -223,7 +224,7 @@ func TestAccAzureRMApplicationInsights_basiciOS(t *testing.T) { } func testCheckAzureRMApplicationInsightsDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).appInsightsClient + conn := testAccProvider.Meta().(*ArmClient).appInsights.ComponentsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -262,7 +263,7 @@ func testCheckAzureRMApplicationInsightsExists(resourceName string) resource.Tes return fmt.Errorf("Bad: no resource group found in state for App Insights: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).appInsightsClient + conn := testAccProvider.Meta().(*ArmClient).appInsights.ComponentsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_application_insights_webtests.go b/azurerm/resource_arm_application_insights_webtests.go new file mode 100644 index 000000000000..d0b70cdb2cdd --- /dev/null +++ b/azurerm/resource_arm_application_insights_webtests.go @@ -0,0 +1,308 @@ +package azurerm + +import ( + "fmt" + "log" + "net/http" + "strings" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + + "github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmApplicationInsightsWebTests() *schema.Resource { + return &schema.Resource{ + Create: resourceArmApplicationInsightsWebTestsCreateUpdate, + Read: resourceArmApplicationInsightsWebTestsRead, + Update: resourceArmApplicationInsightsWebTestsCreateUpdate, + Delete: resourceArmApplicationInsightsWebTestsDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.NoZeroValues, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "application_insights_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "location": azure.SchemaLocation(), + + "kind": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(insights.Multistep), + string(insights.Ping), + }, false), + }, + + "frequency": { + Type: schema.TypeInt, + Optional: true, + Default: 300, + ValidateFunc: validation.IntInSlice([]int{ + 300, + 600, + 900, + }), + }, + + "timeout": { + Type: schema.TypeInt, + Optional: true, + Default: 30, + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + }, + + "retry_enabled": { + Type: schema.TypeBool, + Optional: true, + }, + + "geo_locations": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + StateFunc: azure.NormalizeLocation, + DiffSuppressFunc: azure.SuppressLocationDiff, + }, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "configuration": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.XmlDiff, + }, + + "tags": tags.Schema(), + + "synthetic_monitor_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmApplicationInsightsWebTestsCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appInsights.WebTestsClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for AzureRM Application Insights WebTest creation.") + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + appInsightsID := d.Get("application_insights_id").(string) + + id, err := azure.ParseAzureResourceID(appInsightsID) + if err != nil { + return err + } + + appInsightsName := id.Path["components"] + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Application Insights WebTests %q (Resource Group %q): %s", name, resGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_application_insights_web_tests", *existing.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + kind := d.Get("kind").(string) + description := d.Get("description").(string) + frequency := int32(d.Get("frequency").(int)) + timeout := int32(d.Get("timeout").(int)) + isEnabled := d.Get("enabled").(bool) + retryEnabled := d.Get("retry_enabled").(bool) + geoLocationsRaw := d.Get("geo_locations").([]interface{}) + geoLocations := expandApplicationInsightsWebTestGeoLocations(geoLocationsRaw) + testConf := d.Get("configuration").(string) + + t := d.Get("tags").(map[string]interface{}) + tagKey := fmt.Sprintf("hidden-link:/subscriptions/%s/resourceGroups/%s/providers/microsoft.insights/components/%s", client.SubscriptionID, resGroup, appInsightsName) + t[tagKey] = "Resource" + + webTest := insights.WebTest{ + Name: &name, + Location: &location, + Kind: insights.WebTestKind(kind), + WebTestProperties: &insights.WebTestProperties{ + SyntheticMonitorID: &name, + WebTestName: &name, + Description: &description, + Enabled: &isEnabled, + Frequency: &frequency, + Timeout: &timeout, + WebTestKind: insights.WebTestKind(kind), + RetryEnabled: &retryEnabled, + Locations: &geoLocations, + Configuration: &insights.WebTestPropertiesConfiguration{ + WebTest: &testConf, + }, + }, + Tags: tags.Expand(t), + } + + resp, err := client.CreateOrUpdate(ctx, resGroup, name, webTest) + if err != nil { + return fmt.Errorf("Error creating Application Insights WebTest %q (Resource Group %q): %+v", name, resGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmApplicationInsightsWebTestsRead(d, meta) +} + +func resourceArmApplicationInsightsWebTestsRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appInsights.WebTestsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + log.Printf("[DEBUG] Reading AzureRM Application Insights WebTests '%s'", id) + + resGroup := id.ResourceGroup + name := id.Path["webtests"] + + resp, err := client.Get(ctx, resGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Application Insights WebTest %q was not found in Resource Group %q - removing from state!", name, resGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error retrieving Application Insights WebTests %q (Resource Group %q): %+v", name, resGroup, err) + } + + appInsightsId := "" + for i := range resp.Tags { + if strings.HasPrefix(i, "hidden-link") { + appInsightsId = strings.Split(i, ":")[1] + } + } + d.Set("application_insights_id", appInsightsId) + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + d.Set("kind", resp.Kind) + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.WebTestProperties; props != nil { + d.Set("synthetic_monitor_id", props.SyntheticMonitorID) + d.Set("description", props.Description) + d.Set("enabled", props.Enabled) + d.Set("frequency", props.Frequency) + d.Set("timeout", props.Timeout) + d.Set("retry_enabled", props.RetryEnabled) + + if config := props.Configuration; config != nil { + d.Set("configuration", config.WebTest) + } + + if err := d.Set("geo_locations", flattenApplicationInsightsWebTestGeoLocations(props.Locations)); err != nil { + return fmt.Errorf("Error setting `geo_locations`: %+v", err) + } + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmApplicationInsightsWebTestsDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).appInsights.WebTestsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["webtests"] + + log.Printf("[DEBUG] Deleting AzureRM Application Insights WebTest '%s' (resource group '%s')", name, resGroup) + + resp, err := client.Delete(ctx, resGroup, name) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + return fmt.Errorf("Error issuing AzureRM delete request for Application Insights WebTest '%s': %+v", name, err) + } + + return err +} + +func expandApplicationInsightsWebTestGeoLocations(input []interface{}) []insights.WebTestGeolocation { + locations := make([]insights.WebTestGeolocation, 0) + + for _, v := range input { + lc := v.(string) + loc := insights.WebTestGeolocation{ + Location: &lc, + } + locations = append(locations, loc) + } + + return locations +} + +func flattenApplicationInsightsWebTestGeoLocations(input *[]insights.WebTestGeolocation) []string { + results := make([]string, 0) + if input == nil { + return results + } + + for _, prop := range *input { + if prop.Location != nil { + results = append(results, azure.NormalizeLocation(*prop.Location)) + } + + } + + return results +} diff --git a/azurerm/resource_arm_application_insights_webtests_test.go b/azurerm/resource_arm_application_insights_webtests_test.go new file mode 100644 index 000000000000..226620c86b9a --- /dev/null +++ b/azurerm/resource_arm_application_insights_webtests_test.go @@ -0,0 +1,269 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMApplicationInsightsWebTests_basic(t *testing.T) { + resourceName := "azurerm_application_insights_web_test.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMApplicationInsightsWebTests_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsWebTestsDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsWebTestExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApplicationInsightsWebTests_complete(t *testing.T) { + resourceName := "azurerm_application_insights_web_test.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsWebTestsDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationInsightsWebTests_complete(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsWebTestExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMApplicationInsightsWebTests_update(t *testing.T) { + resourceName := "azurerm_application_insights_web_test.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsWebTestsDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMApplicationInsightsWebTests_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsWebTestExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "geo_locations.#", "1"), + resource.TestCheckResourceAttr(resourceName, "frequency", "300"), + resource.TestCheckResourceAttr(resourceName, "timeout", "30"), + ), + }, + { + Config: testAccAzureRMApplicationInsightsWebTests_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsWebTestExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "geo_locations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "frequency", "900"), + resource.TestCheckResourceAttr(resourceName, "timeout", "120"), + ), + }, + { + Config: testAccAzureRMApplicationInsightsWebTests_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsWebTestExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "geo_locations.#", "1"), + resource.TestCheckResourceAttr(resourceName, "frequency", "300"), + resource.TestCheckResourceAttr(resourceName, "timeout", "30"), + ), + }, + }, + }) +} + +func TestAccAzureRMApplicationInsightsWebTests_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_application_insights_web_test.test" + ri := tf.AccRandTimeInt() + location := testLocation() + config := testAccAzureRMApplicationInsightsWebTests_basic(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMApplicationInsightsWebTestsDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMApplicationInsightsWebTestExists(resourceName), + ), + }, + { + Config: testAccAzureRMApplicationInsightsWebTests_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_application_insights_web_test"), + }, + }, + }) +} + +func testCheckAzureRMApplicationInsightsWebTestsDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).appInsights.WebTestsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_application_insights_web_test" { + continue + } + + name := rs.Primary.Attributes["name"] + resGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resGroup, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Application Insights WebTest still exists:\n%#v", resp) + } + } + + return nil +} + +func testCheckAzureRMApplicationInsightsWebTestExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up a WebTest + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resGroup := rs.Primary.Attributes["resource_group_name"] + conn := testAccProvider.Meta().(*ArmClient).appInsights.WebTestsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Bad: Get on appInsightsWebTestClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Application Insights WebTest '%q' (resource group: '%q') does not exist", name, resGroup) + } + + return nil + } +} + +func testAccAzureRMApplicationInsightsWebTests_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestappinsights-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_type = "web" +} + +resource "azurerm_application_insights_web_test" "test" { + name = "acctestappinsightswebtests-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_insights_id = "${azurerm_application_insights.test.id}" + kind = "ping" + geo_locations = ["us-tx-sn1-azr"] + + configuration = < + + + + +XML +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMApplicationInsightsWebTests_complete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestappinsights-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_type = "web" +} + +resource "azurerm_application_insights_web_test" "test" { + name = "acctestappinsightswebtests-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_insights_id = "${azurerm_application_insights.test.id}" + kind = "ping" + frequency = 900 + timeout = 120 + enabled = true + geo_locations = ["us-tx-sn1-azr", "us-il-ch1-azr"] + + configuration = < + + + + +XML +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMApplicationInsightsWebTests_requiresImport(rInt int, location string) string { + template := testAccAzureRMApplicationInsightsWebTests_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_application_insights_web_test" "import" { + name = "${azurerm_application_insights_web_test.test.name}" + location = "${azurerm_application_insights_web_test.test.location}" + resource_group_name = "${azurerm_application_insights_web_test.test.resource_group_name}" + application_insights_id = "${azurerm_application_insights_web_test.test.application_insights_id}" + kind = "${azurerm_application_insights_web_test.test.kind}" + configuration = "${azurerm_application_insights_web_test.test.configuration}" +} +`, template) +} diff --git a/azurerm/resource_arm_application_security_group.go b/azurerm/resource_arm_application_security_group.go index 6c00a0b8853b..57ce551dec13 100644 --- a/azurerm/resource_arm_application_security_group.go +++ b/azurerm/resource_arm_application_security_group.go @@ -4,10 +4,13 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -28,23 +31,23 @@ func resourceArmApplicationSecurityGroup() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmApplicationSecurityGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationSecurityGroupsClient + client := meta.(*ArmClient).network.ApplicationSecurityGroupsClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -57,12 +60,12 @@ func resourceArmApplicationSecurityGroupCreateUpdate(d *schema.ResourceData, met } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) securityGroup := network.ApplicationSecurityGroup{ Location: utils.String(location), - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resourceGroup, name, securityGroup) if err != nil { @@ -87,10 +90,10 @@ func resourceArmApplicationSecurityGroupCreateUpdate(d *schema.ResourceData, met } func resourceArmApplicationSecurityGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationSecurityGroupsClient + client := meta.(*ArmClient).network.ApplicationSecurityGroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -110,18 +113,16 @@ func resourceArmApplicationSecurityGroupRead(d *schema.ResourceData, meta interf d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmApplicationSecurityGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationSecurityGroupsClient + client := meta.(*ArmClient).network.ApplicationSecurityGroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_application_security_group_test.go b/azurerm/resource_arm_application_security_group_test.go index e8a31054c64e..8ed3ef1b9c3d 100644 --- a/azurerm/resource_arm_application_security_group_test.go +++ b/azurerm/resource_arm_application_security_group_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,7 +33,7 @@ func TestAccAzureRMApplicationSecurityGroup_basic(t *testing.T) { } func TestAccAzureRMApplicationSecurityGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -120,7 +121,7 @@ func testCheckAzureRMApplicationSecurityGroupDestroy(s *terraform.State) error { name := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).applicationSecurityGroupsClient + client := testAccProvider.Meta().(*ArmClient).network.ApplicationSecurityGroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -153,7 +154,7 @@ func testCheckAzureRMApplicationSecurityGroupExists(resourceName string) resourc return fmt.Errorf("Bad: no resource group found in state for Application Security Group: %q", name) } - client := testAccProvider.Meta().(*ArmClient).applicationSecurityGroupsClient + client := testAccProvider.Meta().(*ArmClient).network.ApplicationSecurityGroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -210,7 +211,7 @@ resource "azurerm_application_security_group" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tags = { - "Hello" = "World" + Hello = "World" } } `, rInt, location, rInt) diff --git a/azurerm/resource_arm_automation_account.go b/azurerm/resource_arm_automation_account.go index ac2d6e3dcc67..fb3c42e86686 100644 --- a/azurerm/resource_arm_automation_account.go +++ b/azurerm/resource_arm_automation_account.go @@ -8,8 +8,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,20 +38,23 @@ func resourceArmAutomationAccount() *schema.Resource { ), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), + // Remove in 2.0 "sku": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, + Type: schema.TypeList, + Optional: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the 'sku_name' property and will be removed in version 2.0 of the provider", + ConflictsWith: []string{"sku_name"}, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Optional: true, - Default: string(automation.Basic), DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(automation.Basic), @@ -59,7 +65,18 @@ func resourceArmAutomationAccount() *schema.Resource { }, }, - "tags": tagsSchema(), + "sku_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"sku"}, + ValidateFunc: validation.StringInSlice([]string{ + string(automation.Basic), + string(automation.Free), + }, false), + }, + + "tags": tags.Schema(), "dsc_server_endpoint": { Type: schema.TypeString, @@ -78,19 +95,40 @@ func resourceArmAutomationAccount() *schema.Resource { } func resourceArmAutomationAccountCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationAccountClient + client := meta.(*ArmClient).automation.AccountClient ctx := meta.(*ArmClient).StopContext + // Remove in 2.0 + var sku automation.Sku + + if inputs := d.Get("sku").([]interface{}); len(inputs) != 0 { + input := inputs[0].(map[string]interface{}) + v := input["name"].(string) + + sku = automation.Sku{ + Name: automation.SkuNameEnum(v), + } + } else { + // Keep in 2.0 + sku = automation.Sku{ + Name: automation.SkuNameEnum(d.Get("sku_name").(string)), + } + } + + if sku.Name == "" { + return fmt.Errorf("either 'sku_name' or 'sku' must be defined in the configuration file") + } + log.Printf("[INFO] preparing arguments for Automation Account create/update.") name := d.Get("name").(string) - resGroup := d.Get("resource_group_name").(string) + resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { - existing, err := client.Get(ctx, resGroup, name) + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of existing Automation Account %q (Resource Group %q): %s", name, resGroup, err) + return fmt.Errorf("Error checking for presence of existing Automation Account %q (Resource Group %q): %s", name, resourceGroup, err) } } @@ -99,29 +137,28 @@ func resourceArmAutomationAccountCreateUpdate(d *schema.ResourceData, meta inter } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) - sku := expandAutomationAccountSku(d) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) parameters := automation.AccountCreateOrUpdateParameters{ AccountCreateOrUpdateProperties: &automation.AccountCreateOrUpdateProperties{ - Sku: sku, + Sku: &sku, }, Location: utils.String(location), - Tags: expandTags(tags), + Tags: tags.Expand(t), } - if _, err := client.CreateOrUpdate(ctx, resGroup, name, parameters); err != nil { - return fmt.Errorf("Error creating/updating Automation Account %q (Resource Group %q) %+v", name, resGroup, err) + if _, err := client.CreateOrUpdate(ctx, resourceGroup, name, parameters); err != nil { + return fmt.Errorf("Error creating/updating Automation Account %q (Resource Group %q) %+v", name, resourceGroup, err) } - read, err := client.Get(ctx, resGroup, name) + read, err := client.Get(ctx, resourceGroup, name) if err != nil { - return fmt.Errorf("Error retrieving Automation Account %q (Resource Group %q) %+v", name, resGroup, err) + return fmt.Errorf("Error retrieving Automation Account %q (Resource Group %q) %+v", name, resourceGroup, err) } if read.ID == nil { - return fmt.Errorf("Cannot read Automation Account %q (Resource Group %q) ID", name, resGroup) + return fmt.Errorf("Cannot read Automation Account %q (Resource Group %q) ID", name, resourceGroup) } d.SetId(*read.ID) @@ -130,47 +167,56 @@ func resourceArmAutomationAccountCreateUpdate(d *schema.ResourceData, meta inter } func resourceArmAutomationAccountRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationAccountClient - registrationClient := meta.(*ArmClient).automationAgentRegistrationInfoClient + client := meta.(*ArmClient).automation.AccountClient + registrationClient := meta.(*ArmClient).automation.AgentRegistrationInfoClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup name := id.Path["automationAccounts"] - resp, err := client.Get(ctx, resGroup, name) + resp, err := client.Get(ctx, resourceGroup, name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[DEBUG] Automation Account %q was not found in Resource Group %q - removing from state!", name, resGroup) + log.Printf("[DEBUG] Automation Account %q was not found in Resource Group %q - removing from state!", name, resourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error making Read request on Automation Account %q (Resource Group %q): %+v", name, resGroup, err) + return fmt.Errorf("Error making Read request on Automation Account %q (Resource Group %q): %+v", name, resourceGroup, err) } - keysResp, err := registrationClient.Get(ctx, resGroup, name) + keysResp, err := registrationClient.Get(ctx, resourceGroup, name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[DEBUG] Agent Registration Info for Automation Account %q was not found in Resource Group %q - removing from state!", name, resGroup) + log.Printf("[DEBUG] Agent Registration Info for Automation Account %q was not found in Resource Group %q - removing from state!", name, resourceGroup) d.SetId("") return nil } - return fmt.Errorf("Error making Read request for Agent Registration Info for Automation Account %q (Resource Group %q): %+v", name, resGroup, err) + return fmt.Errorf("Error making Read request for Agent Registration Info for Automation Account %q (Resource Group %q): %+v", name, resourceGroup, err) } d.Set("name", resp.Name) - d.Set("resource_group_name", resGroup) + d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } - if err := d.Set("sku", flattenAutomationAccountSku(resp.Sku)); err != nil { - return fmt.Errorf("Error setting `sku`: %+v", err) + if sku := resp.Sku; sku != nil { + // Remove in 2.0 + if err := d.Set("sku", flattenAutomationAccountSku(sku)); err != nil { + return fmt.Errorf("Error setting 'sku': %+v", err) + } + + if err := d.Set("sku_name", string(sku.Name)); err != nil { + return fmt.Errorf("Error setting 'sku_name': %+v", err) + } + } else { + return fmt.Errorf("Error making Read request on Automation Account %q (Resource Group %q): Unable to retrieve 'sku' value", name, resourceGroup) } d.Set("dsc_server_endpoint", keysResp.Endpoint) @@ -179,25 +225,25 @@ func resourceArmAutomationAccountRead(d *schema.ResourceData, meta interface{}) d.Set("dsc_secondary_access_key", keys.Secondary) } - if tags := resp.Tags; tags != nil { - flattenAndSetTags(d, tags) + if t := resp.Tags; t != nil { + return tags.FlattenAndSet(d, t) } return nil } func resourceArmAutomationAccountDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationAccountClient + client := meta.(*ArmClient).automation.AccountClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup name := id.Path["automationAccounts"] - resp, err := client.Delete(ctx, resGroup, name) + resp, err := client.Delete(ctx, resourceGroup, name) if err != nil { if utils.ResponseWasNotFound(resp) { @@ -210,6 +256,7 @@ func resourceArmAutomationAccountDelete(d *schema.ResourceData, meta interface{} return nil } +// Remove in 2.0 func flattenAutomationAccountSku(sku *automation.Sku) []interface{} { if sku == nil { return []interface{}{} @@ -219,15 +266,3 @@ func flattenAutomationAccountSku(sku *automation.Sku) []interface{} { result["name"] = string(sku.Name) return []interface{}{result} } - -func expandAutomationAccountSku(d *schema.ResourceData) *automation.Sku { - inputs := d.Get("sku").([]interface{}) - input := inputs[0].(map[string]interface{}) - name := automation.SkuNameEnum(input["name"].(string)) - - sku := automation.Sku{ - Name: name, - } - - return &sku -} diff --git a/azurerm/resource_arm_automation_account_test.go b/azurerm/resource_arm_automation_account_test.go index 25e3c5a279b0..439e8c77f076 100644 --- a/azurerm/resource_arm_automation_account_test.go +++ b/azurerm/resource_arm_automation_account_test.go @@ -2,11 +2,13 @@ package azurerm import ( "fmt" + "regexp" "testing" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -21,6 +23,35 @@ func TestAccAzureRMAutomationAccount_basic(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccAzureRMAutomationAccount_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku_name", "Basic"), + resource.TestCheckResourceAttrSet(resourceName, "dsc_server_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "dsc_primary_access_key"), + resource.TestCheckResourceAttrSet(resourceName, "dsc_secondary_access_key"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +// Remove in 2.0 +func TestAccAzureRMAutomationAccount_basicClassic(t *testing.T) { + resourceName := "azurerm_automation_account.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationAccount_basicClassic(ri, testLocation()), Check: resource.ComposeTestCheckFunc( testCheckAzureRMAutomationAccountExists(resourceName), resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Basic"), @@ -38,8 +69,25 @@ func TestAccAzureRMAutomationAccount_basic(t *testing.T) { }) } +// Remove in 2.0 +func TestAccAzureRMAutomationAccount_basicNotDefined(t *testing.T) { + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationAccount_basicNotDefined(ri, testLocation()), + ExpectError: regexp.MustCompile("either 'sku_name' or 'sku' must be defined in the configuration file"), + }, + }, + }) +} + func TestAccAzureRMAutomationAccount_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -80,7 +128,7 @@ func TestAccAzureRMAutomationAccount_complete(t *testing.T) { Config: testAccAzureRMAutomationAccount_complete(ri, testLocation()), Check: resource.ComposeTestCheckFunc( testCheckAzureRMAutomationAccountExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Basic"), + resource.TestCheckResourceAttr(resourceName, "sku_name", "Basic"), resource.TestCheckResourceAttr(resourceName, "tags.hello", "world"), ), }, @@ -94,7 +142,7 @@ func TestAccAzureRMAutomationAccount_complete(t *testing.T) { } func testCheckAzureRMAutomationAccountDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).automationAccountClient + conn := testAccProvider.Meta().(*ArmClient).automation.AccountClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -136,7 +184,7 @@ func testCheckAzureRMAutomationAccountExists(resourceName string) resource.TestC return fmt.Errorf("Bad: no resource group found in state for Automation Account: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).automationAccountClient + conn := testAccProvider.Meta().(*ArmClient).automation.AccountClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) @@ -160,6 +208,24 @@ resource "azurerm_resource_group" "test" { location = "%s" } +resource "azurerm_automation_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku_name = "Basic" +} +`, rInt, location, rInt) +} + +// Remove in 2.0 +func testAccAzureRMAutomationAccount_basicClassic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + resource "azurerm_automation_account" "test" { name = "acctest-%d" location = "${azurerm_resource_group.test.location}" @@ -167,7 +233,23 @@ resource "azurerm_automation_account" "test" { sku { name = "Basic" - } + } +} +`, rInt, location, rInt) +} + +// Remove in 2.0 +func testAccAzureRMAutomationAccount_basicNotDefined(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" } `, rInt, location, rInt) } @@ -182,9 +264,7 @@ resource "azurerm_automation_account" "import" { location = "${azurerm_automation_account.test.location}" resource_group_name = "${azurerm_automation_account.test.resource_group_name}" - sku { - name = "Basic" - } + sku_name = "Basic" } `, template) } @@ -201,10 +281,8 @@ resource "azurerm_automation_account" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - sku { - name = "Basic" - } - + sku_name = "Basic" + tags = { "hello" = "world" } diff --git a/azurerm/resource_arm_automation_credential.go b/azurerm/resource_arm_automation_credential.go index f829fe0cf703..2d9003d73314 100644 --- a/azurerm/resource_arm_automation_credential.go +++ b/azurerm/resource_arm_automation_credential.go @@ -6,7 +6,9 @@ import ( "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -28,7 +30,7 @@ func resourceArmAutomationCredential() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "account_name": { Type: schema.TypeString, @@ -56,7 +58,7 @@ func resourceArmAutomationCredential() *schema.Resource { } func resourceArmAutomationCredentialCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationCredentialClient + client := meta.(*ArmClient).automation.CredentialClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Automation Credential creation.") @@ -65,7 +67,7 @@ func resourceArmAutomationCredentialCreateUpdate(d *schema.ResourceData, meta in resGroup := d.Get("resource_group_name").(string) accName := d.Get("account_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, accName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -110,10 +112,10 @@ func resourceArmAutomationCredentialCreateUpdate(d *schema.ResourceData, meta in } func resourceArmAutomationCredentialRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationCredentialClient + client := meta.(*ArmClient).automation.CredentialClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -143,10 +145,10 @@ func resourceArmAutomationCredentialRead(d *schema.ResourceData, meta interface{ } func resourceArmAutomationCredentialDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationCredentialClient + client := meta.(*ArmClient).automation.CredentialClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_automation_credential_test.go b/azurerm/resource_arm_automation_credential_test.go index 732020f33b5a..927ba45ba360 100644 --- a/azurerm/resource_arm_automation_credential_test.go +++ b/azurerm/resource_arm_automation_credential_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMAutomationCredential_basic(t *testing.T) { } func TestAccAzureRMAutomationCredential_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -93,7 +94,7 @@ func TestAccAzureRMAutomationCredential_complete(t *testing.T) { } func testCheckAzureRMAutomationCredentialDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).automationCredentialClient + conn := testAccProvider.Meta().(*ArmClient).automation.CredentialClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -143,7 +144,7 @@ func testCheckAzureRMAutomationCredentialExists(resourceName string) resource.Te return fmt.Errorf("Bad: no resource group found in state for Automation Credential: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).automationCredentialClient + conn := testAccProvider.Meta().(*ArmClient).automation.CredentialClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accName, name) diff --git a/azurerm/resource_arm_automation_dsc_configuration.go b/azurerm/resource_arm_automation_dsc_configuration.go index 40446b834cbc..5cf167791d69 100644 --- a/azurerm/resource_arm_automation_dsc_configuration.go +++ b/azurerm/resource_arm_automation_dsc_configuration.go @@ -9,8 +9,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -49,9 +51,9 @@ func resourceArmAutomationDscConfiguration() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "log_verbose": { Type: schema.TypeBool, @@ -73,7 +75,7 @@ func resourceArmAutomationDscConfiguration() *schema.Resource { } func resourceArmAutomationDscConfigurationCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationDscConfigurationClient + client := meta.(*ArmClient).automation.DscConfigurationClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Automation Dsc Configuration creation.") @@ -82,7 +84,7 @@ func resourceArmAutomationDscConfigurationCreateUpdate(d *schema.ResourceData, m resGroup := d.Get("resource_group_name").(string) accName := d.Get("automation_account_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, accName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -96,7 +98,7 @@ func resourceArmAutomationDscConfigurationCreateUpdate(d *schema.ResourceData, m } contentEmbedded := d.Get("content_embedded").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) logVerbose := d.Get("log_verbose").(bool) description := d.Get("description").(string) @@ -131,10 +133,10 @@ func resourceArmAutomationDscConfigurationCreateUpdate(d *schema.ResourceData, m } func resourceArmAutomationDscConfigurationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationDscConfigurationClient + client := meta.(*ArmClient).automation.DscConfigurationClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -157,7 +159,7 @@ func resourceArmAutomationDscConfigurationRead(d *schema.ResourceData, meta inte d.Set("automation_account_name", accName) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.DscConfigurationProperties; props != nil { @@ -183,10 +185,10 @@ func resourceArmAutomationDscConfigurationRead(d *schema.ResourceData, meta inte } func resourceArmAutomationDscConfigurationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationDscConfigurationClient + client := meta.(*ArmClient).automation.DscConfigurationClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_automation_dsc_configuration_test.go b/azurerm/resource_arm_automation_dsc_configuration_test.go index 1eb90d5532f9..b87ca202f45e 100644 --- a/azurerm/resource_arm_automation_dsc_configuration_test.go +++ b/azurerm/resource_arm_automation_dsc_configuration_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,7 +41,7 @@ func TestAccAzureRMAutomationDscConfiguration_basic(t *testing.T) { } func TestAccAzureRMAutomationDscConfiguration_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -69,7 +70,7 @@ func TestAccAzureRMAutomationDscConfiguration_requiresImport(t *testing.T) { } func testCheckAzureRMAutomationDscConfigurationDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).automationDscConfigurationClient + conn := testAccProvider.Meta().(*ArmClient).automation.DscConfigurationClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -119,7 +120,7 @@ func testCheckAzureRMAutomationDscConfigurationExists(resourceName string) resou return fmt.Errorf("Bad: no resource group found in state for Automation Dsc Configuration: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).automationDscConfigurationClient + conn := testAccProvider.Meta().(*ArmClient).automation.DscConfigurationClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accName, name) diff --git a/azurerm/resource_arm_automation_dsc_nodeconfiguration.go b/azurerm/resource_arm_automation_dsc_nodeconfiguration.go index 500e16880a8e..c439c50f40ff 100644 --- a/azurerm/resource_arm_automation_dsc_nodeconfiguration.go +++ b/azurerm/resource_arm_automation_dsc_nodeconfiguration.go @@ -7,8 +7,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +40,7 @@ func resourceArmAutomationDscNodeConfiguration() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "content_embedded": { Type: schema.TypeString, @@ -55,7 +57,7 @@ func resourceArmAutomationDscNodeConfiguration() *schema.Resource { } func resourceArmAutomationDscNodeConfigurationCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationDscNodeConfigurationClient + client := meta.(*ArmClient).automation.DscNodeConfigurationClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Automation Dsc Node Configuration creation.") @@ -64,7 +66,7 @@ func resourceArmAutomationDscNodeConfigurationCreateUpdate(d *schema.ResourceDat resGroup := d.Get("resource_group_name").(string) accName := d.Get("automation_account_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, accName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -114,10 +116,10 @@ func resourceArmAutomationDscNodeConfigurationCreateUpdate(d *schema.ResourceDat } func resourceArmAutomationDscNodeConfigurationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationDscNodeConfigurationClient + client := meta.(*ArmClient).automation.DscNodeConfigurationClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -146,10 +148,10 @@ func resourceArmAutomationDscNodeConfigurationRead(d *schema.ResourceData, meta } func resourceArmAutomationDscNodeConfigurationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationDscNodeConfigurationClient + client := meta.(*ArmClient).automation.DscNodeConfigurationClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_automation_dsc_nodeconfiguration_test.go b/azurerm/resource_arm_automation_dsc_nodeconfiguration_test.go index 15c475404139..447f76160b98 100644 --- a/azurerm/resource_arm_automation_dsc_nodeconfiguration_test.go +++ b/azurerm/resource_arm_automation_dsc_nodeconfiguration_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +39,7 @@ func TestAccAzureRMAutomationDscNodeConfiguration_basic(t *testing.T) { } func TestAccAzureRMAutomationDscNodeConfiguration_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -67,7 +68,7 @@ func TestAccAzureRMAutomationDscNodeConfiguration_requiresImport(t *testing.T) { } func testCheckAzureRMAutomationDscNodeConfigurationDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).automationDscNodeConfigurationClient + conn := testAccProvider.Meta().(*ArmClient).automation.DscNodeConfigurationClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -117,7 +118,7 @@ func testCheckAzureRMAutomationDscNodeConfigurationExists(resourceName string) r return fmt.Errorf("Bad: no resource group found in state for Automation Dsc Node Configuration: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).automationDscNodeConfigurationClient + conn := testAccProvider.Meta().(*ArmClient).automation.DscNodeConfigurationClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accName, name) diff --git a/azurerm/resource_arm_automation_module.go b/azurerm/resource_arm_automation_module.go index f7ee717b3cf3..4c4d957f495d 100644 --- a/azurerm/resource_arm_automation_module.go +++ b/azurerm/resource_arm_automation_module.go @@ -3,11 +3,15 @@ package azurerm import ( "fmt" "log" + "time" "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +41,7 @@ func resourceArmAutomationModule() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "module_link": { Type: schema.TypeList, @@ -75,7 +79,7 @@ func resourceArmAutomationModule() *schema.Resource { } func resourceArmAutomationModuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationModuleClient + client := meta.(*ArmClient).automation.ModuleClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Automation Module creation.") @@ -84,7 +88,7 @@ func resourceArmAutomationModuleCreateUpdate(d *schema.ResourceData, meta interf resGroup := d.Get("resource_group_name").(string) accName := d.Get("automation_account_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, accName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -109,6 +113,48 @@ func resourceArmAutomationModuleCreateUpdate(d *schema.ResourceData, meta interf return err } + // the API returns 'done' but it's not actually finished provisioning yet + stateConf := &resource.StateChangeConf{ + Pending: []string{ + string(automation.ModuleProvisioningStateActivitiesStored), + string(automation.ModuleProvisioningStateConnectionTypeImported), + string(automation.ModuleProvisioningStateContentDownloaded), + string(automation.ModuleProvisioningStateContentRetrieved), + string(automation.ModuleProvisioningStateContentStored), + string(automation.ModuleProvisioningStateContentValidated), + string(automation.ModuleProvisioningStateCreated), + string(automation.ModuleProvisioningStateCreating), + string(automation.ModuleProvisioningStateModuleDataStored), + string(automation.ModuleProvisioningStateModuleImportRunbookComplete), + string(automation.ModuleProvisioningStateRunningImportModuleRunbook), + string(automation.ModuleProvisioningStateStartingImportModuleRunbook), + string(automation.ModuleProvisioningStateUpdating), + }, + Target: []string{ + string(automation.ModuleProvisioningStateSucceeded), + }, + Timeout: 30 * time.Minute, + MinTimeout: 30 * time.Second, + Refresh: func() (interface{}, string, error) { + + resp, err2 := client.Get(ctx, resGroup, accName, name) + if err2 != nil { + return resp, "Error", fmt.Errorf("Error retrieving Module %q (Automation Account %q / Resource Group %q): %+v", name, accName, resGroup, err2) + } + + if properties := resp.ModuleProperties; properties != nil { + return resp, string(properties.ProvisioningState), nil + } + + return resp, "Unknown", nil + }, + } + + _, err := stateConf.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for Module %q (Automation Account %q / Resource Group %q) to finish provisioning: %+v", name, accName, resGroup, err) + } + read, err := client.Get(ctx, resGroup, accName, name) if err != nil { return err @@ -124,10 +170,10 @@ func resourceArmAutomationModuleCreateUpdate(d *schema.ResourceData, meta interf } func resourceArmAutomationModuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationModuleClient + client := meta.(*ArmClient).automation.ModuleClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -153,10 +199,10 @@ func resourceArmAutomationModuleRead(d *schema.ResourceData, meta interface{}) e } func resourceArmAutomationModuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationModuleClient + client := meta.(*ArmClient).automation.ModuleClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_automation_module_test.go b/azurerm/resource_arm_automation_module_test.go index 7a2964b58b61..90007ca18e4e 100644 --- a/azurerm/resource_arm_automation_module_test.go +++ b/azurerm/resource_arm_automation_module_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMAutomationModule_basic(t *testing.T) { } func TestAccAzureRMAutomationModule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -65,8 +66,35 @@ func TestAccAzureRMAutomationModule_requiresImport(t *testing.T) { }) } +func TestAccAzureRMAutomationModule_multipleModules(t *testing.T) { + resourceName := "azurerm_automation_module.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationModuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationModule_multipleModules(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationModuleExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + // Module link is not returned by api in Get operation + ImportStateVerifyIgnore: []string{"module_link"}, + }, + }, + }) +} + func testCheckAzureRMAutomationModuleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).automationModuleClient + conn := testAccProvider.Meta().(*ArmClient).automation.ModuleClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -116,7 +144,7 @@ func testCheckAzureRMAutomationModuleExists(resourceName string) resource.TestCh return fmt.Errorf("Bad: no resource group found in state for Automation Module: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).automationModuleClient + conn := testAccProvider.Meta().(*ArmClient).automation.ModuleClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accName, name) @@ -162,6 +190,47 @@ resource "azurerm_automation_module" "test" { `, rInt, location, rInt) } +func testAccAzureRMAutomationModule_multipleModules(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_module" "test" { + name = "AzureRM.Profile" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + + module_link { + uri = "https://psg-prod-eastus.azureedge.net/packages/azurerm.profile.5.8.2.nupkg" + } +} + +resource "azurerm_automation_module" "second" { + name = "AzureRM.OperationalInsights" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + + module_link { + uri = "https://psg-prod-eastus.azureedge.net/packages/azurerm.operationalinsights.5.0.6.nupkg" + } + + depends_on = ["azurerm_automation_module.test"] +} +`, rInt, location, rInt) +} + func testAccAzureRMAutomationModule_requiresImport(rInt int, location string) string { template := testAccAzureRMAutomationModule_basic(rInt, location) return fmt.Sprintf(` diff --git a/azurerm/resource_arm_automation_runbook.go b/azurerm/resource_arm_automation_runbook.go index 1f697dbc1b80..ebb76c9c7899 100644 --- a/azurerm/resource_arm_automation_runbook.go +++ b/azurerm/resource_arm_automation_runbook.go @@ -9,7 +9,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,15 +41,15 @@ func resourceArmAutomationRunbook() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "runbook_type": { Type: schema.TypeString, Required: true, ForceNew: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(automation.Graph), string(automation.GraphPowerShell), @@ -114,13 +118,13 @@ func resourceArmAutomationRunbook() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmAutomationRunbookCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationRunbookClient + client := meta.(*ArmClient).automation.RunbookClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Automation Runbook creation.") @@ -129,7 +133,7 @@ func resourceArmAutomationRunbookCreateUpdate(d *schema.ResourceData, meta inter accName := d.Get("account_name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, accName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -142,8 +146,8 @@ func resourceArmAutomationRunbookCreateUpdate(d *schema.ResourceData, meta inter } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) runbookType := automation.RunbookTypeEnum(d.Get("runbook_type").(string)) logProgress := d.Get("log_progress").(bool) @@ -162,7 +166,7 @@ func resourceArmAutomationRunbookCreateUpdate(d *schema.ResourceData, meta inter }, Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.CreateOrUpdate(ctx, resGroup, accName, name, parameters); err != nil { @@ -172,7 +176,7 @@ func resourceArmAutomationRunbookCreateUpdate(d *schema.ResourceData, meta inter if v, ok := d.GetOk("content"); ok { content := v.(string) reader := ioutil.NopCloser(bytes.NewBufferString(content)) - draftClient := meta.(*ArmClient).automationRunbookDraftClient + draftClient := meta.(*ArmClient).automation.RunbookDraftClient if _, err := draftClient.ReplaceContent(ctx, resGroup, accName, name, reader); err != nil { return fmt.Errorf("Error setting the draft Automation Runbook %q (Account %q / Resource Group %q): %+v", name, accName, resGroup, err) @@ -198,10 +202,10 @@ func resourceArmAutomationRunbookCreateUpdate(d *schema.ResourceData, meta inter } func resourceArmAutomationRunbookRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationRunbookClient + client := meta.(*ArmClient).automation.RunbookClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -222,7 +226,7 @@ func resourceArmAutomationRunbookRead(d *schema.ResourceData, meta interface{}) d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("account_name", accName) @@ -233,10 +237,6 @@ func resourceArmAutomationRunbookRead(d *schema.ResourceData, meta interface{}) d.Set("description", props.Description) } - if tags := resp.Tags; tags != nil { - flattenAndSetTags(d, tags) - } - response, err := client.GetContent(ctx, resGroup, accName, name) if err != nil { return fmt.Errorf("Error retrieving content for Automation Runbook %q (Account %q / Resource Group %q): %+v", name, accName, resGroup, err) @@ -253,14 +253,18 @@ func resourceArmAutomationRunbookRead(d *schema.ResourceData, meta interface{}) } } + if t := resp.Tags; t != nil { + return tags.FlattenAndSet(d, t) + } + return nil } func resourceArmAutomationRunbookDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationRunbookClient + client := meta.(*ArmClient).automation.RunbookClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_automation_runbook_test.go b/azurerm/resource_arm_automation_runbook_test.go index 7714bcba1b78..bff57309170d 100644 --- a/azurerm/resource_arm_automation_runbook_test.go +++ b/azurerm/resource_arm_automation_runbook_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMAutomationRunbook_PSWorkflow(t *testing.T) { } func TestAccAzureRMAutomationRunbook_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -119,7 +120,7 @@ func TestAccAzureRMAutomationRunbook_PSWithContent(t *testing.T) { } func testCheckAzureRMAutomationRunbookDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).automationRunbookClient + conn := testAccProvider.Meta().(*ArmClient).automation.RunbookClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -168,7 +169,7 @@ func testCheckAzureRMAutomationRunbookExists(resourceName string) resource.TestC return fmt.Errorf("Bad: no resource group found in state for Automation Runbook: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).automationRunbookClient + conn := testAccProvider.Meta().(*ArmClient).automation.RunbookClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accName, name) diff --git a/azurerm/resource_arm_automation_schedule.go b/azurerm/resource_arm_automation_schedule.go index 14041a10d472..9665cb2e7cd8 100644 --- a/azurerm/resource_arm_automation_schedule.go +++ b/azurerm/resource_arm_automation_schedule.go @@ -11,10 +11,12 @@ import ( "github.com/Azure/go-autorest/autorest/date" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,7 +42,7 @@ func resourceArmAutomationSchedule() *schema.Resource { ), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), //this is AutomationAccountName in the SDK "account_name": { @@ -216,7 +218,7 @@ func resourceArmAutomationSchedule() *schema.Resource { } func resourceArmAutomationScheduleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationScheduleClient + client := meta.(*ArmClient).automation.ScheduleClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Automation Schedule creation.") @@ -232,7 +234,7 @@ func resourceArmAutomationScheduleCreateUpdate(d *schema.ResourceData, meta inte accountName = v.(string) } - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, accountName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -309,10 +311,10 @@ func resourceArmAutomationScheduleCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmAutomationScheduleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationScheduleClient + client := meta.(*ArmClient).automation.ScheduleClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -369,10 +371,10 @@ func resourceArmAutomationScheduleRead(d *schema.ResourceData, meta interface{}) } func resourceArmAutomationScheduleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).automationScheduleClient + client := meta.(*ArmClient).automation.ScheduleClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_automation_schedule_test.go b/azurerm/resource_arm_automation_schedule_test.go index 300fa33fbefd..2a1aac8b36c4 100644 --- a/azurerm/resource_arm_automation_schedule_test.go +++ b/azurerm/resource_arm_automation_schedule_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -34,7 +35,7 @@ func TestAccAzureRMAutomationSchedule_oneTime_basic(t *testing.T) { }) } func TestAccAzureRMAutomationSchedule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -268,7 +269,7 @@ func TestAccAzureRMAutomationSchedule_monthly_advanced_by_week_day(t *testing.T) } func testCheckAzureRMAutomationScheduleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).automationScheduleClient + conn := testAccProvider.Meta().(*ArmClient).automation.ScheduleClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -302,7 +303,7 @@ func testCheckAzureRMAutomationScheduleDestroy(s *terraform.State) error { func testCheckAzureRMAutomationScheduleExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).automationScheduleClient + conn := testAccProvider.Meta().(*ArmClient).automation.ScheduleClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API diff --git a/azurerm/resource_arm_automation_variable_bool.go b/azurerm/resource_arm_automation_variable_bool.go new file mode 100644 index 000000000000..6b1bc9c2770d --- /dev/null +++ b/azurerm/resource_arm_automation_variable_bool.go @@ -0,0 +1,32 @@ +package azurerm + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmAutomationVariableBool() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAutomationVariableBoolCreateUpdate, + Read: resourceArmAutomationVariableBoolRead, + Update: resourceArmAutomationVariableBoolCreateUpdate, + Delete: resourceArmAutomationVariableBoolDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: resourceAutomationVariableCommonSchema(schema.TypeBool, nil), + } +} + +func resourceArmAutomationVariableBoolCreateUpdate(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableCreateUpdate(d, meta, "Bool") +} + +func resourceArmAutomationVariableBoolRead(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableRead(d, meta, "Bool") +} + +func resourceArmAutomationVariableBoolDelete(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableDelete(d, meta, "Bool") +} diff --git a/azurerm/resource_arm_automation_variable_bool_test.go b/azurerm/resource_arm_automation_variable_bool_test.go new file mode 100644 index 000000000000..f01d31f7bd69 --- /dev/null +++ b/azurerm/resource_arm_automation_variable_bool_test.go @@ -0,0 +1,160 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMAutomationVariableBool_basic(t *testing.T) { + resourceName := "azurerm_automation_variable_bool.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableBoolDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableBool_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableBoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "false"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAutomationVariableBool_complete(t *testing.T) { + resourceName := "azurerm_automation_variable_bool.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableBoolDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableBool_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableBoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "This variable is created by Terraform acceptance test."), + resource.TestCheckResourceAttr(resourceName, "value", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAutomationVariableBool_basicCompleteUpdate(t *testing.T) { + resourceName := "azurerm_automation_variable_bool.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableBoolDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableBool_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableBoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "false"), + ), + }, + { + Config: testAccAzureRMAutomationVariableBool_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableBoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "This variable is created by Terraform acceptance test."), + resource.TestCheckResourceAttr(resourceName, "value", "true"), + ), + }, + { + Config: testAccAzureRMAutomationVariableBool_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableBoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "false"), + ), + }, + }, + }) +} + +func testCheckAzureRMAutomationVariableBoolExists(resourceName string) resource.TestCheckFunc { + return testCheckAzureRMAutomationVariableExists(resourceName, "Bool") +} + +func testCheckAzureRMAutomationVariableBoolDestroy(s *terraform.State) error { + return testCheckAzureRMAutomationVariableDestroy(s, "Bool") +} + +func testAccAzureRMAutomationVariableBool_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctestAutoAcct-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_bool" "test" { + name = "acctestAutoVar-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + value = false +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAutomationVariableBool_complete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctestAutoAcct-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_bool" "test" { + name = "acctestAutoVar-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + description = "This variable is created by Terraform acceptance test." + value = true +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_automation_variable_datetime.go b/azurerm/resource_arm_automation_variable_datetime.go new file mode 100644 index 000000000000..8343052c029d --- /dev/null +++ b/azurerm/resource_arm_automation_variable_datetime.go @@ -0,0 +1,33 @@ +package azurerm + +import ( + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" +) + +func resourceArmAutomationVariableDateTime() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAutomationVariableDateTimeCreateUpdate, + Read: resourceArmAutomationVariableDateTimeRead, + Update: resourceArmAutomationVariableDateTimeCreateUpdate, + Delete: resourceArmAutomationVariableDateTimeDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: resourceAutomationVariableCommonSchema(schema.TypeString, validate.RFC3339Time), + } +} + +func resourceArmAutomationVariableDateTimeCreateUpdate(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableCreateUpdate(d, meta, "Datetime") +} + +func resourceArmAutomationVariableDateTimeRead(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableRead(d, meta, "Datetime") +} + +func resourceArmAutomationVariableDateTimeDelete(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableDelete(d, meta, "Datetime") +} diff --git a/azurerm/resource_arm_automation_variable_datetime_test.go b/azurerm/resource_arm_automation_variable_datetime_test.go new file mode 100644 index 000000000000..935d006a77d7 --- /dev/null +++ b/azurerm/resource_arm_automation_variable_datetime_test.go @@ -0,0 +1,160 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMAutomationVariableDateTime_basic(t *testing.T) { + resourceName := "azurerm_automation_variable_datetime.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableDateTimeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableDateTime_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableDateTimeExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "2019-04-24T21:40:54.074Z"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAutomationVariableDateTime_complete(t *testing.T) { + resourceName := "azurerm_automation_variable_datetime.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableDateTimeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableDateTime_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableDateTimeExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "This variable is created by Terraform acceptance test."), + resource.TestCheckResourceAttr(resourceName, "value", "2019-04-20T08:40:04.02Z"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAutomationVariableDateTime_basicCompleteUpdate(t *testing.T) { + resourceName := "azurerm_automation_variable_datetime.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableDateTimeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableDateTime_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableDateTimeExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "2019-04-24T21:40:54.074Z"), + ), + }, + { + Config: testAccAzureRMAutomationVariableDateTime_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableDateTimeExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "This variable is created by Terraform acceptance test."), + resource.TestCheckResourceAttr(resourceName, "value", "2019-04-20T08:40:04.02Z"), + ), + }, + { + Config: testAccAzureRMAutomationVariableDateTime_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableDateTimeExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "2019-04-24T21:40:54.074Z"), + ), + }, + }, + }) +} + +func testCheckAzureRMAutomationVariableDateTimeExists(resourceName string) resource.TestCheckFunc { + return testCheckAzureRMAutomationVariableExists(resourceName, "Datetime") +} + +func testCheckAzureRMAutomationVariableDateTimeDestroy(s *terraform.State) error { + return testCheckAzureRMAutomationVariableDestroy(s, "Datetime") +} + +func testAccAzureRMAutomationVariableDateTime_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctestAutoAcct-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_datetime" "test" { + name = "acctestAutoVar-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + value = "2019-04-24T21:40:54.074Z" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAutomationVariableDateTime_complete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctestAutoAcct-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_datetime" "test" { + name = "acctestAutoVar-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + description = "This variable is created by Terraform acceptance test." + value = "2019-04-20T08:40:04.02Z" +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_automation_variable_int.go b/azurerm/resource_arm_automation_variable_int.go new file mode 100644 index 000000000000..ea2c5992f235 --- /dev/null +++ b/azurerm/resource_arm_automation_variable_int.go @@ -0,0 +1,32 @@ +package azurerm + +import ( + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmAutomationVariableInt() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAutomationVariableIntCreateUpdate, + Read: resourceArmAutomationVariableIntRead, + Update: resourceArmAutomationVariableIntCreateUpdate, + Delete: resourceArmAutomationVariableIntDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: resourceAutomationVariableCommonSchema(schema.TypeInt, nil), + } +} + +func resourceArmAutomationVariableIntCreateUpdate(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableCreateUpdate(d, meta, "Int") +} + +func resourceArmAutomationVariableIntRead(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableRead(d, meta, "Int") +} + +func resourceArmAutomationVariableIntDelete(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableDelete(d, meta, "Int") +} diff --git a/azurerm/resource_arm_automation_variable_int_test.go b/azurerm/resource_arm_automation_variable_int_test.go new file mode 100644 index 000000000000..4cb43fb41cd3 --- /dev/null +++ b/azurerm/resource_arm_automation_variable_int_test.go @@ -0,0 +1,160 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMAutomationVariableInt_basic(t *testing.T) { + resourceName := "azurerm_automation_variable_int.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableIntDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableInt_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableIntExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "1234"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAutomationVariableInt_complete(t *testing.T) { + resourceName := "azurerm_automation_variable_int.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableIntDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableInt_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableIntExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "This variable is created by Terraform acceptance test."), + resource.TestCheckResourceAttr(resourceName, "value", "12345"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAutomationVariableInt_basicCompleteUpdate(t *testing.T) { + resourceName := "azurerm_automation_variable_int.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableIntDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableInt_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableIntExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "1234"), + ), + }, + { + Config: testAccAzureRMAutomationVariableInt_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableIntExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "This variable is created by Terraform acceptance test."), + resource.TestCheckResourceAttr(resourceName, "value", "12345"), + ), + }, + { + Config: testAccAzureRMAutomationVariableInt_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableIntExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "1234"), + ), + }, + }, + }) +} + +func testCheckAzureRMAutomationVariableIntExists(resourceName string) resource.TestCheckFunc { + return testCheckAzureRMAutomationVariableExists(resourceName, "Int") +} + +func testCheckAzureRMAutomationVariableIntDestroy(s *terraform.State) error { + return testCheckAzureRMAutomationVariableDestroy(s, "Int") +} + +func testAccAzureRMAutomationVariableInt_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctestAutoAcct-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_int" "test" { + name = "acctestAutoVar-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + value = 1234 +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAutomationVariableInt_complete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctestAutoAcct-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_int" "test" { + name = "acctestAutoVar-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + description = "This variable is created by Terraform acceptance test." + value = 12345 +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_automation_variable_string.go b/azurerm/resource_arm_automation_variable_string.go new file mode 100644 index 000000000000..b52b84e4eb26 --- /dev/null +++ b/azurerm/resource_arm_automation_variable_string.go @@ -0,0 +1,33 @@ +package azurerm + +import ( + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" +) + +func resourceArmAutomationVariableString() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAutomationVariableStringCreateUpdate, + Read: resourceArmAutomationVariableStringRead, + Update: resourceArmAutomationVariableStringCreateUpdate, + Delete: resourceArmAutomationVariableStringDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: resourceAutomationVariableCommonSchema(schema.TypeString, validate.NoEmptyStrings), + } +} + +func resourceArmAutomationVariableStringCreateUpdate(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableCreateUpdate(d, meta, "String") +} + +func resourceArmAutomationVariableStringRead(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableRead(d, meta, "String") +} + +func resourceArmAutomationVariableStringDelete(d *schema.ResourceData, meta interface{}) error { + return resourceAutomationVariableDelete(d, meta, "String") +} diff --git a/azurerm/resource_arm_automation_variable_string_test.go b/azurerm/resource_arm_automation_variable_string_test.go new file mode 100644 index 000000000000..403f204811ef --- /dev/null +++ b/azurerm/resource_arm_automation_variable_string_test.go @@ -0,0 +1,160 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMAutomationVariableString_basic(t *testing.T) { + resourceName := "azurerm_automation_variable_string.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableStringDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableString_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableStringExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "Hello, Terraform Basic Test."), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAutomationVariableString_complete(t *testing.T) { + resourceName := "azurerm_automation_variable_string.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableStringDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableString_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableStringExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "This variable is created by Terraform acceptance test."), + resource.TestCheckResourceAttr(resourceName, "value", "Hello, Terraform Complete Test."), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMAutomationVariableString_basicCompleteUpdate(t *testing.T) { + resourceName := "azurerm_automation_variable_string.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAutomationVariableStringDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMAutomationVariableString_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableStringExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "Hello, Terraform Basic Test."), + ), + }, + { + Config: testAccAzureRMAutomationVariableString_complete(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableStringExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "This variable is created by Terraform acceptance test."), + resource.TestCheckResourceAttr(resourceName, "value", "Hello, Terraform Complete Test."), + ), + }, + { + Config: testAccAzureRMAutomationVariableString_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAutomationVariableStringExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "value", "Hello, Terraform Basic Test."), + ), + }, + }, + }) +} + +func testCheckAzureRMAutomationVariableStringExists(resourceName string) resource.TestCheckFunc { + return testCheckAzureRMAutomationVariableExists(resourceName, "String") +} + +func testCheckAzureRMAutomationVariableStringDestroy(s *terraform.State) error { + return testCheckAzureRMAutomationVariableDestroy(s, "String") +} + +func testAccAzureRMAutomationVariableString_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctestAutoAcct-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_string" "test" { + name = "acctestAutoVar-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + value = "Hello, Terraform Basic Test." +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMAutomationVariableString_complete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_automation_account" "test" { + name = "acctestAutoAcct-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_string" "test" { + name = "acctestAutoVar-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + automation_account_name = "${azurerm_automation_account.test.name}" + description = "This variable is created by Terraform acceptance test." + value = "Hello, Terraform Complete Test." +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_autoscale_setting.go b/azurerm/resource_arm_autoscale_setting.go index 8de1667ab976..cf43d322dea3 100644 --- a/azurerm/resource_arm_autoscale_setting.go +++ b/azurerm/resource_arm_autoscale_setting.go @@ -12,8 +12,11 @@ import ( "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -42,9 +45,9 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "target_resource_id": { Type: schema.TypeString, @@ -119,7 +122,7 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will "time_grain": { Type: schema.TypeString, Required: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "statistic": { Type: schema.TypeString, @@ -130,12 +133,12 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will string(insights.MetricStatisticTypeMin), string(insights.MetricStatisticTypeSum), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "time_window": { Type: schema.TypeString, Required: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "time_aggregation": { Type: schema.TypeString, @@ -147,7 +150,7 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will string(insights.TimeAggregationTypeMinimum), string(insights.TimeAggregationTypeTotal), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "operator": { Type: schema.TypeString, @@ -160,7 +163,7 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will string(insights.LessThanOrEqual), string(insights.NotEquals), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "threshold": { Type: schema.TypeFloat, @@ -182,7 +185,7 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will string(insights.ScaleDirectionDecrease), string(insights.ScaleDirectionIncrease), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "type": { Type: schema.TypeString, @@ -192,7 +195,7 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will string(insights.ExactCount), string(insights.PercentChangeCount), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "value": { Type: schema.TypeInt, @@ -202,7 +205,7 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will "cooldown": { Type: schema.TypeString, Required: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, }, }, @@ -225,12 +228,12 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will "start": { Type: schema.TypeString, Required: true, - ValidateFunc: validateRFC3339Date, + ValidateFunc: validate.RFC3339Time, }, "end": { Type: schema.TypeString, Required: true, - ValidateFunc: validateRFC3339Date, + ValidateFunc: validate.RFC3339Time, }, }, }, @@ -261,7 +264,7 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will "Saturday", "Sunday", }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, "hours": { @@ -342,19 +345,19 @@ As such the existing 'azurerm_autoscale_setting' resource is deprecated and will }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmAutoScaleSettingCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).autoscaleSettingsClient + client := meta.(*ArmClient).monitor.AutoscaleSettingsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -367,7 +370,7 @@ func resourceArmAutoScaleSettingCreateUpdate(d *schema.ResourceData, meta interf } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) enabled := d.Get("enabled").(bool) targetResourceId := d.Get("target_resource_id").(string) @@ -380,8 +383,8 @@ func resourceArmAutoScaleSettingCreateUpdate(d *schema.ResourceData, meta interf return fmt.Errorf("Error expanding `profile`: %+v", err) } - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) parameters := insights.AutoscaleSettingResource{ Location: utils.String(location), @@ -412,10 +415,10 @@ func resourceArmAutoScaleSettingCreateUpdate(d *schema.ResourceData, meta interf } func resourceArmAutoScaleSettingRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).autoscaleSettingsClient + client := meta.(*ArmClient).monitor.AutoscaleSettingsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -436,7 +439,7 @@ func resourceArmAutoScaleSettingRead(d *schema.ResourceData, meta interface{}) e d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("enabled", resp.Enabled) @@ -456,17 +459,15 @@ func resourceArmAutoScaleSettingRead(d *schema.ResourceData, meta interface{}) e } // Return a new tag map filtered by the specified tag names. - tagMap := filterTags(resp.Tags, "$type") - flattenAndSetTags(d, tagMap) - - return nil + tagMap := tags.Filter(resp.Tags, "$type") + return tags.FlattenAndSet(d, tagMap) } func resourceArmAutoScaleSettingDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).autoscaleSettingsClient + client := meta.(*ArmClient).monitor.AutoscaleSettingsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_autoscale_setting_test.go b/azurerm/resource_arm_autoscale_setting_test.go index 30bef543a9d7..063c0de8caa1 100644 --- a/azurerm/resource_arm_autoscale_setting_test.go +++ b/azurerm/resource_arm_autoscale_setting_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMAutoScaleSetting_basic(t *testing.T) { @@ -43,7 +44,7 @@ func TestAccAzureRMAutoScaleSetting_basic(t *testing.T) { } func TestAccAzureRMAutoScaleSetting_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -332,7 +333,7 @@ func testCheckAzureRMAutoScaleSettingExists(resourceName string) resource.TestCh return fmt.Errorf("Bad: no resource group found in state for AutoScale Setting: %s", autoscaleSettingName) } - conn := testAccProvider.Meta().(*ArmClient).autoscaleSettingsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.AutoscaleSettingsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, autoscaleSettingName) @@ -349,7 +350,7 @@ func testCheckAzureRMAutoScaleSettingExists(resourceName string) resource.TestCh } func testCheckAzureRMAutoScaleSettingDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).autoscaleSettingsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.AutoscaleSettingsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_availability_set.go b/azurerm/resource_arm_availability_set.go index be1ff3cff3a3..255bb168234a 100644 --- a/azurerm/resource_arm_availability_set.go +++ b/azurerm/resource_arm_availability_set.go @@ -8,7 +8,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -29,9 +32,9 @@ func resourceArmAvailabilitySet() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "platform_update_domain_count": { Type: schema.TypeInt, @@ -56,13 +59,13 @@ func resourceArmAvailabilitySet() *schema.Resource { ForceNew: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmAvailabilitySetCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).availSetClient + client := meta.(*ArmClient).compute.AvailabilitySetsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Availability Set creation.") @@ -70,7 +73,7 @@ func resourceArmAvailabilitySetCreateUpdate(d *schema.ResourceData, meta interfa name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -83,11 +86,11 @@ func resourceArmAvailabilitySetCreateUpdate(d *schema.ResourceData, meta interfa } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) updateDomainCount := d.Get("platform_update_domain_count").(int) faultDomainCount := d.Get("platform_fault_domain_count").(int) managed := d.Get("managed").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) availSet := compute.AvailabilitySet{ Name: &name, @@ -96,7 +99,7 @@ func resourceArmAvailabilitySetCreateUpdate(d *schema.ResourceData, meta interfa PlatformFaultDomainCount: utils.Int32(int32(faultDomainCount)), PlatformUpdateDomainCount: utils.Int32(int32(updateDomainCount)), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if managed { @@ -117,10 +120,10 @@ func resourceArmAvailabilitySetCreateUpdate(d *schema.ResourceData, meta interfa } func resourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).availSetClient + client := meta.(*ArmClient).compute.AvailabilitySetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -139,7 +142,7 @@ func resourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) er d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if resp.Sku != nil && resp.Sku.Name != nil { d.Set("managed", strings.EqualFold(*resp.Sku.Name, "Aligned")) @@ -150,16 +153,14 @@ func resourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) er d.Set("platform_fault_domain_count", props.PlatformFaultDomainCount) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmAvailabilitySetDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).availSetClient + client := meta.(*ArmClient).compute.AvailabilitySetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_availability_set_test.go b/azurerm/resource_arm_availability_set_test.go index 470c7899071a..40fe47c26bf8 100644 --- a/azurerm/resource_arm_availability_set_test.go +++ b/azurerm/resource_arm_availability_set_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -39,7 +40,7 @@ func TestAccAzureRMAvailabilitySet_basic(t *testing.T) { } func TestAccAzureRMAvailabilitySet_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -198,7 +199,7 @@ func testCheckAzureRMAvailabilitySetExists(resourceName string) resource.TestChe return fmt.Errorf("Bad: no resource group found in state for availability set: %s", availSetName) } - client := testAccProvider.Meta().(*ArmClient).availSetClient + client := testAccProvider.Meta().(*ArmClient).compute.AvailabilitySetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, availSetName) if err != nil { @@ -227,7 +228,7 @@ func testCheckAzureRMAvailabilitySetDisappears(resourceName string) resource.Tes return fmt.Errorf("Bad: no resource group found in state for availability set: %s", availSetName) } - client := testAccProvider.Meta().(*ArmClient).availSetClient + client := testAccProvider.Meta().(*ArmClient).compute.AvailabilitySetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Delete(ctx, resourceGroup, availSetName) if err != nil { @@ -249,7 +250,7 @@ func testCheckAzureRMAvailabilitySetDestroy(s *terraform.State) error { name := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).availSetClient + client := testAccProvider.Meta().(*ArmClient).compute.AvailabilitySetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_azuread_application.go b/azurerm/resource_arm_azuread_application.go index b6ce02826768..606cc0c3f6c5 100644 --- a/azurerm/resource_arm_azuread_application.go +++ b/azurerm/resource_arm_azuread_application.go @@ -81,7 +81,7 @@ As such the Azure Active Directory resources within the AzureRM Provider are now } func resourceArmActiveDirectoryApplicationCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationsClient + client := meta.(*ArmClient).graph.ApplicationsClient ctx := meta.(*ArmClient).StopContext // NOTE: name isn't the Resource ID here, so we don't check it exists @@ -111,7 +111,7 @@ func resourceArmActiveDirectoryApplicationCreate(d *schema.ResourceData, meta in } func resourceArmActiveDirectoryApplicationUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationsClient + client := meta.(*ArmClient).graph.ApplicationsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -152,7 +152,7 @@ func resourceArmActiveDirectoryApplicationUpdate(d *schema.ResourceData, meta in } func resourceArmActiveDirectoryApplicationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationsClient + client := meta.(*ArmClient).graph.ApplicationsClient ctx := meta.(*ArmClient).StopContext resp, err := client.Get(ctx, d.Id()) @@ -192,7 +192,7 @@ func resourceArmActiveDirectoryApplicationRead(d *schema.ResourceData, meta inte } func resourceArmActiveDirectoryApplicationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).applicationsClient + client := meta.(*ArmClient).graph.ApplicationsClient ctx := meta.(*ArmClient).StopContext // in order to delete an application which is available to other tenants, we first have to disable this setting diff --git a/azurerm/resource_arm_azuread_application_test.go b/azurerm/resource_arm_azuread_application_test.go index 0031b274c5a3..7822ffde2e1b 100644 --- a/azurerm/resource_arm_azuread_application_test.go +++ b/azurerm/resource_arm_azuread_application_test.go @@ -138,7 +138,7 @@ func testCheckAzureRMActiveDirectoryApplicationExists(resourceName string) resou return fmt.Errorf("Not found: %q", resourceName) } - client := testAccProvider.Meta().(*ArmClient).applicationsClient + client := testAccProvider.Meta().(*ArmClient).graph.ApplicationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, rs.Primary.ID) @@ -159,7 +159,7 @@ func testCheckAzureRMActiveDirectoryApplicationDestroy(s *terraform.State) error continue } - client := testAccProvider.Meta().(*ArmClient).applicationsClient + client := testAccProvider.Meta().(*ArmClient).graph.ApplicationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, rs.Primary.ID) diff --git a/azurerm/resource_arm_azuread_service_principal.go b/azurerm/resource_arm_azuread_service_principal.go index b422b1a144ca..a40a07a5ad4a 100644 --- a/azurerm/resource_arm_azuread_service_principal.go +++ b/azurerm/resource_arm_azuread_service_principal.go @@ -43,7 +43,7 @@ As such the Azure Active Directory resources within the AzureRM Provider are now } func resourceArmActiveDirectoryServicePrincipalCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).servicePrincipalsClient + client := meta.(*ArmClient).graph.ServicePrincipalsClient ctx := meta.(*ArmClient).StopContext applicationId := d.Get("application_id").(string) @@ -93,7 +93,7 @@ func resourceArmActiveDirectoryServicePrincipalCreate(d *schema.ResourceData, me } func resourceArmActiveDirectoryServicePrincipalRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).servicePrincipalsClient + client := meta.(*ArmClient).graph.ServicePrincipalsClient ctx := meta.(*ArmClient).StopContext objectId := d.Id() @@ -114,7 +114,7 @@ func resourceArmActiveDirectoryServicePrincipalRead(d *schema.ResourceData, meta } func resourceArmActiveDirectoryServicePrincipalDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).servicePrincipalsClient + client := meta.(*ArmClient).graph.ServicePrincipalsClient ctx := meta.(*ArmClient).StopContext applicationId := d.Id() diff --git a/azurerm/resource_arm_azuread_service_principal_password.go b/azurerm/resource_arm_azuread_service_principal_password.go index 33a87042d21f..79b325a8d620 100644 --- a/azurerm/resource_arm_azuread_service_principal_password.go +++ b/azurerm/resource_arm_azuread_service_principal_password.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -72,7 +73,7 @@ As such the Azure Active Directory resources within the AzureRM Provider are now } func resourceArmActiveDirectoryServicePrincipalPasswordCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).servicePrincipalsClient + client := meta.(*ArmClient).graph.ServicePrincipalsClient ctx := meta.(*ArmClient).StopContext objectId := d.Get("service_principal_id").(string) @@ -104,8 +105,8 @@ func resourceArmActiveDirectoryServicePrincipalPasswordCreate(d *schema.Resource credential.StartDate = &date.Time{Time: startDate} } - azureRMLockByName(objectId, servicePrincipalResourceName) - defer azureRMUnlockByName(objectId, servicePrincipalResourceName) + locks.ByName(objectId, servicePrincipalResourceName) + defer locks.UnlockByName(objectId, servicePrincipalResourceName) existingCredentials, err := client.ListPasswordCredentials(ctx, objectId) if err != nil { @@ -143,7 +144,7 @@ func resourceArmActiveDirectoryServicePrincipalPasswordCreate(d *schema.Resource } func resourceArmActiveDirectoryServicePrincipalPasswordRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).servicePrincipalsClient + client := meta.(*ArmClient).graph.ServicePrincipalsClient ctx := meta.(*ArmClient).StopContext id := strings.Split(d.Id(), "/") @@ -205,7 +206,7 @@ func resourceArmActiveDirectoryServicePrincipalPasswordRead(d *schema.ResourceDa } func resourceArmActiveDirectoryServicePrincipalPasswordDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).servicePrincipalsClient + client := meta.(*ArmClient).graph.ServicePrincipalsClient ctx := meta.(*ArmClient).StopContext id := strings.Split(d.Id(), "/") @@ -216,8 +217,8 @@ func resourceArmActiveDirectoryServicePrincipalPasswordDelete(d *schema.Resource objectId := id[0] keyId := id[1] - azureRMLockByName(objectId, servicePrincipalResourceName) - defer azureRMUnlockByName(objectId, servicePrincipalResourceName) + locks.ByName(objectId, servicePrincipalResourceName) + defer locks.UnlockByName(objectId, servicePrincipalResourceName) // ensure the parent Service Principal exists servicePrincipal, err := client.Get(ctx, objectId) diff --git a/azurerm/resource_arm_azuread_service_principal_password_test.go b/azurerm/resource_arm_azuread_service_principal_password_test.go index 5c7e1a5f15b1..6332ace8cf40 100644 --- a/azurerm/resource_arm_azuread_service_principal_password_test.go +++ b/azurerm/resource_arm_azuread_service_principal_password_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -44,7 +45,7 @@ func TestAccAzureRMActiveDirectoryServicePrincipalPassword_basic(t *testing.T) { } func TestAccAzureRMActiveDirectoryServicePrincipalPassword_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -120,7 +121,7 @@ func testCheckAzureRMActiveDirectoryServicePrincipalPasswordExists(resourceName return fmt.Errorf("Not found: %q", resourceName) } - client := testAccProvider.Meta().(*ArmClient).servicePrincipalsClient + client := testAccProvider.Meta().(*ArmClient).graph.ServicePrincipalsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext id := strings.Split(rs.Primary.ID, "/") diff --git a/azurerm/resource_arm_azuread_service_principal_test.go b/azurerm/resource_arm_azuread_service_principal_test.go index 46ba1ae7ddd7..f0e670078f6b 100644 --- a/azurerm/resource_arm_azuread_service_principal_test.go +++ b/azurerm/resource_arm_azuread_service_principal_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +39,7 @@ func TestAccAzureRMActiveDirectoryServicePrincipal_basic(t *testing.T) { } func TestAccAzureRMActiveDirectoryServicePrincipal_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -72,7 +73,7 @@ func testCheckAzureRMActiveDirectoryServicePrincipalExists(resourceName string) return fmt.Errorf("Not found: %q", resourceName) } - client := testAccProvider.Meta().(*ArmClient).servicePrincipalsClient + client := testAccProvider.Meta().(*ArmClient).graph.ServicePrincipalsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, rs.Primary.ID) @@ -93,7 +94,7 @@ func testCheckAzureRMActiveDirectoryServicePrincipalDestroy(s *terraform.State) continue } - client := testAccProvider.Meta().(*ArmClient).servicePrincipalsClient + client := testAccProvider.Meta().(*ArmClient).graph.ServicePrincipalsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, rs.Primary.ID) diff --git a/azurerm/resource_arm_batch_account.go b/azurerm/resource_arm_batch_account.go index 8eb7e547ca92..45c6e93035ac 100644 --- a/azurerm/resource_arm_batch_account.go +++ b/azurerm/resource_arm_batch_account.go @@ -5,7 +5,11 @@ import ( "log" "regexp" - "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2017-09-01/batch" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" @@ -31,8 +35,12 @@ func resourceArmBatchAccount() *schema.Resource { ForceNew: true, ValidateFunc: validateAzureRMBatchAccountName, }, - "resource_group_name": resourceGroupNameSchema(), - "location": locationSchema(), + + // TODO: make this case sensitive once this API bug has been fixed: + // https://github.com/Azure/azure-rest-api-specs/issues/5574 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "location": azure.SchemaLocation(), "storage_account_id": { Type: schema.TypeString, Optional: true, @@ -48,6 +56,25 @@ func resourceArmBatchAccount() *schema.Resource { string(batch.UserSubscription), }, false), }, + "key_vault_reference": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + "url": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.URLIsHTTPS, + }, + }, + }, + }, "primary_access_key": { Type: schema.TypeString, Sensitive: true, @@ -62,25 +89,25 @@ func resourceArmBatchAccount() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmBatchAccountCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).batchAccountClient + client := meta.(*ArmClient).batch.AccountClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure Batch account creation.") resourceGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) storageAccountId := d.Get("storage_account_id").(string) poolAllocationMode := d.Get("pool_allocation_mode").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -98,7 +125,22 @@ func resourceArmBatchAccountCreate(d *schema.ResourceData, meta interface{}) err AccountCreateProperties: &batch.AccountCreateProperties{ PoolAllocationMode: batch.PoolAllocationMode(poolAllocationMode), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), + } + + // if pool allocation mode is UserSubscription, a key vault reference needs to be set + if poolAllocationMode == string(batch.UserSubscription) { + keyVaultReferenceSet := d.Get("key_vault_reference").([]interface{}) + keyVaultReference, err := azure.ExpandBatchAccountKeyVaultReference(keyVaultReferenceSet) + if err != nil { + return fmt.Errorf("Error creating Batch account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if keyVaultReference == nil { + return fmt.Errorf("Error creating Batch account %q (Resource Group %q): When setting pool allocation mode to UserSubscription, a Key Vault reference needs to be set", name, resourceGroup) + } + + parameters.KeyVaultReference = keyVaultReference } if storageAccountId != "" { @@ -131,10 +173,10 @@ func resourceArmBatchAccountCreate(d *schema.ResourceData, meta interface{}) err } func resourceArmBatchAccountRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).batchAccountClient + client := meta.(*ArmClient).batch.AccountClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -156,7 +198,7 @@ func resourceArmBatchAccountRead(d *schema.ResourceData, meta interface{}) error d.Set("account_endpoint", resp.AccountEndpoint) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.AccountProperties; props != nil { @@ -177,18 +219,16 @@ func resourceArmBatchAccountRead(d *schema.ResourceData, meta interface{}) error d.Set("secondary_access_key", keys.Secondary) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmBatchAccountUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).batchAccountClient + client := meta.(*ArmClient).batch.AccountClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure Batch account update.") - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -196,7 +236,7 @@ func resourceArmBatchAccountUpdate(d *schema.ResourceData, meta interface{}) err resourceGroup := id.ResourceGroup storageAccountId := d.Get("storage_account_id").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := batch.AccountUpdateParameters{ AccountUpdateProperties: &batch.AccountUpdateProperties{ @@ -204,7 +244,7 @@ func resourceArmBatchAccountUpdate(d *schema.ResourceData, meta interface{}) err StorageAccountID: &storageAccountId, }, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err = client.Update(ctx, resourceGroup, name, parameters); err != nil { @@ -226,10 +266,10 @@ func resourceArmBatchAccountUpdate(d *schema.ResourceData, meta interface{}) err } func resourceArmBatchAccountDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).batchAccountClient + client := meta.(*ArmClient).batch.AccountClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_batch_account_test.go b/azurerm/resource_arm_batch_account_test.go index 25e066a8799c..504c782b5ef7 100644 --- a/azurerm/resource_arm_batch_account_test.go +++ b/azurerm/resource_arm_batch_account_test.go @@ -3,12 +3,14 @@ package azurerm import ( "fmt" "net/http" + "os" "testing" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -63,7 +65,7 @@ func TestAccAzureRMBatchAccount_basic(t *testing.T) { } func TestAccAzureRMBatchAccount_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -130,6 +132,32 @@ func TestAccAzureRMBatchAccount_complete(t *testing.T) { }) } +func TestAccAzureRMBatchAccount_userSubscription(t *testing.T) { + resourceName := "azurerm_batch_account.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + + tenantID := os.Getenv("ARM_TENANT_ID") + + config := testAccAzureRMBatchAccount_userSubscription(ri, rs, location, tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchAccountDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "pool_allocation_mode", "UserSubscription"), + ), + }, + }, + }) +} + func testCheckAzureRMBatchAccountExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -143,7 +171,7 @@ func testCheckAzureRMBatchAccountExists(resourceName string) resource.TestCheckF // Ensure resource group exists in API ctx := testAccProvider.Meta().(*ArmClient).StopContext - conn := testAccProvider.Meta().(*ArmClient).batchAccountClient + conn := testAccProvider.Meta().(*ArmClient).batch.AccountClient resp, err := conn.Get(ctx, resourceGroup, batchAccount) if err != nil { @@ -159,7 +187,7 @@ func testCheckAzureRMBatchAccountExists(resourceName string) resource.TestCheckF } func testCheckAzureRMBatchAccountDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).batchAccountClient + conn := testAccProvider.Meta().(*ArmClient).batch.AccountClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -186,7 +214,7 @@ func testCheckAzureRMBatchAccountDestroy(s *terraform.State) error { func testAccAzureRMBatchAccount_basic(rInt int, batchAccountSuffix string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "testaccbatch%d" + name = "testaccRG-%d-batchaccount" location = "%s" } @@ -215,7 +243,7 @@ resource "azurerm_batch_account" "import" { func testAccAzureRMBatchAccount_complete(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "testaccbatch%d" + name = "testaccRG-%d-batchaccount" location = "%s" } @@ -244,7 +272,7 @@ resource "azurerm_batch_account" "test" { func testAccAzureRMBatchAccount_completeUpdated(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "testaccbatch%d" + name = "testaccRG-%d-batchaccount" location = "%s" } @@ -270,3 +298,56 @@ resource "azurerm_batch_account" "test" { } `, rInt, location, rString, rString) } + +func testAccAzureRMBatchAccount_userSubscription(rInt int, batchAccountSuffix string, location string, tenantID string) string { + return fmt.Sprintf(` +data "azuread_service_principal" "test" { + display_name = "Microsoft Azure Batch" +} + +resource "azurerm_resource_group" "test" { + name = "testaccRG-%d-batchaccount" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "batchkv%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + enabled_for_disk_encryption = true + enabled_for_deployment = true + enabled_for_template_deployment = true + tenant_id = "%s" + + sku { + name = "standard" + } + + access_policy { + tenant_id = "%s" + object_id = "${data.azuread_service_principal.test.object_id}" + + secret_permissions = [ + "get", + "list", + "set", + "delete" + ] + + } +} + +resource "azurerm_batch_account" "test" { + name = "testaccbatch%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + pool_allocation_mode = "UserSubscription" + + key_vault_reference { + id = "${azurerm_key_vault.test.id}" + url = "${azurerm_key_vault.test.vault_uri}" + } +} +`, rInt, location, batchAccountSuffix, tenantID, tenantID, batchAccountSuffix) +} diff --git a/azurerm/resource_arm_batch_application.go b/azurerm/resource_arm_batch_application.go new file mode 100644 index 000000000000..74bce9103076 --- /dev/null +++ b/azurerm/resource_arm_batch_application.go @@ -0,0 +1,240 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmBatchApplication() *schema.Resource { + return &schema.Resource{ + Create: resourceArmBatchApplicationCreate, + Read: resourceArmBatchApplicationRead, + Update: resourceArmBatchApplicationUpdate, + Delete: resourceArmBatchApplicationDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMBatchApplicationName, + }, + + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMBatchAccountName, + }, + + "allow_updates": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "default_version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAzureRMBatchApplicationVersion, + }, + + "display_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAzureRMBatchApplicationDisplayName, + }, + }, + } +} + +func resourceArmBatchApplicationCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batch.ApplicationClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + accountName := d.Get("account_name").(string) + + if features.ShouldResourcesBeImported() { + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Error checking for present of existing Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + } + if !utils.ResponseWasNotFound(resp.Response) { + return tf.ImportAsExistsError("azurerm_batch_application", *resp.ID) + } + } + + allowUpdates := d.Get("allow_updates").(bool) + defaultVersion := d.Get("default_version").(string) + displayName := d.Get("display_name").(string) + + parameters := batch.Application{ + ApplicationProperties: &batch.ApplicationProperties{ + AllowUpdates: utils.Bool(allowUpdates), + DefaultVersion: utils.String(defaultVersion), + DisplayName: utils.String(displayName), + }, + } + + if _, err := client.Create(ctx, resourceGroup, accountName, name, ¶meters); err != nil { + return fmt.Errorf("Error creating Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + return fmt.Errorf("Error retrieving Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read Batch Application %q (Account Name %q / Resource Group %q) ID", name, accountName, resourceGroup) + } + d.SetId(*resp.ID) + + return resourceArmBatchApplicationRead(d, meta) +} + +func resourceArmBatchApplicationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batch.ApplicationClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + accountName := id.Path["batchAccounts"] + name := id.Path["applications"] + + resp, err := client.Get(ctx, resourceGroup, accountName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Batch Application %q does not exist - removing from state", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + d.Set("account_name", accountName) + if applicationProperties := resp.ApplicationProperties; applicationProperties != nil { + d.Set("allow_updates", applicationProperties.AllowUpdates) + d.Set("default_version", applicationProperties.DefaultVersion) + d.Set("display_name", applicationProperties.DisplayName) + } + + return nil +} + +func resourceArmBatchApplicationUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batch.ApplicationClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + accountName := d.Get("account_name").(string) + allowUpdates := d.Get("allow_updates").(bool) + defaultVersion := d.Get("default_version").(string) + displayName := d.Get("display_name").(string) + + parameters := batch.Application{ + ApplicationProperties: &batch.ApplicationProperties{ + AllowUpdates: utils.Bool(allowUpdates), + DefaultVersion: utils.String(defaultVersion), + DisplayName: utils.String(displayName), + }, + } + + if _, err := client.Update(ctx, resourceGroup, accountName, name, parameters); err != nil { + return fmt.Errorf("Error updating Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + + return resourceArmBatchApplicationRead(d, meta) +} + +func resourceArmBatchApplicationDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batch.ApplicationClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + accountName := id.Path["batchAccounts"] + name := id.Path["applications"] + + if _, err := client.Delete(ctx, resourceGroup, accountName, name); err != nil { + return fmt.Errorf("Error deleting Batch Application %q (Account Name %q / Resource Group %q): %+v", name, accountName, resourceGroup, err) + } + + return nil +} + +func validateAzureRMBatchApplicationName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if !regexp.MustCompile(`^[-_\da-zA-Z]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf("%q can contain any combination of alphanumeric characters, hyphens, and underscores: %q", k, value)) + } + + if 1 > len(value) { + errors = append(errors, fmt.Errorf("%q cannot be less than 1 character: %q", k, value)) + } + + if len(value) > 64 { + errors = append(errors, fmt.Errorf("%q cannot be longer than 64 characters: %q %d", k, value, len(value))) + } + + return warnings, errors +} + +func validateAzureRMBatchApplicationVersion(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if !regexp.MustCompile(`^[-._\da-zA-Z]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf("%q can contain any combination of alphanumeric characters, hyphens, underscores, and periods: %q", k, value)) + } + + if 1 > len(value) { + errors = append(errors, fmt.Errorf("%q cannot be less than 1 character: %q", k, value)) + } + + if len(value) > 64 { + errors = append(errors, fmt.Errorf("%q cannot be longer than 64 characters: %q %d", k, value, len(value))) + } + + return warnings, errors +} + +func validateAzureRMBatchApplicationDisplayName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if 1 > len(value) { + errors = append(errors, fmt.Errorf("%q cannot be less than 1 character: %q", k, value)) + } + + if len(value) > 1024 { + errors = append(errors, fmt.Errorf("%q cannot be longer than 1024 characters: %q %d", k, value, len(value))) + } + + return warnings, errors +} diff --git a/azurerm/resource_arm_batch_application_test.go b/azurerm/resource_arm_batch_application_test.go new file mode 100644 index 000000000000..8c2fb855e45b --- /dev/null +++ b/azurerm/resource_arm_batch_application_test.go @@ -0,0 +1,150 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMBatchApplication_basic(t *testing.T) { + resourceName := "azurerm_batch_application.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchApplicationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMBatchApplication_template(ri, rs, location, ""), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchApplicationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMBatchApplication_update(t *testing.T) { + resourceName := "azurerm_batch_application.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + displayName := fmt.Sprintf("TestAccDisplayName-%d", ri) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchApplicationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMBatchApplication_template(ri, rs, location, ""), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchApplicationExists(resourceName), + ), + }, + { + Config: testAccAzureRMBatchApplication_template(ri, rs, location, fmt.Sprintf(`display_name = "%s"`, displayName)), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchApplicationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "display_name", displayName), + ), + }, + }, + }) +} + +func testCheckAzureRMBatchApplicationExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Batch Application not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + accountName := rs.Primary.Attributes["account_name"] + + client := testAccProvider.Meta().(*ArmClient).batch.ApplicationClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + if resp, err := client.Get(ctx, resourceGroup, accountName, name); err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Batch Application %q (Account Name %q / Resource Group %q) does not exist", name, accountName, resourceGroup) + } + return fmt.Errorf("Bad: Get on batchApplicationClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMBatchApplicationDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).batch.ApplicationClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_batch_application" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + accountName := rs.Primary.Attributes["account_name"] + + if resp, err := client.Get(ctx, resourceGroup, accountName, name); err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Get on batchApplicationClient: %+v", err) + } + } + + return nil + } + + return nil +} + +func testAccAzureRMBatchApplication_template(rInt int, rString string, location string, displayName string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_batch_account" "test" { + name = "acctestba%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + pool_allocation_mode = "BatchService" + storage_account_id = "${azurerm_storage_account.test.id}" +} + +resource "azurerm_batch_application" "test" { + name = "acctestbatchapp-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + %s +} +`, rInt, location, rString, rString, rInt, displayName) +} diff --git a/azurerm/resource_arm_batch_certificate.go b/azurerm/resource_arm_batch_certificate.go new file mode 100644 index 000000000000..506b9fc4e479 --- /dev/null +++ b/azurerm/resource_arm_batch_certificate.go @@ -0,0 +1,273 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmBatchCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceArmBatchCertificateCreate, + Read: resourceArmBatchCertificateRead, + Update: resourceArmBatchCertificateUpdate, + Delete: resourceArmBatchCertificateDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMBatchAccountName, + }, + + // TODO: make this case sensitive once this API bug has been fixed: + // https://github.com/Azure/azure-rest-api-specs/issues/5574 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "certificate": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validation.StringLenBetween(1, 10000), + }, + + "format": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(batch.Cer), + string(batch.Pfx), + }, false), + }, + + "password": { + Type: schema.TypeString, + Optional: true, // Required if `format` is "Pfx" + Sensitive: true, + }, + + "thumbprint": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: suppress.CaseDifference, + }, + + "thumbprint_algorithm": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"SHA1"}, false), + DiffSuppressFunc: suppress.CaseDifference, + }, + + "public_data": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmBatchCertificateCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batch.CertificateClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Azure Batch certificate creation.") + + resourceGroupName := d.Get("resource_group_name").(string) + accountName := d.Get("account_name").(string) + certificate := d.Get("certificate").(string) + format := d.Get("format").(string) + password := d.Get("password").(string) + thumbprint := d.Get("thumbprint").(string) + thumbprintAlgorithm := d.Get("thumbprint_algorithm").(string) + name := thumbprintAlgorithm + "-" + thumbprint + + if err := validateBatchCertificateFormatAndPassword(format, password); err != nil { + return err + } + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroupName, accountName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Batch Certificate %q (Account %q / Resource Group %q): %s", name, accountName, resourceGroupName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_batch_certificate", *existing.ID) + } + } + certificateProperties := batch.CertificateCreateOrUpdateProperties{ + Data: &certificate, + Format: batch.CertificateFormat(format), + Thumbprint: &thumbprint, + ThumbprintAlgorithm: &thumbprintAlgorithm, + } + if password != "" { + certificateProperties.Password = &password + } + parameters := batch.CertificateCreateOrUpdateParameters{ + Name: &name, + CertificateCreateOrUpdateProperties: &certificateProperties, + } + + future, err := client.Create(ctx, resourceGroupName, accountName, name, parameters, "", "") + if err != nil { + return fmt.Errorf("Error creating Batch certificate %q (Account %q / Resource Group %q): %+v", name, accountName, resourceGroupName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of Batch certificate %q (Account %q / Resource Group %q): %+v", name, accountName, resourceGroupName, err) + } + + read, err := client.Get(ctx, resourceGroupName, accountName, name) + if err != nil { + return fmt.Errorf("Error retrieving Batch certificate %q (Account %q / Resource Group %q): %+v", name, accountName, resourceGroupName, err) + } + d.SetId(*read.ID) + return resourceArmBatchCertificateRead(d, meta) +} + +func resourceArmBatchCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batch.CertificateClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + accountName := id.Path["batchAccounts"] + name := id.Path["certificates"] + resourceGroupName := id.ResourceGroup + + resp, err := client.Get(ctx, resourceGroupName, accountName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + log.Printf("[DEBUG] Batch certificate %q was not found in Account %q / Resource Group %q - removing from state!", name, accountName, resourceGroupName) + return nil + } + return fmt.Errorf("Error retrieving Batch Certificate %q (Account %q / Resource Group %q): %+v", name, accountName, resourceGroupName, err) + } + + d.Set("name", resp.Name) + d.Set("account_name", accountName) + d.Set("resource_group_name", resourceGroupName) + + if props := resp.CertificateProperties; props != nil { + d.Set("format", props.Format) + d.Set("public_data", props.PublicData) + d.Set("thumbprint", props.Thumbprint) + d.Set("thumbprint_algorithm", props.ThumbprintAlgorithm) + } + + return nil +} + +func resourceArmBatchCertificateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batch.CertificateClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Azure Batch certificate update.") + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + accountName := id.Path["batchAccounts"] + name := id.Path["certificates"] + resourceGroupName := id.ResourceGroup + + certificate := d.Get("certificate").(string) + format := d.Get("format").(string) + password := d.Get("password").(string) + thumbprint := d.Get("thumbprint").(string) + thumbprintAlgorithm := d.Get("thumbprint_algorithm").(string) + + if err := validateBatchCertificateFormatAndPassword(format, password); err != nil { + return err + } + + parameters := batch.CertificateCreateOrUpdateParameters{ + Name: &name, + CertificateCreateOrUpdateProperties: &batch.CertificateCreateOrUpdateProperties{ + Data: &certificate, + Format: batch.CertificateFormat(format), + Password: &password, + Thumbprint: &thumbprint, + ThumbprintAlgorithm: &thumbprintAlgorithm, + }, + } + + if _, err = client.Update(ctx, resourceGroupName, accountName, name, parameters, ""); err != nil { + return fmt.Errorf("Error updating Batch certificate %q (Account %q / Resource Group %q): %+v", name, accountName, resourceGroupName, err) + } + + read, err := client.Get(ctx, resourceGroupName, accountName, name) + if err != nil { + return fmt.Errorf("Error retrieving Batch Certificate %q (Account %q / Resource Group %q): %+v", name, accountName, resourceGroupName, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read ID for Batch certificate %q (Account: %q, Resource Group %q) ID", name, accountName, resourceGroupName) + } + + return resourceArmBatchCertificateRead(d, meta) +} + +func resourceArmBatchCertificateDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).batch.CertificateClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + accountName := id.Path["batchAccounts"] + name := id.Path["certificates"] + resourceGroupName := id.ResourceGroup + + future, err := client.Delete(ctx, resourceGroupName, accountName, name) + if err != nil { + return fmt.Errorf("Error deleting Batch Certificate %q (Account %q / Resource Group %q): %+v", name, accountName, resourceGroupName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error waiting for deletion of Batch Certificate %q (Account %q / Resource Group %q): %+v", name, accountName, resourceGroupName, err) + } + } + + return nil +} + +func validateBatchCertificateFormatAndPassword(format string, password string) error { + if format == "Pfx" && password == "" { + return fmt.Errorf("Batch Certificate Password is required when Format is `Pfx`") + } + if format == "Cer" && password != "" { + return fmt.Errorf(" Batch Certificate Password must not be specified when Format is `Cer`") + } + return nil +} diff --git a/azurerm/resource_arm_batch_certificate_test.go b/azurerm/resource_arm_batch_certificate_test.go new file mode 100644 index 000000000000..daa42d594d40 --- /dev/null +++ b/azurerm/resource_arm_batch_certificate_test.go @@ -0,0 +1,251 @@ +package azurerm + +import ( + "fmt" + "os" + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMBatchCertificate_Pfx(t *testing.T) { + resourceName := "azurerm_batch_certificate.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + + subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") + certificateID := fmt.Sprintf("/subscriptions/%s/resourceGroups/testaccbatch%d/providers/Microsoft.Batch/batchAccounts/testaccbatch%s/certificates/sha1-42c107874fd0e4a9583292a2f1098e8fe4b2edda", subscriptionID, ri, rs) + + config := testAccAzureRMBatchCertificatePfx(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "id", certificateID), + resource.TestCheckResourceAttr(resourceName, "format", "Pfx"), + resource.TestCheckResourceAttr(resourceName, "thumbprint", "42c107874fd0e4a9583292a2f1098e8fe4b2edda"), + resource.TestCheckResourceAttr(resourceName, "thumbprint_algorithm", "sha1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"certificate", "password"}, + }, + }, + }) +} + +func TestAccAzureRMBatchCertificate_PfxWithoutPassword(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + + config := testAccAzureRMBatchCertificatePfxWithoutPassword(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ExpectError: regexp.MustCompile("Password is required"), + }, + }, + }) +} + +func TestAccAzureRMBatchCertificate_Cer(t *testing.T) { + resourceName := "azurerm_batch_certificate.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + + subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") + certificateID := fmt.Sprintf("/subscriptions/%s/resourceGroups/testaccbatch%d/providers/Microsoft.Batch/batchAccounts/testaccbatch%s/certificates/sha1-312d31a79fa0cef49c00f769afc2b73e9f4edf34", subscriptionID, ri, rs) + + config := testAccAzureRMBatchCertificateCer(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + + resource.TestCheckResourceAttr(resourceName, "id", certificateID), + resource.TestCheckResourceAttr(resourceName, "format", "Cer"), + resource.TestCheckResourceAttr(resourceName, "thumbprint", "312d31a79fa0cef49c00f769afc2b73e9f4edf34"), + resource.TestCheckResourceAttr(resourceName, "thumbprint_algorithm", "sha1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"certificate"}, + }, + }, + }) +} + +func TestAccAzureRMBatchCertificate_CerWithPassword(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + + config := testAccAzureRMBatchCertificateCerWithPassword(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ExpectError: regexp.MustCompile("Password must not be specified"), + }, + }, + }) +} + +func testAccAzureRMBatchCertificatePfx(rInt int, batchAccountSuffix string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "testaccbatch%d" + location = "%s" +} + +resource "azurerm_batch_account" "test" { + name = "testaccbatch%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + pool_allocation_mode = "BatchService" +} + +resource "azurerm_batch_certificate" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + certificate = "${filebase64("testdata/batch_certificate.pfx")}" + format = "Pfx" + password = "terraform" + thumbprint = "42c107874fd0e4a9583292a2f1098e8fe4b2edda" + thumbprint_algorithm = "SHA1" +} +`, rInt, location, batchAccountSuffix) +} + +func testAccAzureRMBatchCertificatePfxWithoutPassword(rInt int, batchAccountSuffix string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "testaccbatch%d" + location = "%s" +} + +resource "azurerm_batch_account" "test" { + name = "testaccbatch%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + pool_allocation_mode = "BatchService" +} + +resource "azurerm_batch_certificate" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + certificate = "${filebase64("testdata/batch_certificate.pfx")}" + format = "Pfx" + thumbprint = "42c107874fd0e4a9583292a2f1098e8fe4b2edda" + thumbprint_algorithm = "SHA1" +} +`, rInt, location, batchAccountSuffix) +} +func testAccAzureRMBatchCertificateCer(rInt int, batchAccountSuffix string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "testaccbatch%d" + location = "%s" +} + +resource "azurerm_batch_account" "test" { + name = "testaccbatch%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + pool_allocation_mode = "BatchService" +} + +resource "azurerm_batch_certificate" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + certificate = "${filebase64("testdata/batch_certificate.cer")}" + format = "Cer" + thumbprint = "312d31a79fa0cef49c00f769afc2b73e9f4edf34" + thumbprint_algorithm = "SHA1" +} +`, rInt, location, batchAccountSuffix) +} +func testAccAzureRMBatchCertificateCerWithPassword(rInt int, batchAccountSuffix string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "testaccbatch%d" + location = "%s" +} + +resource "azurerm_batch_account" "test" { + name = "testaccbatch%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + pool_allocation_mode = "BatchService" +} + +resource "azurerm_batch_certificate" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + certificate = "${filebase64("testdata/batch_certificate.cer")}" + format = "Cer" + password = "should not have a password for Cer" + thumbprint = "312d31a79fa0cef49c00f769afc2b73e9f4edf34" + thumbprint_algorithm = "SHA1" +} +`, rInt, location, batchAccountSuffix) +} + +func testCheckAzureRMBatchCertificateDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).batch.CertificateClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_batch_certificate" { + continue + } + + name := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, accountName, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + + return nil +} diff --git a/azurerm/resource_arm_batch_pool.go b/azurerm/resource_arm_batch_pool.go index 5834c1f28c87..5507de20dccd 100644 --- a/azurerm/resource_arm_batch_pool.go +++ b/azurerm/resource_arm_batch_pool.go @@ -8,16 +8,18 @@ import ( "strings" "time" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" - - "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2017-09-01/batch" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + + "github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch" ) func resourceArmBatchPool() *schema.Resource { @@ -37,7 +39,11 @@ func resourceArmBatchPool() *schema.Resource { ForceNew: true, ValidateFunc: azure.ValidateAzureRMBatchPoolName, }, - "resource_group_name": resourceGroupNameSchema(), + + // TODO: make this case sensitive once this API bug has been fixed: + // https://github.com/Azure/azure-rest-api-specs/issues/5574 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + "account_name": { Type: schema.TypeString, Required: true, @@ -109,6 +115,50 @@ func resourceArmBatchPool() *schema.Resource { }, }, }, + "container_configuration": { + Type: schema.TypeList, + Optional: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "container_registries": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + ConfigMode: schema.SchemaConfigModeAttr, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "registry_server": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "user_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "password": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + }, + }, "storage_image_reference": { Type: schema.TypeList, Required: true, @@ -119,26 +169,27 @@ func resourceArmBatchPool() *schema.Resource { "id": { Type: schema.TypeString, Optional: true, + ForceNew: true, ValidateFunc: azure.ValidateResourceID, }, "publisher": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, ValidateFunc: validate.NoEmptyStrings, }, "offer": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, ValidateFunc: validate.NoEmptyStrings, }, "sku": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validate.NoEmptyStrings, @@ -146,7 +197,7 @@ func resourceArmBatchPool() *schema.Resource { "version": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, ValidateFunc: validate.NoEmptyStrings, }, @@ -163,6 +214,49 @@ func resourceArmBatchPool() *schema.Resource { Optional: true, Default: false, }, + "certificate": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + // The ID returned for the certificate in the batch account and the certificate applied to the pool + // are not consistent in their casing which causes issues when referencing IDs across resources + // (as Terraform still sees differences to apply due to the casing) + // Handling by ignoring casing for now. Raised as an issue: https://github.com/Azure/azure-rest-api-specs/issues/5574 + DiffSuppressFunc: suppress.CaseDifference, + }, + "store_location": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "CurrentUser", + "LocalMachine", + }, false), + }, + "store_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "visibility": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + "StartTask", + "Task", + "RemoteUser", + }, false), + }, + }, + }, + }, + }, "start_task": { Type: schema.TypeList, Optional: true, @@ -232,6 +326,39 @@ func resourceArmBatchPool() *schema.Resource { }, }, }, + + "resource_file": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "auto_storage_container_name": { + Type: schema.TypeString, + Optional: true, + }, + "blob_prefix": { + Type: schema.TypeString, + Optional: true, + }, + "file_mode": { + Type: schema.TypeString, + Optional: true, + }, + "file_path": { + Type: schema.TypeString, + Optional: true, + }, + "http_url": { + Type: schema.TypeString, + Optional: true, + }, + "storage_container_url": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, }, }, }, @@ -240,7 +367,7 @@ func resourceArmBatchPool() *schema.Resource { } func resourceArmBatchPoolCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).batchPoolClient + client := meta.(*ArmClient).batch.PoolClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure Batch pool creation.") @@ -252,7 +379,7 @@ func resourceArmBatchPoolCreate(d *schema.ResourceData, meta interface{}) error vmSize := d.Get("vm_size").(string) maxTasksPerNode := int32(d.Get("max_tasks_per_node").(int)) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, accountName, poolName) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -288,6 +415,17 @@ func resourceArmBatchPoolCreate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): %+v", poolName, resourceGroup, err) } + if imageReference != nil { + // if an image reference ID is specified, the user wants use a custom image. This property is mutually exclusive with other properties. + if imageReference.ID != nil && (imageReference.Offer != nil || imageReference.Publisher != nil || imageReference.Sku != nil || imageReference.Version != nil) { + return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): Properties version, offer, publish cannot be defined when using a custom image id", poolName, resourceGroup) + } else if imageReference.ID == nil && (imageReference.Offer == nil || imageReference.Publisher == nil || imageReference.Sku == nil || imageReference.Version == nil) { + return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): Properties version, offer, publish and sku are mandatory when not using a custom image", poolName, resourceGroup) + } + } else { + return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): image reference property can not be empty", poolName, resourceGroup) + } + if startTaskValue, startTaskOk := d.GetOk("start_task"); startTaskOk { startTaskList := startTaskValue.([]interface{}) startTask, startTaskErr := azure.ExpandBatchPoolStartTask(startTaskList) @@ -305,13 +443,31 @@ func resourceArmBatchPoolCreate(d *schema.ResourceData, meta interface{}) error parameters.PoolProperties.StartTask = startTask } + containerConfigurationSet := d.Get("container_configuration").([]interface{}) + containerConfiguration, err := azure.ExpandBatchPoolContainerConfiguration(containerConfigurationSet) + if err != nil { + return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): %+v", poolName, resourceGroup, err) + } + parameters.PoolProperties.DeploymentConfiguration = &batch.DeploymentConfiguration{ VirtualMachineConfiguration: &batch.VirtualMachineConfiguration{ - NodeAgentSkuID: &nodeAgentSkuID, - ImageReference: imageReference, + NodeAgentSkuID: &nodeAgentSkuID, + ImageReference: imageReference, + ContainerConfiguration: containerConfiguration, }, } + certificates := d.Get("certificate").([]interface{}) + certificateReferences, err := azure.ExpandBatchPoolCertificateReferences(certificates) + if err != nil { + return fmt.Errorf("Error expanding `certificate`: %+v", err) + } + parameters.PoolProperties.Certificates = certificateReferences + + if err := validateBatchPoolCrossFieldRules(¶meters); err != nil { + return err + } + future, err := client.Create(ctx, resourceGroup, accountName, poolName, parameters, "", "") if err != nil { return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): %+v", poolName, resourceGroup, err) @@ -344,9 +500,9 @@ func resourceArmBatchPoolCreate(d *schema.ResourceData, meta interface{}) error func resourceArmBatchPoolUpdate(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).batchPoolClient + client := meta.(*ArmClient).batch.PoolClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -404,6 +560,16 @@ func resourceArmBatchPoolUpdate(d *schema.ResourceData, meta interface{}) error parameters.PoolProperties.StartTask = startTask } + certificates := d.Get("certificate").([]interface{}) + certificateReferences, err := azure.ExpandBatchPoolCertificateReferences(certificates) + if err != nil { + return fmt.Errorf("Error expanding `certificate`: %+v", err) + } + parameters.PoolProperties.Certificates = certificateReferences + + if err := validateBatchPoolCrossFieldRules(¶meters); err != nil { + return err + } result, err := client.Update(ctx, resourceGroup, accountName, poolName, parameters, "") if err != nil { @@ -422,9 +588,9 @@ func resourceArmBatchPoolUpdate(d *schema.ResourceData, meta interface{}) error func resourceArmBatchPoolRead(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).batchPoolClient + client := meta.(*ArmClient).batch.PoolClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -466,6 +632,16 @@ func resourceArmBatchPoolRead(d *schema.ResourceData, meta interface{}) error { d.Set("node_agent_sku_id", props.DeploymentConfiguration.VirtualMachineConfiguration.NodeAgentSkuID) } + if dcfg := props.DeploymentConfiguration; dcfg != nil { + if vmcfg := dcfg.VirtualMachineConfiguration; vmcfg != nil { + d.Set("container_configuration", azure.FlattenBatchPoolContainerConfiguration(d, vmcfg.ContainerConfiguration)) + } + } + + if err := d.Set("certificate", azure.FlattenBatchPoolCertificateReferences(props.Certificates)); err != nil { + return fmt.Errorf("Error flattening `certificate`: %+v", err) + } + d.Set("start_task", azure.FlattenBatchPoolStartTask(props.StartTask)) } @@ -474,9 +650,9 @@ func resourceArmBatchPoolRead(d *schema.ResourceData, meta interface{}) error { func resourceArmBatchPoolDelete(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).batchPoolClient + client := meta.(*ArmClient).batch.PoolClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -548,7 +724,7 @@ func expandBatchPoolScaleSettings(d *schema.ResourceData) (*batch.ScaleSettings, return scaleSettings, nil } -func waitForBatchPoolPendingResizeOperation(ctx context.Context, client batch.PoolClient, resourceGroup string, accountName string, poolName string) error { +func waitForBatchPoolPendingResizeOperation(ctx context.Context, client *batch.PoolClient, resourceGroup string, accountName string, poolName string) error { // waiting for the pool to be in steady state log.Printf("[INFO] waiting for the pending resize operation on this pool to be stopped...") isSteady := false @@ -583,3 +759,43 @@ func validateUserIdentity(userIdentity *batch.UserIdentity) error { return nil } + +func validateBatchPoolCrossFieldRules(pool *batch.Pool) error { + // Perform validation across multiple fields as per https://docs.microsoft.com/en-us/rest/api/batchmanagement/pool/create#resourcefile + + if pool.StartTask != nil { + startTask := *pool.StartTask + if startTask.ResourceFiles != nil { + for _, referenceFile := range *startTask.ResourceFiles { + // Must specify exactly one of AutoStorageContainerName, StorageContainerUrl or HttpUrl + sourceCount := 0 + if referenceFile.AutoStorageContainerName != nil { + sourceCount++ + } + if referenceFile.StorageContainerURL != nil { + sourceCount++ + } + if referenceFile.HTTPURL != nil { + sourceCount++ + } + if sourceCount != 1 { + return fmt.Errorf("Exactly one of auto_storage_container_name, storage_container_url and http_url must be specified") + } + + if referenceFile.BlobPrefix != nil { + if referenceFile.AutoStorageContainerName == nil && referenceFile.StorageContainerURL == nil { + return fmt.Errorf("auto_storage_container_name or storage_container_url must be specified when using blob_prefix") + } + } + + if referenceFile.HTTPURL != nil { + if referenceFile.FilePath == nil { + return fmt.Errorf("file_path must be specified when using http_url") + } + } + } + } + } + + return nil +} diff --git a/azurerm/resource_arm_batch_pool_test.go b/azurerm/resource_arm_batch_pool_test.go index 640a6ec39db5..9a41ca3ebed9 100644 --- a/azurerm/resource_arm_batch_pool_test.go +++ b/azurerm/resource_arm_batch_pool_test.go @@ -3,9 +3,12 @@ package azurerm import ( "fmt" "net/http" + "os" + "regexp" "testing" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" @@ -44,7 +47,7 @@ func TestAccAzureRMBatchPool_basic(t *testing.T) { } func TestAccAzureRMBatchPool_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -238,6 +241,168 @@ func TestAccAzureRMBatchPoolStartTask_basic(t *testing.T) { }) } +func TestAccAzureRMBatchPool_certificates(t *testing.T) { + resourceName := "azurerm_batch_pool.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") + certificate0ID := fmt.Sprintf("/subscriptions/%s/resourceGroups/testaccbatch%d/providers/Microsoft.Batch/batchAccounts/testaccbatch%s/certificates/sha1-312d31a79fa0cef49c00f769afc2b73e9f4edf34", subscriptionID, ri, rs) + certificate1ID := fmt.Sprintf("/subscriptions/%s/resourceGroups/testaccbatch%d/providers/Microsoft.Batch/batchAccounts/testaccbatch%s/certificates/sha1-42c107874fd0e4a9583292a2f1098e8fe4b2edda", subscriptionID, ri, rs) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testaccAzureRMBatchPoolCertificates(ri, rs, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchPoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "vm_size", "STANDARD_A1"), + resource.TestCheckResourceAttr(resourceName, "node_agent_sku_id", "batch.node.ubuntu 16.04"), + resource.TestCheckResourceAttr(resourceName, "account_name", fmt.Sprintf("testaccbatch%s", rs)), + resource.TestCheckResourceAttr(resourceName, "certificate.#", "2"), + resource.TestCheckResourceAttr(resourceName, "certificate.0.id", certificate0ID), + resource.TestCheckResourceAttr(resourceName, "certificate.0.store_location", "CurrentUser"), + resource.TestCheckResourceAttr(resourceName, "certificate.0.store_name", ""), + resource.TestCheckResourceAttr(resourceName, "certificate.0.visibility.#", "1"), + resource.TestCheckResourceAttr(resourceName, "certificate.0.visibility.3294600504", "StartTask"), + resource.TestCheckResourceAttr(resourceName, "certificate.1.id", certificate1ID), + resource.TestCheckResourceAttr(resourceName, "certificate.1.store_location", "CurrentUser"), + resource.TestCheckResourceAttr(resourceName, "certificate.1.store_name", ""), + resource.TestCheckResourceAttr(resourceName, "certificate.1.visibility.#", "2"), + resource.TestCheckResourceAttr(resourceName, "certificate.1.visibility.3294600504", "StartTask"), + resource.TestCheckResourceAttr(resourceName, "certificate.1.visibility.4077195354", "RemoteUser"), + ), + }, + }, + }) +} + +func TestAccAzureRMBatchPool_validateResourceFileWithoutSource(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testaccAzureRMBatchPoolValidateResourceFileWithoutSource(ri, rs, testLocation()), + ExpectError: regexp.MustCompile("Exactly one of auto_storage_container_name, storage_container_url and http_url must be specified"), + }, + }, + }) +} + +func TestAccAzureRMBatchPool_container(t *testing.T) { + resourceName := "azurerm_batch_pool.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testaccAzureRMBatchPoolContainerConfiguration(ri, rs, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchPoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "container_configuration.0.type", "DockerCompatible"), + resource.TestCheckResourceAttr(resourceName, "container_configuration.0.container_registries.#", "1"), + resource.TestCheckResourceAttr(resourceName, "container_configuration.0.container_registries.0.registry_server", "myContainerRegistry.azurecr.io"), + resource.TestCheckResourceAttr(resourceName, "container_configuration.0.container_registries.0.user_name", "myUserName"), + resource.TestCheckResourceAttr(resourceName, "container_configuration.0.container_registries.0.password", "myPassword"), + ), + }, + }, + }) +} + +func TestAccAzureRMBatchPool_validateResourceFileWithMultipleSources(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testaccAzureRMBatchPoolValidateResourceFileWithMultipleSources(ri, rs, testLocation()), + ExpectError: regexp.MustCompile("Exactly one of auto_storage_container_name, storage_container_url and http_url must be specified"), + }, + }, + }) +} + +func TestAccAzureRMBatchPool_validateResourceFileBlobPrefixWithoutAutoStorageContainerUrl(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testaccAzureRMBatchPoolValidateResourceFileBlobPrefixWithoutAutoStorageContainerName(ri, rs, testLocation()), + ExpectError: regexp.MustCompile("auto_storage_container_name or storage_container_url must be specified when using blob_prefix"), + }, + }, + }) +} + +func TestAccAzureRMBatchPool_validateResourceFileHttpURLWithoutFilePath(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testaccAzureRMBatchPoolValidateResourceFileHttpURLWithoutFilePath(ri, rs, testLocation()), + ExpectError: regexp.MustCompile("file_path must be specified when using http_url"), + }, + }, + }) +} + +func TestAccAzureRMBatchPool_customImage(t *testing.T) { + resourceName := "azurerm_batch_pool.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMBatchPoolDestroy, + Steps: []resource.TestStep{ + { + Config: testaccAzureRMBatchPoolCustomImageConfiguration(ri, rs, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMBatchPoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "vm_size", "STANDARD_A1"), + resource.TestCheckResourceAttr(resourceName, "max_tasks_per_node", "2"), + resource.TestCheckResourceAttr(resourceName, "node_agent_sku_id", "batch.node.ubuntu 16.04"), + resource.TestCheckResourceAttr(resourceName, "account_name", fmt.Sprintf("testaccbatch%s", rs)), + resource.TestCheckResourceAttr(resourceName, "auto_scale.#", "0"), + resource.TestCheckResourceAttr(resourceName, "fixed_scale.#", "1"), + resource.TestCheckResourceAttr(resourceName, "fixed_scale.0.target_dedicated_nodes", "2"), + resource.TestCheckResourceAttr(resourceName, "fixed_scale.0.resize_timeout", "PT15M"), + resource.TestCheckResourceAttr(resourceName, "fixed_scale.0.target_low_priority_nodes", "0"), + resource.TestCheckResourceAttr(resourceName, "start_task.#", "0"), + ), + }, + }, + }) +} + func testCheckAzureRMBatchPoolExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -251,7 +416,7 @@ func testCheckAzureRMBatchPoolExists(name string) resource.TestCheckFunc { accountName := rs.Primary.Attributes["account_name"] ctx := testAccProvider.Meta().(*ArmClient).StopContext - conn := testAccProvider.Meta().(*ArmClient).batchPoolClient + conn := testAccProvider.Meta().(*ArmClient).batch.PoolClient resp, err := conn.Get(ctx, resourceGroup, accountName, poolName) if err != nil { @@ -277,7 +442,7 @@ func testCheckAzureRMBatchPoolDestroy(s *terraform.State) error { accountName := rs.Primary.Attributes["account_name"] ctx := testAccProvider.Meta().(*ArmClient).StopContext - conn := testAccProvider.Meta().(*ArmClient).batchPoolClient + conn := testAccProvider.Meta().(*ArmClient).batch.PoolClient resp, err := conn.Get(ctx, resourceGroup, accountName, poolName) if err != nil { @@ -295,7 +460,7 @@ func testCheckAzureRMBatchPoolDestroy(s *terraform.State) error { func testaccAzureRMBatchPool_fixedScale_complete(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "testaccbatch%d" + name = "testaccRG-%d-batchpool" location = "%s" } @@ -327,11 +492,11 @@ resource "azurerm_batch_pool" "test" { vm_size = "Standard_A1" max_tasks_per_node = 2 node_agent_sku_id = "batch.node.ubuntu 16.04" - + fixed_scale { target_dedicated_nodes = 2 } - + storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" @@ -345,7 +510,7 @@ resource "azurerm_batch_pool" "test" { func testaccAzureRMBatchPool_autoScale_complete(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "testaccbatch%d" + name = "testaccRG-%d-batchpool" location = "%s" } @@ -380,7 +545,8 @@ resource "azurerm_batch_pool" "test" { auto_scale { evaluation_interval = "PT15M" - formula = < 0 { + probe.InitialDelaySeconds = utils.Int32(int32(v)) + } + + if v := probeConfig["period_seconds"].(int); v > 0 { + probe.PeriodSeconds = utils.Int32(int32(v)) + } + + if v := probeConfig["failure_threshold"].(int); v > 0 { + probe.FailureThreshold = utils.Int32(int32(v)) + } + + if v := probeConfig["success_threshold"].(int); v > 0 { + probe.SuccessThreshold = utils.Int32(int32(v)) + } + + if v := probeConfig["timeout_seconds"].(int); v > 0 { + probe.TimeoutSeconds = utils.Int32(int32(v)) + } + + commands := probeConfig["exec"].([]interface{}) + if len(commands) > 0 { + exec := containerinstance.ContainerExec{ + Command: utils.ExpandStringSlice(commands), + } + probe.Exec = &exec + } + + httpRaw := probeConfig["http_get"].([]interface{}) + if len(httpRaw) > 0 { + + for _, httpget := range httpRaw { + x := httpget.(map[string]interface{}) + + path := x["path"].(string) + port := x["port"].(int) + scheme := x["scheme"].(string) + + probe.HTTPGet = &containerinstance.ContainerHTTPGet{ + Path: utils.String(path), + Port: utils.Int32(int32(port)), + Scheme: containerinstance.Scheme(scheme), + } + } + } + } + return &probe +} + +func flattenContainerGroupIdentity(identity *containerinstance.ContainerGroupIdentity) []interface{} { + if identity == nil { + return make([]interface{}, 0) + } + + result := make(map[string]interface{}) + result["type"] = string(identity.Type) + if identity.PrincipalID != nil { + result["principal_id"] = *identity.PrincipalID + } + + identityIds := make([]string, 0) + if identity.UserAssignedIdentities != nil { + /* + "userAssignedIdentities": { + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tomdevidentity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/tom123": { + "principalId": "00000000-0000-0000-0000-000000000000", + "clientId": "00000000-0000-0000-0000-000000000000" + } + } + */ + for key := range identity.UserAssignedIdentities { + identityIds = append(identityIds, key) + } + } + result["identity_ids"] = identityIds + + return []interface{}{result} +} + func flattenContainerImageRegistryCredentials(d *schema.ResourceData, input *[]containerinstance.ImageRegistryCredential) []interface{} { if input == nil { return nil @@ -907,6 +1197,9 @@ func flattenContainerGroupContainers(d *schema.ResourceData, containers *[]conta containerConfig["volume"] = flattenContainerVolumes(container.VolumeMounts, containerGroupVolumes, containerVolumesConfig) } + containerConfig["liveness_probe"] = flattenContainerProbes(container.LivenessProbe) + containerConfig["readiness_probe"] = flattenContainerProbes(container.ReadinessProbe) + containerCfg = append(containerCfg, containerConfig) } @@ -1002,6 +1295,62 @@ func flattenContainerVolumes(volumeMounts *[]containerinstance.VolumeMount, cont return volumeConfigs } +func flattenContainerProbes(input *containerinstance.ContainerProbe) []interface{} { + outputs := make([]interface{}, 0) + if input == nil { + return outputs + } + + output := make(map[string]interface{}) + + if v := input.Exec; v != nil { + output["exec"] = *v.Command + } + + httpGets := make([]interface{}, 0) + if get := input.HTTPGet; get != nil { + httpGet := make(map[string]interface{}) + + if v := get.Path; v != nil { + httpGet["path"] = *v + } + + if v := get.Port; v != nil { + httpGet["port"] = *v + } + + if get.Scheme != "" { + httpGet["scheme"] = get.Scheme + } + + httpGets = append(httpGets, httpGet) + } + output["http_get"] = httpGets + + if v := input.FailureThreshold; v != nil { + output["failure_threshold"] = *v + } + + if v := input.InitialDelaySeconds; v != nil { + output["initial_delay_seconds"] = *v + } + + if v := input.PeriodSeconds; v != nil { + output["period_seconds"] = *v + } + + if v := input.SuccessThreshold; v != nil { + output["success_threshold"] = *v + } + + if v := input.TimeoutSeconds; v != nil { + output["timeout_seconds"] = *v + } + + outputs = append(outputs, output) + return outputs +} + func expandContainerGroupDiagnostics(input []interface{}) *containerinstance.ContainerGroupDiagnostics { if len(input) == 0 { return nil @@ -1014,23 +1363,26 @@ func expandContainerGroupDiagnostics(input []interface{}) *containerinstance.Con workspaceId := analyticsV["workspace_id"].(string) workspaceKey := analyticsV["workspace_key"].(string) - logType := containerinstance.LogAnalyticsLogType(analyticsV["log_type"].(string)) - metadataMap := analyticsV["metadata"].(map[string]interface{}) - metadata := make(map[string]*string) - for k, v := range metadataMap { - strValue := v.(string) - metadata[k] = &strValue + logAnalytics := containerinstance.LogAnalytics{ + WorkspaceID: utils.String(workspaceId), + WorkspaceKey: utils.String(workspaceKey), } - return &containerinstance.ContainerGroupDiagnostics{ - LogAnalytics: &containerinstance.LogAnalytics{ - WorkspaceID: utils.String(workspaceId), - WorkspaceKey: utils.String(workspaceKey), - LogType: logType, - Metadata: metadata, - }, + if logType := analyticsV["log_type"].(string); logType != "" { + logAnalytics.LogType = containerinstance.LogAnalyticsLogType(logType) + + metadataMap := analyticsV["metadata"].(map[string]interface{}) + metadata := make(map[string]*string) + for k, v := range metadataMap { + strValue := v.(string) + metadata[k] = &strValue + } + + logAnalytics.Metadata = metadata } + + return &containerinstance.ContainerGroupDiagnostics{LogAnalytics: &logAnalytics} } func flattenContainerGroupDiagnostics(d *schema.ResourceData, input *containerinstance.ContainerGroupDiagnostics) []interface{} { diff --git a/azurerm/resource_arm_container_group_test.go b/azurerm/resource_arm_container_group_test.go old mode 100644 new mode 100755 index 3e189e649e60..f108d1b93685 --- a/azurerm/resource_arm_container_group_test.go +++ b/azurerm/resource_arm_container_group_test.go @@ -2,15 +2,107 @@ package azurerm import ( "fmt" - "net/http" "testing" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +func TestAccAzureRMContainerGroup_SystemAssignedIdentity(t *testing.T) { + resourceName := "azurerm_container_group.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMContainerGroup_SystemAssignedIdentity(ri, testLocation()) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned"), + resource.TestCheckResourceAttr(resourceName, "identity.0.identity_ids.#", "0"), + resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "identity.0.principal_id", + }, + }, + }, + }) +} + +func TestAccAzureRMContainerGroup_UserAssignedIdentity(t *testing.T) { + resourceName := "azurerm_container_group.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(14) + config := testAccAzureRMContainerGroup_UserAssignedIdentity(ri, testLocation(), rs) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "UserAssigned"), + resource.TestCheckResourceAttr(resourceName, "identity.0.identity_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "identity.0.principal_id", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMContainerGroup_multipleAssignedIdentities(t *testing.T) { + resourceName := "azurerm_container_group.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(14) + config := testAccAzureRMContainerGroup_MultipleAssignedIdentities(ri, testLocation(), rs) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "identity.0.type", "SystemAssigned, UserAssigned"), + resource.TestCheckResourceAttr(resourceName, "identity.0.identity_ids.#", "1"), + resource.TestMatchResourceAttr(resourceName, "identity.0.principal_id", validate.UUIDRegExp), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "identity.0.principal_id", + }, + }, + }, + }) +} + func TestAccAzureRMContainerGroup_imageRegistryCredentials(t *testing.T) { resourceName := "azurerm_container_group.test" ri := tf.AccRandTimeInt() @@ -90,6 +182,38 @@ func TestAccAzureRMContainerGroup_imageRegistryCredentialsUpdate(t *testing.T) { }) } +func TestAccAzureRMContainerGroup_logTypeUnset(t *testing.T) { + resourceName := "azurerm_container_group.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMContainerGroup_logTypeUnset(ri, testLocation()) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.#", "1"), + resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.0.log_type", ""), + resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.0.metadata.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_id"), + resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_key"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "diagnostics.0.log_analytics.0.workspace_key", + }, + }, + }, + }) +} + func TestAccAzureRMContainerGroup_linuxBasic(t *testing.T) { resourceName := "azurerm_container_group.test" ri := tf.AccRandTimeInt() @@ -124,7 +248,7 @@ func TestAccAzureRMContainerGroup_linuxBasic(t *testing.T) { } func TestAccAzureRMContainerGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -225,6 +349,26 @@ func TestAccAzureRMContainerGroup_linuxComplete(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.0.metadata.%", "1"), resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_id"), resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_key"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.#", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.exec.#", "2"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.exec.0", "cat"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.exec.1", "/tmp/healthy"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.http_get.#", "0"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.initial_delay_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.period_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.failure_threshold", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.success_threshold", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.timeout_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.#", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.failure_threshold", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.http_get.#", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.http_get.0.path", "/"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.http_get.0.port", "443"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.http_get.0.scheme", "Http"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.initial_delay_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.period_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.success_threshold", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.timeout_seconds", "1"), ), }, { @@ -243,6 +387,33 @@ func TestAccAzureRMContainerGroup_linuxComplete(t *testing.T) { }) } +func TestAccAzureRMContainerGroup_virtualNetwork(t *testing.T) { + resourceName := "azurerm_container_group.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMContainerGroup_virtualNetwork(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerGroupExists(resourceName), + resource.TestCheckNoResourceAttr(resourceName, "dns_label_name"), + resource.TestCheckNoResourceAttr(resourceName, "identity"), + resource.TestCheckResourceAttr(resourceName, "container.#", "1"), + resource.TestCheckResourceAttr(resourceName, "os_type", "Linux"), + resource.TestCheckResourceAttr(resourceName, "container.0.port", "80"), + resource.TestCheckResourceAttr(resourceName, "ip_address_type", "Private"), + resource.TestCheckResourceAttrSet(resourceName, "network_profile_id"), + ), + }, + }, + }) +} + func TestAccAzureRMContainerGroup_windowsBasic(t *testing.T) { resourceName := "azurerm_container_group.test" ri := tf.AccRandTimeInt() @@ -307,6 +478,26 @@ func TestAccAzureRMContainerGroup_windowsComplete(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.0.metadata.%", "1"), resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_id"), resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_key"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.#", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.exec.#", "2"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.exec.0", "cat"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.exec.1", "/tmp/healthy"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.http_get.#", "0"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.initial_delay_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.period_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.failure_threshold", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.success_threshold", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.readiness_probe.0.timeout_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.#", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.failure_threshold", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.http_get.#", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.http_get.0.path", "/"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.http_get.0.port", "443"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.http_get.0.scheme", "Http"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.initial_delay_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.period_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.success_threshold", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.liveness_probe.0.timeout_seconds", "1"), ), }, { @@ -324,6 +515,121 @@ func TestAccAzureRMContainerGroup_windowsComplete(t *testing.T) { }) } +func testAccAzureRMContainerGroup_SystemAssignedIdentity(ri int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_group" "test" { + name = "acctestcontainergroup-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + ip_address_type = "public" + os_type = "Linux" + + container { + name = "hw" + image = "microsoft/aci-helloworld:latest" + cpu = "0.5" + memory = "0.5" + port = 80 + } + + identity { + type = "SystemAssigned" + } + + tags = { + environment = "Testing" + } +} +`, ri, location, ri) +} + +func testAccAzureRMContainerGroup_UserAssignedIdentity(ri int, location string, rString string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_user_assigned_identity" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + name = "acctest%s" +} + +resource "azurerm_container_group" "test" { + name = "acctestcontainergroup-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + ip_address_type = "public" + os_type = "Linux" + + container { + name = "hw" + image = "microsoft/aci-helloworld:latest" + cpu = "0.5" + memory = "0.5" + port = 80 + } + + identity { + type = "UserAssigned" + identity_ids = ["${azurerm_user_assigned_identity.test.id}"] + } + + tags = { + environment = "Testing" + } +} +`, ri, location, rString, ri) +} + +func testAccAzureRMContainerGroup_MultipleAssignedIdentities(ri int, location string, rString string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_user_assigned_identity" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + name = "acctest%s" +} + +resource "azurerm_container_group" "test" { + name = "acctestcontainergroup-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + ip_address_type = "public" + os_type = "Linux" + + container { + name = "hw" + image = "microsoft/aci-helloworld:latest" + cpu = "0.5" + memory = "0.5" + port = 80 + } + + identity { + type = "SystemAssigned, UserAssigned" + identity_ids = ["${azurerm_user_assigned_identity.test.id}"] + } + + tags = { + environment = "Testing" + } +} +`, ri, location, rString, ri) +} + func testAccAzureRMContainerGroup_linuxBasic(ri int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -448,7 +754,8 @@ resource "azurerm_container_group" "test" { image = "microsoft/aci-helloworld:latest" cpu = "0.5" memory = "0.5" - ports { + + ports { port = 80 } } @@ -473,6 +780,49 @@ resource "azurerm_container_group" "test" { `, ri, location, ri) } +func testAccAzureRMContainerGroup_logTypeUnset(ri int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_log_analytics_workspace" "test" { + name = "acctestLAW-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "PerGB2018" +} + +resource "azurerm_container_group" "test" { + name = "acctestcontainergroup-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + ip_address_type = "public" + os_type = "Linux" + + container { + name = "hw" + image = "microsoft/aci-helloworld:latest" + cpu = "0.5" + memory = "0.5" + port = 80 + } + + diagnostics { + log_analytics { + workspace_id = "${azurerm_log_analytics_workspace.test.workspace_id}" + workspace_key = "${azurerm_log_analytics_workspace.test.primary_shared_key}" + } + } + + tags = { + environment = "Testing" + } +} +`, ri, location, ri, ri) +} + func testAccAzureRMContainerGroup_linuxBasicUpdated(ri int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -492,9 +842,11 @@ resource "azurerm_container_group" "test" { image = "microsoft/aci-helloworld:latest" cpu = "0.5" memory = "0.5" - ports { - port = 80 + + ports { + port = 80 } + ports { port = 5443 protocol = "UDP" @@ -515,6 +867,74 @@ resource "azurerm_container_group" "test" { `, ri, location, ri) } +func testAccAzureRMContainerGroup_virtualNetwork(ri int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "testvnet" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = ["10.1.0.0/16"] +} + +resource "azurerm_subnet" "test" { + name = "testsubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.1.0.0/24" + + delegation { + name = "delegation" + + service_delegation { + name = "Microsoft.ContainerInstance/containerGroups" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } +} + +resource "azurerm_network_profile" "test" { + name = "testnetprofile" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + container_network_interface { + name = "testcnic" + + ip_configuration { + name = "testipconfig" + subnet_id = "${azurerm_subnet.test.id}" + } + } +} + +resource "azurerm_container_group" "test" { + name = "acctestcontainergroup-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + ip_address_type = "Private" + network_profile_id = "${azurerm_network_profile.test.id}" + os_type = "Linux" + + container { + name = "hw" + image = "microsoft/aci-helloworld:latest" + cpu = "0.5" + memory = "0.5" + port = 80 + } + + tags = { + environment = "Testing" + } +} +`, ri, location, ri) +} + func testAccAzureRMContainerGroup_windowsBasic(ri int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -531,13 +951,15 @@ resource "azurerm_container_group" "test" { container { name = "windowsservercore" - image = "microsoft/windowsservercore:latest" + image = "microsoft/iis:windowsservercore" cpu = "2.0" memory = "3.5" + ports { port = 80 protocol = "TCP" } + ports { port = 443 protocol = "TCP" @@ -589,22 +1011,46 @@ resource "azurerm_container_group" "test" { container { name = "windowsservercore" - image = "microsoft/windowsservercore:latest" + image = "microsoft/iis:windowsservercore" cpu = "2.0" memory = "3.5" + ports { port = 80 protocol = "TCP" - } + } environment_variables = { - "foo" = "bar" - "foo1" = "bar1" + foo = "bar" + foo1 = "bar1" } secure_environment_variables = { - "secureFoo" = "secureBar" - "secureFoo1" = "secureBar1" + secureFoo = "secureBar" + secureFoo1 = "secureBar1" + } + + readiness_probe { + exec = ["cat", "/tmp/healthy"] + initial_delay_seconds = 1 + period_seconds = 1 + failure_threshold = 1 + success_threshold = 1 + timeout_seconds = 1 + } + + liveness_probe { + http_get { + path = "/" + port = 443 + scheme = "Http" + } + + initial_delay_seconds = 1 + period_seconds = 1 + failure_threshold = 1 + success_threshold = 1 + timeout_seconds = 1 } commands = ["cmd.exe", "echo", "hi"] @@ -615,8 +1061,9 @@ resource "azurerm_container_group" "test" { workspace_id = "${azurerm_log_analytics_workspace.test.workspace_id}" workspace_key = "${azurerm_log_analytics_workspace.test.primary_shared_key}" log_type = "ContainerInsights" - metadata { - "node-name" = "acctestContainerGroup" + + metadata = { + node-name = "acctestContainerGroup" } } } @@ -692,9 +1139,9 @@ resource "azurerm_container_group" "test" { protocol = "TCP" } - gpu = { + gpu { count = 1 - sku = "K80" + sku = "K80" } volume { @@ -704,29 +1151,53 @@ resource "azurerm_container_group" "test" { share_name = "${azurerm_storage_share.test.name}" storage_account_name = "${azurerm_storage_account.test.name}" - storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" } environment_variables = { - "foo" = "bar" - "foo1" = "bar1" + foo = "bar" + foo1 = "bar1" } secure_environment_variables = { - "secureFoo" = "secureBar" - "secureFoo1" = "secureBar1" + secureFoo = "secureBar" + secureFoo1 = "secureBar1" + } + + readiness_probe { + exec = ["cat", "/tmp/healthy"] + initial_delay_seconds = 1 + period_seconds = 1 + failure_threshold = 1 + success_threshold = 1 + timeout_seconds = 1 + } + + liveness_probe { + http_get { + path = "/" + port = 443 + scheme = "Http" + } + + initial_delay_seconds = 1 + period_seconds = 1 + failure_threshold = 1 + success_threshold = 1 + timeout_seconds = 1 } commands = ["/bin/bash", "-c", "ls"] } diagnostics { - log_analytics { + log_analytics { workspace_id = "${azurerm_log_analytics_workspace.test.workspace_id}" workspace_key = "${azurerm_log_analytics_workspace.test.primary_shared_key}" log_type = "ContainerInsights" - metadata { - "node-name" = "acctestContainerGroup" + + metadata = { + node-name = "acctestContainerGroup" } } } @@ -752,7 +1223,7 @@ func testCheckAzureRMContainerGroupExists(resourceName string) resource.TestChec return fmt.Errorf("Bad: no resource group found in state for Container Registry: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).containerGroupsClient + conn := testAccProvider.Meta().(*ArmClient).containers.GroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) @@ -767,7 +1238,7 @@ func testCheckAzureRMContainerGroupExists(resourceName string) resource.TestChec } func testCheckAzureRMContainerGroupDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).containerGroupsClient + conn := testAccProvider.Meta().(*ArmClient).containers.GroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -781,7 +1252,7 @@ func testCheckAzureRMContainerGroupDestroy(s *terraform.State) error { resp, err := conn.Get(ctx, resourceGroup, name) if err != nil { - if resp.StatusCode != http.StatusNotFound { + if !utils.ResponseWasNotFound(resp.Response) { return fmt.Errorf("Container Group still exists:\n%#v", resp) } diff --git a/azurerm/resource_arm_container_registry.go b/azurerm/resource_arm_container_registry.go index 1312f960cba8..7e3596a7cd3d 100644 --- a/azurerm/resource_arm_container_registry.go +++ b/azurerm/resource_arm_container_registry.go @@ -7,12 +7,16 @@ import ( "strings" - "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry" + "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2018-09-01/containerregistry" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,15 +40,15 @@ func resourceArmContainerRegistry() *schema.Resource { ValidateFunc: validateAzureRMContainerRegistryName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "sku": { Type: schema.TypeString, Optional: true, Default: string(containerregistry.Classic), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(containerregistry.Classic), string(containerregistry.Basic), @@ -67,7 +71,7 @@ func resourceArmContainerRegistry() *schema.Resource { Type: schema.TypeString, ValidateFunc: validate.NoEmptyStrings, }, - Set: azureRMHashLocation, + Set: azure.HashAzureLocation, }, "storage_account_id": { @@ -112,7 +116,50 @@ func resourceArmContainerRegistry() *schema.Resource { Sensitive: true, }, - "tags": tagsSchema(), + "network_rule_set": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + ConfigMode: schema.SchemaConfigModeAttr, // make sure we can set this to an empty array for Premium -> Basic + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "default_action": { + Type: schema.TypeString, + Optional: true, + Default: containerregistry.DefaultActionAllow, + ValidateFunc: validation.StringInSlice([]string{ + string(containerregistry.DefaultActionAllow), + string(containerregistry.DefaultActionDeny), + }, false), + }, + + "ip_rule": { + Type: schema.TypeSet, + Optional: true, + ConfigMode: schema.SchemaConfigModeAttr, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "action": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(containerregistry.Allow), + }, false), + }, + "ip_range": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.CIDR, + }, + }, + }, + }, + }, + }, + }, + + "tags": tags.Schema(), }, CustomizeDiff: func(d *schema.ResourceDiff, v interface{}) error { @@ -129,14 +176,14 @@ func resourceArmContainerRegistry() *schema.Resource { } func resourceArmContainerRegistryCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).containerRegistryClient + client := meta.(*ArmClient).containers.RegistriesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Container Registry creation.") resourceGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -149,12 +196,17 @@ func resourceArmContainerRegistryCreate(d *schema.ResourceData, meta interface{} } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) sku := d.Get("sku").(string) adminUserEnabled := d.Get("admin_enabled").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) geoReplicationLocations := d.Get("georeplication_locations").(*schema.Set) + networkRuleSet := expandNetworkRuleSet(d.Get("network_rule_set").([]interface{})) + if networkRuleSet != nil && !strings.EqualFold(sku, string(containerregistry.Premium)) { + return fmt.Errorf("`network_rule_set_set` can only be specified for a Premium Sku. If you are reverting from a Premium to Basic SKU plese set network_rule_set = []") + } + parameters := containerregistry.Registry{ Location: &location, Sku: &containerregistry.Sku{ @@ -163,8 +215,10 @@ func resourceArmContainerRegistryCreate(d *schema.ResourceData, meta interface{} }, RegistryProperties: &containerregistry.RegistryProperties{ AdminUserEnabled: utils.Bool(adminUserEnabled), + NetworkRuleSet: networkRuleSet, }, - Tags: expandTags(tags), + + Tags: tags.Expand(t), } if v, ok := d.GetOk("storage_account_id"); ok { @@ -215,7 +269,7 @@ func resourceArmContainerRegistryCreate(d *schema.ResourceData, meta interface{} } func resourceArmContainerRegistryUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).containerRegistryClient + client := meta.(*ArmClient).containers.RegistriesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Container Registry update.") @@ -224,22 +278,28 @@ func resourceArmContainerRegistryUpdate(d *schema.ResourceData, meta interface{} sku := d.Get("sku").(string) adminUserEnabled := d.Get("admin_enabled").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) old, new := d.GetChange("georeplication_locations") hasGeoReplicationChanges := d.HasChange("georeplication_locations") oldGeoReplicationLocations := old.(*schema.Set) newGeoReplicationLocations := new.(*schema.Set) + networkRuleSet := expandNetworkRuleSet(d.Get("network_rule_set").([]interface{})) + if networkRuleSet != nil && !strings.EqualFold(sku, string(containerregistry.Premium)) { + return fmt.Errorf("`network_rule_set_set` can only be specified for a Premium Sku. If you are reverting from a Premium to Basic SKU plese set network_rule_set = []") + } + parameters := containerregistry.RegistryUpdateParameters{ RegistryPropertiesUpdateParameters: &containerregistry.RegistryPropertiesUpdateParameters{ AdminUserEnabled: utils.Bool(adminUserEnabled), + NetworkRuleSet: networkRuleSet, }, Sku: &containerregistry.Sku{ Name: containerregistry.SkuName(sku), Tier: containerregistry.SkuTier(sku), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if v, ok := d.GetOk("storage_account_id"); ok { @@ -300,7 +360,7 @@ func resourceArmContainerRegistryUpdate(d *schema.ResourceData, meta interface{} } func applyGeoReplicationLocations(meta interface{}, resourceGroup string, name string, oldGeoReplicationLocations []interface{}, newGeoReplicationLocations []interface{}) error { - replicationClient := meta.(*ArmClient).containerRegistryReplicationsClient + replicationClient := meta.(*ArmClient).containers.ReplicationsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing to apply geo-replications for AzureRM Container Registry.") @@ -308,14 +368,14 @@ func applyGeoReplicationLocations(meta interface{}, resourceGroup string, name s // loop on the new location values for _, nl := range newGeoReplicationLocations { - newLocation := azureRMNormalizeLocation(nl) + newLocation := azure.NormalizeLocation(nl) createLocations[newLocation] = true // the location needs to be created } // loop on the old location values for _, ol := range oldGeoReplicationLocations { // oldLocation was created from a previous deployment - oldLocation := azureRMNormalizeLocation(ol) + oldLocation := azure.NormalizeLocation(ol) // if the list of locations to create already contains the location if _, ok := createLocations[oldLocation]; ok { @@ -348,7 +408,7 @@ func applyGeoReplicationLocations(meta interface{}, resourceGroup string, name s // loop on the list of previously deployed locations for _, ol := range oldGeoReplicationLocations { - oldLocation := azureRMNormalizeLocation(ol) + oldLocation := azure.NormalizeLocation(ol) // if the old location is still in the list of locations, then continue if _, ok := createLocations[oldLocation]; ok { continue @@ -369,11 +429,11 @@ func applyGeoReplicationLocations(meta interface{}, resourceGroup string, name s } func resourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).containerRegistryClient - replicationClient := meta.(*ArmClient).containerRegistryReplicationsClient + client := meta.(*ArmClient).containers.RegistriesClient + replicationClient := meta.(*ArmClient).containers.ReplicationsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -396,11 +456,16 @@ func resourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{}) location := resp.Location if location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("admin_enabled", resp.AdminUserEnabled) d.Set("login_server", resp.LoginServer) + networkRuleSet := flattenNetworkRuleSet(resp.NetworkRuleSet) + if err := d.Set("network_rule_set", networkRuleSet); err != nil { + return fmt.Errorf("Error setting `network_rule_set`: %+v", err) + } + if sku := resp.Sku; sku != nil { d.Set("sku", string(sku.Tier)) } @@ -425,8 +490,6 @@ func resourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{}) d.Set("admin_password", "") } - flattenAndSetTags(d, resp.Tags) - replications, err := replicationClient.List(ctx, resourceGroup, name) if err != nil { return fmt.Errorf("Error making Read request on Azure Container Registry %s for replications: %s", name, err) @@ -440,8 +503,8 @@ func resourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{}) for _, value := range replicationValues { if value.Location != nil { - valueLocation := azureRMNormalizeLocation(*value.Location) - if location != nil && valueLocation != azureRMNormalizeLocation(*location) { + valueLocation := azure.NormalizeLocation(*value.Location) + if location != nil && valueLocation != azure.NormalizeLocation(*location) { georeplication_locations.Add(valueLocation) } } @@ -450,14 +513,14 @@ func resourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{}) d.Set("georeplication_locations", georeplication_locations) } - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmContainerRegistryDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).containerRegistryClient + client := meta.(*ArmClient).containers.RegistriesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -499,3 +562,56 @@ func validateAzureRMContainerRegistryName(v interface{}, k string) (warnings []s return warnings, errors } + +func expandNetworkRuleSet(profiles []interface{}) *containerregistry.NetworkRuleSet { + if len(profiles) == 0 { + return nil + } + + profile := profiles[0].(map[string]interface{}) + + ipRuleConfigs := profile["ip_rule"].(*schema.Set).List() + ipRules := make([]containerregistry.IPRule, 0) + for _, ipRuleInterface := range ipRuleConfigs { + config := ipRuleInterface.(map[string]interface{}) + ipRules = + append(ipRules, containerregistry.IPRule{ + Action: containerregistry.Action(config["action"].(string)), + IPAddressOrRange: utils.String(config["ip_range"].(string)), + }) + } + + networkRuleSet := containerregistry.NetworkRuleSet{ + DefaultAction: containerregistry.DefaultAction(profile["default_action"].(string)), + IPRules: &ipRules, + } + return &networkRuleSet +} + +func flattenNetworkRuleSet(networkRuleSet *containerregistry.NetworkRuleSet) []interface{} { + if networkRuleSet == nil { + return []interface{}{} + } + + values := make(map[string]interface{}) + + values["default_action"] = string(networkRuleSet.DefaultAction) + + ipRules := make([]interface{}, 0) + for _, ipRule := range *networkRuleSet.IPRules { + value := make(map[string]interface{}) + value["action"] = string(ipRule.Action) + + //When a /32 CIDR is passed as an ip rule, Azure will drop the /32 leading to the resource wanting to be re-created next run + if !strings.Contains(*ipRule.IPAddressOrRange, "/") { + *ipRule.IPAddressOrRange += "/32" + } + + value["ip_range"] = ipRule.IPAddressOrRange + ipRules = append(ipRules, value) + } + + values["ip_rule"] = ipRules + + return []interface{}{values} +} diff --git a/azurerm/resource_arm_container_registry_migrate.go b/azurerm/resource_arm_container_registry_migrate.go index 392588a247eb..ab0b0a48b5d0 100644 --- a/azurerm/resource_arm_container_registry_migrate.go +++ b/azurerm/resource_arm_container_registry_migrate.go @@ -92,7 +92,7 @@ func updateV1ToV2StorageAccountName(is *terraform.InstanceState, meta interface{ func findAzureStorageAccountIdFromName(name string, meta interface{}) (string, error) { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).storageServiceClient + client := meta.(*ArmClient).storage.AccountsClient accounts, err := client.List(ctx) if err != nil { return "", err diff --git a/azurerm/resource_arm_container_registry_migrate_test.go b/azurerm/resource_arm_container_registry_migrate_test.go index bc715a2f3f1e..d1f888b0c3d6 100644 --- a/azurerm/resource_arm_container_registry_migrate_test.go +++ b/azurerm/resource_arm_container_registry_migrate_test.go @@ -8,9 +8,10 @@ import ( "testing" "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources" - "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-02-01/storage" + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" ) func TestAccAzureRMContainerRegistryMigrateState(t *testing.T) { @@ -20,7 +21,7 @@ func TestAccAzureRMContainerRegistryMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false, "") + client, err := getArmClient(config, false, "", true) if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return @@ -31,7 +32,7 @@ func TestAccAzureRMContainerRegistryMigrateState(t *testing.T) { rs := acctest.RandString(4) resourceGroupName := fmt.Sprintf("acctestRG%s", rs) storageAccountName := fmt.Sprintf("acctestsa%s", rs) - location := azureRMNormalizeLocation(testLocation()) + location := azure.NormalizeLocation(testLocation()) ctx := client.StopContext err = createResourceGroup(ctx, client, resourceGroupName, location) @@ -104,14 +105,14 @@ func createResourceGroup(ctx context.Context, client *ArmClient, resourceGroupNa Location: &location, } - if _, err := client.resourceGroupsClient.CreateOrUpdate(ctx, resourceGroupName, group); err != nil { + if _, err := client.resource.GroupsClient.CreateOrUpdate(ctx, resourceGroupName, group); err != nil { return fmt.Errorf("Error creating Resource Group %q: %+v", resourceGroupName, err) } return nil } func createStorageAccount(client *ArmClient, resourceGroupName, storageAccountName, location string) (*storage.Account, error) { - storageClient := client.storageServiceClient + storageClient := client.storage.AccountsClient createParams := storage.AccountCreateParameters{ Location: &location, Kind: storage.Storage, @@ -130,7 +131,7 @@ func createStorageAccount(client *ArmClient, resourceGroupName, storageAccountNa return nil, fmt.Errorf("Error waiting for creation of Storage Account %q: %+v", resourceGroupName, err) } - account, err := storageClient.GetProperties(ctx, resourceGroupName, storageAccountName) + account, err := storageClient.GetProperties(ctx, resourceGroupName, storageAccountName, "") if err != nil { return nil, fmt.Errorf("Error retrieving Storage Account %q: %+v", resourceGroupName, err) } @@ -140,10 +141,10 @@ func createStorageAccount(client *ArmClient, resourceGroupName, storageAccountNa func destroyStorageAccountAndResourceGroup(client *ArmClient, resourceGroupName, storageAccountName string) { ctx := client.StopContext - if _, err := client.storageServiceClient.Delete(ctx, resourceGroupName, storageAccountName); err != nil { + if _, err := client.storage.AccountsClient.Delete(ctx, resourceGroupName, storageAccountName); err != nil { log.Printf("[DEBUG] Error deleting Storage Account %q (Resource Group %q): %v", storageAccountName, resourceGroupName, err) } - if _, err := client.resourceGroupsClient.Delete(ctx, resourceGroupName); err != nil { + if _, err := client.resource.GroupsClient.Delete(ctx, resourceGroupName); err != nil { log.Printf("[DEBUG] Error deleting Resource Group %q): %v", resourceGroupName, err) } } diff --git a/azurerm/resource_arm_container_registry_test.go b/azurerm/resource_arm_container_registry_test.go index ed84b1869009..6cab70951069 100644 --- a/azurerm/resource_arm_container_registry_test.go +++ b/azurerm/resource_arm_container_registry_test.go @@ -6,10 +6,11 @@ import ( "strings" "testing" - "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry" + "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2018-09-01/containerregistry" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -69,10 +70,10 @@ func TestAccAzureRMContainerRegistryName_validation(t *testing.T) { } } -func TestAccAzureRMContainerRegistry_basicBasic(t *testing.T) { - resourceName := "azurerm_container_registry.test" +func TestAccAzureRMContainerRegistry_basic_basic(t *testing.T) { + rn := "azurerm_container_registry.test" ri := tf.AccRandTimeInt() - location := testLocation() + l := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -80,13 +81,13 @@ func TestAccAzureRMContainerRegistry_basicBasic(t *testing.T) { CheckDestroy: testCheckAzureRMContainerRegistryDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMContainerRegistry_basicManaged(ri, location, "Basic"), + Config: testAccAzureRMContainerRegistry_basic_basic(ri, l), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), + testCheckAzureRMContainerRegistryExists(rn), ), }, { - ResourceName: resourceName, + ResourceName: rn, ImportState: true, ImportStateVerify: true, }, @@ -95,14 +96,14 @@ func TestAccAzureRMContainerRegistry_basicBasic(t *testing.T) { } func TestAccAzureRMContainerRegistry_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } - resourceName := "azurerm_container_registry.test" + rn := "azurerm_container_registry.test" ri := tf.AccRandTimeInt() - location := testLocation() + l := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -110,23 +111,22 @@ func TestAccAzureRMContainerRegistry_requiresImport(t *testing.T) { CheckDestroy: testCheckAzureRMContainerRegistryDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMContainerRegistry_basicManaged(ri, location, "Basic"), + Config: testAccAzureRMContainerRegistry_basicManaged(ri, l, "Basic"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), + testCheckAzureRMContainerRegistryExists(rn), ), }, { - Config: testAccAzureRMContainerRegistry_requiresImport(ri, location, "Basic"), + Config: testAccAzureRMContainerRegistry_requiresImport(ri, l, "Basic"), ExpectError: testRequiresImportError("azurerm_container_registry"), }, }, }) } -func TestAccAzureRMContainerRegistry_basicStandard(t *testing.T) { - resourceName := "azurerm_container_registry.test" +func TestAccAzureRMContainerRegistry_basic_standard(t *testing.T) { + rn := "azurerm_container_registry.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMContainerRegistry_basicManaged(ri, testLocation(), "Standard") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -134,13 +134,13 @@ func TestAccAzureRMContainerRegistry_basicStandard(t *testing.T) { CheckDestroy: testCheckAzureRMContainerRegistryDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMContainerRegistry_basicManaged(ri, testLocation(), "Standard"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), + testCheckAzureRMContainerRegistryExists(rn), ), }, { - ResourceName: resourceName, + ResourceName: rn, ImportState: true, ImportStateVerify: true, }, @@ -148,10 +148,9 @@ func TestAccAzureRMContainerRegistry_basicStandard(t *testing.T) { }) } -func TestAccAzureRMContainerRegistry_basicPremium(t *testing.T) { - resourceName := "azurerm_container_registry.test" +func TestAccAzureRMContainerRegistry_basic_premium(t *testing.T) { + rn := "azurerm_container_registry.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMContainerRegistry_basicManaged(ri, testLocation(), "Premium") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -159,13 +158,13 @@ func TestAccAzureRMContainerRegistry_basicPremium(t *testing.T) { CheckDestroy: testCheckAzureRMContainerRegistryDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMContainerRegistry_basicManaged(ri, testLocation(), "Premium"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), + testCheckAzureRMContainerRegistryExists(rn), ), }, { - ResourceName: resourceName, + ResourceName: rn, ImportState: true, ImportStateVerify: true, }, @@ -173,11 +172,9 @@ func TestAccAzureRMContainerRegistry_basicPremium(t *testing.T) { }) } -func TestAccAzureRMContainerRegistry_basicBasicUpgradePremium(t *testing.T) { - resourceName := "azurerm_container_registry.test" +func TestAccAzureRMContainerRegistry_basic_basic2Premium2basic(t *testing.T) { + rn := "azurerm_container_registry.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMContainerRegistry_basicManaged(ri, testLocation(), "Basic") - configUpdated := testAccAzureRMContainerRegistry_basicManaged(ri, testLocation(), "Premium") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -185,17 +182,24 @@ func TestAccAzureRMContainerRegistry_basicBasicUpgradePremium(t *testing.T) { CheckDestroy: testCheckAzureRMContainerRegistryDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMContainerRegistry_basic_basic(ri, testLocation()), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "sku", "Basic"), + testCheckAzureRMContainerRegistryExists(rn), + resource.TestCheckResourceAttr(rn, "sku", "Basic"), ), }, { - Config: configUpdated, + Config: testAccAzureRMContainerRegistry_basicManaged(ri, testLocation(), "Premium"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "sku", "Premium"), + testCheckAzureRMContainerRegistryExists(rn), + resource.TestCheckResourceAttr(rn, "sku", "Premium"), + ), + }, + { + Config: testAccAzureRMContainerRegistry_basic_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryExists(rn), + resource.TestCheckResourceAttr(rn, "sku", "Basic"), ), }, }, @@ -203,9 +207,8 @@ func TestAccAzureRMContainerRegistry_basicBasicUpgradePremium(t *testing.T) { } func TestAccAzureRMContainerRegistry_complete(t *testing.T) { - resourceName := "azurerm_container_registry.test" + rn := "azurerm_container_registry.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMContainerRegistry_complete(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -213,13 +216,13 @@ func TestAccAzureRMContainerRegistry_complete(t *testing.T) { CheckDestroy: testCheckAzureRMContainerRegistryDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMContainerRegistry_complete(ri, testLocation()), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), + testCheckAzureRMContainerRegistryExists(rn), ), }, { - ResourceName: resourceName, + ResourceName: rn, ImportState: true, ImportStateVerify: true, }, @@ -228,11 +231,9 @@ func TestAccAzureRMContainerRegistry_complete(t *testing.T) { } func TestAccAzureRMContainerRegistry_update(t *testing.T) { - resourceName := "azurerm_container_registry.test" + rn := "azurerm_container_registry.test" ri := tf.AccRandTimeInt() - location := testLocation() - config := testAccAzureRMContainerRegistry_complete(ri, location) - updatedConfig := testAccAzureRMContainerRegistry_completeUpdated(ri, location) + l := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -240,15 +241,15 @@ func TestAccAzureRMContainerRegistry_update(t *testing.T) { CheckDestroy: testCheckAzureRMContainerRegistryDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMContainerRegistry_complete(ri, l), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), + testCheckAzureRMContainerRegistryExists(rn), ), }, { - Config: updatedConfig, + Config: testAccAzureRMContainerRegistry_completeUpdated(ri, l), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMContainerRegistryExists(resourceName), + testCheckAzureRMContainerRegistryExists(rn), ), }, }, @@ -256,16 +257,14 @@ func TestAccAzureRMContainerRegistry_update(t *testing.T) { } func TestAccAzureRMContainerRegistry_geoReplication(t *testing.T) { - dataSourceName := "azurerm_container_registry.test" + dsn := "azurerm_container_registry.test" + ri := tf.AccRandTimeInt() + skuPremium := "Premium" skuBasic := "Basic" - ri := tf.AccRandTimeInt() + containerRegistryName := fmt.Sprintf("testacccr%d", ri) resourceGroupName := fmt.Sprintf("testAccRg-%d", ri) - config := testAccAzureRMContainerRegistry_geoReplication(ri, testLocation(), skuPremium, `eastus", "westus`) - updatedConfig := testAccAzureRMContainerRegistry_geoReplication(ri, testLocation(), skuPremium, `centralus", "eastus`) - updatedConfigWithNoLocation := testAccAzureRMContainerRegistry_geoReplicationUpdateWithNoLocation(ri, testLocation(), skuPremium) - updatedConfigBasicSku := testAccAzureRMContainerRegistry_geoReplicationUpdateWithNoLocation(ri, testLocation(), skuBasic) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -274,68 +273,134 @@ func TestAccAzureRMContainerRegistry_geoReplication(t *testing.T) { Steps: []resource.TestStep{ // first config creates an ACR with locations { - Config: config, + Config: testAccAzureRMContainerRegistry_geoReplication(ri, testLocation(), skuPremium, `eastus", "westus`), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "name", containerRegistryName), - resource.TestCheckResourceAttr(dataSourceName, "resource_group_name", resourceGroupName), - resource.TestCheckResourceAttr(dataSourceName, "sku", skuPremium), - resource.TestCheckResourceAttr(dataSourceName, "georeplication_locations.#", "2"), - testCheckAzureRMContainerRegistryExists(dataSourceName), - testCheckAzureRMContainerRegistryGeoreplications(dataSourceName, skuPremium, []string{`"eastus"`, `"westus"`}), + resource.TestCheckResourceAttr(dsn, "name", containerRegistryName), + resource.TestCheckResourceAttr(dsn, "resource_group_name", resourceGroupName), + resource.TestCheckResourceAttr(dsn, "sku", skuPremium), + resource.TestCheckResourceAttr(dsn, "georeplication_locations.#", "2"), + testCheckAzureRMContainerRegistryExists(dsn), + testCheckAzureRMContainerRegistryGeoreplications(dsn, skuPremium, []string{`"eastus"`, `"westus"`}), ), }, // second config udpates the ACR with updated locations { - Config: updatedConfig, + Config: testAccAzureRMContainerRegistry_geoReplication(ri, testLocation(), skuPremium, `centralus", "eastus`), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "name", containerRegistryName), - resource.TestCheckResourceAttr(dataSourceName, "resource_group_name", resourceGroupName), - resource.TestCheckResourceAttr(dataSourceName, "sku", skuPremium), - resource.TestCheckResourceAttr(dataSourceName, "georeplication_locations.#", "2"), - testCheckAzureRMContainerRegistryExists(dataSourceName), - testCheckAzureRMContainerRegistryGeoreplications(dataSourceName, skuPremium, []string{`"eastus"`, `"centralus"`}), + resource.TestCheckResourceAttr(dsn, "name", containerRegistryName), + resource.TestCheckResourceAttr(dsn, "resource_group_name", resourceGroupName), + resource.TestCheckResourceAttr(dsn, "sku", skuPremium), + resource.TestCheckResourceAttr(dsn, "georeplication_locations.#", "2"), + testCheckAzureRMContainerRegistryExists(dsn), + testCheckAzureRMContainerRegistryGeoreplications(dsn, skuPremium, []string{`"eastus"`, `"centralus"`}), ), }, // third config udpates the ACR with no location { - Config: updatedConfigWithNoLocation, + Config: testAccAzureRMContainerRegistry_geoReplicationUpdateWithNoLocation(ri, testLocation(), skuPremium), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "name", containerRegistryName), - resource.TestCheckResourceAttr(dataSourceName, "resource_group_name", resourceGroupName), - resource.TestCheckResourceAttr(dataSourceName, "sku", skuPremium), - testCheckAzureRMContainerRegistryExists(dataSourceName), - testCheckAzureRMContainerRegistryGeoreplications(dataSourceName, skuPremium, nil), + resource.TestCheckResourceAttr(dsn, "name", containerRegistryName), + resource.TestCheckResourceAttr(dsn, "resource_group_name", resourceGroupName), + resource.TestCheckResourceAttr(dsn, "sku", skuPremium), + testCheckAzureRMContainerRegistryExists(dsn), + testCheckAzureRMContainerRegistryGeoreplications(dsn, skuPremium, nil), ), }, // fourth config updates an ACR with replicas { - Config: config, + Config: testAccAzureRMContainerRegistry_geoReplication(ri, testLocation(), skuPremium, `eastus", "westus`), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "name", containerRegistryName), - resource.TestCheckResourceAttr(dataSourceName, "resource_group_name", resourceGroupName), - resource.TestCheckResourceAttr(dataSourceName, "sku", skuPremium), - resource.TestCheckResourceAttr(dataSourceName, "georeplication_locations.#", "2"), - testCheckAzureRMContainerRegistryExists(dataSourceName), - testCheckAzureRMContainerRegistryGeoreplications(dataSourceName, skuPremium, []string{`"eastus"`, `"westus"`}), + resource.TestCheckResourceAttr(dsn, "name", containerRegistryName), + resource.TestCheckResourceAttr(dsn, "resource_group_name", resourceGroupName), + resource.TestCheckResourceAttr(dsn, "sku", skuPremium), + resource.TestCheckResourceAttr(dsn, "georeplication_locations.#", "2"), + testCheckAzureRMContainerRegistryExists(dsn), + testCheckAzureRMContainerRegistryGeoreplications(dsn, skuPremium, []string{`"eastus"`, `"westus"`}), ), }, // fifth config updates the SKU to basic and no replicas (should remove the existing replicas if any) { - Config: updatedConfigBasicSku, + Config: testAccAzureRMContainerRegistry_geoReplicationUpdateWithNoLocation_basic(ri, testLocation()), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "name", containerRegistryName), - resource.TestCheckResourceAttr(dataSourceName, "resource_group_name", resourceGroupName), - resource.TestCheckResourceAttr(dataSourceName, "sku", skuBasic), - testCheckAzureRMContainerRegistryExists(dataSourceName), - testCheckAzureRMContainerRegistryGeoreplications(dataSourceName, skuBasic, nil), + resource.TestCheckResourceAttr(dsn, "name", containerRegistryName), + resource.TestCheckResourceAttr(dsn, "resource_group_name", resourceGroupName), + resource.TestCheckResourceAttr(dsn, "sku", skuBasic), + testCheckAzureRMContainerRegistryExists(dsn), + testCheckAzureRMContainerRegistryGeoreplications(dsn, skuBasic, nil), ), }, }, }) } +func TestAccAzureRMContainerRegistry_networkAccessProfile_ip(t *testing.T) { + rn := "azurerm_container_registry.test" + ri := tf.AccRandTimeInt() + l := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMContainerRegistry_networkAccessProfile_ip(ri, l, "Premium"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryExists(rn), + resource.TestCheckResourceAttr(rn, "network_rule_set.0.default_action", "Allow"), + resource.TestCheckResourceAttr(rn, "network_rule_set.0.ip_rule.#", "1"), + ), + }, + { + ResourceName: rn, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMContainerRegistry_networkAccessProfile_update(t *testing.T) { + rn := "azurerm_container_registry.test" + ri := tf.AccRandTimeInt() + l := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMContainerRegistry_basicManaged(ri, l, "Basic"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryExists(rn), + ), + }, + { + Config: testAccAzureRMContainerRegistry_networkAccessProfile_ip(ri, l, "Premium"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryExists(rn), + resource.TestCheckResourceAttr(rn, "network_rule_set.0.default_action", "Allow"), + resource.TestCheckResourceAttr(rn, "network_rule_set.0.ip_rule.#", "1"), + ), + }, + { + Config: testAccAzureRMContainerRegistry_basic_basic(ri, l), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryExists(rn), + ), + }, + { + ResourceName: rn, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMContainerRegistryDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).containerRegistryClient + conn := testAccProvider.Meta().(*ArmClient).containers.RegistriesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -373,7 +438,7 @@ func testCheckAzureRMContainerRegistryExists(resourceName string) resource.TestC return fmt.Errorf("Bad: no resource group found in state for Container Registry: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).containerRegistryClient + conn := testAccProvider.Meta().(*ArmClient).containers.RegistriesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) @@ -403,7 +468,7 @@ func testCheckAzureRMContainerRegistryGeoreplications(resourceName string, sku s return fmt.Errorf("Bad: no resource group found in state for Container Registry: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).containerRegistryReplicationsClient + conn := testAccProvider.Meta().(*ArmClient).containers.ReplicationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.List(ctx, resourceGroup, name) @@ -429,6 +494,26 @@ func testCheckAzureRMContainerRegistryGeoreplications(resourceName string, sku s } } +func testAccAzureRMContainerRegistry_basic_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRg-%d" + location = "%s" +} + +resource "azurerm_container_registry" "test" { + name = "testacccr%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + sku = "Basic" + + # make sure network_rule_set is empty for basic SKU + # premiuim SKU will automaticcally populate network_rule_set.default_action to allow + network_rule_set = [] +} +`, rInt, location, rInt) +} + func testAccAzureRMContainerRegistry_basicManaged(rInt int, location string, sku string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -455,6 +540,7 @@ resource "azurerm_container_registry" "import" { resource_group_name = "${azurerm_container_registry.test.resource_group_name}" location = "${azurerm_container_registry.test.location}" sku = "${azurerm_container_registry.test.sku}" + } `, template) } @@ -533,3 +619,49 @@ resource "azurerm_container_registry" "test" { } `, rInt, location, rInt, sku) } + +func testAccAzureRMContainerRegistry_geoReplicationUpdateWithNoLocation_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "testAccRg-%d" + location = "%s" +} + +resource "azurerm_container_registry" "test" { + name = "testacccr%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + sku = "Basic" + + # make sure network_rule_set is empty for basic SKU + # premiuim SKU will automaticcally populate network_rule_set.default_action to allow + network_rule_set = [] +} +`, rInt, location, rInt) +} + +func testAccAzureRMContainerRegistry_networkAccessProfile_ip(rInt int, location string, sku string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "testAccRg-%[1]d" + location = "%[2]s" +} + +resource "azurerm_container_registry" "test" { + name = "testAccCr%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + sku = "%[3]s" + admin_enabled = false + + network_rule_set { + default_action = "Allow" + + ip_rule { + action = "Allow" + ip_range = "8.8.8.8/32" + } + } +} +`, rInt, location, sku) +} diff --git a/azurerm/resource_arm_container_registry_webhook.go b/azurerm/resource_arm_container_registry_webhook.go new file mode 100644 index 000000000000..b8846f2cd734 --- /dev/null +++ b/azurerm/resource_arm_container_registry_webhook.go @@ -0,0 +1,350 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2018-09-01/containerregistry" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmContainerRegistryWebhook() *schema.Resource { + return &schema.Resource{ + Create: resourceArmContainerRegistryWebhookCreate, + Read: resourceArmContainerRegistryWebhookRead, + Update: resourceArmContainerRegistryWebhookUpdate, + Delete: resourceArmContainerRegistryWebhookDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMContainerRegistryWebhookName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "registry_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMContainerRegistryName, + }, + + "service_uri": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateAzureRMContainerRegistryWebhookServiceUri, + }, + + "custom_headers": { + Type: schema.TypeMap, + Optional: true, + }, + + "status": { + Type: schema.TypeString, + Optional: true, + Default: containerregistry.WebhookStatusEnabled, + ValidateFunc: validation.StringInSlice([]string{ + string(containerregistry.WebhookStatusDisabled), + string(containerregistry.WebhookStatusEnabled), + }, false), + }, + + "scope": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + + "actions": { + Type: schema.TypeSet, + Required: true, + MinItems: 1, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(containerregistry.ChartDelete), + string(containerregistry.ChartPush), + string(containerregistry.Delete), + string(containerregistry.Push), + string(containerregistry.Quarantine), + }, false), + }, + }, + + "location": azure.SchemaLocation(), + + "tags": tags.Schema(), + }, + } +} + +func resourceArmContainerRegistryWebhookCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).containers.WebhooksClient + ctx := meta.(*ArmClient).StopContext + log.Printf("[INFO] preparing arguments for AzureRM Container Registry Webhook creation.") + + resourceGroup := d.Get("resource_group_name").(string) + registryName := d.Get("registry_name").(string) + name := d.Get("name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, registryName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Container Registry Webhook %q (Resource Group %q, Registry %q): %s", name, resourceGroup, registryName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_container_registry_webhook", *existing.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) + + webhook := containerregistry.WebhookCreateParameters{ + Location: &location, + WebhookPropertiesCreateParameters: expandWebhookPropertiesCreateParameters(d), + Tags: tags.Expand(t), + } + + future, err := client.Create(ctx, resourceGroup, registryName, name, webhook) + if err != nil { + return fmt.Errorf("Error creating Container Registry Webhook %q (Resource Group %q, Registry %q): %+v", name, resourceGroup, registryName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of Container Registry %q (Resource Group %q, Registry %q): %+v", name, resourceGroup, registryName, err) + } + + read, err := client.Get(ctx, resourceGroup, registryName, name) + if err != nil { + return fmt.Errorf("Error retrieving Container Registry %q (Resource Group %q, Registry %q): %+v", name, resourceGroup, registryName, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read Container Registry %q (resource group %q, Registry %q) ID", name, resourceGroup, registryName) + } + + d.SetId(*read.ID) + + return resourceArmContainerRegistryWebhookRead(d, meta) +} + +func resourceArmContainerRegistryWebhookUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).containers.WebhooksClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for AzureRM Container Registry Webhook update.") + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + registryName := id.Path["registries"] + name := id.Path["webhooks"] + + t := d.Get("tags").(map[string]interface{}) + + webhook := containerregistry.WebhookUpdateParameters{ + WebhookPropertiesUpdateParameters: expandWebhookPropertiesUpdateParameters(d), + Tags: tags.Expand(t), + } + + future, err := client.Update(ctx, resourceGroup, registryName, name, webhook) + if err != nil { + return fmt.Errorf("Error updating Container Registry Webhook %q (Resource Group %q, Registry %q): %+v", name, resourceGroup, registryName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Container Registry Webhook %q (Resource Group %q, Registry %q): %+v", name, resourceGroup, registryName, err) + } + + return resourceArmContainerRegistryWebhookRead(d, meta) +} + +func resourceArmContainerRegistryWebhookRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).containers.WebhooksClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + registryName := id.Path["registries"] + name := id.Path["webhooks"] + + resp, err := client.Get(ctx, resourceGroup, registryName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Container Registry Webhook %q was not found in Resource Group %q for Registry %q", name, resourceGroup, registryName) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Azure Container Registry Webhook %q (Resource Group %q, Registry %q): %+v", name, resourceGroup, registryName, err) + } + + callbackConfig, err := client.GetCallbackConfig(ctx, resourceGroup, registryName, name) + if err != nil { + return fmt.Errorf("Error making Read request on Azure Container Registry Webhook Callback Config %q (Resource Group %q, Registry %q): %+v", name, resourceGroup, registryName, err) + } + + d.Set("resource_group_name", resourceGroup) + d.Set("registry_name", registryName) + d.Set("name", name) + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + d.Set("service_uri", callbackConfig.ServiceURI) + + if callbackConfig.CustomHeaders != nil { + customHeaders := make(map[string]string) + for k, v := range callbackConfig.CustomHeaders { + customHeaders[k] = *v + } + d.Set("custom_headers", customHeaders) + } + + if webhookProps := resp.WebhookProperties; webhookProps != nil { + if webhookProps.Status != "" { + d.Set("status", string(webhookProps.Status)) + } + + if webhookProps.Scope != nil { + d.Set("scope", webhookProps.Scope) + } + + webhookActions := make([]string, len(*webhookProps.Actions)) + for i, action := range *webhookProps.Actions { + webhookActions[i] = string(action) + } + d.Set("actions", webhookActions) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmContainerRegistryWebhookDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).containers.WebhooksClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + registryName := id.Path["registries"] + name := id.Path["webhooks"] + + future, err := client.Delete(ctx, resourceGroup, registryName, name) + if err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + return fmt.Errorf("Error issuing Azure ARM delete request of Container Registry Webhook '%s': %+v", name, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + return fmt.Errorf("Error issuing Azure ARM delete request of Container Registry Webhook '%s': %+v", name, err) + } + + return nil +} + +func validateAzureRMContainerRegistryWebhookName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + if !regexp.MustCompile(`^[a-zA-Z0-9]{5,50}$`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "alpha numeric characters only are allowed and between 5 and 50 characters in %q: %q", k, value)) + } + + return warnings, errors +} + +func validateAzureRMContainerRegistryWebhookServiceUri(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + if !regexp.MustCompile(`^https?://[^\s]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q must start with http:// or https:// and must not contain whitespaces: %q", k, value)) + } + + return warnings, errors +} + +func expandWebhookPropertiesCreateParameters(d *schema.ResourceData) *containerregistry.WebhookPropertiesCreateParameters { + serviceUri := d.Get("service_uri").(string) + scope := d.Get("scope").(string) + + customHeaders := make(map[string]*string) + for k, v := range d.Get("custom_headers").(map[string]interface{}) { + customHeaders[k] = utils.String(v.(string)) + } + + actions := expandWebhookActions(d) + + webhookProperties := containerregistry.WebhookPropertiesCreateParameters{ + ServiceURI: &serviceUri, + CustomHeaders: customHeaders, + Actions: actions, + Scope: &scope, + } + + webhookProperties.Status = containerregistry.WebhookStatus(d.Get("status").(string)) + + return &webhookProperties +} + +func expandWebhookPropertiesUpdateParameters(d *schema.ResourceData) *containerregistry.WebhookPropertiesUpdateParameters { + serviceUri := d.Get("service_uri").(string) + scope := d.Get("scope").(string) + + customHeaders := make(map[string]*string) + for k, v := range d.Get("custom_headers").(map[string]interface{}) { + customHeaders[k] = utils.String(v.(string)) + } + + webhookProperties := containerregistry.WebhookPropertiesUpdateParameters{ + ServiceURI: &serviceUri, + CustomHeaders: customHeaders, + Actions: expandWebhookActions(d), + Scope: &scope, + Status: containerregistry.WebhookStatus(d.Get("status").(string)), + } + + return &webhookProperties +} + +func expandWebhookActions(d *schema.ResourceData) *[]containerregistry.WebhookAction { + actions := make([]containerregistry.WebhookAction, 0) + for _, action := range d.Get("actions").(*schema.Set).List() { + actions = append(actions, containerregistry.WebhookAction(action.(string))) + } + + return &actions +} diff --git a/azurerm/resource_arm_container_registry_webhook_test.go b/azurerm/resource_arm_container_registry_webhook_test.go new file mode 100644 index 000000000000..65454369f0d9 --- /dev/null +++ b/azurerm/resource_arm_container_registry_webhook_test.go @@ -0,0 +1,685 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMContainerRegistryWebhook_basic(t *testing.T) { + resourceName := "azurerm_container_registry_webhook.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMContainerRegistryWebhook_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMContainerRegistryWebhook_withTags(t *testing.T) { + resourceName := "azurerm_container_registry_webhook.test" + ri := tf.AccRandTimeInt() + preConfig := testAccAzureRMContainerRegistryWebhook_withTags(ri, testLocation()) + postConfig := testAccAzureRMContainerRegistryWebhook_withTagsUpdate(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.label", "test"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.label", "test1"), + resource.TestCheckResourceAttr(resourceName, "tags.ENV", "prod"), + ), + }, + }, + }) +} + +func TestAccAzureRMContainerRegistryWebhook_actions(t *testing.T) { + resourceName := "azurerm_container_registry_webhook.test" + ri := tf.AccRandTimeInt() + preConfig := testAccAzureRMContainerRegistryWebhook_actions(ri, testLocation()) + postConfig := testAccAzureRMContainerRegistryWebhook_actionsUpdate(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: postConfig, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMContainerRegistryWebhook_status(t *testing.T) { + resourceName := "azurerm_container_registry_webhook.test" + ri := tf.AccRandTimeInt() + preConfig := testAccAzureRMContainerRegistryWebhook_status(ri, testLocation()) + postConfig := testAccAzureRMContainerRegistryWebhook_statusUpdate(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "status", "enabled"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "status", "disabled"), + ), + }, + }, + }) +} + +func TestAccAzureRMContainerRegistryWebhook_serviceUri(t *testing.T) { + resourceName := "azurerm_container_registry_webhook.test" + ri := tf.AccRandTimeInt() + preConfig := testAccAzureRMContainerRegistryWebhook_serviceUri(ri, testLocation()) + postConfig := testAccAzureRMContainerRegistryWebhook_serviceUriUpdate(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "service_uri", "https://mywebhookreceiver.example/mytag"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "service_uri", "https://my.webhookreceiver.example/mytag/2"), + ), + }, + }, + }) +} + +func TestAccAzureRMContainerRegistryWebhook_scope(t *testing.T) { + resourceName := "azurerm_container_registry_webhook.test" + ri := tf.AccRandTimeInt() + preConfig := testAccAzureRMContainerRegistryWebhook_scope(ri, testLocation()) + postConfig := testAccAzureRMContainerRegistryWebhook_scopeUpdate(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "scope", "mytag:*"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "scope", "mytag:4"), + ), + }, + }, + }) +} + +func TestAccAzureRMContainerRegistryWebhook_customHeaders(t *testing.T) { + resourceName := "azurerm_container_registry_webhook.test" + ri := tf.AccRandTimeInt() + preConfig := testAccAzureRMContainerRegistryWebhook_customHeaders(ri, testLocation()) + postConfig := testAccAzureRMContainerRegistryWebhook_customHeadersUpdate(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerRegistryWebhookDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "custom_headers.%", "1"), + resource.TestCheckResourceAttr(resourceName, "custom_headers.Content-Type", "application/json"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerRegistryWebhookExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "custom_headers.%", "2"), + resource.TestCheckResourceAttr(resourceName, "custom_headers.Content-Type", "application/xml"), + resource.TestCheckResourceAttr(resourceName, "custom_headers.Accept-Charset", "utf-8"), + ), + }, + }, + }) +} + +func testAccAzureRMContainerRegistryWebhook_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_withTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + actions = [ + "push" + ] + + tags = { + label = "test" + } +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_withTagsUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + actions = [ + "push" + ] + + tags = { + label = "test1" + ENV = "prod" + } +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_actions(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_actionsUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + actions = [ + "push", + "delete" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_status(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + status = "enabled" + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_statusUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + status = "disabled" + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_serviceUri(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_serviceUriUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://my.webhookreceiver.example/mytag/2" + + status = "disabled" + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_scope(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + scope = "mytag:*" + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_scopeUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + scope = "mytag:4" + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_customHeaders(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + custom_headers = { + "Content-Type" = "application/json" + } + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testAccAzureRMContainerRegistryWebhook_customHeadersUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "rg" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_container_registry" "acr" { + name = "acrwebhooktest%d" + resource_group_name = azurerm_resource_group.rg.name + location = "%s" + sku = "Standard" +} + +resource "azurerm_container_registry_webhook" "test" { + name = "testwebhook%d" + resource_group_name = azurerm_resource_group.rg.name + registry_name = azurerm_container_registry.acr.name + location = "%s" + + service_uri = "https://mywebhookreceiver.example/mytag" + + custom_headers = { + "Content-Type" = "application/xml" + "Accept-Charset" = "utf-8" + } + + actions = [ + "push" + ] +} +`, rInt, location, rInt, location, rInt, location) +} + +func testCheckAzureRMContainerRegistryWebhookDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).containers.WebhooksClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_container_registry_webhook" { + continue + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + registryName := rs.Primary.Attributes["registry_name"] + name := rs.Primary.Attributes["name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, registryName, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMContainerRegistryWebhookExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + webhookName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Container Registry Webhook: %s", webhookName) + } + + registryName, hasRegistryName := rs.Primary.Attributes["registry_name"] + if !hasRegistryName { + return fmt.Errorf("Bad: no registry name found in state for Container Registry Webhook: %s", webhookName) + } + + client := testAccProvider.Meta().(*ArmClient).containers.WebhooksClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, registryName, webhookName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Container Registry Webhook %q (resource group: %q) does not exist", webhookName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on WebhooksClient: %+v", err) + } + + return nil + } +} diff --git a/azurerm/resource_arm_container_service.go b/azurerm/resource_arm_container_service.go index 92a5e6c9b96c..e9208788d040 100644 --- a/azurerm/resource_arm_container_service.go +++ b/azurerm/resource_arm_container_service.go @@ -8,11 +8,15 @@ import ( "bytes" - "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2018-03-31/containerservice" + "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2019-06-01/containerservice" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -39,9 +43,9 @@ More information can be found here: https://azure.microsoft.com/en-us/updates/az ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "orchestration_platform": { Type: schema.TypeString, @@ -138,7 +142,7 @@ More information can be found here: https://azure.microsoft.com/en-us/updates/az "vm_size": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, }, @@ -186,7 +190,7 @@ More information can be found here: https://azure.microsoft.com/en-us/updates/az Set: resourceAzureRMContainerServiceDiagnosticProfilesHash, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } @@ -194,14 +198,14 @@ More information can be found here: https://azure.microsoft.com/en-us/updates/az func resourceArmContainerServiceCreateUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) ctx := meta.(*ArmClient).StopContext - containerServiceClient := client.containerServicesClient + containerServiceClient := client.containers.ServicesClient log.Printf("[INFO] preparing arguments for Azure ARM Container Service creation.") resGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := containerServiceClient.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -214,7 +218,7 @@ func resourceArmContainerServiceCreateUpdate(d *schema.ResourceData, meta interf } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) orchestrationPlatform := d.Get("orchestration_platform").(string) @@ -223,7 +227,7 @@ func resourceArmContainerServiceCreateUpdate(d *schema.ResourceData, meta interf agentProfiles := expandAzureRmContainerServiceAgentProfiles(d) diagnosticsProfile := expandAzureRmContainerServiceDiagnostics(d) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := containerservice.ContainerService{ Name: &name, @@ -237,7 +241,7 @@ func resourceArmContainerServiceCreateUpdate(d *schema.ResourceData, meta interf AgentPoolProfiles: &agentProfiles, DiagnosticsProfile: &diagnosticsProfile, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } servicePrincipalProfile := expandAzureRmContainerServiceServicePrincipal(d) @@ -276,9 +280,9 @@ func resourceArmContainerServiceCreateUpdate(d *schema.ResourceData, meta interf } func resourceArmContainerServiceRead(d *schema.ResourceData, meta interface{}) error { - containerServiceClient := meta.(*ArmClient).containerServicesClient + containerServiceClient := meta.(*ArmClient).containers.ServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -299,7 +303,7 @@ func resourceArmContainerServiceRead(d *schema.ResourceData, meta interface{}) e d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("orchestration_platform", string(resp.Properties.OrchestratorProfile.OrchestratorType)) @@ -323,16 +327,14 @@ func resourceArmContainerServiceRead(d *schema.ResourceData, meta interface{}) e d.Set("diagnostics_profile", diagnosticProfile) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmContainerServiceDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) - containerServiceClient := client.containerServicesClient + containerServiceClient := client.containers.ServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -548,7 +550,7 @@ func expandAzureRmContainerServiceAgentProfiles(d *schema.ResourceData) []contai func containerServiceStateRefreshFunc(client *ArmClient, resourceGroupName string, containerServiceName string) resource.StateRefreshFunc { return func() (interface{}, string, error) { ctx := client.StopContext - res, err := client.containerServicesClient.Get(ctx, resourceGroupName, containerServiceName) + res, err := client.containers.ServicesClient.Get(ctx, resourceGroupName, containerServiceName) if err != nil { return nil, "", fmt.Errorf("Error issuing read request in containerServiceStateRefreshFunc to Azure ARM for Container Service '%s' (RG: '%s'): %s", containerServiceName, resourceGroupName, err) } diff --git a/azurerm/resource_arm_container_service_test.go b/azurerm/resource_arm_container_service_test.go index 82b5f92c1f77..814cb8011e23 100644 --- a/azurerm/resource_arm_container_service_test.go +++ b/azurerm/resource_arm_container_service_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMContainerService_orchestrationPlatformValidation(t *testing.T) { @@ -96,7 +97,7 @@ func TestAccAzureRMContainerService_dcosBasic(t *testing.T) { } func TestAccAzureRMContainerService_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -410,7 +411,7 @@ func testCheckAzureRMContainerServiceExists(resourceName string) resource.TestCh return fmt.Errorf("Bad: no resource group found in state for Container Service Instance: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).containerServicesClient + conn := testAccProvider.Meta().(*ArmClient).containers.ServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) @@ -427,7 +428,7 @@ func testCheckAzureRMContainerServiceExists(resourceName string) resource.TestCh } func testCheckAzureRMContainerServiceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).containerServicesClient + conn := testAccProvider.Meta().(*ArmClient).containers.ServicesClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_container_service" { diff --git a/azurerm/resource_arm_cosmos_db_account.go b/azurerm/resource_arm_cosmos_db_account.go deleted file mode 100644 index 41704b418ba4..000000000000 --- a/azurerm/resource_arm_cosmos_db_account.go +++ /dev/null @@ -1,1070 +0,0 @@ -package azurerm - -import ( - "bytes" - "context" - "fmt" - "log" - "regexp" - "strings" - "time" - - "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" - - "github.com/hashicorp/terraform/helper/hashcode" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/helper/validation" - - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" -) - -func resourceArmCosmosDBAccount() *schema.Resource { - return &schema.Resource{ - Create: resourceArmCosmosDBAccountCreate, - Read: resourceArmCosmosDBAccountRead, - Update: resourceArmCosmosDBAccountUpdate, - Delete: resourceArmCosmosDBAccountDelete, - Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, - }, - - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringMatch( - regexp.MustCompile("^[-a-z0-9]{3,50}$"), - "Cosmos DB Account name must be 3 - 50 characters long, contain only letters, numbers and hyphens.", - ), - }, - - "location": locationSchema(), - - "resource_group_name": resourceGroupNameSchema(), - - "tags": tagsSchema(), - - //resource fields - "offer_type": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, - ValidateFunc: validation.StringInSlice([]string{ - string(documentdb.Standard), - }, true), - }, - - "kind": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Default: string(documentdb.GlobalDocumentDB), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, - ValidateFunc: validation.StringInSlice([]string{ - string(documentdb.GlobalDocumentDB), - string(documentdb.MongoDB), - }, true), - }, - - "ip_range_filter": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringMatch( - regexp.MustCompile(`^(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\/([1-2][0-9]|3[0-2]))?\b[,]?)*$`), - "Cosmos DB ip_range_filter must be a set of CIDR IP addresses separated by commas with no spaces: '10.0.0.1,10.0.0.2,10.20.0.0/16'", - ), - }, - - "enable_automatic_failover": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - - "consistency_policy": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "consistency_level": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, - ValidateFunc: validation.StringInSlice([]string{ - string(documentdb.BoundedStaleness), - string(documentdb.ConsistentPrefix), - string(documentdb.Eventual), - string(documentdb.Session), - string(documentdb.Strong), - }, true), - }, - - "max_interval_in_seconds": { - Type: schema.TypeInt, - Optional: true, - Default: 5, - ValidateFunc: validation.IntBetween(5, 86400), - }, - - "max_staleness_prefix": { - Type: schema.TypeInt, - Optional: true, - Default: 100, - ValidateFunc: validation.IntBetween(10, 2147483647), - }, - }, - }, - }, - - // this actually maps to the Location field in the API/SDK on create/update so has been renamed - // failover_policy is just the name of the field we get back from the API on a read - "failover_policy": { - Type: schema.TypeSet, - Optional: true, - Deprecated: "This field has been renamed to 'geo_location' to match Azure's usage", - ConflictsWith: []string{"geo_location"}, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - - "location": { - Type: schema.TypeString, - Required: true, - StateFunc: azureRMNormalizeLocation, - DiffSuppressFunc: azureRMSuppressLocationDiff, - }, - - "priority": { - Type: schema.TypeInt, - Required: true, - }, - }, - }, - Set: resourceAzureRMCosmosDBAccountFailoverPolicyHash, - }, - - "geo_location": { - Type: schema.TypeSet, - //Required: true, //todo needs to be required when failover_policy is removed - Optional: true, - Computed: true, - ConflictsWith: []string{"failover_policy"}, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - - "prefix": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringMatch( - regexp.MustCompile("^[-a-z0-9]{3,50}$"), - "Cosmos DB location prefix (ID) must be 3 - 50 characters long, contain only letters, numbers and hyphens.", - ), - }, - - "id": { - Type: schema.TypeString, - Computed: true, - }, - - "location": locationSchema(), - - "failover_priority": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(0), - }, - }, - }, - Set: resourceAzureRMCosmosDBAccountGeoLocationHash, - }, - - "capabilities": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, - ValidateFunc: validation.StringInSlice([]string{ - "EnableTable", - "EnableGremlin", - "EnableCassandra", - "EnableAggregationPipeline", - "MongoDBv3.4", - "mongoEnableDocLevelTTL", - }, true), - }, - }, - }, - Set: resourceAzureRMCosmosDBAccountCapabilitiesHash, - }, - - "is_virtual_network_filter_enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - - "virtual_network_rule": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Required: true, - ValidateFunc: azure.ValidateResourceID, - }, - }, - }, - Set: resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash, - }, - - "enable_multiple_write_locations": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - - //computed - "endpoint": { - Type: schema.TypeString, - Computed: true, - }, - - "read_endpoints": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - - "write_endpoints": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - - "primary_master_key": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, - - "secondary_master_key": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, - - "primary_readonly_master_key": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, - - "secondary_readonly_master_key": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, - - "connection_strings": { - Type: schema.TypeList, - Computed: true, - Sensitive: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - } -} - -func resourceArmCosmosDBAccountCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).cosmosDBClient - ctx := meta.(*ArmClient).StopContext - log.Printf("[INFO] preparing arguments for AzureRM Cosmos DB Account creation.") - - name := d.Get("name").(string) - resourceGroup := d.Get("resource_group_name").(string) - - if requireResourcesToBeImported && d.IsNewResource() { - existing, err := client.Get(ctx, resourceGroup, name) - if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of existing CosmosDB Account %q (Resource Group %q): %s", name, resourceGroup, err) - } - } - - if existing.ID != nil && *existing.ID != "" { - return tf.ImportAsExistsError("azurerm_cosmosdb_account", *existing.ID) - } - } - - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) - kind := d.Get("kind").(string) - offerType := d.Get("offer_type").(string) - ipRangeFilter := d.Get("ip_range_filter").(string) - isVirtualNetworkFilterEnabled := d.Get("is_virtual_network_filter_enabled").(bool) - enableAutomaticFailover := d.Get("enable_automatic_failover").(bool) - enableMultipleWriteLocations := d.Get("enable_multiple_write_locations").(bool) - - r, err := client.CheckNameExists(ctx, name) - if err != nil { - return fmt.Errorf("Error checking if CosmosDB Account %q already exists (Resource Group %q): %+v", name, resourceGroup, err) - } - if !utils.ResponseWasNotFound(r) { - return fmt.Errorf("CosmosDB Account %s already exists, please import the resource via terraform import", name) - } - - //hacky, todo fix up once deprecated field 'failover_policy' is removed - var geoLocations []documentdb.Location - if _, ok := d.GetOk("geo_location"); ok { - geoLocations, err = expandAzureRmCosmosDBAccountGeoLocations(name, d) - if err != nil { - return fmt.Errorf("Error expanding CosmosDB Account %q (Resource Group %q) geo locations: %+v", name, resourceGroup, err) - } - } else if _, ok := d.GetOk("failover_policy"); ok { - geoLocations, err = expandAzureRmCosmosDBAccountFailoverPolicy(name, d) - if err != nil { - return fmt.Errorf("Error expanding CosmosDB Account %q (Resource Group %q) failover_policy: %+v", name, resourceGroup, err) - } - } else { - //could be a CustomizeDiff?, but this is temporary - return fmt.Errorf("Neither `geo_location` or `failover_policy` is set for CosmosDB Account %s", name) - } - - account := documentdb.DatabaseAccountCreateUpdateParameters{ - Location: utils.String(location), - Kind: documentdb.DatabaseAccountKind(kind), - DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{ - DatabaseAccountOfferType: utils.String(offerType), - IPRangeFilter: utils.String(ipRangeFilter), - IsVirtualNetworkFilterEnabled: utils.Bool(isVirtualNetworkFilterEnabled), - EnableAutomaticFailover: utils.Bool(enableAutomaticFailover), - ConsistencyPolicy: expandAzureRmCosmosDBAccountConsistencyPolicy(d), - Locations: &geoLocations, - Capabilities: expandAzureRmCosmosDBAccountCapabilities(d), - VirtualNetworkRules: expandAzureRmCosmosDBAccountVirtualNetworkRules(d), - EnableMultipleWriteLocations: utils.Bool(enableMultipleWriteLocations), - }, - Tags: expandTags(tags), - } - - resp, err := resourceArmCosmosDBAccountApiUpsert(client, ctx, resourceGroup, name, account) - if err != nil { - return fmt.Errorf("Error creating CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) - } - - //for some reason capabilities doesn't always work on create, so lets patch it - //tracked: https://github.com/Azure/azure-sdk-for-go/issues/2864 - future, err := client.Patch(ctx, resourceGroup, name, documentdb.DatabaseAccountPatchParameters{ - DatabaseAccountPatchProperties: &documentdb.DatabaseAccountPatchProperties{ - Capabilities: account.Capabilities, - }, - }) - if err != nil { - return fmt.Errorf("Error Patching CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) - } - - if err := future.WaitForCompletionRef(context.Background(), client.Client); err != nil { - return fmt.Errorf("Error waiting on patch future CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) - } - - id := resp.ID - if id == nil { - return fmt.Errorf("Cannot read CosmosDB Account '%s' (resource group %s) ID", name, resourceGroup) - } - - d.SetId(*id) - - return resourceArmCosmosDBAccountRead(d, meta) -} - -func resourceArmCosmosDBAccountUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).cosmosDBClient - ctx := meta.(*ArmClient).StopContext - log.Printf("[INFO] preparing arguments for AzureRM Cosmos DB Account update.") - - //move to function - name := d.Get("name").(string) - location := d.Get("location").(string) - resourceGroup := d.Get("resource_group_name").(string) - tags := d.Get("tags").(map[string]interface{}) - - kind := d.Get("kind").(string) - offerType := d.Get("offer_type").(string) - ipRangeFilter := d.Get("ip_range_filter").(string) - isVirtualNetworkFilterEnabled := d.Get("is_virtual_network_filter_enabled").(bool) - enableAutomaticFailover := d.Get("enable_automatic_failover").(bool) - enableMultipleWriteLocations := d.Get("enable_multiple_write_locations").(bool) - - //hacky, todo fix up once deprecated field 'failover_policy' is removed - var newLocations []documentdb.Location - var err error - if _, ok := d.GetOk("geo_location"); ok { - newLocations, err = expandAzureRmCosmosDBAccountGeoLocations(name, d) - if err != nil { - return fmt.Errorf("Error expanding CosmosDB Account %q (Resource Group %q) geo locations: %+v", name, resourceGroup, err) - } - } else if _, ok := d.GetOk("failover_policy"); ok { - newLocations, err = expandAzureRmCosmosDBAccountFailoverPolicy(name, d) - if err != nil { - return fmt.Errorf("Error expanding CosmosDB Account %q (Resource Group %q) failover_policy: %+v", name, resourceGroup, err) - } - } else { - //could be a CustomizeDiff?, but this is temporary - return fmt.Errorf("Neither `geo_location` or `failover_policy` is set for CosmosDB Account '%s'", name) - } - - //get existing locations (if exists) - resp, err := client.Get(ctx, resourceGroup, name) - if err != nil { - return fmt.Errorf("Error making Read request on AzureRM CosmosDB Account '%s': %s", name, err) - } - - oldLocations := make([]documentdb.Location, 0) - oldLocationsMap := map[string]documentdb.Location{} - for _, l := range *resp.FailoverPolicies { - location := documentdb.Location{ - ID: l.ID, - LocationName: l.LocationName, - FailoverPriority: l.FailoverPriority, - } - - oldLocations = append(oldLocations, location) - oldLocationsMap[azureRMNormalizeLocation(*location.LocationName)] = location - } - - //cannot update properties and add/remove replication locations at the same time - //so first just update any changed properties - account := documentdb.DatabaseAccountCreateUpdateParameters{ - Location: utils.String(location), - Kind: documentdb.DatabaseAccountKind(kind), - DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{ - DatabaseAccountOfferType: utils.String(offerType), - IPRangeFilter: utils.String(ipRangeFilter), - IsVirtualNetworkFilterEnabled: utils.Bool(isVirtualNetworkFilterEnabled), - EnableAutomaticFailover: utils.Bool(enableAutomaticFailover), - Capabilities: expandAzureRmCosmosDBAccountCapabilities(d), - ConsistencyPolicy: expandAzureRmCosmosDBAccountConsistencyPolicy(d), - Locations: &oldLocations, - VirtualNetworkRules: expandAzureRmCosmosDBAccountVirtualNetworkRules(d), - EnableMultipleWriteLocations: utils.Bool(enableMultipleWriteLocations), - }, - Tags: expandTags(tags), - } - - if _, err = resourceArmCosmosDBAccountApiUpsert(client, ctx, resourceGroup, name, account); err != nil { - return fmt.Errorf("Error updating CosmosDB Account %q properties (Resource Group %q): %+v", name, resourceGroup, err) - } - - //determine if any locations have been renamed/priority reordered and remove them - removedOne := false - for _, l := range newLocations { - if ol, ok := oldLocationsMap[*l.LocationName]; ok { - if *l.FailoverPriority != *ol.FailoverPriority { - if *l.FailoverPriority == 0 { - return fmt.Errorf("Cannot change the failover priority of primary Cosmos DB account %q location %s to %d (Resource Group %q)", name, *l.LocationName, *l.FailoverPriority, resourceGroup) - } - delete(oldLocationsMap, *l.LocationName) - removedOne = true - continue - } - if *l.ID == "" && *ol.ID == resourceArmCosmosDBAccountGenerateDefaultId(name, *l.LocationName) { - continue - } - if *l.ID != *ol.ID { - if *l.FailoverPriority == 0 { - return fmt.Errorf("Cannot change the prefix/ID of the primary Cosmos DB account %q location %s (Resource Group %q)", name, *l.LocationName, resourceGroup) - } - delete(oldLocationsMap, *l.LocationName) - removedOne = true - } - } - - } - - if removedOne { - locationsUnchanged := make([]documentdb.Location, 0, len(oldLocationsMap)) - for _, value := range oldLocationsMap { - locationsUnchanged = append(locationsUnchanged, value) - } - - account.DatabaseAccountCreateUpdateProperties.Locations = &locationsUnchanged - if _, err = resourceArmCosmosDBAccountApiUpsert(client, ctx, resourceGroup, name, account); err != nil { - return fmt.Errorf("Error removing CosmosDB Account %q renamed locations (Resource Group %q): %+v", name, resourceGroup, err) - } - } - - //add any new/renamed locations - account.DatabaseAccountCreateUpdateProperties.Locations = &newLocations - upsertResponse, err := resourceArmCosmosDBAccountApiUpsert(client, ctx, resourceGroup, name, account) - if err != nil { - return fmt.Errorf("Error updating CosmosDB Account %q locations (Resource Group %q): %+v", name, resourceGroup, err) - } - - id := (*upsertResponse).ID - if id == nil { - return fmt.Errorf("Cannot read CosmosDB Account '%s' (resource group %s) ID", name, resourceGroup) - } - - //for some reason capabilities doesn't always work on create, so lets patch it - //tracked: https://github.com/Azure/azure-sdk-for-go/issues/2864 - future, err := client.Patch(ctx, resourceGroup, name, documentdb.DatabaseAccountPatchParameters{ - DatabaseAccountPatchProperties: &documentdb.DatabaseAccountPatchProperties{ - Capabilities: account.Capabilities, - }, - }) - if err != nil { - return fmt.Errorf("Error Patching CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) - } - - if err := future.WaitForCompletionRef(context.Background(), client.Client); err != nil { - return fmt.Errorf("Error waiting on patch future CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) - } - - d.SetId(*id) - - return resourceArmCosmosDBAccountRead(d, meta) -} - -func resourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).cosmosDBClient - ctx := meta.(*ArmClient).StopContext - - id, err := parseAzureResourceID(d.Id()) - if err != nil { - return err - } - - name := id.Path["databaseAccounts"] - resourceGroup := id.ResourceGroup - - resp, err := client.Get(ctx, resourceGroup, name) - if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - d.SetId("") - return nil - } - - return fmt.Errorf("Error making Read request on AzureRM CosmosDB Account '%s': %s", name, err) - } - - d.Set("name", resp.Name) - if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) - } - d.Set("resource_group_name", resourceGroup) - flattenAndSetTags(d, resp.Tags) - - d.Set("kind", string(resp.Kind)) - d.Set("offer_type", string(resp.DatabaseAccountOfferType)) - d.Set("ip_range_filter", resp.IPRangeFilter) - d.Set("endpoint", resp.DocumentEndpoint) - - if v := resp.IsVirtualNetworkFilterEnabled; v != nil { - d.Set("is_virtual_network_filter_enabled", resp.IsVirtualNetworkFilterEnabled) - } - - if v := resp.EnableAutomaticFailover; v != nil { - d.Set("enable_automatic_failover", resp.EnableAutomaticFailover) - } - - if v := resp.EnableMultipleWriteLocations; v != nil { - d.Set("enable_multiple_write_locations", resp.EnableMultipleWriteLocations) - } - - if err = d.Set("consistency_policy", flattenAzureRmCosmosDBAccountConsistencyPolicy(resp.ConsistencyPolicy)); err != nil { - return fmt.Errorf("Error setting CosmosDB Account %q `consistency_policy` (Resource Group %q): %+v", name, resourceGroup, err) - } - if _, ok := d.GetOk("failover_policy"); ok { - if err = d.Set("failover_policy", flattenAzureRmCosmosDBAccountFailoverPolicy(resp.FailoverPolicies)); err != nil { - return fmt.Errorf("Error setting `failover_policy`: %+v", err) - } - } else { - //if failover policy isn't default to using geo_location - if err = d.Set("geo_location", flattenAzureRmCosmosDBAccountGeoLocations(d, resp)); err != nil { - return fmt.Errorf("Error setting `geo_location`: %+v", err) - } - } - - if err = d.Set("capabilities", flattenAzureRmCosmosDBAccountCapabilities(resp.Capabilities)); err != nil { - return fmt.Errorf("Error setting `capabilities`: %+v", err) - } - - if err = d.Set("virtual_network_rule", flattenAzureRmCosmosDBAccountVirtualNetworkRules(resp.VirtualNetworkRules)); err != nil { - return fmt.Errorf("Error setting `virtual_network_rule`: %+v", err) - } - - if p := resp.ReadLocations; p != nil { - readEndpoints := make([]string, 0) - for _, l := range *p { - readEndpoints = append(readEndpoints, *l.DocumentEndpoint) - } - d.Set("read_endpoints", readEndpoints) - } - - if p := resp.WriteLocations; p != nil { - writeEndpoints := make([]string, 0) - for _, l := range *p { - writeEndpoints = append(writeEndpoints, *l.DocumentEndpoint) - } - d.Set("write_endpoints", writeEndpoints) - } - - // ListKeys returns a data structure containing a DatabaseAccountListReadOnlyKeysResult pointer - // implying that it also returns the read only keys, however this appears to not be the case - keys, err := client.ListKeys(ctx, resourceGroup, name) - if err != nil { - if utils.ResponseWasNotFound(keys.Response) { - log.Printf("[DEBUG] Keys were not found for CosmosDB Account %q (Resource Group %q) - removing from state!", name, resourceGroup) - d.SetId("") - return nil - } - - return fmt.Errorf("[ERROR] Unable to List Write keys for CosmosDB Account %s: %s", name, err) - } - d.Set("primary_master_key", keys.PrimaryMasterKey) - d.Set("secondary_master_key", keys.SecondaryMasterKey) - - readonlyKeys, err := client.ListReadOnlyKeys(ctx, resourceGroup, name) - if err != nil { - if utils.ResponseWasNotFound(keys.Response) { - log.Printf("[DEBUG] Read Only Keys were not found for CosmosDB Account %q (Resource Group %q) - removing from state!", name, resourceGroup) - d.SetId("") - return nil - } - - return fmt.Errorf("[ERROR] Unable to List read-only keys for CosmosDB Account %s: %s", name, err) - } - d.Set("primary_readonly_master_key", readonlyKeys.PrimaryReadonlyMasterKey) - d.Set("secondary_readonly_master_key", readonlyKeys.SecondaryReadonlyMasterKey) - - connStringResp, err := client.ListConnectionStrings(ctx, resourceGroup, name) - if err != nil { - if utils.ResponseWasNotFound(keys.Response) { - log.Printf("[DEBUG] Connection Strings were not found for CosmosDB Account %q (Resource Group %q) - removing from state!", name, resourceGroup) - d.SetId("") - return nil - } - - return fmt.Errorf("[ERROR] Unable to List connection strings for CosmosDB Account %s: %s", name, err) - } - - var connStrings []string - if connStringResp.ConnectionStrings != nil { - connStrings = make([]string, len(*connStringResp.ConnectionStrings)) - for i, v := range *connStringResp.ConnectionStrings { - connStrings[i] = *v.ConnectionString - } - - } - d.Set("connection_strings", connStrings) - - return nil -} - -func resourceArmCosmosDBAccountDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).cosmosDBClient - ctx := meta.(*ArmClient).StopContext - - id, err := parseAzureResourceID(d.Id()) - if err != nil { - return err - } - - resourceGroup := id.ResourceGroup - name := id.Path["databaseAccounts"] - - future, err := client.Delete(ctx, resourceGroup, name) - if err != nil { - if response.WasNotFound(future.Response()) { - return nil - } - return fmt.Errorf("Error issuing AzureRM delete request for CosmosDB Account '%s': %+v", name, err) - } - - //the SDK now will return a `WasNotFound` response even when still deleting - stateConf := &resource.StateChangeConf{ - Pending: []string{"Deleting"}, - Target: []string{"NotFound"}, - Timeout: 60 * time.Minute, - MinTimeout: 30 * time.Second, - Refresh: func() (interface{}, string, error) { - - resp, err2 := client.Get(ctx, resourceGroup, name) - if err2 != nil { - - if utils.ResponseWasNotFound(resp.Response) { - return resp, "NotFound", nil - } - return nil, "", fmt.Errorf("Error reading CosmosDB Account %q after delete (Resource Group %q): %+v", name, resourceGroup, err2) - } - - return resp, "Deleting", nil - }, - } - if _, err = stateConf.WaitForState(); err != nil { - return fmt.Errorf("Waiting forCosmosDB Account %q to delete (Resource Group %q): %+v", name, resourceGroup, err) - } - - return nil -} - -func resourceArmCosmosDBAccountApiUpsert(client documentdb.DatabaseAccountsClient, ctx context.Context, resourceGroup string, name string, account documentdb.DatabaseAccountCreateUpdateParameters) (*documentdb.DatabaseAccount, error) { - future, err := client.CreateOrUpdate(ctx, resourceGroup, name, account) - if err != nil { - return nil, fmt.Errorf("Error creating/updating CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) - } - - if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return nil, fmt.Errorf("Error waiting for the CosmosDB Account %q (Resource Group %q) to finish creating/updating: %+v", name, resourceGroup, err) - } - - //if a replication location is added or removed it can take some time to provision - stateConf := &resource.StateChangeConf{ - Pending: []string{"Creating", "Updating", "Deleting"}, - Target: []string{"Succeeded"}, - Timeout: 60 * time.Minute, - MinTimeout: 30 * time.Second, - Delay: 30 * time.Second, // required because it takes some time before the 'creating' location shows up - Refresh: func() (interface{}, string, error) { - - resp, err2 := client.Get(ctx, resourceGroup, name) - if err2 != nil { - return nil, "", fmt.Errorf("Error reading CosmosDB Account %q after create/update (Resource Group %q): %+v", name, resourceGroup, err2) - } - - status := "Succeeded" - for _, l := range append(*resp.ReadLocations, *resp.WriteLocations...) { - if status = *l.ProvisioningState; status == "Creating" || status == "Updating" || status == "Deleting" { - break //return the first non successful status. - } - } - - return resp, status, nil - }, - } - - resp, err := stateConf.WaitForState() - if err != nil { - return nil, fmt.Errorf("Error waiting for the CosmosDB Account %q (Resource Group %q) to provision: %+v", name, resourceGroup, err) - } - - r := resp.(documentdb.DatabaseAccount) - return &r, nil -} - -func expandAzureRmCosmosDBAccountConsistencyPolicy(d *schema.ResourceData) *documentdb.ConsistencyPolicy { - input := d.Get("consistency_policy").([]interface{})[0].(map[string]interface{}) - - consistencyLevel := input["consistency_level"].(string) - policy := documentdb.ConsistencyPolicy{ - DefaultConsistencyLevel: documentdb.DefaultConsistencyLevel(consistencyLevel), - } - - if stalenessPrefix, ok := input["max_staleness_prefix"].(int); ok { - policy.MaxStalenessPrefix = utils.Int64(int64(stalenessPrefix)) - } - if maxInterval, ok := input["max_interval_in_seconds"].(int); ok { - policy.MaxIntervalInSeconds = utils.Int32(int32(maxInterval)) - } - - return &policy -} - -func resourceArmCosmosDBAccountGenerateDefaultId(databaseName string, location string) string { - return fmt.Sprintf("%s-%s", databaseName, location) -} - -func expandAzureRmCosmosDBAccountGeoLocations(databaseName string, d *schema.ResourceData) ([]documentdb.Location, error) { - - locations := make([]documentdb.Location, 0) - for _, l := range d.Get("geo_location").(*schema.Set).List() { - data := l.(map[string]interface{}) - - location := documentdb.Location{ - LocationName: utils.String(azureRMNormalizeLocation(data["location"].(string))), - FailoverPriority: utils.Int32(int32(data["failover_priority"].(int))), - } - - if v, ok := data["prefix"].(string); ok { - data["id"] = v - } else { - data["id"] = utils.String(resourceArmCosmosDBAccountGenerateDefaultId(databaseName, *location.LocationName)) - } - location.ID = utils.String(data["id"].(string)) - - locations = append(locations, location) - } - - //TODO maybe this should be in a CustomizeDiff - // all priorities & locations must be unique - byPriorities := make(map[int]interface{}, len(locations)) - byName := make(map[string]interface{}, len(locations)) - for _, location := range locations { - - priority := int(*location.FailoverPriority) - name := *location.LocationName - - if _, ok := byPriorities[priority]; ok { - return nil, fmt.Errorf("Each `geo_location` needs to have a unique failover_prioroty. Multiple instances of '%d' found", priority) - } - - if _, ok := byName[name]; ok { - return nil, fmt.Errorf("Each `geo_location` needs to be in unique location. Multiple instances of '%s' found", name) - } - - byPriorities[priority] = location - byName[name] = location - } - - //and must have one of 0 priority - if _, ok := byPriorities[0]; !ok { - return nil, fmt.Errorf("There needs to be a `geo_location` with a failover_priority of 0") - } - - return locations, nil -} - -//todo remove when deprecated field `failover_policy` is -func expandAzureRmCosmosDBAccountFailoverPolicy(databaseName string, d *schema.ResourceData) ([]documentdb.Location, error) { - - input := d.Get("failover_policy").(*schema.Set).List() - locations := make([]documentdb.Location, 0, len(input)) - - for _, configRaw := range input { - data := configRaw.(map[string]interface{}) - - locationName := azureRMNormalizeLocation(data["location"].(string)) - id := fmt.Sprintf("%s-%s", databaseName, locationName) - failoverPriority := int32(data["priority"].(int)) - - location := documentdb.Location{ - ID: &id, - LocationName: &locationName, - FailoverPriority: &failoverPriority, - } - - locations = append(locations, location) - } - - containsWriteLocation := false - writeFailoverPriority := int32(0) - for _, location := range locations { - if *location.FailoverPriority == writeFailoverPriority { - containsWriteLocation = true - break - } - } - - // all priorities must be unique - locationIds := make(map[int]struct{}, len(locations)) - for _, location := range locations { - priority := int(*location.FailoverPriority) - if _, ok := locationIds[priority]; ok { - return nil, fmt.Errorf("Each Failover Policy needs to be unique") - } - - locationIds[priority] = struct{}{} - } - - if !containsWriteLocation { - return nil, fmt.Errorf("Failover Policy should contain a Write Location (Location '0')") - } - - return locations, nil -} - -func expandAzureRmCosmosDBAccountCapabilities(d *schema.ResourceData) *[]documentdb.Capability { - - capabilities := d.Get("capabilities").(*schema.Set).List() - s := make([]documentdb.Capability, 0) - - for _, c := range capabilities { - m := c.(map[string]interface{}) - s = append(s, documentdb.Capability{Name: utils.String(m["name"].(string))}) - } - - return &s -} - -func expandAzureRmCosmosDBAccountVirtualNetworkRules(d *schema.ResourceData) *[]documentdb.VirtualNetworkRule { - virtualNetworkRules := d.Get("virtual_network_rule").(*schema.Set).List() - - s := make([]documentdb.VirtualNetworkRule, len(virtualNetworkRules)) - for i, r := range virtualNetworkRules { - m := r.(map[string]interface{}) - s[i] = documentdb.VirtualNetworkRule{ID: utils.String(m["id"].(string))} - } - return &s -} - -func flattenAzureRmCosmosDBAccountConsistencyPolicy(policy *documentdb.ConsistencyPolicy) []interface{} { - - result := map[string]interface{}{} - result["consistency_level"] = string(policy.DefaultConsistencyLevel) - if policy.MaxIntervalInSeconds != nil { - result["max_interval_in_seconds"] = int(*policy.MaxIntervalInSeconds) - } - if policy.MaxStalenessPrefix != nil { - result["max_staleness_prefix"] = int(*policy.MaxStalenessPrefix) - } - - return []interface{}{result} -} - -//todo remove when failover_policy field is removed -func flattenAzureRmCosmosDBAccountFailoverPolicy(list *[]documentdb.FailoverPolicy) *schema.Set { - results := schema.Set{ - F: resourceAzureRMCosmosDBAccountFailoverPolicyHash, - } - - for _, i := range *list { - result := map[string]interface{}{ - "id": *i.ID, - "location": azureRMNormalizeLocation(*i.LocationName), - "priority": int(*i.FailoverPriority), - } - - results.Add(result) - } - - return &results -} - -func flattenAzureRmCosmosDBAccountGeoLocations(d *schema.ResourceData, account documentdb.DatabaseAccount) *schema.Set { - locationSet := schema.Set{ - F: resourceAzureRMCosmosDBAccountGeoLocationHash, - } - - //we need to propagate the `prefix` field so fetch existing - prefixMap := map[string]string{} - if locations, ok := d.GetOk("geo_location"); ok { - for _, lRaw := range locations.(*schema.Set).List() { - lb := lRaw.(map[string]interface{}) - prefixMap[lb["location"].(string)] = lb["prefix"].(string) - } - } - - for _, l := range *account.FailoverPolicies { - id := *l.ID - lb := map[string]interface{}{ - "id": id, - "location": azureRMNormalizeLocation(*l.LocationName), - "failover_priority": int(*l.FailoverPriority), - } - - //if id is not the default then it must be set via prefix - if id != resourceArmCosmosDBAccountGenerateDefaultId(d.Get("name").(string), lb["location"].(string)) { - lb["prefix"] = id - } - - locationSet.Add(lb) - } - - return &locationSet -} - -func flattenAzureRmCosmosDBAccountCapabilities(capabilities *[]documentdb.Capability) *schema.Set { - s := schema.Set{ - F: resourceAzureRMCosmosDBAccountCapabilitiesHash, - } - - for _, c := range *capabilities { - if v := c.Name; v != nil { - e := map[string]interface{}{ - "name": *v, - } - s.Add(e) - } - } - - return &s -} - -func flattenAzureRmCosmosDBAccountVirtualNetworkRules(rules *[]documentdb.VirtualNetworkRule) *schema.Set { - results := schema.Set{ - F: resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash, - } - - if rules != nil { - for _, r := range *rules { - rule := map[string]interface{}{ - "id": *r.ID, - } - results.Add(rule) - } - } - - return &results -} - -//todo remove once deprecated field `failover_policy` is removed -func resourceAzureRMCosmosDBAccountFailoverPolicyHash(v interface{}) int { - var buf bytes.Buffer - - if m, ok := v.(map[string]interface{}); ok { - location := azureRMNormalizeLocation(m["location"].(string)) - priority := int32(m["priority"].(int)) - - buf.WriteString(fmt.Sprintf("%s-%d", location, priority)) - } - - return hashcode.String(buf.String()) -} - -func resourceAzureRMCosmosDBAccountGeoLocationHash(v interface{}) int { - var buf bytes.Buffer - - if m, ok := v.(map[string]interface{}); ok { - prefix := "" - if v, ok := m["prefix"].(string); ok { - prefix = v - } - location := azureRMNormalizeLocation(m["location"].(string)) - priority := int32(m["failover_priority"].(int)) - - buf.WriteString(fmt.Sprintf("%s-%s-%d", prefix, location, priority)) - } - - return hashcode.String(buf.String()) -} - -func resourceAzureRMCosmosDBAccountCapabilitiesHash(v interface{}) int { - var buf bytes.Buffer - - if m, ok := v.(map[string]interface{}); ok { - buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) - } - - return hashcode.String(buf.String()) -} - -func resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash(v interface{}) int { - var buf bytes.Buffer - - if m, ok := v.(map[string]interface{}); ok { - buf.WriteString(strings.ToLower(m["id"].(string))) - } - - return hashcode.String(buf.String()) -} diff --git a/azurerm/resource_arm_cosmos_db_account_failover_test.go b/azurerm/resource_arm_cosmos_db_account_failover_test.go deleted file mode 100644 index 0a4288d75f2d..000000000000 --- a/azurerm/resource_arm_cosmos_db_account_failover_test.go +++ /dev/null @@ -1,333 +0,0 @@ -package azurerm - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform/helper/resource" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" -) - -func TestAccAzureRMCosmosDBAccount_failover_boundedStaleness(t *testing.T) { - resourceName := "azurerm_cosmosdb_account.test" - ri := tf.AccRandTimeInt() - config := testAccAzureRMCosmosDBAccount_failover_boundedStaleness(ri, testLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMCosmosDBAccountExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), - ), - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_failover_boundedStalenessComplete(t *testing.T) { - - ri := tf.AccRandTimeInt() - config := testAccAzureRMCosmosDBAccount_failover_boundedStalenessComplete(ri, testLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), - ), - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_failover_eventualConsistency(t *testing.T) { - ri := tf.AccRandTimeInt() - config := testAccAzureRMCosmosDBAccount_failover_eventualConsistency(ri, testLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), - ), - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_failover_mongoDB(t *testing.T) { - resourceName := "azurerm_cosmosdb_account.test" - ri := tf.AccRandTimeInt() - config := testAccAzureRMCosmosDBAccount_failover_mongoDB(ri, testLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMCosmosDBAccountExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), - ), - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_failover_session(t *testing.T) { - ri := tf.AccRandTimeInt() - config := testAccAzureRMCosmosDBAccount_failover_session(ri, testLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), - ), - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_failover_strong(t *testing.T) { - ri := tf.AccRandTimeInt() - config := testAccAzureRMCosmosDBAccount_failover_strong(ri, testLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), - ), - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_failover_geoReplicated(t *testing.T) { - - ri := tf.AccRandTimeInt() - config := testAccAzureRMCosmosDBAccount_failover_geoReplicated(ri, testLocation(), testAltLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), - ), - }, - }, - }) -} - -func testAccAzureRMCosmosDBAccount_failover_boundedStaleness(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_cosmosdb_account" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - offer_type = "Standard" - - consistency_policy { - consistency_level = "BoundedStaleness" - } - - failover_policy { - location = "${azurerm_resource_group.test.location}" - priority = 0 - } -} -`, rInt, location, rInt) -} - -func testAccAzureRMCosmosDBAccount_failover_boundedStalenessComplete(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_cosmosdb_account" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - offer_type = "Standard" - - consistency_policy { - consistency_level = "BoundedStaleness" - max_interval_in_seconds = 10 - max_staleness_prefix = 200 - } - - failover_policy { - location = "${azurerm_resource_group.test.location}" - priority = 0 - } -} -`, rInt, location, rInt) -} - -func testAccAzureRMCosmosDBAccount_failover_eventualConsistency(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_cosmosdb_account" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - offer_type = "Standard" - - consistency_policy { - consistency_level = "Eventual" - } - - failover_policy { - location = "${azurerm_resource_group.test.location}" - priority = 0 - } -} -`, rInt, location, rInt) -} - -func testAccAzureRMCosmosDBAccount_failover_session(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_cosmosdb_account" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - offer_type = "Standard" - - consistency_policy { - consistency_level = "Session" - } - - failover_policy { - location = "${azurerm_resource_group.test.location}" - priority = 0 - } -} -`, rInt, location, rInt) -} - -func testAccAzureRMCosmosDBAccount_failover_mongoDB(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_cosmosdb_account" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - kind = "MongoDB" - offer_type = "Standard" - - consistency_policy { - consistency_level = "BoundedStaleness" - } - - failover_policy { - location = "${azurerm_resource_group.test.location}" - priority = 0 - } -} -`, rInt, location, rInt) -} - -func testAccAzureRMCosmosDBAccount_failover_strong(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_cosmosdb_account" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - offer_type = "Standard" - - consistency_policy { - consistency_level = "Strong" - } - - failover_policy { - location = "${azurerm_resource_group.test.location}" - priority = 0 - } -} -`, rInt, location, rInt) -} - -func testAccAzureRMCosmosDBAccount_failover_geoReplicated(rInt int, location string, altLocation string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_cosmosdb_account" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - offer_type = "Standard" - - consistency_policy { - consistency_level = "BoundedStaleness" - max_interval_in_seconds = 10 - max_staleness_prefix = 200 - } - - failover_policy { - location = "${azurerm_resource_group.test.location}" - priority = 0 - } - - failover_policy { - location = "%s" - priority = 1 - } -} -`, rInt, location, rInt, altLocation) -} diff --git a/azurerm/resource_arm_cosmos_db_account_test.go b/azurerm/resource_arm_cosmos_db_account_test.go deleted file mode 100644 index 6e676dbfb458..000000000000 --- a/azurerm/resource_arm_cosmos_db_account_test.go +++ /dev/null @@ -1,950 +0,0 @@ -package azurerm - -import ( - "fmt" - "net/http" - "strconv" - "testing" - - "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" -) - -// TODO: refactor the test configs - -//consistency -func TestAccAzureRMCosmosDBAccount_eventualConsistency(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Eventual), "", ""), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Eventual), 1), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} -func TestAccAzureRMCosmosDBAccount_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { - t.Skip("Skipping since resources aren't required to be imported") - return - } - - resourceName := "azurerm_cosmosdb_account.test" - ri := tf.AccRandTimeInt() - location := testLocation() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, location, string(documentdb.Eventual), "", ""), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Eventual), 1), - ), - }, - { - Config: testAccAzureRMCosmosDBAccount_requiresImport(ri, location, string(documentdb.Eventual), "", ""), - ExpectError: testRequiresImportError("azurerm_cosmosdb_account"), - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_session(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Session), "", ""), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Session), 1), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_strong(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Strong), "", ""), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Strong), 1), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_consistentPrefix(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.ConsistentPrefix), "", ""), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.ConsistentPrefix), 1), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_boundedStaleness(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.BoundedStaleness), "", ""), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_boundedStaleness_complete(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_boundedStaleness_complete(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "consistency_policy.0.max_interval_in_seconds", "10"), - resource.TestCheckResourceAttr(resourceName, "consistency_policy.0.max_staleness_prefix", "200"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_consistency_change(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Session), "", ""), - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Session), 1), - }, - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.BoundedStaleness), "", ""), - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -//DB kinds -func TestAccAzureRMCosmosDBAccount_mongoDB(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_mongoDB(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), - resource.TestCheckResourceAttr(resourceName, "connection_strings.#", "4"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_capabilityGremlin(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_capabilityGremlin(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_capabilityTable(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_capabilityTable(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_capabilityCassandra(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_capabilityCassandra(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_capabilityAggregationPipeline(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_capabilityAggregationPipeline(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_capabilityMongo35(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_capabilityMongo34(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_capabilityDocLevelTTL(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_capabilityDocLevelTTL(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_capabilityUpdate(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_capabilityDocLevelTTL(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), - ), - }, - { - Config: testAccAzureRMCosmosDBAccount_capabilityMongo34(ri, testLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAbcAzureRMCosmosDBAccount_updatePropertiesAndLocation(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Session), "", ""), - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Session), 1), - }, - { - Config: testAccAzureRMCosmosDBAccount_geoReplicated_customId(ri, testLocation(), testAltLocation()), - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -//replication -func TestAccAzureRMCosmosDBAccount_geoReplicated_customId(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_geoReplicated_customId(ri, testLocation(), testAltLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_geoReplicated_add_remove(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - configBasic := testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.BoundedStaleness), "", "") - configReplicated := testAccAzureRMCosmosDBAccount_geoReplicated_customId(ri, testLocation(), testAltLocation()) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: configBasic, - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - }, - { - Config: configReplicated, - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), - ), - }, - { - Config: configBasic, - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_geoReplicated_rename(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_geoReplicated(ri, testLocation(), testAltLocation()), - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), - }, - { - Config: testAccAzureRMCosmosDBAccount_geoReplicated_customId(ri, testLocation(), testAltLocation()), - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_virtualNetworkFilter(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_virtualNetworkFilter(ri, testLocation()), - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -//basic --> complete ( -func TestAccAzureRMCosmosDBAccount_complete(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Session), "", ""), - Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Session), 1), - }, - { - Config: testAccAzureRMCosmosDBAccount_complete(ri, testLocation(), testAltLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), - resource.TestCheckResourceAttr(resourceName, "ip_range_filter", "104.42.195.92,40.76.54.131,52.176.6.30,52.169.50.45/32,52.187.184.26,10.20.0.0/16"), - resource.TestCheckResourceAttr(resourceName, "enable_automatic_failover", "true"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_emptyIpFilter(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_emptyIpFilter(ri, testLocation(), testAltLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), - resource.TestCheckResourceAttr(resourceName, "ip_range_filter", ""), - resource.TestCheckResourceAttr(resourceName, "enable_automatic_failover", "true"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAzureRMCosmosDBAccount_multiMaster(t *testing.T) { - ri := tf.AccRandTimeInt() - resourceName := "azurerm_cosmosdb_account.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMCosmosDBAccount_multiMaster(ri, testLocation(), testAltLocation()), - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "geo_location.#", "2"), - resource.TestCheckResourceAttr(resourceName, "write_endpoints.#", "2"), - resource.TestCheckResourceAttr(resourceName, "enable_multiple_write_locations", "true"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testCheckAzureRMCosmosDBAccountDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).cosmosDBClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - - for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_cosmosdb_account" { - continue - } - - name := rs.Primary.Attributes["name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] - - resp, err := conn.Get(ctx, resourceGroup, name) - - if err != nil { - return nil - } - - if resp.StatusCode != http.StatusNotFound { - return fmt.Errorf("CosmosDB Account still exists:\n%#v", resp) - } - } - - return nil -} - -func testCheckAzureRMCosmosDBAccountExists(resourceName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - // Ensure we have enough information in state to look up in API - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("Not found: %s", resourceName) - } - - name := rs.Primary.Attributes["name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for CosmosDB Account: '%s'", name) - } - - conn := testAccProvider.Meta().(*ArmClient).cosmosDBClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - - resp, err := conn.Get(ctx, resourceGroup, name) - if err != nil { - return fmt.Errorf("Bad: Get on cosmosDBClient: %+v", err) - } - - if resp.StatusCode == http.StatusNotFound { - return fmt.Errorf("Bad: CosmosDB Account '%s' (resource group: '%s') does not exist", name, resourceGroup) - } - - return nil - } -} - -func testAccAzureRMCosmosDBAccount_basic(rInt int, location string, consistency string, consistencyOptions string, additional string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_cosmosdb_account" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - offer_type = "Standard" - - consistency_policy { - consistency_level = "%s" - - %s - } - - geo_location { - location = "${azurerm_resource_group.test.location}" - failover_priority = 0 - } - - %s -} -`, rInt, location, rInt, consistency, consistencyOptions, additional) -} - -func testAccAzureRMCosmosDBAccount_requiresImport(rInt int, location string, consistency string, consistencyOptions string, additional string) string { - template := testAccAzureRMCosmosDBAccount_basic(rInt, location, consistency, consistencyOptions, additional) - return fmt.Sprintf(` -%s - -resource "azurerm_cosmosdb_account" "import" { - name = "${azurerm_cosmosdb_account.test.name}" - location = "${azurerm_cosmosdb_account.test.location}" - resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" - offer_type = "Standard" - - consistency_policy { - consistency_level = "%s" - - %s - } - - geo_location { - location = "${azurerm_resource_group.test.location}" - failover_priority = 0 - } - - %s -} -`, template, consistency, consistencyOptions, additional) -} - -func testAccAzureRMCosmosDBAccount_boundedStaleness_complete(rInt int, location string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), ` - max_interval_in_seconds = 10 - max_staleness_prefix = 200 -`, "") -} - -func testAccAzureRMCosmosDBAccount_mongoDB(rInt int, location string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` - kind = "MongoDB" - `) -} - -func testAccAzureRMCosmosDBAccount_capabilityGremlin(rInt int, location string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` - kind = "GlobalDocumentDB" - - capabilities { - name = "EnableGremlin" - } - `) -} - -func testAccAzureRMCosmosDBAccount_capabilityTable(rInt int, location string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` - kind = "GlobalDocumentDB" - - capabilities { - name = "EnableTable" - } - `) -} - -func testAccAzureRMCosmosDBAccount_capabilityCassandra(rInt int, location string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` - kind = "GlobalDocumentDB" - - capabilities { - name = "EnableCassandra" - } - `) -} - -func testAccAzureRMCosmosDBAccount_capabilityAggregationPipeline(rInt int, location string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` - kind = "GlobalDocumentDB" - - capabilities { - name = "EnableAggregationPipeline" - } - `) -} - -func testAccAzureRMCosmosDBAccount_capabilityMongo34(rInt int, location string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` - kind = "MongoDB" - - capabilities { - name = "MongoDBv3.4" - } - `) -} - -func testAccAzureRMCosmosDBAccount_capabilityDocLevelTTL(rInt int, location string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` - kind = "MongoDB" - - capabilities { - name = "mongoEnableDocLevelTTL" - } - `) -} - -func testAccAzureRMCosmosDBAccount_geoReplicated(rInt int, location string, altLocation string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", fmt.Sprintf(` - geo_location { - location = "%s" - failover_priority = 1 - } - - `, altLocation)) -} - -func testAccAzureRMCosmosDBAccount_multiMaster(rInt int, location string, altLocation string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", fmt.Sprintf(` - enable_multiple_write_locations = true - - geo_location { - location = "%s" - failover_priority = 1 - } - - `, altLocation)) -} - -func testAccAzureRMCosmosDBAccount_geoReplicated_customId(rInt int, location string, altLocation string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", fmt.Sprintf(` - geo_location { - prefix = "acctest-%d-custom-id" - location = "%s" - failover_priority = 1 - } - - `, rInt, altLocation)) -} - -func testAccAzureRMCosmosDBAccount_complete(rInt int, location string, altLocation string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", fmt.Sprintf(` - ip_range_filter = "104.42.195.92,40.76.54.131,52.176.6.30,52.169.50.45/32,52.187.184.26,10.20.0.0/16" - enable_automatic_failover = true - - geo_location { - prefix = "acctest-%d-custom-id" - location = "%s" - failover_priority = 1 - } - `, rInt, altLocation)) -} - -func testAccAzureRMCosmosDBAccount_emptyIpFilter(rInt int, location string, altLocation string) string { - return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", fmt.Sprintf(` - ip_range_filter = "" - enable_automatic_failover = true - - geo_location { - prefix = "acctest-%d-custom-id" - location = "%s" - failover_priority = 1 - } - `, rInt, altLocation)) -} - -func testAccAzureRMCosmosDBAccount_virtualNetworkFilter(rInt int, location string) string { - vnetConfig := fmt.Sprintf(` -resource "azurerm_virtual_network" "test" { - name = "acctest-%[1]d" - resource_group_name = "${azurerm_resource_group.test.name}" - address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.test.location}" - dns_servers = ["10.0.0.4", "10.0.0.5"] -} - -resource "azurerm_subnet" "subnet1" { - name = "acctest-%[1]d-1" - resource_group_name = "${azurerm_resource_group.test.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.0.1.0/24" - service_endpoints = ["Microsoft.AzureCosmosDB"] -} - -resource "azurerm_subnet" "subnet2" { - name = "acctest-%[1]d-2" - resource_group_name = "${azurerm_resource_group.test.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.0.2.0/24" - service_endpoints = ["Microsoft.AzureCosmosDB"] -} -`, rInt) - - basic := testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` - is_virtual_network_filter_enabled = true - - virtual_network_rule { - id = "${azurerm_subnet.subnet1.id}" - } - - virtual_network_rule { - id = "${azurerm_subnet.subnet2.id}" - } - `) - - return vnetConfig + basic -} - -func checkAccAzureRMCosmosDBAccount_basic(resourceName string, location string, consistency string, locationCount int) resource.TestCheckFunc { - return resource.ComposeTestCheckFunc( - testCheckAzureRMCosmosDBAccountExists(resourceName), - resource.TestCheckResourceAttrSet(resourceName, "name"), - resource.TestCheckResourceAttrSet(resourceName, "resource_group_name"), - resource.TestCheckResourceAttr(resourceName, "location", azureRMNormalizeLocation(location)), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), - resource.TestCheckResourceAttr(resourceName, "offer_type", string(documentdb.Standard)), - resource.TestCheckResourceAttr(resourceName, "consistency_policy.0.consistency_level", consistency), - resource.TestCheckResourceAttr(resourceName, "geo_location.#", strconv.Itoa(locationCount)), - resource.TestCheckResourceAttrSet(resourceName, "endpoint"), - resource.TestCheckResourceAttr(resourceName, "read_endpoints.#", strconv.Itoa(locationCount)), - resource.TestCheckResourceAttr(resourceName, "write_endpoints.#", "1"), - resource.TestCheckResourceAttr(resourceName, "enable_multiple_write_locations", "false"), - resource.TestCheckResourceAttrSet(resourceName, "primary_master_key"), - resource.TestCheckResourceAttrSet(resourceName, "secondary_master_key"), - resource.TestCheckResourceAttrSet(resourceName, "primary_readonly_master_key"), - resource.TestCheckResourceAttrSet(resourceName, "secondary_readonly_master_key"), - ) -} diff --git a/azurerm/resource_arm_cosmosdb_account.go b/azurerm/resource_arm_cosmosdb_account.go new file mode 100644 index 000000000000..9421bedcf6ef --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_account.go @@ -0,0 +1,1104 @@ +package azurerm + +import ( + "bytes" + "context" + "fmt" + "log" + "net/http" + "regexp" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + + "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmCosmosDbAccount() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCosmosDbAccountCreate, + Read: resourceArmCosmosDbAccountRead, + Update: resourceArmCosmosDbAccountUpdate, + Delete: resourceArmCosmosDbAccountDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile("^[-a-z0-9]{3,50}$"), + "Cosmos DB Account name must be 3 - 50 characters long, contain only lowercase letters, numbers and hyphens.", + ), + }, + + "location": azure.SchemaLocation(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "tags": tags.Schema(), + + //resource fields + "offer_type": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(documentdb.Standard), + }, true), + }, + + "kind": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: string(documentdb.GlobalDocumentDB), + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(documentdb.GlobalDocumentDB), + string(documentdb.MongoDB), + }, true), + }, + + "ip_range_filter": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\/([1-2][0-9]|3[0-2]))?\b[,]?)*$`), + "Cosmos DB ip_range_filter must be a set of CIDR IP addresses separated by commas with no spaces: '10.0.0.1,10.0.0.2,10.20.0.0/16'", + ), + }, + + "enable_automatic_failover": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "consistency_policy": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "consistency_level": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(documentdb.BoundedStaleness), + string(documentdb.ConsistentPrefix), + string(documentdb.Eventual), + string(documentdb.Session), + string(documentdb.Strong), + }, true), + }, + + "max_interval_in_seconds": { + Type: schema.TypeInt, + Optional: true, + Default: 5, + ValidateFunc: validation.IntBetween(5, 86400), // single region values + }, + + "max_staleness_prefix": { + Type: schema.TypeInt, + Optional: true, + Default: 100, + ValidateFunc: validation.IntBetween(10, 1000000), // single region values + }, + }, + }, + }, + + // this actually maps to the Location field in the API/SDK on create/update so has been renamed + // failover_policy is just the name of the field we get back from the API on a read + "failover_policy": { + Type: schema.TypeSet, + Optional: true, + Deprecated: "This field has been renamed to 'geo_location' to match Azure's usage", + ConflictsWith: []string{"geo_location"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "location": { + Type: schema.TypeString, + Required: true, + StateFunc: azure.NormalizeLocation, + DiffSuppressFunc: azure.SuppressLocationDiff, + }, + + "priority": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + Set: resourceAzureRMCosmosDBAccountFailoverPolicyHash, + }, + + "geo_location": { + Type: schema.TypeSet, + //Required: true, //todo needs to be required when failover_policy is removed + Optional: true, + Computed: true, + ConflictsWith: []string{"failover_policy"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + "prefix": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile("^[-a-z0-9]{3,50}$"), + "Cosmos DB location prefix (ID) must be 3 - 50 characters long, contain only lowercase letters, numbers and hyphens.", + ), + }, + + "id": { + Type: schema.TypeString, + Computed: true, + }, + + "location": azure.SchemaLocation(), + + "failover_priority": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(0), + }, + }, + }, + Set: resourceAzureRMCosmosDBAccountGeoLocationHash, + }, + + "capabilities": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + "EnableTable", + "EnableGremlin", + "EnableCassandra", + "EnableAggregationPipeline", + "MongoDBv3.4", + "mongoEnableDocLevelTTL", + }, true), + }, + }, + }, + Set: resourceAzureRMCosmosDBAccountCapabilitiesHash, + }, + + "is_virtual_network_filter_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "virtual_network_rule": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + }, + }, + Set: resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash, + }, + + "enable_multiple_write_locations": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + //computed + "endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "read_endpoints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "write_endpoints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "primary_master_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + + "secondary_master_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + + "primary_readonly_master_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + + "secondary_readonly_master_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + + "connection_strings": { + Type: schema.TypeList, + Computed: true, + Sensitive: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +func resourceArmCosmosDbAccountCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + log.Printf("[INFO] preparing arguments for AzureRM Cosmos DB Account creation.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing CosmosDB Account %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_cosmosdb_account", *existing.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) + kind := d.Get("kind").(string) + offerType := d.Get("offer_type").(string) + ipRangeFilter := d.Get("ip_range_filter").(string) + isVirtualNetworkFilterEnabled := d.Get("is_virtual_network_filter_enabled").(bool) + enableAutomaticFailover := d.Get("enable_automatic_failover").(bool) + enableMultipleWriteLocations := d.Get("enable_multiple_write_locations").(bool) + + r, err := client.CheckNameExists(ctx, name) + if err != nil { + // todo remove when https://github.com/Azure/azure-sdk-for-go/issues/5157 is fixed + if !utils.ResponseWasStatusCode(r, http.StatusInternalServerError) { + return fmt.Errorf("Error checking if CosmosDB Account %q already exists (Resource Group %q): %+v", name, resourceGroup, err) + } + } else { + if !utils.ResponseWasNotFound(r) { + return fmt.Errorf("CosmosDB Account %s already exists, please import the resource via terraform import", name) + } + } + + //hacky, todo fix up once deprecated field 'failover_policy' is removed + var geoLocations []documentdb.Location + if _, ok := d.GetOk("geo_location"); ok { + geoLocations, err = expandAzureRmCosmosDBAccountGeoLocations(name, d) + if err != nil { + return fmt.Errorf("Error expanding CosmosDB Account %q (Resource Group %q) geo locations: %+v", name, resourceGroup, err) + } + } else if _, ok := d.GetOk("failover_policy"); ok { + geoLocations, err = expandAzureRmCosmosDBAccountFailoverPolicy(name, d) + if err != nil { + return fmt.Errorf("Error expanding CosmosDB Account %q (Resource Group %q) failover_policy: %+v", name, resourceGroup, err) + } + } else { + //could be a CustomizeDiff?, but this is temporary + return fmt.Errorf("Neither `geo_location` or `failover_policy` is set for CosmosDB Account %s", name) + } + + account := documentdb.DatabaseAccountCreateUpdateParameters{ + Location: utils.String(location), + Kind: documentdb.DatabaseAccountKind(kind), + DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{ + DatabaseAccountOfferType: utils.String(offerType), + IPRangeFilter: utils.String(ipRangeFilter), + IsVirtualNetworkFilterEnabled: utils.Bool(isVirtualNetworkFilterEnabled), + EnableAutomaticFailover: utils.Bool(enableAutomaticFailover), + ConsistencyPolicy: expandAzureRmCosmosDBAccountConsistencyPolicy(d), + Locations: &geoLocations, + Capabilities: expandAzureRmCosmosDBAccountCapabilities(d), + VirtualNetworkRules: expandAzureRmCosmosDBAccountVirtualNetworkRules(d), + EnableMultipleWriteLocations: utils.Bool(enableMultipleWriteLocations), + }, + Tags: tags.Expand(t), + } + + // additional validation on MaxStalenessPrefix as it varies depending on if the DB is multi region or not + + if cp := account.DatabaseAccountCreateUpdateProperties.ConsistencyPolicy; len(geoLocations) > 1 && cp != nil { + if msp := cp.MaxStalenessPrefix; msp != nil && *msp < 100000 { + return fmt.Errorf("Error max_staleness_prefix (%d) must be greater then 100000 when more then one geo_location is used", *msp) + } + if mis := cp.MaxIntervalInSeconds; mis != nil && *mis < 300 { + return fmt.Errorf("Error max_interval_in_seconds (%d) must be greater then 300 (5min) when more then one geo_location is used", *mis) + } + } + + resp, err := resourceArmCosmosDbAccountApiUpsert(client, ctx, resourceGroup, name, account) + if err != nil { + return fmt.Errorf("Error creating CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + //for some reason capabilities doesn't always work on create, so lets patch it + //tracked: https://github.com/Azure/azure-sdk-for-go/issues/2864 + future, err := client.Patch(ctx, resourceGroup, name, documentdb.DatabaseAccountPatchParameters{ + DatabaseAccountPatchProperties: &documentdb.DatabaseAccountPatchProperties{ + Capabilities: account.Capabilities, + }, + }) + if err != nil { + return fmt.Errorf("Error Patching CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(context.Background(), client.Client); err != nil { + return fmt.Errorf("Error waiting on patch future CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + id := resp.ID + if id == nil { + return fmt.Errorf("Cannot read CosmosDB Account '%s' (resource group %s) ID", name, resourceGroup) + } + + d.SetId(*id) + + return resourceArmCosmosDbAccountRead(d, meta) +} + +func resourceArmCosmosDbAccountUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + log.Printf("[INFO] preparing arguments for AzureRM Cosmos DB Account update.") + + //move to function + name := d.Get("name").(string) + location := d.Get("location").(string) + resourceGroup := d.Get("resource_group_name").(string) + t := d.Get("tags").(map[string]interface{}) + + kind := d.Get("kind").(string) + offerType := d.Get("offer_type").(string) + ipRangeFilter := d.Get("ip_range_filter").(string) + isVirtualNetworkFilterEnabled := d.Get("is_virtual_network_filter_enabled").(bool) + enableAutomaticFailover := d.Get("enable_automatic_failover").(bool) + enableMultipleWriteLocations := d.Get("enable_multiple_write_locations").(bool) + + //hacky, todo fix up once deprecated field 'failover_policy' is removed + var newLocations []documentdb.Location + var err error + if _, ok := d.GetOk("geo_location"); ok { + newLocations, err = expandAzureRmCosmosDBAccountGeoLocations(name, d) + if err != nil { + return fmt.Errorf("Error expanding CosmosDB Account %q (Resource Group %q) geo locations: %+v", name, resourceGroup, err) + } + } else if _, ok := d.GetOk("failover_policy"); ok { + newLocations, err = expandAzureRmCosmosDBAccountFailoverPolicy(name, d) + if err != nil { + return fmt.Errorf("Error expanding CosmosDB Account %q (Resource Group %q) failover_policy: %+v", name, resourceGroup, err) + } + } else { + //could be a CustomizeDiff?, but this is temporary + return fmt.Errorf("Neither `geo_location` or `failover_policy` is set for CosmosDB Account '%s'", name) + } + + //get existing locations (if exists) + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error making Read request on AzureRM CosmosDB Account '%s': %s", name, err) + } + + oldLocations := make([]documentdb.Location, 0) + oldLocationsMap := map[string]documentdb.Location{} + for _, l := range *resp.FailoverPolicies { + location := documentdb.Location{ + ID: l.ID, + LocationName: l.LocationName, + FailoverPriority: l.FailoverPriority, + } + + oldLocations = append(oldLocations, location) + oldLocationsMap[azure.NormalizeLocation(*location.LocationName)] = location + } + + //cannot update properties and add/remove replication locations at the same time + //so first just update any changed properties + account := documentdb.DatabaseAccountCreateUpdateParameters{ + Location: utils.String(location), + Kind: documentdb.DatabaseAccountKind(kind), + DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{ + DatabaseAccountOfferType: utils.String(offerType), + IPRangeFilter: utils.String(ipRangeFilter), + IsVirtualNetworkFilterEnabled: utils.Bool(isVirtualNetworkFilterEnabled), + EnableAutomaticFailover: utils.Bool(enableAutomaticFailover), + Capabilities: expandAzureRmCosmosDBAccountCapabilities(d), + ConsistencyPolicy: expandAzureRmCosmosDBAccountConsistencyPolicy(d), + Locations: &oldLocations, + VirtualNetworkRules: expandAzureRmCosmosDBAccountVirtualNetworkRules(d), + EnableMultipleWriteLocations: utils.Bool(enableMultipleWriteLocations), + }, + Tags: tags.Expand(t), + } + + if _, err = resourceArmCosmosDbAccountApiUpsert(client, ctx, resourceGroup, name, account); err != nil { + return fmt.Errorf("Error updating CosmosDB Account %q properties (Resource Group %q): %+v", name, resourceGroup, err) + } + + //determine if any locations have been renamed/priority reordered and remove them + removedOne := false + for _, l := range newLocations { + if ol, ok := oldLocationsMap[*l.LocationName]; ok { + if *l.FailoverPriority != *ol.FailoverPriority { + if *l.FailoverPriority == 0 { + return fmt.Errorf("Cannot change the failover priority of primary Cosmos DB account %q location %s to %d (Resource Group %q)", name, *l.LocationName, *l.FailoverPriority, resourceGroup) + } + delete(oldLocationsMap, *l.LocationName) + removedOne = true + continue + } + if *l.ID == "" && *ol.ID == resourceArmCosmosDbAccountGenerateDefaultId(name, *l.LocationName) { + continue + } + if *l.ID != *ol.ID { + if *l.FailoverPriority == 0 { + return fmt.Errorf("Cannot change the prefix/ID of the primary Cosmos DB account %q location %s (Resource Group %q)", name, *l.LocationName, resourceGroup) + } + delete(oldLocationsMap, *l.LocationName) + removedOne = true + } + } + + } + + if removedOne { + locationsUnchanged := make([]documentdb.Location, 0, len(oldLocationsMap)) + for _, value := range oldLocationsMap { + locationsUnchanged = append(locationsUnchanged, value) + } + + account.DatabaseAccountCreateUpdateProperties.Locations = &locationsUnchanged + if _, err = resourceArmCosmosDbAccountApiUpsert(client, ctx, resourceGroup, name, account); err != nil { + return fmt.Errorf("Error removing CosmosDB Account %q renamed locations (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + //add any new/renamed locations + account.DatabaseAccountCreateUpdateProperties.Locations = &newLocations + upsertResponse, err := resourceArmCosmosDbAccountApiUpsert(client, ctx, resourceGroup, name, account) + if err != nil { + return fmt.Errorf("Error updating CosmosDB Account %q locations (Resource Group %q): %+v", name, resourceGroup, err) + } + + id := (*upsertResponse).ID + if id == nil { + return fmt.Errorf("Cannot read CosmosDB Account '%s' (resource group %s) ID", name, resourceGroup) + } + + //for some reason capabilities doesn't always work on create, so lets patch it + //tracked: https://github.com/Azure/azure-sdk-for-go/issues/2864 + future, err := client.Patch(ctx, resourceGroup, name, documentdb.DatabaseAccountPatchParameters{ + DatabaseAccountPatchProperties: &documentdb.DatabaseAccountPatchProperties{ + Capabilities: account.Capabilities, + }, + }) + if err != nil { + return fmt.Errorf("Error Patching CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(context.Background(), client.Client); err != nil { + return fmt.Errorf("Error waiting on patch future CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*id) + + return resourceArmCosmosDbAccountRead(d, meta) +} + +func resourceArmCosmosDbAccountRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + name := id.Path["databaseAccounts"] + resourceGroup := id.ResourceGroup + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on AzureRM CosmosDB Account '%s': %s", name, err) + } + + d.Set("name", resp.Name) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + d.Set("resource_group_name", resourceGroup) + + d.Set("kind", string(resp.Kind)) + d.Set("offer_type", string(resp.DatabaseAccountOfferType)) + d.Set("ip_range_filter", resp.IPRangeFilter) + d.Set("endpoint", resp.DocumentEndpoint) + + if v := resp.IsVirtualNetworkFilterEnabled; v != nil { + d.Set("is_virtual_network_filter_enabled", resp.IsVirtualNetworkFilterEnabled) + } + + if v := resp.EnableAutomaticFailover; v != nil { + d.Set("enable_automatic_failover", resp.EnableAutomaticFailover) + } + + if v := resp.EnableMultipleWriteLocations; v != nil { + d.Set("enable_multiple_write_locations", resp.EnableMultipleWriteLocations) + } + + if err = d.Set("consistency_policy", flattenAzureRmCosmosDBAccountConsistencyPolicy(resp.ConsistencyPolicy)); err != nil { + return fmt.Errorf("Error setting CosmosDB Account %q `consistency_policy` (Resource Group %q): %+v", name, resourceGroup, err) + } + if _, ok := d.GetOk("failover_policy"); ok { + if err = d.Set("failover_policy", flattenAzureRmCosmosDBAccountFailoverPolicy(resp.FailoverPolicies)); err != nil { + return fmt.Errorf("Error setting `failover_policy`: %+v", err) + } + } else { + //if failover policy isn't default to using geo_location + if err = d.Set("geo_location", flattenAzureRmCosmosDBAccountGeoLocations(d, resp)); err != nil { + return fmt.Errorf("Error setting `geo_location`: %+v", err) + } + } + + if err = d.Set("capabilities", flattenAzureRmCosmosDBAccountCapabilities(resp.Capabilities)); err != nil { + return fmt.Errorf("Error setting `capabilities`: %+v", err) + } + + if err = d.Set("virtual_network_rule", flattenAzureRmCosmosDBAccountVirtualNetworkRules(resp.VirtualNetworkRules)); err != nil { + return fmt.Errorf("Error setting `virtual_network_rule`: %+v", err) + } + + readEndpoints := make([]string, 0) + if p := resp.ReadLocations; p != nil { + for _, l := range *p { + if l.DocumentEndpoint == nil { + continue + } + + readEndpoints = append(readEndpoints, *l.DocumentEndpoint) + } + } + if err := d.Set("read_endpoints", readEndpoints); err != nil { + return fmt.Errorf("Error setting `read_endpoints`: %s", err) + } + + writeEndpoints := make([]string, 0) + if p := resp.WriteLocations; p != nil { + for _, l := range *p { + if l.DocumentEndpoint == nil { + continue + } + + writeEndpoints = append(writeEndpoints, *l.DocumentEndpoint) + } + } + if err := d.Set("write_endpoints", writeEndpoints); err != nil { + return fmt.Errorf("Error setting `write_endpoints`: %s", err) + } + + // ListKeys returns a data structure containing a DatabaseAccountListReadOnlyKeysResult pointer + // implying that it also returns the read only keys, however this appears to not be the case + keys, err := client.ListKeys(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(keys.Response) { + log.Printf("[DEBUG] Keys were not found for CosmosDB Account %q (Resource Group %q) - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("[ERROR] Unable to List Write keys for CosmosDB Account %s: %s", name, err) + } + d.Set("primary_master_key", keys.PrimaryMasterKey) + d.Set("secondary_master_key", keys.SecondaryMasterKey) + + readonlyKeys, err := client.ListReadOnlyKeys(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(keys.Response) { + log.Printf("[DEBUG] Read Only Keys were not found for CosmosDB Account %q (Resource Group %q) - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("[ERROR] Unable to List read-only keys for CosmosDB Account %s: %s", name, err) + } + d.Set("primary_readonly_master_key", readonlyKeys.PrimaryReadonlyMasterKey) + d.Set("secondary_readonly_master_key", readonlyKeys.SecondaryReadonlyMasterKey) + + connStringResp, err := client.ListConnectionStrings(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(keys.Response) { + log.Printf("[DEBUG] Connection Strings were not found for CosmosDB Account %q (Resource Group %q) - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("[ERROR] Unable to List connection strings for CosmosDB Account %s: %s", name, err) + } + + var connStrings []string + if connStringResp.ConnectionStrings != nil { + connStrings = make([]string, len(*connStringResp.ConnectionStrings)) + for i, v := range *connStringResp.ConnectionStrings { + connStrings[i] = *v.ConnectionString + } + + } + d.Set("connection_strings", connStrings) + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmCosmosDbAccountDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["databaseAccounts"] + + future, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + return fmt.Errorf("Error issuing AzureRM delete request for CosmosDB Account '%s': %+v", name, err) + } + + //the SDK now will return a `WasNotFound` response even when still deleting + stateConf := &resource.StateChangeConf{ + Pending: []string{"Deleting"}, + Target: []string{"NotFound"}, + Timeout: 60 * time.Minute, + MinTimeout: 30 * time.Second, + Refresh: func() (interface{}, string, error) { + + resp, err2 := client.Get(ctx, resourceGroup, name) + if err2 != nil { + + if utils.ResponseWasNotFound(resp.Response) { + return resp, "NotFound", nil + } + return nil, "", fmt.Errorf("Error reading CosmosDB Account %q after delete (Resource Group %q): %+v", name, resourceGroup, err2) + } + + return resp, "Deleting", nil + }, + } + if _, err = stateConf.WaitForState(); err != nil { + return fmt.Errorf("Waiting forCosmosDB Account %q to delete (Resource Group %q): %+v", name, resourceGroup, err) + } + + return nil +} + +func resourceArmCosmosDbAccountApiUpsert(client *documentdb.DatabaseAccountsClient, ctx context.Context, resourceGroup string, name string, account documentdb.DatabaseAccountCreateUpdateParameters) (*documentdb.DatabaseAccount, error) { + future, err := client.CreateOrUpdate(ctx, resourceGroup, name, account) + if err != nil { + return nil, fmt.Errorf("Error creating/updating CosmosDB Account %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return nil, fmt.Errorf("Error waiting for the CosmosDB Account %q (Resource Group %q) to finish creating/updating: %+v", name, resourceGroup, err) + } + + //if a replication location is added or removed it can take some time to provision + stateConf := &resource.StateChangeConf{ + Pending: []string{"Creating", "Updating", "Deleting"}, + Target: []string{"Succeeded"}, + Timeout: 60 * time.Minute, + MinTimeout: 30 * time.Second, + Delay: 30 * time.Second, // required because it takes some time before the 'creating' location shows up + Refresh: func() (interface{}, string, error) { + + resp, err2 := client.Get(ctx, resourceGroup, name) + if err2 != nil { + return nil, "", fmt.Errorf("Error reading CosmosDB Account %q after create/update (Resource Group %q): %+v", name, resourceGroup, err2) + } + + status := "Succeeded" + for _, l := range append(*resp.ReadLocations, *resp.WriteLocations...) { + if status = *l.ProvisioningState; status == "Creating" || status == "Updating" || status == "Deleting" { + break //return the first non successful status. + } + } + + return resp, status, nil + }, + } + + resp, err := stateConf.WaitForState() + if err != nil { + return nil, fmt.Errorf("Error waiting for the CosmosDB Account %q (Resource Group %q) to provision: %+v", name, resourceGroup, err) + } + + r := resp.(documentdb.DatabaseAccount) + return &r, nil +} + +func expandAzureRmCosmosDBAccountConsistencyPolicy(d *schema.ResourceData) *documentdb.ConsistencyPolicy { + i := d.Get("consistency_policy").([]interface{}) + if len(i) <= 0 || i[0] == nil { + return nil + } + input := i[0].(map[string]interface{}) + + consistencyLevel := input["consistency_level"].(string) + policy := documentdb.ConsistencyPolicy{ + DefaultConsistencyLevel: documentdb.DefaultConsistencyLevel(consistencyLevel), + } + + if stalenessPrefix, ok := input["max_staleness_prefix"].(int); ok { + policy.MaxStalenessPrefix = utils.Int64(int64(stalenessPrefix)) + } + if maxInterval, ok := input["max_interval_in_seconds"].(int); ok { + policy.MaxIntervalInSeconds = utils.Int32(int32(maxInterval)) + } + + return &policy +} + +func resourceArmCosmosDbAccountGenerateDefaultId(databaseName string, location string) string { + return fmt.Sprintf("%s-%s", databaseName, location) +} + +func expandAzureRmCosmosDBAccountGeoLocations(databaseName string, d *schema.ResourceData) ([]documentdb.Location, error) { + + locations := make([]documentdb.Location, 0) + for _, l := range d.Get("geo_location").(*schema.Set).List() { + data := l.(map[string]interface{}) + + location := documentdb.Location{ + LocationName: utils.String(azure.NormalizeLocation(data["location"].(string))), + FailoverPriority: utils.Int32(int32(data["failover_priority"].(int))), + } + + if v, ok := data["prefix"].(string); ok { + data["id"] = v + } else { + data["id"] = utils.String(resourceArmCosmosDbAccountGenerateDefaultId(databaseName, *location.LocationName)) + } + location.ID = utils.String(data["id"].(string)) + + locations = append(locations, location) + } + + //TODO maybe this should be in a CustomizeDiff + // all priorities & locations must be unique + byPriorities := make(map[int]interface{}, len(locations)) + byName := make(map[string]interface{}, len(locations)) + for _, location := range locations { + + priority := int(*location.FailoverPriority) + name := *location.LocationName + + if _, ok := byPriorities[priority]; ok { + return nil, fmt.Errorf("Each `geo_location` needs to have a unique failover_prioroty. Multiple instances of '%d' found", priority) + } + + if _, ok := byName[name]; ok { + return nil, fmt.Errorf("Each `geo_location` needs to be in unique location. Multiple instances of '%s' found", name) + } + + byPriorities[priority] = location + byName[name] = location + } + + //and must have one of 0 priority + if _, ok := byPriorities[0]; !ok { + return nil, fmt.Errorf("There needs to be a `geo_location` with a failover_priority of 0") + } + + return locations, nil +} + +//todo remove when deprecated field `failover_policy` is +func expandAzureRmCosmosDBAccountFailoverPolicy(databaseName string, d *schema.ResourceData) ([]documentdb.Location, error) { + + input := d.Get("failover_policy").(*schema.Set).List() + locations := make([]documentdb.Location, 0, len(input)) + + for _, configRaw := range input { + data := configRaw.(map[string]interface{}) + + locationName := azure.NormalizeLocation(data["location"].(string)) + id := fmt.Sprintf("%s-%s", databaseName, locationName) + failoverPriority := int32(data["priority"].(int)) + + location := documentdb.Location{ + ID: &id, + LocationName: &locationName, + FailoverPriority: &failoverPriority, + } + + locations = append(locations, location) + } + + containsWriteLocation := false + writeFailoverPriority := int32(0) + for _, location := range locations { + if *location.FailoverPriority == writeFailoverPriority { + containsWriteLocation = true + break + } + } + + // all priorities must be unique + locationIds := make(map[int]struct{}, len(locations)) + for _, location := range locations { + priority := int(*location.FailoverPriority) + if _, ok := locationIds[priority]; ok { + return nil, fmt.Errorf("Each Failover Policy needs to be unique") + } + + locationIds[priority] = struct{}{} + } + + if !containsWriteLocation { + return nil, fmt.Errorf("Failover Policy should contain a Write Location (Location '0')") + } + + return locations, nil +} + +func expandAzureRmCosmosDBAccountCapabilities(d *schema.ResourceData) *[]documentdb.Capability { + + capabilities := d.Get("capabilities").(*schema.Set).List() + s := make([]documentdb.Capability, 0) + + for _, c := range capabilities { + m := c.(map[string]interface{}) + s = append(s, documentdb.Capability{Name: utils.String(m["name"].(string))}) + } + + return &s +} + +func expandAzureRmCosmosDBAccountVirtualNetworkRules(d *schema.ResourceData) *[]documentdb.VirtualNetworkRule { + virtualNetworkRules := d.Get("virtual_network_rule").(*schema.Set).List() + + s := make([]documentdb.VirtualNetworkRule, len(virtualNetworkRules)) + for i, r := range virtualNetworkRules { + m := r.(map[string]interface{}) + s[i] = documentdb.VirtualNetworkRule{ID: utils.String(m["id"].(string))} + } + return &s +} + +func flattenAzureRmCosmosDBAccountConsistencyPolicy(policy *documentdb.ConsistencyPolicy) []interface{} { + + result := map[string]interface{}{} + result["consistency_level"] = string(policy.DefaultConsistencyLevel) + if policy.MaxIntervalInSeconds != nil { + result["max_interval_in_seconds"] = int(*policy.MaxIntervalInSeconds) + } + if policy.MaxStalenessPrefix != nil { + result["max_staleness_prefix"] = int(*policy.MaxStalenessPrefix) + } + + return []interface{}{result} +} + +//todo remove when failover_policy field is removed +func flattenAzureRmCosmosDBAccountFailoverPolicy(list *[]documentdb.FailoverPolicy) *schema.Set { + results := schema.Set{ + F: resourceAzureRMCosmosDBAccountFailoverPolicyHash, + } + + for _, i := range *list { + result := map[string]interface{}{ + "id": *i.ID, + "location": azure.NormalizeLocation(*i.LocationName), + "priority": int(*i.FailoverPriority), + } + + results.Add(result) + } + + return &results +} + +func flattenAzureRmCosmosDBAccountGeoLocations(d *schema.ResourceData, account documentdb.DatabaseAccount) *schema.Set { + locationSet := schema.Set{ + F: resourceAzureRMCosmosDBAccountGeoLocationHash, + } + + //we need to propagate the `prefix` field so fetch existing + prefixMap := map[string]string{} + if locations, ok := d.GetOk("geo_location"); ok { + for _, lRaw := range locations.(*schema.Set).List() { + lb := lRaw.(map[string]interface{}) + prefixMap[lb["location"].(string)] = lb["prefix"].(string) + } + } + + for _, l := range *account.FailoverPolicies { + id := *l.ID + lb := map[string]interface{}{ + "id": id, + "location": azure.NormalizeLocation(*l.LocationName), + "failover_priority": int(*l.FailoverPriority), + } + + //if id is not the default then it must be set via prefix + if id != resourceArmCosmosDbAccountGenerateDefaultId(d.Get("name").(string), lb["location"].(string)) { + lb["prefix"] = id + } + + locationSet.Add(lb) + } + + return &locationSet +} + +func flattenAzureRmCosmosDBAccountCapabilities(capabilities *[]documentdb.Capability) *schema.Set { + s := schema.Set{ + F: resourceAzureRMCosmosDBAccountCapabilitiesHash, + } + + for _, c := range *capabilities { + if v := c.Name; v != nil { + e := map[string]interface{}{ + "name": *v, + } + s.Add(e) + } + } + + return &s +} + +func flattenAzureRmCosmosDBAccountVirtualNetworkRules(rules *[]documentdb.VirtualNetworkRule) *schema.Set { + results := schema.Set{ + F: resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash, + } + + if rules != nil { + for _, r := range *rules { + rule := map[string]interface{}{ + "id": *r.ID, + } + results.Add(rule) + } + } + + return &results +} + +//todo remove once deprecated field `failover_policy` is removed +func resourceAzureRMCosmosDBAccountFailoverPolicyHash(v interface{}) int { + var buf bytes.Buffer + + if m, ok := v.(map[string]interface{}); ok { + location := azure.NormalizeLocation(m["location"].(string)) + priority := int32(m["priority"].(int)) + + buf.WriteString(fmt.Sprintf("%s-%d", location, priority)) + } + + return hashcode.String(buf.String()) +} + +func resourceAzureRMCosmosDBAccountGeoLocationHash(v interface{}) int { + var buf bytes.Buffer + + if m, ok := v.(map[string]interface{}); ok { + prefix := "" + if v, ok := m["prefix"].(string); ok { + prefix = v + } + location := azure.NormalizeLocation(m["location"].(string)) + priority := int32(m["failover_priority"].(int)) + + buf.WriteString(fmt.Sprintf("%s-%s-%d", prefix, location, priority)) + } + + return hashcode.String(buf.String()) +} + +func resourceAzureRMCosmosDBAccountCapabilitiesHash(v interface{}) int { + var buf bytes.Buffer + + if m, ok := v.(map[string]interface{}); ok { + buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) + } + + return hashcode.String(buf.String()) +} + +func resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash(v interface{}) int { + var buf bytes.Buffer + + if m, ok := v.(map[string]interface{}); ok { + buf.WriteString(strings.ToLower(m["id"].(string))) + } + + return hashcode.String(buf.String()) +} diff --git a/azurerm/resource_arm_cosmosdb_account_failover_test.go b/azurerm/resource_arm_cosmosdb_account_failover_test.go new file mode 100644 index 000000000000..d515c674e9d8 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_account_failover_test.go @@ -0,0 +1,333 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMCosmosDBAccount_failover_boundedStaleness(t *testing.T) { + resourceName := "azurerm_cosmosdb_account.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMCosmosDBAccount_failover_boundedStaleness(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCosmosDBAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), + ), + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_failover_boundedStalenessComplete(t *testing.T) { + + ri := tf.AccRandTimeInt() + config := testAccAzureRMCosmosDBAccount_failover_boundedStalenessComplete(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_failover_eventualConsistency(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMCosmosDBAccount_failover_eventualConsistency(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_failover_mongoDB(t *testing.T) { + resourceName := "azurerm_cosmosdb_account.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMCosmosDBAccount_failover_mongoDB(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCosmosDBAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), + ), + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_failover_session(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMCosmosDBAccount_failover_session(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_failover_strong(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMCosmosDBAccount_failover_strong(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_failover_geoReplicated(t *testing.T) { + + ri := tf.AccRandTimeInt() + config := testAccAzureRMCosmosDBAccount_failover_geoReplicated(ri, testLocation(), testAltLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCosmosDBAccountExists("azurerm_cosmosdb_account.test"), + ), + }, + }, + }) +} + +func testAccAzureRMCosmosDBAccount_failover_boundedStaleness(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_cosmosdb_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + offer_type = "Standard" + + consistency_policy { + consistency_level = "BoundedStaleness" + } + + failover_policy { + location = "${azurerm_resource_group.test.location}" + priority = 0 + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMCosmosDBAccount_failover_boundedStalenessComplete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_cosmosdb_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + offer_type = "Standard" + + consistency_policy { + consistency_level = "BoundedStaleness" + max_interval_in_seconds = 10 + max_staleness_prefix = 200 + } + + failover_policy { + location = "${azurerm_resource_group.test.location}" + priority = 0 + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMCosmosDBAccount_failover_eventualConsistency(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_cosmosdb_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + offer_type = "Standard" + + consistency_policy { + consistency_level = "Eventual" + } + + failover_policy { + location = "${azurerm_resource_group.test.location}" + priority = 0 + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMCosmosDBAccount_failover_session(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_cosmosdb_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + offer_type = "Standard" + + consistency_policy { + consistency_level = "Session" + } + + failover_policy { + location = "${azurerm_resource_group.test.location}" + priority = 0 + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMCosmosDBAccount_failover_mongoDB(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_cosmosdb_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + kind = "MongoDB" + offer_type = "Standard" + + consistency_policy { + consistency_level = "BoundedStaleness" + } + + failover_policy { + location = "${azurerm_resource_group.test.location}" + priority = 0 + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMCosmosDBAccount_failover_strong(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_cosmosdb_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + offer_type = "Standard" + + consistency_policy { + consistency_level = "Strong" + } + + failover_policy { + location = "${azurerm_resource_group.test.location}" + priority = 0 + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMCosmosDBAccount_failover_geoReplicated(rInt int, location string, altLocation string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_cosmosdb_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + offer_type = "Standard" + + consistency_policy { + consistency_level = "BoundedStaleness" + max_interval_in_seconds = 333 + max_staleness_prefix = 101101 + } + + failover_policy { + location = "${azurerm_resource_group.test.location}" + priority = 0 + } + + failover_policy { + location = "%s" + priority = 1 + } +} +`, rInt, location, rInt, altLocation) +} diff --git a/azurerm/resource_arm_cosmosdb_account_test.go b/azurerm/resource_arm_cosmosdb_account_test.go new file mode 100644 index 000000000000..e8521dafce56 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_account_test.go @@ -0,0 +1,972 @@ +package azurerm + +import ( + "fmt" + "net/http" + "strconv" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +// TODO: refactor the test configs + +//consistency +func TestAccAzureRMCosmosDBAccount_eventualConsistency(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Eventual), "", ""), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Eventual), 1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccAzureRMCosmosDBAccount_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_cosmosdb_account.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, location, string(documentdb.Eventual), "", ""), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Eventual), 1), + ), + }, + { + Config: testAccAzureRMCosmosDBAccount_requiresImport(ri, location, string(documentdb.Eventual), "", ""), + ExpectError: testRequiresImportError("azurerm_cosmosdb_account"), + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_session(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Session), "", ""), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Session), 1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_strong(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Strong), "", ""), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Strong), 1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_consistentPrefix(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.ConsistentPrefix), "", ""), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.ConsistentPrefix), 1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_boundedStaleness(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.BoundedStaleness), "", ""), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_boundedStaleness_complete(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_boundedStaleness_complete(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "consistency_policy.0.max_interval_in_seconds", "10"), + resource.TestCheckResourceAttr(resourceName, "consistency_policy.0.max_staleness_prefix", "200"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_consistency_change(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Session), "", ""), + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Session), 1), + }, + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.BoundedStaleness), "", ""), + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +//DB kinds +func TestAccAzureRMCosmosDBAccount_mongoDB(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_mongoDB(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), + resource.TestCheckResourceAttr(resourceName, "connection_strings.#", "4"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_capabilityGremlin(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_capabilityGremlin(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_capabilityTable(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_capabilityTable(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_capabilityCassandra(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_capabilityCassandra(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_capabilityAggregationPipeline(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_capabilityAggregationPipeline(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "GlobalDocumentDB"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_capabilityMongo35(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_capabilityMongo34(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_capabilityDocLevelTTL(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_capabilityDocLevelTTL(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_capabilityUpdate(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_capabilityDocLevelTTL(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), + ), + }, + { + Config: testAccAzureRMCosmosDBAccount_capabilityMongo34(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + resource.TestCheckResourceAttr(resourceName, "kind", "MongoDB"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAbcAzureRMCosmosDBAccount_updatePropertiesAndLocation(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Session), "", ""), + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Session), 1), + }, + { + Config: testAccAzureRMCosmosDBAccount_geoReplicated_customId(ri, testLocation(), testAltLocation()), + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +//replication +func TestAccAzureRMCosmosDBAccount_geoReplicated_customId(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_geoReplicated_customId(ri, testLocation(), testAltLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_geoReplicated_add_remove(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + configBasic := testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.BoundedStaleness), "", "") + configReplicated := testAccAzureRMCosmosDBAccount_geoReplicated_customId(ri, testLocation(), testAltLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: configBasic, + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + }, + { + Config: configReplicated, + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), + ), + }, + { + Config: configBasic, + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_geoReplicated_rename(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_geoReplicated(ri, testLocation(), testAltLocation()), + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), + }, + { + Config: testAccAzureRMCosmosDBAccount_geoReplicated_customId(ri, testLocation(), testAltLocation()), + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_virtualNetworkFilter(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_virtualNetworkFilter(ri, testLocation()), + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +//basic --> complete ( +func TestAccAzureRMCosmosDBAccount_complete(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_basic(ri, testLocation(), string(documentdb.Session), "", ""), + Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.Session), 1), + }, + { + Config: testAccAzureRMCosmosDBAccount_complete(ri, testLocation(), testAltLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), + resource.TestCheckResourceAttr(resourceName, "ip_range_filter", "104.42.195.92,40.76.54.131,52.176.6.30,52.169.50.45/32,52.187.184.26,10.20.0.0/16"), + resource.TestCheckResourceAttr(resourceName, "enable_automatic_failover", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_emptyIpFilter(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_emptyIpFilter(ri, testLocation(), testAltLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 2), + resource.TestCheckResourceAttr(resourceName, "ip_range_filter", ""), + resource.TestCheckResourceAttr(resourceName, "enable_automatic_failover", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDBAccount_multiMaster(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_account.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDBAccount_multiMaster(ri, testLocation(), testAltLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "geo_location.#", "2"), + resource.TestCheckResourceAttr(resourceName, "write_endpoints.#", "2"), + resource.TestCheckResourceAttr(resourceName, "enable_multiple_write_locations", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMCosmosDBAccountDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cosmosdb_account" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, name) + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("CosmosDB Account still exists:\n%#v", resp) + } + } + + return nil +} + +func testCheckAzureRMCosmosDBAccountExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Bad: Get on cosmosAccountsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: CosmosDB Account '%s' (resource group: '%s') does not exist", name, resourceGroup) + } + + return nil + } +} + +func testAccAzureRMCosmosDBAccount_basic(rInt int, location string, consistency string, consistencyOptions string, additional string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_cosmosdb_account" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + offer_type = "Standard" + + consistency_policy { + consistency_level = "%s" + + %s + } + + geo_location { + location = "${azurerm_resource_group.test.location}" + failover_priority = 0 + } + + %s +} +`, rInt, location, rInt, consistency, consistencyOptions, additional) +} + +func testAccAzureRMCosmosDBAccount_requiresImport(rInt int, location string, consistency string, consistencyOptions string, additional string) string { + template := testAccAzureRMCosmosDBAccount_basic(rInt, location, consistency, consistencyOptions, additional) + return fmt.Sprintf(` +%s + +resource "azurerm_cosmosdb_account" "import" { + name = "${azurerm_cosmosdb_account.test.name}" + location = "${azurerm_cosmosdb_account.test.location}" + resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" + offer_type = "Standard" + + consistency_policy { + consistency_level = "%s" + + %s + } + + geo_location { + location = "${azurerm_resource_group.test.location}" + failover_priority = 0 + } + + %s +} +`, template, consistency, consistencyOptions, additional) +} + +func testAccAzureRMCosmosDBAccount_boundedStaleness_complete(rInt int, location string) string { + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), ` + max_interval_in_seconds = 10 + max_staleness_prefix = 200 +`, "") +} + +func testAccAzureRMCosmosDBAccount_mongoDB(rInt int, location string) string { + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` + kind = "MongoDB" + `) +} + +func testAccAzureRMCosmosDBAccount_capabilityGremlin(rInt int, location string) string { + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` + kind = "GlobalDocumentDB" + + capabilities { + name = "EnableGremlin" + } + `) +} + +func testAccAzureRMCosmosDBAccount_capabilityTable(rInt int, location string) string { + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` + kind = "GlobalDocumentDB" + + capabilities { + name = "EnableTable" + } + `) +} + +func testAccAzureRMCosmosDBAccount_capabilityCassandra(rInt int, location string) string { + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` + kind = "GlobalDocumentDB" + + capabilities { + name = "EnableCassandra" + } + `) +} + +func testAccAzureRMCosmosDBAccount_capabilityAggregationPipeline(rInt int, location string) string { + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` + kind = "GlobalDocumentDB" + + capabilities { + name = "EnableAggregationPipeline" + } + `) +} + +func testAccAzureRMCosmosDBAccount_capabilityMongo34(rInt int, location string) string { + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` + kind = "MongoDB" + + capabilities { + name = "MongoDBv3.4" + } + `) +} + +func testAccAzureRMCosmosDBAccount_capabilityDocLevelTTL(rInt int, location string) string { + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` + kind = "MongoDB" + + capabilities { + name = "mongoEnableDocLevelTTL" + } + `) +} + +func testAccAzureRMCosmosDBAccount_geoReplicated(rInt int, location string, altLocation string) string { + co := ` + max_interval_in_seconds = 373 + max_staleness_prefix = 100001 +` + + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), co, fmt.Sprintf(` + geo_location { + location = "%s" + failover_priority = 1 + } + + `, altLocation)) +} + +func testAccAzureRMCosmosDBAccount_multiMaster(rInt int, location string, altLocation string) string { + co := ` + max_interval_in_seconds = 373 + max_staleness_prefix = 100001 +` + + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), co, fmt.Sprintf(` + enable_multiple_write_locations = true + + geo_location { + location = "%s" + failover_priority = 1 + } + + `, altLocation)) +} + +func testAccAzureRMCosmosDBAccount_geoReplicated_customId(rInt int, location string, altLocation string) string { + co := ` + max_interval_in_seconds = 373 + max_staleness_prefix = 100001 +` + + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), co, fmt.Sprintf(` + geo_location { + prefix = "acctest-%d-custom-id" + location = "%s" + failover_priority = 1 + } + + `, rInt, altLocation)) +} + +func testAccAzureRMCosmosDBAccount_complete(rInt int, location string, altLocation string) string { + co := ` + max_interval_in_seconds = 373 + max_staleness_prefix = 100001 +` + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), co, fmt.Sprintf(` + ip_range_filter = "104.42.195.92,40.76.54.131,52.176.6.30,52.169.50.45/32,52.187.184.26,10.20.0.0/16" + enable_automatic_failover = true + + geo_location { + prefix = "acctest-%d-custom-id" + location = "%s" + failover_priority = 1 + } + `, rInt, altLocation)) +} + +func testAccAzureRMCosmosDBAccount_emptyIpFilter(rInt int, location string, altLocation string) string { + co := ` + max_interval_in_seconds = 373 + max_staleness_prefix = 100001 +` + + return testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), co, fmt.Sprintf(` + ip_range_filter = "" + enable_automatic_failover = true + + geo_location { + prefix = "acctest-%d-custom-id" + location = "%s" + failover_priority = 1 + } + `, rInt, altLocation)) +} + +func testAccAzureRMCosmosDBAccount_virtualNetworkFilter(rInt int, location string) string { + vnetConfig := fmt.Sprintf(` +resource "azurerm_virtual_network" "test" { + name = "acctest-%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + dns_servers = ["10.0.0.4", "10.0.0.5"] +} + +resource "azurerm_subnet" "subnet1" { + name = "acctest-%[1]d-1" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.1.0/24" + service_endpoints = ["Microsoft.AzureCosmosDB"] +} + +resource "azurerm_subnet" "subnet2" { + name = "acctest-%[1]d-2" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + service_endpoints = ["Microsoft.AzureCosmosDB"] +} +`, rInt) + + basic := testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", ` + is_virtual_network_filter_enabled = true + + virtual_network_rule { + id = "${azurerm_subnet.subnet1.id}" + } + + virtual_network_rule { + id = "${azurerm_subnet.subnet2.id}" + } + `) + + return vnetConfig + basic +} + +func checkAccAzureRMCosmosDBAccount_basic(resourceName string, location string, consistency string, locationCount int) resource.TestCheckFunc { + return resource.ComposeTestCheckFunc( + testCheckAzureRMCosmosDBAccountExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "name"), + resource.TestCheckResourceAttrSet(resourceName, "resource_group_name"), + resource.TestCheckResourceAttr(resourceName, "location", azure.NormalizeLocation(location)), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "offer_type", string(documentdb.Standard)), + resource.TestCheckResourceAttr(resourceName, "consistency_policy.0.consistency_level", consistency), + resource.TestCheckResourceAttr(resourceName, "geo_location.#", strconv.Itoa(locationCount)), + resource.TestCheckResourceAttrSet(resourceName, "endpoint"), + resource.TestCheckResourceAttr(resourceName, "read_endpoints.#", strconv.Itoa(locationCount)), + resource.TestCheckResourceAttr(resourceName, "write_endpoints.#", "1"), + resource.TestCheckResourceAttr(resourceName, "enable_multiple_write_locations", "false"), + resource.TestCheckResourceAttrSet(resourceName, "primary_master_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_master_key"), + resource.TestCheckResourceAttrSet(resourceName, "primary_readonly_master_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_readonly_master_key"), + ) +} diff --git a/azurerm/resource_arm_cosmosdb_cassandra_keyspace.go b/azurerm/resource_arm_cosmosdb_cassandra_keyspace.go new file mode 100644 index 000000000000..8793bceb3386 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_cassandra_keyspace.go @@ -0,0 +1,154 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmCosmosDbCassandraKeyspace() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCosmosDbCassandraKeyspaceCreate, + Read: resourceArmCosmosDbCassandraKeyspaceRead, + Delete: resourceArmCosmosDbCassandraKeyspaceDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosAccountName, + }, + }, + } +} + +func resourceArmCosmosDbCassandraKeyspaceCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + account := d.Get("account_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.GetCassandraKeyspace(ctx, resourceGroup, account, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Cassandra Keyspace %s (Account %s): %+v", name, account, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos Cassandra Keyspace '%s' (Account %s)", name, account) + } + + return tf.ImportAsExistsError("azurerm_cosmosdb_cassandra_keyspace", id) + } + } + + db := documentdb.CassandraKeyspaceCreateUpdateParameters{ + CassandraKeyspaceCreateUpdateProperties: &documentdb.CassandraKeyspaceCreateUpdateProperties{ + Resource: &documentdb.CassandraKeyspaceResource{ + ID: &name, + }, + Options: map[string]*string{}, + }, + } + + future, err := client.CreateUpdateCassandraKeyspace(ctx, resourceGroup, account, name, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos Cassandra Keyspace %s (Account %s): %+v", name, account, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos Cassandra Keyspace %s (Account %s): %+v", name, account, err) + } + + resp, err := client.GetCassandraKeyspace(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos Cassandra Keyspace %s (Account %s): %+v", name, account, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error retrieving the ID for Cosmos Cassandra Keyspace '%s' (Account %s) ID: %v", name, account, err) + } + d.SetId(id) + + return resourceArmCosmosDbCassandraKeyspaceRead(d, meta) +} + +func resourceArmCosmosDbCassandraKeyspaceRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosKeyspaceID(d.Id()) + if err != nil { + return err + } + + resp, err := client.GetCassandraKeyspace(ctx, id.ResourceGroup, id.Account, id.Keyspace) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading Cosmos Cassandra Keyspace %s (Account %s) - removing from state", id.Keyspace, id.Account) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Cosmos Cassandra Keyspace %s (Account %s): %+v", id.Keyspace, id.Account, err) + } + + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.Account) + if props := resp.CassandraKeyspaceProperties; props != nil { + d.Set("name", props.ID) + } + + return nil +} + +func resourceArmCosmosDbCassandraKeyspaceDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosKeyspaceID(d.Id()) + if err != nil { + return err + } + + future, err := client.DeleteCassandraKeyspace(ctx, id.ResourceGroup, id.Account, id.Keyspace) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting Cosmos Cassandra Keyspace %s (Account %s): %+v", id.Keyspace, id.Account, err) + } + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting on delete future for Cosmos Cassandra Keyspace %s (Account %s): %+v", id.Keyspace, id.Account, err) + } + + return nil +} diff --git a/azurerm/resource_arm_cosmosdb_cassandra_keyspace_test.go b/azurerm/resource_arm_cosmosdb_cassandra_keyspace_test.go new file mode 100644 index 000000000000..c40a6033ed5c --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_cassandra_keyspace_test.go @@ -0,0 +1,104 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMCosmosDbCassandraKeyspace_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_cassandra_keyspace.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbCassandraKeyspaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbCassandraKeyspace_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbCassandraKeyspaceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMCosmosDbCassandraKeyspaceDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cosmosdb_cassandra_keyspace" { + continue + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetCassandraKeyspace(ctx, resourceGroup, account, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Error checking destroy for Cosmos Cassandra Keyspace %s (account %s) still exists:\n%v", name, account, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Cosmos Cassandra Keyspace %s (account %s) still exists:\n%#v", name, account, resp) + } + } + + return nil +} + +func testCheckAzureRMCosmosDbCassandraKeyspaceExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetCassandraKeyspace(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Bad: Get on cosmosAccountsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Cosmos database '%s' (account: '%s') does not exist", name, account) + } + + return nil + } +} + +func testAccAzureRMCosmosDbCassandraKeyspace_basic(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_cassandra_keyspace" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_account.test.name}" +} +`, testAccAzureRMCosmosDBAccount_capabilityCassandra(rInt, location), rInt) +} diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection.go b/azurerm/resource_arm_cosmosdb_mongo_collection.go new file mode 100644 index 000000000000..dea152d3d808 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_mongo_collection.go @@ -0,0 +1,303 @@ +package azurerm + +import ( + "fmt" + "log" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmCosmosDbMongoCollection() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCosmosDbMongoCollectionCreateUpdate, + Read: resourceArmCosmosDbMongoCollectionRead, + Update: resourceArmCosmosDbMongoCollectionCreateUpdate, + Delete: resourceArmCosmosDbMongoCollectionDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosAccountName, + }, + + "database_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + // SDK/api accepts an array.. but only one is allowed + "shard_key": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + // default TTL is simply an index on _ts with expireAfterOption, given we can't seem to set TTLs on a given index lets expose this to match the portal + "default_ttl_seconds": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(-1), + }, + + "indexes": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, // this is a list in the SDK/API, however any more then a single value causes a 404 + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "unique": { + Type: schema.TypeBool, + Optional: true, + Default: true, // portal defaults to true + }, + + // expire_after_seconds is only allowed on `_ts`: + // Unable to parse request payload due to the following reason: 'The 'expireAfterSeconds' option is supported on '_ts' field only. + }, + }, + }, + }, + } +} + +func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + account := d.Get("account_name").(string) + database := d.Get("database_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos Mongo Collection %s (Account %s, Database %s)", name, account, database) + } + + return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_collection", id) + } + } + + var ttl *int + if v, ok := d.GetOkExists("default_ttl_seconds"); ok { + ttl = utils.Int(v.(int)) + } + + db := documentdb.MongoDBCollectionCreateUpdateParameters{ + MongoDBCollectionCreateUpdateProperties: &documentdb.MongoDBCollectionCreateUpdateProperties{ + Resource: &documentdb.MongoDBCollectionResource{ + ID: &name, + Indexes: expandCosmosMongoCollectionIndexes(d.Get("indexes"), ttl), + }, + Options: map[string]*string{}, + }, + } + + if v, ok := d.GetOkExists("shard_key"); ok { + db.MongoDBCollectionCreateUpdateProperties.Resource.ShardKey = map[string]*string{ + v.(string): utils.String("Hash"), // looks like only hash is supported for now + } + } + + future, err := client.CreateUpdateMongoDBCollection(ctx, resourceGroup, account, database, name, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + + resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error getting ID for Cosmos Mongo Collection %s (Account %s, Database %s) ID: %v", name, account, database, err) + } + d.SetId(id) + + return resourceArmCosmosDbMongoCollectionRead(d, meta) +} + +func resourceArmCosmosDbMongoCollectionRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseCollectionID(d.Id()) + if err != nil { + return err + } + + resp, err := client.GetMongoDBCollection(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading Cosmos Mongo Collection %s (Account %s, Database %s)", id.Collection, id.Account, id.Database) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.Account) + d.Set("database_name", id.Database) + if props := resp.MongoDBCollectionProperties; props != nil { + d.Set("name", props.ID) + + // you can only have one + if len(props.ShardKey) > 2 { + return fmt.Errorf("unexpected number of shard keys: %d", len(props.ShardKey)) + } + + for k := range props.ShardKey { + d.Set("shard_key", k) + } + + if props.Indexes != nil { + indexes, ttl := flattenCosmosMongoCollectionIndexes(props.Indexes) + d.Set("default_ttl_seconds", ttl) + if err := d.Set("indexes", indexes); err != nil { + return fmt.Errorf("Error setting `indexes`: %+v", err) + } + } + } + + return nil +} + +func resourceArmCosmosDbMongoCollectionDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseCollectionID(d.Id()) + if err != nil { + return err + } + + future, err := client.DeleteMongoDBCollection(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting on delete future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + + return nil +} + +func expandCosmosMongoCollectionIndexes(input interface{}, defaultTtl *int) *[]documentdb.MongoIndex { + outputs := make([]documentdb.MongoIndex, 0) + + for _, i := range input.(*schema.Set).List() { + b := i.(map[string]interface{}) + outputs = append(outputs, documentdb.MongoIndex{ + Key: &documentdb.MongoIndexKeys{ + Keys: &[]string{b["key"].(string)}, + }, + Options: &documentdb.MongoIndexOptions{ + Unique: utils.Bool(b["unique"].(bool)), + }, + }) + } + + if defaultTtl != nil { + outputs = append(outputs, documentdb.MongoIndex{ + Key: &documentdb.MongoIndexKeys{ + Keys: &[]string{"_ts"}, + }, + Options: &documentdb.MongoIndexOptions{ + ExpireAfterSeconds: utils.Int32(int32(*defaultTtl)), + }, + }) + } + + return &outputs +} + +func flattenCosmosMongoCollectionIndexes(indexes *[]documentdb.MongoIndex) (*[]map[string]interface{}, *int) { + slice := make([]map[string]interface{}, 0) + + var ttl int + for _, i := range *indexes { + if key := i.Key; key != nil { + m := map[string]interface{}{} + var ttlInner int32 + + if options := i.Options; options != nil { + if v := options.Unique; v != nil { + m["unique"] = *v + } else { + m["unique"] = false // todo required? API sends back nothing for false + } + + if v := options.ExpireAfterSeconds; v != nil { + ttlInner = *v + } + } + + if keys := key.Keys; keys != nil && len(*keys) > 0 { + k := (*keys)[0] + + if !strings.HasPrefix(k, "_") && k != "DocumentDBDefaultIndex" { // lets ignore system properties? + m["key"] = k + + // only append indexes with a non system key + slice = append(slice, m) + } + + if k == "_ts" { + ttl = int(ttlInner) + } + } + } + } + + return &slice, &ttl +} diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go new file mode 100644 index 000000000000..c67b65e9b284 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go @@ -0,0 +1,236 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMCosmosDbMongoCollection_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoCollection_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDbMongoCollection_complete(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoCollection_complete(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "shard_key", "day"), + resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"), + resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDbMongoCollection_update(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoCollection_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + ), + }, + { + Config: testAccAzureRMCosmosDbMongoCollection_complete(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "shard_key", "day"), + resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"), + resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMCosmosDbMongoCollection_updated(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "70707"), + resource.TestCheckResourceAttr(resourceName, "indexes.#", "3"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMCosmosDbMongoCollectionDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cosmosdb_mongo_collection" { + continue + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + database := rs.Primary.Attributes["database_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Error checking destroy for Cosmos Mongo Collection %s (account %s, database %s) still exists:\n%v", name, account, database, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Cosmos Mongo Collection %s (account %s) still exists:\n%#v", name, account, resp) + } + } + + return nil +} + +func testCheckAzureRMCosmosDbMongoCollectionExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + database := rs.Primary.Attributes["database_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + return fmt.Errorf("Bad: Get on cosmosAccountsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Cosmos database '%s' (account: '%s', database: %s) does not exist", name, account, database) + } + + return nil + } +} + +func testAccAzureRMCosmosDbMongoCollection_basic(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_collection" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_mongo_database.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" + database_name = "${azurerm_cosmosdb_mongo_database.test.name}" +} +`, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt) +} + +func testAccAzureRMCosmosDbMongoCollection_complete(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_collection" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_mongo_database.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" + database_name = "${azurerm_cosmosdb_mongo_database.test.name}" + + default_ttl_seconds = 707 + shard_key = "day" + + indexes { + key = "seven" + unique = false + } + + indexes { + key = "day" + unique = true + } +} +`, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt) +} + +func testAccAzureRMCosmosDbMongoCollection_updated(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_collection" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_mongo_database.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" + database_name = "${azurerm_cosmosdb_mongo_database.test.name}" + + default_ttl_seconds = 70707 + + indexes { + key = "seven" + unique = true + } + + indexes { + key = "day" + unique = false + } + + indexes { + key = "fool" + unique = false + } +} +`, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt) +} diff --git a/azurerm/resource_arm_cosmosdb_mongo_database.go b/azurerm/resource_arm_cosmosdb_mongo_database.go new file mode 100644 index 000000000000..93f82a4d35f2 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_mongo_database.go @@ -0,0 +1,154 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmCosmosDbMongoDatabase() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCosmosDbMongoDatabaseCreate, + Read: resourceArmCosmosDbMongoDatabaseRead, + Delete: resourceArmCosmosDbMongoDatabaseDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosAccountName, + }, + }, + } +} + +func resourceArmCosmosDbMongoDatabaseCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + account := d.Get("account_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Database %s (Account %s): %+v", name, account, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos Mongo Database '%s' (Account %s)", name, account) + } + + return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_database", id) + } + } + + db := documentdb.MongoDBDatabaseCreateUpdateParameters{ + MongoDBDatabaseCreateUpdateProperties: &documentdb.MongoDBDatabaseCreateUpdateProperties{ + Resource: &documentdb.MongoDBDatabaseResource{ + ID: &name, + }, + Options: map[string]*string{}, + }, + } + + future, err := client.CreateUpdateMongoDBDatabase(ctx, resourceGroup, account, name, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) + } + + resp, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error retrieving the ID for Cosmos Mongo Database '%s' (Account %s) ID: %v", name, account, err) + } + d.SetId(id) + + return resourceArmCosmosDbMongoDatabaseRead(d, meta) +} + +func resourceArmCosmosDbMongoDatabaseRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseID(d.Id()) + if err != nil { + return err + } + + resp, err := client.GetMongoDBDatabase(ctx, id.ResourceGroup, id.Account, id.Database) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading Cosmos Mongo Database %s (Account %s) - removing from state", id.Database, id.Account) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) + } + + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.Account) + if props := resp.MongoDBDatabaseProperties; props != nil { + d.Set("name", props.ID) + } + + return nil +} + +func resourceArmCosmosDbMongoDatabaseDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseID(d.Id()) + if err != nil { + return err + } + + future, err := client.DeleteMongoDBDatabase(ctx, id.ResourceGroup, id.Account, id.Database) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) + } + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting on delete future for Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) + } + + return nil +} diff --git a/azurerm/resource_arm_cosmosdb_mongo_database_test.go b/azurerm/resource_arm_cosmosdb_mongo_database_test.go new file mode 100644 index 000000000000..8fdacdb2e43e --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_mongo_database_test.go @@ -0,0 +1,104 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMCosmosDbMongoDatabase_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_database.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoDatabaseDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoDatabase_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoDatabaseExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMCosmosDbMongoDatabaseDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cosmosdb_mongo_database" { + continue + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Error checking destroy for Cosmos Mongo Database %s (account %s) still exists:\n%v", name, account, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Cosmos Mongo Database %s (account %s) still exists:\n%#v", name, account, resp) + } + } + + return nil +} + +func testCheckAzureRMCosmosDbMongoDatabaseExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Bad: Get on cosmosAccountsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Cosmos database '%s' (account: '%s') does not exist", name, account) + } + + return nil + } +} + +func testAccAzureRMCosmosDbMongoDatabase_basic(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_database" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_account.test.name}" +} +`, testAccAzureRMCosmosDBAccount_mongoDB(rInt, location), rInt) +} diff --git a/azurerm/resource_arm_cosmosdb_sql_container.go b/azurerm/resource_arm_cosmosdb_sql_container.go new file mode 100644 index 000000000000..64e92cdc5729 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_sql_container.go @@ -0,0 +1,262 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmCosmosDbSQLContainer() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCosmosDbSQLContainerCreate, + Read: resourceArmCosmosDbSQLContainerRead, + Delete: resourceArmCosmosDbSQLContainerDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosAccountName, + }, + + "database_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "partition_key_path": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "unique_key": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "paths": { + Type: schema.TypeSet, + Required: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + }, + } +} + +func resourceArmCosmosDbSQLContainerCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + database := d.Get("database_name").(string) + account := d.Get("account_name").(string) + partitionkeypaths := d.Get("partition_key_path").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.GetSQLContainer(ctx, resourceGroup, account, database, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos SQL Container %s (Account: %s, Database:%s): %+v", name, account, database, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos SQL Container '%s' (Account: %s, Database:%s)", name, account, database) + } + + return tf.ImportAsExistsError("azurerm_cosmosdb_sql_container", id) + } + } + + db := documentdb.SQLContainerCreateUpdateParameters{ + SQLContainerCreateUpdateProperties: &documentdb.SQLContainerCreateUpdateProperties{ + Resource: &documentdb.SQLContainerResource{ + ID: &name, + }, + Options: map[string]*string{}, + }, + } + + if partitionkeypaths != "" { + db.SQLContainerCreateUpdateProperties.Resource.PartitionKey = &documentdb.ContainerPartitionKey{ + Paths: &[]string{partitionkeypaths}, + Kind: documentdb.PartitionKindHash, + } + } + + if keys := expandCosmosSQLContainerUniqueKeys(d.Get("unique_key").(*schema.Set)); keys != nil { + db.SQLContainerCreateUpdateProperties.Resource.UniqueKeyPolicy = &documentdb.UniqueKeyPolicy{ + UniqueKeys: keys, + } + } + + future, err := client.CreateUpdateSQLContainer(ctx, resourceGroup, account, database, name, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos SQL Container %s (Account: %s, Database:%s): %+v", name, account, database, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos SQL Container %s (Account: %s, Database:%s): %+v", name, account, database, err) + } + + resp, err := client.GetSQLContainer(ctx, resourceGroup, account, database, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos SQL Container %s (Account: %s, Database:%s): %+v", name, account, database, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error retrieving the ID for Cosmos SQL Container '%s' (Account: %s, Database:%s) ID: %v", name, account, database, err) + } + d.SetId(id) + + return resourceArmCosmosDbSQLContainerRead(d, meta) +} + +func resourceArmCosmosDbSQLContainerRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseContainerID(d.Id()) + if err != nil { + return err + } + + resp, err := client.GetSQLContainer(ctx, id.ResourceGroup, id.Account, id.Database, id.Container) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading Cosmos SQL Container %s (Account %s) - removing from state", id.Database, id.Container) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Cosmos SQL Container %s (Account %s): %+v", id.Database, id.Container, err) + } + + d.Set("name", id.Container) + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.Account) + d.Set("database_name", id.Database) + + if props := resp.SQLContainerProperties; props != nil { + if pk := props.PartitionKey; pk != nil { + if paths := pk.Paths; paths != nil { + if len(*paths) > 1 { + return fmt.Errorf("Error reading PartitionKey Paths, more then 1 returned") + } else if len(*paths) == 1 { + d.Set("partition_key_path", (*paths)[0]) + } + } + } + + if ukp := props.UniqueKeyPolicy; ukp != nil { + if err := d.Set("unique_key", flattenCosmosSQLContainerUniqueKeys(ukp.UniqueKeys)); err != nil { + return fmt.Errorf("Error setting `unique_key`: %+v", err) + } + } + } + + return nil +} + +func resourceArmCosmosDbSQLContainerDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseContainerID(d.Id()) + if err != nil { + return err + } + + future, err := client.DeleteSQLContainer(ctx, id.ResourceGroup, id.Account, id.Database, id.Container) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting Cosmos SQL Container %s (Account %s): %+v", id.Database, id.Container, err) + } + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting on delete future for Cosmos SQL Container %s (Account %s): %+v", id.Database, id.Account, err) + } + + return nil +} + +func expandCosmosSQLContainerUniqueKeys(s *schema.Set) *[]documentdb.UniqueKey { + i := s.List() + if len(i) <= 0 || i[0] == nil { + return nil + } + + keys := make([]documentdb.UniqueKey, 0) + for _, k := range i { + key := k.(map[string]interface{}) + + paths := key["paths"].(*schema.Set).List() + if len(paths) == 0 { + continue + } + + keys = append(keys, documentdb.UniqueKey{ + Paths: utils.ExpandStringSlice(paths), + }) + } + + return &keys +} + +func flattenCosmosSQLContainerUniqueKeys(keys *[]documentdb.UniqueKey) *[]map[string]interface{} { + if keys == nil { + return nil + } + + slice := make([]map[string]interface{}, 0) + for _, k := range *keys { + + if k.Paths == nil { + continue + } + + slice = append(slice, map[string]interface{}{ + "paths": *k.Paths, + }) + } + + return &slice +} diff --git a/azurerm/resource_arm_cosmosdb_sql_container_test.go b/azurerm/resource_arm_cosmosdb_sql_container_test.go new file mode 100644 index 000000000000..c4e9d8e6c741 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_sql_container_test.go @@ -0,0 +1,185 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMCosmosDbSqlContainer_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_sql_container.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbSqlContainerDestroy, + Steps: []resource.TestStep{ + { + + Config: testAccAzureRMCosmosDbSqlContainer_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbSqlContainerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDbSqlContainer_complete(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_sql_container.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbSqlContainerDestroy, + Steps: []resource.TestStep{ + { + + Config: testAccAzureRMCosmosDbSqlContainer_complete(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbSqlContainerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDbSqlContainer_update(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_sql_container.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbSqlContainerDestroy, + Steps: []resource.TestStep{ + { + + Config: testAccAzureRMCosmosDbSqlContainer_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbSqlContainerExists(resourceName), + ), + }, + { + + Config: testAccAzureRMCosmosDbSqlContainer_complete(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbSqlContainerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMCosmosDbSqlContainerDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cosmosdb_sql_container" { + continue + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + database := rs.Primary.Attributes["database_name"] + + resp, err := client.GetSQLContainer(ctx, resourceGroup, account, database, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Error checking destroy for Cosmos SQL Container %s (account %s) still exists:\n%v", name, account, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Cosmos SQL Container %s (account %s) still exists:\n%#v", name, account, resp) + } + } + + return nil +} + +func testCheckAzureRMCosmosDbSqlContainerExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + database := rs.Primary.Attributes["database_name"] + + resp, err := client.GetSQLContainer(ctx, resourceGroup, database, account, name) + if err != nil { + return fmt.Errorf("Bad: Get on cosmosAccountsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Cosmos Container '%s' (account: '%s') does not exist", name, account) + } + + return nil + } +} + +func testAccAzureRMCosmosDbSqlContainer_basic(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_sql_container" "test" { + name = "acctest-CSQLC-%[2]d" + resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_account.test.name}" + database_name = "${azurerm_cosmosdb_sql_database.test.name}" +} + + +`, testAccAzureRMCosmosDbSqlDatabase_basic(rInt, location), rInt) +} + +func testAccAzureRMCosmosDbSqlContainer_complete(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_sql_container" "test" { + name = "acctest-CSQLC-%[2]d" + resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_account.test.name}" + database_name = "${azurerm_cosmosdb_sql_database.test.name}" + partition_key_path = "/definition/id" + unique_key { + paths = ["/definition/id1", "/definition/id2"] + } +} + +`, testAccAzureRMCosmosDbSqlDatabase_basic(rInt, location), rInt) +} diff --git a/azurerm/resource_arm_cosmosdb_sql_database.go b/azurerm/resource_arm_cosmosdb_sql_database.go new file mode 100644 index 000000000000..393d5253b5bc --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_sql_database.go @@ -0,0 +1,154 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmCosmosDbSQLDatabase() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCosmosDbSQLDatabaseCreate, + Read: resourceArmCosmosDbSQLDatabaseRead, + Delete: resourceArmCosmosDbSQLDatabaseDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosAccountName, + }, + }, + } +} + +func resourceArmCosmosDbSQLDatabaseCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + account := d.Get("account_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.GetSQLDatabase(ctx, resourceGroup, account, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos SQL Database %s (Account %s): %+v", name, account, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos SQL Database '%s' (Account %s)", name, account) + } + + return tf.ImportAsExistsError("azurerm_cosmosdb_sql_database", id) + } + } + + db := documentdb.SQLDatabaseCreateUpdateParameters{ + SQLDatabaseCreateUpdateProperties: &documentdb.SQLDatabaseCreateUpdateProperties{ + Resource: &documentdb.SQLDatabaseResource{ + ID: &name, + }, + Options: map[string]*string{}, + }, + } + + future, err := client.CreateUpdateSQLDatabase(ctx, resourceGroup, account, name, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos SQL Database %s (Account %s): %+v", name, account, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos SQL Database %s (Account %s): %+v", name, account, err) + } + + resp, err := client.GetSQLDatabase(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos SQL Database %s (Account %s): %+v", name, account, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error retrieving the ID for Cosmos SQL Database '%s' (Account %s) ID: %v", name, account, err) + } + d.SetId(id) + + return resourceArmCosmosDbSQLDatabaseRead(d, meta) +} + +func resourceArmCosmosDbSQLDatabaseRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseID(d.Id()) + if err != nil { + return err + } + + resp, err := client.GetSQLDatabase(ctx, id.ResourceGroup, id.Account, id.Database) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading Cosmos SQL Database %s (Account %s) - removing from state", id.Database, id.Account) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Cosmos SQL Database %s (Account %s): %+v", id.Database, id.Account, err) + } + + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.Account) + if props := resp.SQLDatabaseProperties; props != nil { + d.Set("name", props.ID) + } + + return nil +} + +func resourceArmCosmosDbSQLDatabaseDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseID(d.Id()) + if err != nil { + return err + } + + future, err := client.DeleteSQLDatabase(ctx, id.ResourceGroup, id.Account, id.Database) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting Cosmos SQL Database %s (Account %s): %+v", id.Database, id.Account, err) + } + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting on delete future for Cosmos SQL Database %s (Account %s): %+v", id.Database, id.Account, err) + } + + return nil +} diff --git a/azurerm/resource_arm_cosmosdb_sql_database_test.go b/azurerm/resource_arm_cosmosdb_sql_database_test.go new file mode 100644 index 000000000000..ec27ea549dea --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_sql_database_test.go @@ -0,0 +1,105 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMCosmosDbSqlDatabase_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_sql_database.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbSqlDatabaseDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbSqlDatabase_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbSqlDatabaseExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMCosmosDbSqlDatabaseDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cosmosdb_sql_database" { + continue + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetSQLDatabase(ctx, resourceGroup, account, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Error checking destroy for Cosmos SQL Database %s (account %s) still exists:\n%v", name, account, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Cosmos SQL Database %s (account %s) still exists:\n%#v", name, account, resp) + } + } + + return nil +} + +func testCheckAzureRMCosmosDbSqlDatabaseExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetSQLDatabase(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Bad: Get on cosmosAccountsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Cosmos database '%s' (account: '%s') does not exist", name, account) + } + + return nil + } +} + +func testAccAzureRMCosmosDbSqlDatabase_basic(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_sql_database" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_account.test.name}" +} +`, testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.Eventual), "", ""), rInt) +} diff --git a/azurerm/resource_arm_cosmosdb_table.go b/azurerm/resource_arm_cosmosdb_table.go new file mode 100644 index 000000000000..4f0385315ed3 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_table.go @@ -0,0 +1,154 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmCosmosDbTable() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCosmosDbTableCreate, + Read: resourceArmCosmosDbTableRead, + Delete: resourceArmCosmosDbTableDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosAccountName, + }, + }, + } +} + +func resourceArmCosmosDbTableCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + account := d.Get("account_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.GetTable(ctx, resourceGroup, account, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Table %s (Account %s): %+v", name, account, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos Table '%s' (Account %s)", name, account) + } + + return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_database", id) + } + } + + db := documentdb.TableCreateUpdateParameters{ + TableCreateUpdateProperties: &documentdb.TableCreateUpdateProperties{ + Resource: &documentdb.TableResource{ + ID: &name, + }, + Options: map[string]*string{}, + }, + } + + future, err := client.CreateUpdateTable(ctx, resourceGroup, account, name, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos Table %s (Account %s): %+v", name, account, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos Table %s (Account %s): %+v", name, account, err) + } + + resp, err := client.GetTable(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos Table %s (Account %s): %+v", name, account, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error retrieving the ID for Cosmos Table '%s' (Account %s) ID: %v", name, account, err) + } + d.SetId(id) + + return resourceArmCosmosDbTableRead(d, meta) +} + +func resourceArmCosmosDbTableRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosTableID(d.Id()) + if err != nil { + return err + } + + resp, err := client.GetTable(ctx, id.ResourceGroup, id.Account, id.Table) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading Cosmos Table %s (Account %s) - removing from state", id.Table, id.Account) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Cosmos Table %s (Account %s): %+v", id.Table, id.Account, err) + } + + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.Account) + if props := resp.TableProperties; props != nil { + d.Set("name", props.ID) + } + + return nil +} + +func resourceArmCosmosDbTableDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmos.DatabaseClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosTableID(d.Id()) + if err != nil { + return err + } + + future, err := client.DeleteTable(ctx, id.ResourceGroup, id.Account, id.Table) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting Cosmos Table %s (Account %s): %+v", id.Table, id.Account, err) + } + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting on delete future for Cosmos Table %s (Account %s): %+v", id.Table, id.Account, err) + } + + return nil +} diff --git a/azurerm/resource_arm_cosmosdb_table_test.go b/azurerm/resource_arm_cosmosdb_table_test.go new file mode 100644 index 000000000000..db908aefb753 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_table_test.go @@ -0,0 +1,104 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMCosmosDbTable_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_table.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbTableDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbTable_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbTableExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMCosmosDbTableDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cosmosdb_table" { + continue + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetTable(ctx, resourceGroup, account, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Error checking destroy for Cosmos Table %s (account %s) still exists:\n%v", name, account, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Cosmos Table %s (account %s) still exists:\n%#v", name, account, resp) + } + } + + return nil +} + +func testCheckAzureRMCosmosDbTableExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmos.DatabaseClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetTable(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Bad: Get on cosmosAccountsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Cosmos Table '%s' (account: '%s') does not exist", name, account) + } + + return nil + } +} + +func testAccAzureRMCosmosDbTable_basic(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_table" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_account.test.name}" +} +`, testAccAzureRMCosmosDBAccount_capabilityTable(rInt, location), rInt) +} diff --git a/azurerm/resource_arm_data_factory.go b/azurerm/resource_arm_data_factory.go new file mode 100644 index 000000000000..b91b71cedafe --- /dev/null +++ b/azurerm/resource_arm_data_factory.go @@ -0,0 +1,395 @@ +package azurerm + +import ( + "fmt" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactory() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryCreateOrUpdate, + Read: resourceArmDataFactoryRead, + Update: resourceArmDataFactoryCreateOrUpdate, + Delete: resourceArmDataFactoryDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid name for Data Factory, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + "location": azure.SchemaLocation(), + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "identity": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "SystemAssigned", + }, false), + }, + "principal_id": { + Type: schema.TypeString, + Computed: true, + }, + "tenant_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "github_configuration": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ConflictsWith: []string{"vsts_configuration"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "branch_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "git_url": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "repository_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "root_folder": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + + "vsts_configuration": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ConflictsWith: []string{"github_configuration"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "branch_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "project_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "repository_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "root_folder": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "tenant_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.UUID, + }, + }, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmDataFactoryCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.FactoriesClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + resourceGroup := d.Get("resource_group_name").(string) + t := d.Get("tags").(map[string]interface{}) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory", *existing.ID) + } + } + + dataFactory := datafactory.Factory{ + Location: &location, + Tags: tags.Expand(t), + } + + if v, ok := d.GetOk("identity.0.type"); ok { + identityType := v.(string) + dataFactory.Identity = &datafactory.FactoryIdentity{ + Type: &identityType, + } + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, name, dataFactory, ""); err != nil { + return fmt.Errorf("Error creating/updating Data Factory %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Data Factory %q (Resource Group %q) ID", name, resourceGroup) + } + + if hasRepo, repo := expandArmDataFactoryRepoConfiguration(d); hasRepo { + repoUpdate := datafactory.FactoryRepoUpdate{ + FactoryResourceID: resp.ID, + RepoConfiguration: repo, + } + if _, err = client.ConfigureFactoryRepo(ctx, location, repoUpdate); err != nil { + return fmt.Errorf("Error configuring Repository for Data Factory %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + d.SetId(*resp.ID) + + return resourceArmDataFactoryRead(d, meta) +} + +func resourceArmDataFactoryRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.FactoriesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["factories"] + + resp, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Data Factory %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + d.Set("vsts_configuration", []interface{}{}) + d.Set("github_configuration", []interface{}{}) + repoType, repo := flattenArmDataFactoryRepoConfiguration(&resp) + if repoType == datafactory.TypeFactoryVSTSConfiguration { + if err := d.Set("vsts_configuration", repo); err != nil { + return fmt.Errorf("Error setting `vsts_configuration`: %+v", err) + } + } + if repoType == datafactory.TypeFactoryGitHubConfiguration { + if err := d.Set("github_configuration", repo); err != nil { + return fmt.Errorf("Error setting `github_configuration`: %+v", err) + } + } + if repoType == datafactory.TypeFactoryRepoConfiguration { + d.Set("vsts_configuration", repo) + d.Set("github_configuration", repo) + } + + if err := d.Set("identity", flattenArmDataFactoryIdentity(resp.Identity)); err != nil { + return fmt.Errorf("Error flattening `identity`: %+v", err) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmDataFactoryDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.FactoriesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["factories"] + + response, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(response) { + return fmt.Errorf("Error deleting Data Factory %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + return nil +} + +func expandArmDataFactoryRepoConfiguration(d *schema.ResourceData) (bool, datafactory.BasicFactoryRepoConfiguration) { + if vstsList, ok := d.GetOk("vsts_configuration"); ok { + vsts := vstsList.([]interface{})[0].(map[string]interface{}) + accountName := vsts["account_name"].(string) + branchName := vsts["branch_name"].(string) + projectName := vsts["project_name"].(string) + repositoryName := vsts["repository_name"].(string) + rootFolder := vsts["root_folder"].(string) + tenantID := vsts["tenant_id"].(string) + return true, &datafactory.FactoryVSTSConfiguration{ + AccountName: &accountName, + CollaborationBranch: &branchName, + ProjectName: &projectName, + RepositoryName: &repositoryName, + RootFolder: &rootFolder, + TenantID: &tenantID, + } + } + + if githubList, ok := d.GetOk("github_configuration"); ok { + github := githubList.([]interface{})[0].(map[string]interface{}) + accountName := github["account_name"].(string) + branchName := github["branch_name"].(string) + gitURL := github["git_url"].(string) + repositoryName := github["repository_name"].(string) + rootFolder := github["root_folder"].(string) + return true, &datafactory.FactoryGitHubConfiguration{ + AccountName: &accountName, + CollaborationBranch: &branchName, + HostName: &gitURL, + RepositoryName: &repositoryName, + RootFolder: &rootFolder, + } + } + + return false, nil +} + +func flattenArmDataFactoryRepoConfiguration(factory *datafactory.Factory) (datafactory.TypeBasicFactoryRepoConfiguration, []interface{}) { + result := make([]interface{}, 0) + + if properties := factory.FactoryProperties; properties != nil { + repo := properties.RepoConfiguration + if repo != nil { + settings := map[string]interface{}{} + if config, test := repo.AsFactoryGitHubConfiguration(); test { + if config.AccountName != nil { + settings["account_name"] = *config.AccountName + } + if config.CollaborationBranch != nil { + settings["branch_name"] = *config.CollaborationBranch + } + if config.HostName != nil { + settings["git_url"] = *config.HostName + } + if config.RepositoryName != nil { + settings["repository_name"] = *config.RepositoryName + } + if config.RootFolder != nil { + settings["root_folder"] = *config.RootFolder + } + return datafactory.TypeFactoryGitHubConfiguration, append(result, settings) + } + if config, test := repo.AsFactoryVSTSConfiguration(); test { + if config.AccountName != nil { + settings["account_name"] = *config.AccountName + } + if config.CollaborationBranch != nil { + settings["branch_name"] = *config.CollaborationBranch + } + if config.ProjectName != nil { + settings["project_name"] = *config.ProjectName + } + if config.RepositoryName != nil { + settings["repository_name"] = *config.RepositoryName + } + if config.RootFolder != nil { + settings["root_folder"] = *config.RootFolder + } + if config.TenantID != nil { + settings["tenant_id"] = *config.TenantID + } + return datafactory.TypeFactoryVSTSConfiguration, append(result, settings) + } + } + } + return datafactory.TypeFactoryRepoConfiguration, result +} + +func flattenArmDataFactoryIdentity(identity *datafactory.FactoryIdentity) interface{} { + if identity == nil { + return make([]interface{}, 0) + } + + result := make(map[string]interface{}) + if identity.Type != nil { + result["type"] = *identity.Type + } + if identity.PrincipalID != nil { + result["principal_id"] = identity.PrincipalID.String() + } + if identity.TenantID != nil { + result["tenant_id"] = identity.TenantID.String() + } + + return []interface{}{result} +} diff --git a/azurerm/resource_arm_data_factory_dataset_mysql.go b/azurerm/resource_arm_data_factory_dataset_mysql.go new file mode 100644 index 000000000000..5739f785e766 --- /dev/null +++ b/azurerm/resource_arm_data_factory_dataset_mysql.go @@ -0,0 +1,319 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactoryDatasetMySQL() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryDatasetMySQLCreateOrUpdate, + Read: resourceArmDataFactoryDatasetMySQLRead, + Update: resourceArmDataFactoryDatasetMySQLCreateOrUpdate, + Delete: resourceArmDataFactoryDatasetMySQLDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMDataFactoryLinkedServiceDatasetName, + }, + + "data_factory_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid name for Data Factory, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "linked_service_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "table_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "parameters": { + Type: schema.TypeMap, + Optional: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "folder": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "additional_properties": { + Type: schema.TypeMap, + Optional: true, + }, + + "schema_column": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "Byte", + "Byte[]", + "Boolean", + "Date", + "DateTime", + "DateTimeOffset", + "Decimal", + "Double", + "Guid", + "Int16", + "Int32", + "Int64", + "Single", + "String", + "TimeSpan", + }, false), + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + } +} + +func resourceArmDataFactoryDatasetMySQLCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + dataFactoryName := d.Get("data_factory_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory Dataset MySQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory_dataset_mysql", *existing.ID) + } + } + + mysqlDatasetProperties := datafactory.RelationalTableDatasetTypeProperties{ + TableName: d.Get("table_name").(string), + } + + linkedServiceName := d.Get("linked_service_name").(string) + linkedServiceType := "LinkedServiceReference" + linkedService := &datafactory.LinkedServiceReference{ + ReferenceName: &linkedServiceName, + Type: &linkedServiceType, + } + + description := d.Get("description").(string) + mysqlTableset := datafactory.RelationalTableDataset{ + RelationalTableDatasetTypeProperties: &mysqlDatasetProperties, + LinkedServiceName: linkedService, + Description: &description, + } + + if v, ok := d.GetOk("folder"); ok { + name := v.(string) + mysqlTableset.Folder = &datafactory.DatasetFolder{ + Name: &name, + } + } + + if v, ok := d.GetOk("parameters"); ok { + mysqlTableset.Parameters = expandDataFactoryParameters(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("annotations"); ok { + annotations := v.([]interface{}) + mysqlTableset.Annotations = &annotations + } + + if v, ok := d.GetOk("additional_properties"); ok { + mysqlTableset.AdditionalProperties = v.(map[string]interface{}) + } + + if v, ok := d.GetOk("schema_column"); ok { + mysqlTableset.Structure = expandDataFactoryDatasetStructure(v.([]interface{})) + } + + datasetType := string(datafactory.TypeRelationalTable) + dataset := datafactory.DatasetResource{ + Properties: &mysqlTableset, + Type: &datasetType, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, dataFactoryName, name, dataset, ""); err != nil { + return fmt.Errorf("Error creating/updating Data Factory Dataset MySQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory Dataset MySQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Data Factory Dataset MySQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmDataFactoryDatasetMySQLRead(d, meta) +} + +func resourceArmDataFactoryDatasetMySQLRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["datasets"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Data Factory Dataset MySQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("data_factory_name", dataFactoryName) + + mysqlTable, ok := resp.Properties.AsRelationalTableDataset() + if !ok { + return fmt.Errorf("Error classifiying Data Factory Dataset MySQL %q (Data Factory %q / Resource Group %q): Expected: %q Received: %q", name, dataFactoryName, resourceGroup, datafactory.TypeRelationalTable, *resp.Type) + } + + d.Set("additional_properties", mysqlTable.AdditionalProperties) + + if mysqlTable.Description != nil { + d.Set("description", mysqlTable.Description) + } + + parameters := flattenDataFactoryParameters(mysqlTable.Parameters) + if err := d.Set("parameters", parameters); err != nil { + return fmt.Errorf("Error setting `parameters`: %+v", err) + } + + annotations := flattenDataFactoryAnnotations(mysqlTable.Annotations) + if err := d.Set("annotations", annotations); err != nil { + return fmt.Errorf("Error setting `annotations`: %+v", err) + } + + if linkedService := mysqlTable.LinkedServiceName; linkedService != nil { + if linkedService.ReferenceName != nil { + d.Set("linked_service_name", linkedService.ReferenceName) + } + } + + if properties := mysqlTable.RelationalTableDatasetTypeProperties; properties != nil { + val, ok := properties.TableName.(string) + if !ok { + log.Printf("[DEBUG] Skipping `table_name` since it's not a string") + } else { + d.Set("table_name", val) + } + } + + if folder := mysqlTable.Folder; folder != nil { + if folder.Name != nil { + d.Set("folder", folder.Name) + } + } + + structureColumns := flattenDataFactoryStructureColumns(mysqlTable.Structure) + if err := d.Set("schema_column", structureColumns); err != nil { + return fmt.Errorf("Error setting `schema_column`: %+v", err) + } + + return nil +} + +func resourceArmDataFactoryDatasetMySQLDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["datasets"] + + response, err := client.Delete(ctx, resourceGroup, dataFactoryName, name) + if err != nil { + if !utils.ResponseWasNotFound(response) { + return fmt.Errorf("Error deleting Data Factory Dataset MySQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_data_factory_dataset_mysql_test.go b/azurerm/resource_arm_data_factory_dataset_mysql_test.go new file mode 100644 index 000000000000..3310cc39b81f --- /dev/null +++ b/azurerm/resource_arm_data_factory_dataset_mysql_test.go @@ -0,0 +1,272 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactoryDatasetMySQL_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryDatasetMySQL_basic(ri, testLocation()) + resourceName := "azurerm_data_factory_dataset_mysql.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDatasetMySQLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetMySQLExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactoryDatasetMySQL_update(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryDatasetMySQL_update1(ri, testLocation()) + config2 := testAccAzureRMDataFactoryDatasetMySQL_update2(ri, testLocation()) + resourceName := "azurerm_data_factory_dataset_mysql.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDatasetMySQLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetMySQLExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "2"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "3"), + resource.TestCheckResourceAttr(resourceName, "schema_column.#", "1"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "2"), + resource.TestCheckResourceAttr(resourceName, "description", "test description"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetMySQLExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "3"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "schema_column.#", "2"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "1"), + resource.TestCheckResourceAttr(resourceName, "description", "test description 2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryDatasetMySQLExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.DatasetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on dataFactoryDatasetClient: %+v", err) + } + + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory Dataset MySQL %q (data factory name: %q / resource group: %q) does not exist", name, dataFactoryName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDataFactoryDatasetMySQLDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.DatasetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory_dataset_mysql" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Data Factory Dataset MySQL still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testAccAzureRMDataFactoryDatasetMySQL_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_mysql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test" +} + +resource "azurerm_data_factory_dataset_mysql" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_mysql.test.name}" +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMDataFactoryDatasetMySQL_update1(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_mysql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test" +} + +resource "azurerm_data_factory_dataset_mysql" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_mysql.test.name}" + + description = "test description" + annotations = ["test1", "test2", "test3"] + table_name = "testTable" + folder = "testFolder" + + parameters = { + foo = "test1" + bar = "test2" + } + + additional_properties = { + foo = "test1" + bar = "test2" + } + + schema_column { + name = "test1" + type = "Byte" + description = "description" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMDataFactoryDatasetMySQL_update2(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_mysql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test" +} + +resource "azurerm_data_factory_dataset_mysql" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_mysql.test.name}" + + description = "test description 2" + annotations = ["test1", "test2"] + table_name = "testTable" + folder = "testFolder" + + parameters = { + foo = "test1" + bar = "test2" + buzz = "test3" + } + + additional_properties = { + foo = "test1" + } + + schema_column { + name = "test1" + type = "Byte" + description = "description" + } + + schema_column { + name = "test2" + type = "Byte" + description = "description" + } +} +`, rInt, location, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_factory_dataset_postgresql.go b/azurerm/resource_arm_data_factory_dataset_postgresql.go new file mode 100644 index 000000000000..62c281edec1c --- /dev/null +++ b/azurerm/resource_arm_data_factory_dataset_postgresql.go @@ -0,0 +1,319 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactoryDatasetPostgreSQL() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryDatasetPostgreSQLCreateOrUpdate, + Read: resourceArmDataFactoryDatasetPostgreSQLRead, + Update: resourceArmDataFactoryDatasetPostgreSQLCreateOrUpdate, + Delete: resourceArmDataFactoryDatasetPostgreSQLDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMDataFactoryLinkedServiceDatasetName, + }, + + "data_factory_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid name for Data Factory, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "linked_service_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "table_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "parameters": { + Type: schema.TypeMap, + Optional: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "folder": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "additional_properties": { + Type: schema.TypeMap, + Optional: true, + }, + + "schema_column": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "Byte", + "Byte[]", + "Boolean", + "Date", + "DateTime", + "DateTimeOffset", + "Decimal", + "Double", + "Guid", + "Int16", + "Int32", + "Int64", + "Single", + "String", + "TimeSpan", + }, false), + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + } +} + +func resourceArmDataFactoryDatasetPostgreSQLCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + dataFactoryName := d.Get("data_factory_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory Dataset PostgreSQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory_dataset_postgresql", *existing.ID) + } + } + + postgresqlDatasetProperties := datafactory.RelationalTableDatasetTypeProperties{ + TableName: d.Get("table_name").(string), + } + + linkedServiceName := d.Get("linked_service_name").(string) + linkedServiceType := "LinkedServiceReference" + linkedService := &datafactory.LinkedServiceReference{ + ReferenceName: &linkedServiceName, + Type: &linkedServiceType, + } + + description := d.Get("description").(string) + postgresqlTableset := datafactory.RelationalTableDataset{ + RelationalTableDatasetTypeProperties: &postgresqlDatasetProperties, + LinkedServiceName: linkedService, + Description: &description, + } + + if v, ok := d.GetOk("folder"); ok { + name := v.(string) + postgresqlTableset.Folder = &datafactory.DatasetFolder{ + Name: &name, + } + } + + if v, ok := d.GetOk("parameters"); ok { + postgresqlTableset.Parameters = expandDataFactoryParameters(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("annotations"); ok { + annotations := v.([]interface{}) + postgresqlTableset.Annotations = &annotations + } + + if v, ok := d.GetOk("additional_properties"); ok { + postgresqlTableset.AdditionalProperties = v.(map[string]interface{}) + } + + if v, ok := d.GetOk("schema_column"); ok { + postgresqlTableset.Structure = expandDataFactoryDatasetStructure(v.([]interface{})) + } + + datasetType := string(datafactory.TypeRelationalTable) + dataset := datafactory.DatasetResource{ + Properties: &postgresqlTableset, + Type: &datasetType, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, dataFactoryName, name, dataset, ""); err != nil { + return fmt.Errorf("Error creating/updating Data Factory Dataset PostgreSQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory Dataset PostgreSQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Data Factory Dataset PostgreSQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmDataFactoryDatasetPostgreSQLRead(d, meta) +} + +func resourceArmDataFactoryDatasetPostgreSQLRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["datasets"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Data Factory Dataset PostgreSQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("data_factory_name", dataFactoryName) + + postgresqlTable, ok := resp.Properties.AsRelationalTableDataset() + if !ok { + return fmt.Errorf("Error classifiying Data Factory Dataset PostgreSQL %q (Data Factory %q / Resource Group %q): Expected: %q Received: %q", name, dataFactoryName, resourceGroup, datafactory.TypeRelationalTable, *resp.Type) + } + + d.Set("additional_properties", postgresqlTable.AdditionalProperties) + + if postgresqlTable.Description != nil { + d.Set("description", postgresqlTable.Description) + } + + parameters := flattenDataFactoryParameters(postgresqlTable.Parameters) + if err := d.Set("parameters", parameters); err != nil { + return fmt.Errorf("Error setting `parameters`: %+v", err) + } + + annotations := flattenDataFactoryAnnotations(postgresqlTable.Annotations) + if err := d.Set("annotations", annotations); err != nil { + return fmt.Errorf("Error setting `annotations`: %+v", err) + } + + if linkedService := postgresqlTable.LinkedServiceName; linkedService != nil { + if linkedService.ReferenceName != nil { + d.Set("linked_service_name", linkedService.ReferenceName) + } + } + + if properties := postgresqlTable.RelationalTableDatasetTypeProperties; properties != nil { + val, ok := properties.TableName.(string) + if !ok { + log.Printf("[DEBUG] Skipping `table_name` since it's not a string") + } else { + d.Set("table_name", val) + } + } + + if folder := postgresqlTable.Folder; folder != nil { + if folder.Name != nil { + d.Set("folder", folder.Name) + } + } + + structureColumns := flattenDataFactoryStructureColumns(postgresqlTable.Structure) + if err := d.Set("schema_column", structureColumns); err != nil { + return fmt.Errorf("Error setting `schema_column`: %+v", err) + } + + return nil +} + +func resourceArmDataFactoryDatasetPostgreSQLDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["datasets"] + + response, err := client.Delete(ctx, resourceGroup, dataFactoryName, name) + if err != nil { + if !utils.ResponseWasNotFound(response) { + return fmt.Errorf("Error deleting Data Factory Dataset PostgreSQL %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_data_factory_dataset_postgresql_test.go b/azurerm/resource_arm_data_factory_dataset_postgresql_test.go new file mode 100644 index 000000000000..39769f102798 --- /dev/null +++ b/azurerm/resource_arm_data_factory_dataset_postgresql_test.go @@ -0,0 +1,272 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactoryDatasetPostgreSQL_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryDatasetPostgreSQL_basic(ri, testLocation()) + resourceName := "azurerm_data_factory_dataset_postgresql.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDatasetPostgreSQLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetPostgreSQLExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactoryDatasetPostgreSQL_update(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryDatasetPostgreSQL_update1(ri, testLocation()) + config2 := testAccAzureRMDataFactoryDatasetPostgreSQL_update2(ri, testLocation()) + resourceName := "azurerm_data_factory_dataset_postgresql.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDatasetPostgreSQLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetPostgreSQLExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "2"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "3"), + resource.TestCheckResourceAttr(resourceName, "schema_column.#", "1"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "2"), + resource.TestCheckResourceAttr(resourceName, "description", "test description"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetPostgreSQLExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "3"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "schema_column.#", "2"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "1"), + resource.TestCheckResourceAttr(resourceName, "description", "test description 2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryDatasetPostgreSQLExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.DatasetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on dataFactoryDatasetClient: %+v", err) + } + + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory Dataset PostgreSQL %q (data factory name: %q / resource group: %q) does not exist", name, dataFactoryName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDataFactoryDatasetPostgreSQLDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.DatasetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory_dataset_postgredql" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Data Factory Dataset PostgreSQL still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testAccAzureRMDataFactoryDatasetPostgreSQL_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_postgresql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Host=example;Port=5432;Database=example;UID=example;EncryptionMethod=0;Password=example" +} + +resource "azurerm_data_factory_dataset_postgresql" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_postgresql.test.name}" +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMDataFactoryDatasetPostgreSQL_update1(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_postgresql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Host=example;Port=5432;Database=example;UID=example;EncryptionMethod=0;Password=example" +} + +resource "azurerm_data_factory_dataset_postgresql" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_postgresql.test.name}" + + description = "test description" + annotations = ["test1", "test2", "test3"] + table_name = "testTable" + folder = "testFolder" + + parameters = { + foo = "test1" + bar = "test2" + } + + additional_properties = { + foo = "test1" + bar = "test2" + } + + schema_column { + name = "test1" + type = "Byte" + description = "description" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMDataFactoryDatasetPostgreSQL_update2(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_postgresql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Host=example;Port=5432;Database=example;UID=example;EncryptionMethod=0;Password=example" +} + +resource "azurerm_data_factory_dataset_postgresql" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_postgresql.test.name}" + + description = "test description 2" + annotations = ["test1", "test2"] + table_name = "testTable" + folder = "testFolder" + + parameters = { + foo = "test1" + bar = "test2" + buzz = "test3" + } + + additional_properties = { + foo = "test1" + } + + schema_column { + name = "test1" + type = "Byte" + description = "description" + } + + schema_column { + name = "test2" + type = "Byte" + description = "description" + } +} +`, rInt, location, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_factory_dataset_sql_server_table.go b/azurerm/resource_arm_data_factory_dataset_sql_server_table.go new file mode 100644 index 000000000000..4c675c74c988 --- /dev/null +++ b/azurerm/resource_arm_data_factory_dataset_sql_server_table.go @@ -0,0 +1,319 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactoryDatasetSQLServerTable() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryDatasetSQLServerTableCreateOrUpdate, + Read: resourceArmDataFactoryDatasetSQLServerTableRead, + Update: resourceArmDataFactoryDatasetSQLServerTableCreateOrUpdate, + Delete: resourceArmDataFactoryDatasetSQLServerTableDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMDataFactoryLinkedServiceDatasetName, + }, + + "data_factory_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid name for Data Factory, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "linked_service_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "table_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "parameters": { + Type: schema.TypeMap, + Optional: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "folder": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "additional_properties": { + Type: schema.TypeMap, + Optional: true, + }, + + "schema_column": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "Byte", + "Byte[]", + "Boolean", + "Date", + "DateTime", + "DateTimeOffset", + "Decimal", + "Double", + "Guid", + "Int16", + "Int32", + "Int64", + "Single", + "String", + "TimeSpan", + }, false), + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + } +} + +func resourceArmDataFactoryDatasetSQLServerTableCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + dataFactoryName := d.Get("data_factory_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory Dataset SQL Server Table %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory_dataset_sql_server", *existing.ID) + } + } + + sqlServerDatasetProperties := datafactory.SQLServerTableDatasetTypeProperties{ + TableName: d.Get("table_name").(string), + } + + linkedServiceName := d.Get("linked_service_name").(string) + linkedServiceType := "LinkedServiceReference" + linkedService := &datafactory.LinkedServiceReference{ + ReferenceName: &linkedServiceName, + Type: &linkedServiceType, + } + + description := d.Get("description").(string) + sqlServerTableset := datafactory.SQLServerTableDataset{ + SQLServerTableDatasetTypeProperties: &sqlServerDatasetProperties, + LinkedServiceName: linkedService, + Description: &description, + } + + if v, ok := d.GetOk("folder"); ok { + name := v.(string) + sqlServerTableset.Folder = &datafactory.DatasetFolder{ + Name: &name, + } + } + + if v, ok := d.GetOk("parameters"); ok { + sqlServerTableset.Parameters = expandDataFactoryParameters(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("annotations"); ok { + annotations := v.([]interface{}) + sqlServerTableset.Annotations = &annotations + } + + if v, ok := d.GetOk("additional_properties"); ok { + sqlServerTableset.AdditionalProperties = v.(map[string]interface{}) + } + + if v, ok := d.GetOk("schema_column"); ok { + sqlServerTableset.Structure = expandDataFactoryDatasetStructure(v.([]interface{})) + } + + datasetType := string(datafactory.TypeSQLServerTable) + dataset := datafactory.DatasetResource{ + Properties: &sqlServerTableset, + Type: &datasetType, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, dataFactoryName, name, dataset, ""); err != nil { + return fmt.Errorf("Error creating/updating Data Factory Dataset SQL Server Table %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory Dataset SQL Server Table %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Data Factory Dataset SQL Server Table %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmDataFactoryDatasetSQLServerTableRead(d, meta) +} + +func resourceArmDataFactoryDatasetSQLServerTableRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["datasets"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Data Factory Dataset SQL Server Table %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("data_factory_name", dataFactoryName) + + sqlServerTable, ok := resp.Properties.AsSQLServerTableDataset() + if !ok { + return fmt.Errorf("Error classifiying Data Factory Dataset SQL Server Table %q (Data Factory %q / Resource Group %q): Expected: %q Received: %q", name, dataFactoryName, resourceGroup, datafactory.TypeSQLServerTable, *resp.Type) + } + + d.Set("additional_properties", sqlServerTable.AdditionalProperties) + + if sqlServerTable.Description != nil { + d.Set("description", sqlServerTable.Description) + } + + parameters := flattenDataFactoryParameters(sqlServerTable.Parameters) + if err := d.Set("parameters", parameters); err != nil { + return fmt.Errorf("Error setting `parameters`: %+v", err) + } + + annotations := flattenDataFactoryAnnotations(sqlServerTable.Annotations) + if err := d.Set("annotations", annotations); err != nil { + return fmt.Errorf("Error setting `annotations`: %+v", err) + } + + if linkedService := sqlServerTable.LinkedServiceName; linkedService != nil { + if linkedService.ReferenceName != nil { + d.Set("linked_service_name", linkedService.ReferenceName) + } + } + + if properties := sqlServerTable.SQLServerTableDatasetTypeProperties; properties != nil { + val, ok := properties.TableName.(string) + if !ok { + log.Printf("[DEBUG] Skipping `table_name` since it's not a string") + } else { + d.Set("table_name", val) + } + } + + if folder := sqlServerTable.Folder; folder != nil { + if folder.Name != nil { + d.Set("folder", folder.Name) + } + } + + structureColumns := flattenDataFactoryStructureColumns(sqlServerTable.Structure) + if err := d.Set("schema_column", structureColumns); err != nil { + return fmt.Errorf("Error setting `schema_column`: %+v", err) + } + + return nil +} + +func resourceArmDataFactoryDatasetSQLServerTableDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.DatasetClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["datasets"] + + response, err := client.Delete(ctx, resourceGroup, dataFactoryName, name) + if err != nil { + if !utils.ResponseWasNotFound(response) { + return fmt.Errorf("Error deleting Data Factory Dataset SQL Server Table %q (Data Factory %q / Resource Group %q): %s", name, dataFactoryName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_data_factory_dataset_sql_server_table_test.go b/azurerm/resource_arm_data_factory_dataset_sql_server_table_test.go new file mode 100644 index 000000000000..e326eeb145d6 --- /dev/null +++ b/azurerm/resource_arm_data_factory_dataset_sql_server_table_test.go @@ -0,0 +1,272 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactoryDatasetSQLServerTable_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryDatasetSQLServerTable_basic(ri, testLocation()) + resourceName := "azurerm_data_factory_dataset_sql_server_table.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDatasetSQLServerTableDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetSQLServerTableExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactoryDatasetSQLServerTable_update(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryDatasetSQLServerTable_update1(ri, testLocation()) + config2 := testAccAzureRMDataFactoryDatasetSQLServerTable_update2(ri, testLocation()) + resourceName := "azurerm_data_factory_dataset_sql_server_table.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDatasetSQLServerTableDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetSQLServerTableExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "2"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "3"), + resource.TestCheckResourceAttr(resourceName, "schema_column.#", "1"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "2"), + resource.TestCheckResourceAttr(resourceName, "description", "test description"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryDatasetSQLServerTableExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "3"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "schema_column.#", "2"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "1"), + resource.TestCheckResourceAttr(resourceName, "description", "test description 2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryDatasetSQLServerTableExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.DatasetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on dataFactoryDatasetClient: %+v", err) + } + + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory Dataset SQL Server Table %q (data factory name: %q / resource group: %q) does not exist", name, dataFactoryName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDataFactoryDatasetSQLServerTableDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.DatasetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory_dataset_sql_server_table" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Data Factory Dataset SQL Server Table still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testAccAzureRMDataFactoryDatasetSQLServerTable_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_sql_server" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test" +} + +resource "azurerm_data_factory_dataset_sql_server_table" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_sql_server.test.name}" +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMDataFactoryDatasetSQLServerTable_update1(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_sql_server" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test" +} + +resource "azurerm_data_factory_dataset_sql_server_table" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_sql_server.test.name}" + + description = "test description" + annotations = ["test1", "test2", "test3"] + table_name = "testTable" + folder = "testFolder" + + parameters = { + foo = "test1" + bar = "test2" + } + + additional_properties = { + foo = "test1" + bar = "test2" + } + + schema_column { + name = "test1" + type = "Byte" + description = "description" + } +} +`, rInt, location, rInt, rInt, rInt) +} + +func testAccAzureRMDataFactoryDatasetSQLServerTable_update2(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_sql_server" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test" +} + +resource "azurerm_data_factory_dataset_sql_server_table" "test" { + name = "acctestds%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + linked_service_name = "${azurerm_data_factory_linked_service_sql_server.test.name}" + + description = "test description 2" + annotations = ["test1", "test2"] + table_name = "testTable" + folder = "testFolder" + + parameters = { + foo = "test1" + bar = "test2" + buzz = "test3" + } + + additional_properties = { + foo = "test1" + } + + schema_column { + name = "test1" + type = "Byte" + description = "description" + } + + schema_column { + name = "test2" + type = "Byte" + description = "description" + } +} +`, rInt, location, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_factory_linked_service_data_lake_storage_gen2.go b/azurerm/resource_arm_data_factory_linked_service_data_lake_storage_gen2.go new file mode 100644 index 000000000000..e3731361eb78 --- /dev/null +++ b/azurerm/resource_arm_data_factory_linked_service_data_lake_storage_gen2.go @@ -0,0 +1,273 @@ +package azurerm + +import ( + "fmt" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactoryLinkedServiceDataLakeStorageGen2() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryLinkedServiceDataLakeStorageGen2CreateOrUpdate, + Read: resourceArmDataFactoryLinkedServiceDataLakeStorageGen2Read, + Update: resourceArmDataFactoryLinkedServiceDataLakeStorageGen2CreateOrUpdate, + Delete: resourceArmDataFactoryLinkedServiceDataLakeStorageGen2Delete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMDataFactoryLinkedServiceDatasetName, + }, + + "data_factory_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid name for Data Factory, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "url": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.URLIsHTTPS, + }, + + "service_principal_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.UUID, + }, + + "service_principal_key": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "tenant": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "integration_runtime_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "parameters": { + Type: schema.TypeMap, + Optional: true, + }, + + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "additional_properties": { + Type: schema.TypeMap, + Optional: true, + }, + }, + } +} + +func resourceArmDataFactoryLinkedServiceDataLakeStorageGen2CreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + dataFactoryName := d.Get("data_factory_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory Linked Service Data Lake Storage Gen2 %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory_linked_service_data_lake_storage_gen2", *existing.ID) + } + } + + secureString := datafactory.SecureString{ + Value: utils.String(d.Get("service_principal_key").(string)), + Type: datafactory.TypeSecureString, + } + + datalakeStorageGen2Properties := &datafactory.AzureBlobFSLinkedServiceTypeProperties{ + URL: utils.String(d.Get("url").(string)), + ServicePrincipalID: utils.String(d.Get("service_principal_id").(string)), + Tenant: utils.String(d.Get("tenant").(string)), + ServicePrincipalKey: &secureString, + } + + datalakeStorageGen2LinkedService := &datafactory.AzureBlobFSLinkedService{ + Description: utils.String(d.Get("description").(string)), + AzureBlobFSLinkedServiceTypeProperties: datalakeStorageGen2Properties, + Type: datafactory.TypeAzureBlobFS, + } + + if v, ok := d.GetOk("parameters"); ok { + datalakeStorageGen2LinkedService.Parameters = expandDataFactoryParameters(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("integration_runtime_name"); ok { + datalakeStorageGen2LinkedService.ConnectVia = expandDataFactoryLinkedServiceIntegrationRuntime(v.(string)) + } + + if v, ok := d.GetOk("additional_properties"); ok { + datalakeStorageGen2LinkedService.AdditionalProperties = v.(map[string]interface{}) + } + + if v, ok := d.GetOk("annotations"); ok { + annotations := v.([]interface{}) + datalakeStorageGen2LinkedService.Annotations = &annotations + } + + linkedService := datafactory.LinkedServiceResource{ + Properties: datalakeStorageGen2LinkedService, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, dataFactoryName, name, linkedService, ""); err != nil { + return fmt.Errorf("Error creating/updating Data Factory Linked Service Data Lake Storage Gen2 %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory Linked Service Data Lake Storage Gen2 %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Data Factory Linked Service Data Lake Storage Gen2 %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmDataFactoryLinkedServiceDataLakeStorageGen2Read(d, meta) +} + +func resourceArmDataFactoryLinkedServiceDataLakeStorageGen2Read(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["linkedservices"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Data Factory Linked Service Data Lake Storage Gen2 %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("data_factory_name", dataFactoryName) + + dataLakeStorageGen2, ok := resp.Properties.AsAzureBlobFSLinkedService() + if !ok { + return fmt.Errorf("Error classifiying Data Factory Linked Service Data Lake Storage Gen2 %q (Data Factory %q / Resource Group %q): Expected: %q Received: %q", name, dataFactoryName, resourceGroup, datafactory.TypeAzureBlobFS, *resp.Type) + } + + if dataLakeStorageGen2.Tenant != nil { + d.Set("tenant", dataLakeStorageGen2.Tenant) + } + + if dataLakeStorageGen2.ServicePrincipalID != nil { + d.Set("service_principal_id", dataLakeStorageGen2.ServicePrincipalID) + } + + if dataLakeStorageGen2.URL != nil { + d.Set("url", dataLakeStorageGen2.URL) + } + + d.Set("additional_properties", dataLakeStorageGen2.AdditionalProperties) + + if dataLakeStorageGen2.Description != nil { + d.Set("description", dataLakeStorageGen2.Description) + } + + annotations := flattenDataFactoryAnnotations(dataLakeStorageGen2.Annotations) + if err := d.Set("annotations", annotations); err != nil { + return fmt.Errorf("Error setting `annotations`: %+v", err) + } + + parameters := flattenDataFactoryParameters(dataLakeStorageGen2.Parameters) + if err := d.Set("parameters", parameters); err != nil { + return fmt.Errorf("Error setting `parameters`: %+v", err) + } + + if connectVia := dataLakeStorageGen2.ConnectVia; connectVia != nil { + if connectVia.ReferenceName != nil { + d.Set("integration_runtime_name", connectVia.ReferenceName) + } + } + + return nil +} + +func resourceArmDataFactoryLinkedServiceDataLakeStorageGen2Delete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["linkedservices"] + + response, err := client.Delete(ctx, resourceGroup, dataFactoryName, name) + if err != nil { + if !utils.ResponseWasNotFound(response) { + return fmt.Errorf("Error deleting Data Factory Linked Service Data Lake Storage Gen2 %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_data_factory_linked_service_data_lake_storage_gen2_test.go b/azurerm/resource_arm_data_factory_linked_service_data_lake_storage_gen2_test.go new file mode 100644 index 000000000000..192ceb805cbd --- /dev/null +++ b/azurerm/resource_arm_data_factory_linked_service_data_lake_storage_gen2_test.go @@ -0,0 +1,246 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactoryLinkedServiceDataLakeStorageGen2_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryLinkedServiceDataLakeStorageGen2_basic(ri, testLocation()) + resourceName := "azurerm_data_factory_linked_service_data_lake_storage_gen2.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryLinkedServiceDataLakeStorageGen2Destroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServiceDataLakeStorageGen2Exists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "service_principal_key", + }, + }, + }, + }) +} + +func TestAccAzureRMDataFactoryLinkedServiceDataLakeStorageGen2_update(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryLinkedServiceDataLakeStorageGen2_update1(ri, testLocation()) + config2 := testAccAzureRMDataFactoryLinkedServiceDataLakeStorageGen2_update2(ri, testLocation()) + resourceName := "azurerm_data_factory_linked_service_data_lake_storage_gen2.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryLinkedServiceDataLakeStorageGen2Destroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServiceDataLakeStorageGen2Exists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "2"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "3"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "2"), + resource.TestCheckResourceAttr(resourceName, "description", "test description"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServiceDataLakeStorageGen2Exists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "3"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "1"), + resource.TestCheckResourceAttr(resourceName, "description", "test description 2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "service_principal_key", + }, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryLinkedServiceDataLakeStorageGen2Exists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory Storage: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.LinkedServiceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on dataFactoryLinkedServiceClient: %+v", err) + } + + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory Linked Service Data Lake Storage Gen2 %q (data factory name: %q / resource group: %q) does not exist", name, dataFactoryName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDataFactoryLinkedServiceDataLakeStorageGen2Destroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.LinkedServiceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory_linked_service_data_lake_storage_gen2" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Data Factory Linked Service Data Lake Storage Gen2 still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testAccAzureRMDataFactoryLinkedServiceDataLakeStorageGen2_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_data_factory_linked_service_data_lake_storage_gen2" "test" { + name = "acctestDataLake%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + service_principal_id = "${data.azurerm_client_config.current.client_id}" + service_principal_key = "testkey" + tenant = "11111111-1111-1111-1111-111111111111" + url = "https://test.azure.com" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryLinkedServiceDataLakeStorageGen2_update1(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_data_factory_linked_service_data_lake_storage_gen2" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + service_principal_id = "${data.azurerm_client_config.current.client_id}" + service_principal_key = "testkey" + tenant = "11111111-1111-1111-1111-111111111111" + url = "https://test.azure.com" + annotations = ["test1", "test2", "test3"] + description = "test description" + + parameters = { + foo = "test1" + bar = "test2" + } + + additional_properties = { + foo = "test1" + bar = "test2" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryLinkedServiceDataLakeStorageGen2_update2(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_data_factory_linked_service_data_lake_storage_gen2" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + service_principal_id = "${data.azurerm_client_config.current.client_id}" + service_principal_key = "testkey" + tenant = "11111111-1111-1111-1111-111111111111" + url = "https://test.azure.com" + annotations = ["test1", "test2"] + description = "test description 2" + + parameters = { + foo = "test1" + bar = "test2" + buzz = "test3" + } + + additional_properties = { + foo = "test1" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_factory_linked_service_mysql.go b/azurerm/resource_arm_data_factory_linked_service_mysql.go new file mode 100644 index 000000000000..dda8446216cb --- /dev/null +++ b/azurerm/resource_arm_data_factory_linked_service_mysql.go @@ -0,0 +1,244 @@ +package azurerm + +import ( + "fmt" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactoryLinkedServiceMySQL() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryLinkedServiceMySQLCreateOrUpdate, + Read: resourceArmDataFactoryLinkedServiceMySQLRead, + Update: resourceArmDataFactoryLinkedServiceMySQLCreateOrUpdate, + Delete: resourceArmDataFactoryLinkedServiceMySQLDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMDataFactoryLinkedServiceDatasetName, + }, + + "data_factory_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid name for Data Factory, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "connection_string": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: azureRmDataFactoryLinkedServiceConnectionStringDiff, + ValidateFunc: validate.NoEmptyStrings, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "integration_runtime_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "parameters": { + Type: schema.TypeMap, + Optional: true, + }, + + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "additional_properties": { + Type: schema.TypeMap, + Optional: true, + }, + }, + } +} + +func resourceArmDataFactoryLinkedServiceMySQLCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + dataFactoryName := d.Get("data_factory_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory Linked Service MySQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory_linked_service_mysql", *existing.ID) + } + } + + connectionString := d.Get("connection_string").(string) + secureString := datafactory.SecureString{ + Value: &connectionString, + Type: datafactory.TypeSecureString, + } + + mysqlProperties := &datafactory.MySQLLinkedServiceTypeProperties{ + ConnectionString: &secureString, + } + + description := d.Get("description").(string) + + mysqlLinkedService := &datafactory.MySQLLinkedService{ + Description: &description, + MySQLLinkedServiceTypeProperties: mysqlProperties, + Type: datafactory.TypeMySQL, + } + + if v, ok := d.GetOk("parameters"); ok { + mysqlLinkedService.Parameters = expandDataFactoryParameters(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("integration_runtime_name"); ok { + mysqlLinkedService.ConnectVia = expandDataFactoryLinkedServiceIntegrationRuntime(v.(string)) + } + + if v, ok := d.GetOk("additional_properties"); ok { + mysqlLinkedService.AdditionalProperties = v.(map[string]interface{}) + } + + if v, ok := d.GetOk("annotations"); ok { + annotations := v.([]interface{}) + mysqlLinkedService.Annotations = &annotations + } + + linkedService := datafactory.LinkedServiceResource{ + Properties: mysqlLinkedService, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, dataFactoryName, name, linkedService, ""); err != nil { + return fmt.Errorf("Error creating/updating Data Factory Linked Service MySQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory Linked Service MySQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Data Factory Linked Service MySQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmDataFactoryLinkedServiceMySQLRead(d, meta) +} + +func resourceArmDataFactoryLinkedServiceMySQLRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["linkedservices"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Data Factory Linked Service MySQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("data_factory_name", dataFactoryName) + + mysql, ok := resp.Properties.AsMySQLLinkedService() + if !ok { + return fmt.Errorf("Error classifiying Data Factory Linked Service MySQL %q (Data Factory %q / Resource Group %q): Expected: %q Received: %q", name, dataFactoryName, resourceGroup, datafactory.TypeMySQL, *resp.Type) + } + + d.Set("additional_properties", mysql.AdditionalProperties) + + if mysql.Description != nil { + d.Set("description", *mysql.Description) + } + + annotations := flattenDataFactoryAnnotations(mysql.Annotations) + if err := d.Set("annotations", annotations); err != nil { + return fmt.Errorf("Error setting `annotations`: %+v", err) + } + + parameters := flattenDataFactoryParameters(mysql.Parameters) + if err := d.Set("parameters", parameters); err != nil { + return fmt.Errorf("Error setting `parameters`: %+v", err) + } + + if connectVia := mysql.ConnectVia; connectVia != nil { + if connectVia.ReferenceName != nil { + d.Set("integration_runtime_name", connectVia.ReferenceName) + } + } + + return nil +} + +func resourceArmDataFactoryLinkedServiceMySQLDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["linkedservices"] + + response, err := client.Delete(ctx, resourceGroup, dataFactoryName, name) + if err != nil { + if !utils.ResponseWasNotFound(response) { + return fmt.Errorf("Error deleting Data Factory Linked Service MySQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_data_factory_linked_service_mysql_test.go b/azurerm/resource_arm_data_factory_linked_service_mysql_test.go new file mode 100644 index 000000000000..c1ecb670b949 --- /dev/null +++ b/azurerm/resource_arm_data_factory_linked_service_mysql_test.go @@ -0,0 +1,233 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactoryLinkedServiceMySQL_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryLinkedServiceMySQL_basic(ri, testLocation()) + resourceName := "azurerm_data_factory_linked_service_mysql.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryLinkedServiceMySQLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServiceMySQLExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // returned as ***** from the api + "connection_string", + }, + }, + }, + }) +} + +func TestAccAzureRMDataFactoryLinkedServiceMySQL_update(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryLinkedServiceMySQL_update1(ri, testLocation()) + config2 := testAccAzureRMDataFactoryLinkedServiceMySQL_update2(ri, testLocation()) + resourceName := "azurerm_data_factory_linked_service_mysql.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryLinkedServiceMySQLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServiceMySQLExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "2"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "3"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "2"), + resource.TestCheckResourceAttr(resourceName, "description", "test description"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServiceMySQLExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "3"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "1"), + resource.TestCheckResourceAttr(resourceName, "description", "test description 2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // returned as ***** from the api + "connection_string", + }, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryLinkedServiceMySQLExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.LinkedServiceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on dataFactoryLinkedServiceClient: %+v", err) + } + + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory Linked Service MySQL %q (data factory name: %q / resource group: %q) does not exist", name, dataFactoryName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDataFactoryLinkedServiceMySQLDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.LinkedServiceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory_linked_service_mysql" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Data Factory Linked Service MySQL still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testAccAzureRMDataFactoryLinkedServiceMySQL_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_mysql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryLinkedServiceMySQL_update1(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_mysql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test" + annotations = ["test1", "test2", "test3"] + description = "test description" + + parameters = { + foo = "test1" + bar = "test2" + } + + additional_properties = { + foo = "test1" + bar = "test2" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryLinkedServiceMySQL_update2(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_mysql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test" + annotations = ["test1", "test2"] + description = "test description 2" + + parameters = { + foo = "test1" + bar = "test2" + buzz = "test3" + } + + additional_properties = { + foo = "test1" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_factory_linked_service_postgresql.go b/azurerm/resource_arm_data_factory_linked_service_postgresql.go new file mode 100644 index 000000000000..69c07f67a30a --- /dev/null +++ b/azurerm/resource_arm_data_factory_linked_service_postgresql.go @@ -0,0 +1,244 @@ +package azurerm + +import ( + "fmt" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactoryLinkedServicePostgreSQL() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryLinkedServicePostgreSQLCreateOrUpdate, + Read: resourceArmDataFactoryLinkedServicePostgreSQLRead, + Update: resourceArmDataFactoryLinkedServicePostgreSQLCreateOrUpdate, + Delete: resourceArmDataFactoryLinkedServicePostgreSQLDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMDataFactoryLinkedServiceDatasetName, + }, + + "data_factory_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid name for Data Factory, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "connection_string": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: azureRmDataFactoryLinkedServiceConnectionStringDiff, + ValidateFunc: validate.NoEmptyStrings, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "integration_runtime_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "parameters": { + Type: schema.TypeMap, + Optional: true, + }, + + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "additional_properties": { + Type: schema.TypeMap, + Optional: true, + }, + }, + } +} + +func resourceArmDataFactoryLinkedServicePostgreSQLCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + dataFactoryName := d.Get("data_factory_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory Linked Service PostgreSQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory_linked_service_postgresql", *existing.ID) + } + } + + connectionString := d.Get("connection_string").(string) + secureString := datafactory.SecureString{ + Value: &connectionString, + Type: datafactory.TypeSecureString, + } + + postgresqlProperties := &datafactory.PostgreSQLLinkedServiceTypeProperties{ + ConnectionString: &secureString, + } + + description := d.Get("description").(string) + + postgresqlLinkedService := &datafactory.PostgreSQLLinkedService{ + Description: &description, + PostgreSQLLinkedServiceTypeProperties: postgresqlProperties, + Type: datafactory.TypePostgreSQL, + } + + if v, ok := d.GetOk("parameters"); ok { + postgresqlLinkedService.Parameters = expandDataFactoryParameters(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("integration_runtime_name"); ok { + postgresqlLinkedService.ConnectVia = expandDataFactoryLinkedServiceIntegrationRuntime(v.(string)) + } + + if v, ok := d.GetOk("additional_properties"); ok { + postgresqlLinkedService.AdditionalProperties = v.(map[string]interface{}) + } + + if v, ok := d.GetOk("annotations"); ok { + annotations := v.([]interface{}) + postgresqlLinkedService.Annotations = &annotations + } + + linkedService := datafactory.LinkedServiceResource{ + Properties: postgresqlLinkedService, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, dataFactoryName, name, linkedService, ""); err != nil { + return fmt.Errorf("Error creating/updating Data Factory Linked Service PostgreSQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory Linked Service PostgreSQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Data Factory Linked Service PostgreSQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmDataFactoryLinkedServicePostgreSQLRead(d, meta) +} + +func resourceArmDataFactoryLinkedServicePostgreSQLRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["linkedservices"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Data Factory Linked Service PostgreSQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("data_factory_name", dataFactoryName) + + postgresql, ok := resp.Properties.AsPostgreSQLLinkedService() + if !ok { + return fmt.Errorf("Error classifiying Data Factory Linked Service PostgreSQL %q (Data Factory %q / Resource Group %q): Expected: %q Received: %q", name, dataFactoryName, resourceGroup, datafactory.TypeMySQL, *resp.Type) + } + + d.Set("additional_properties", postgresql.AdditionalProperties) + + if postgresql.Description != nil { + d.Set("description", *postgresql.Description) + } + + annotations := flattenDataFactoryAnnotations(postgresql.Annotations) + if err := d.Set("annotations", annotations); err != nil { + return fmt.Errorf("Error setting `annotations`: %+v", err) + } + + parameters := flattenDataFactoryParameters(postgresql.Parameters) + if err := d.Set("parameters", parameters); err != nil { + return fmt.Errorf("Error setting `parameters`: %+v", err) + } + + if connectVia := postgresql.ConnectVia; connectVia != nil { + if connectVia.ReferenceName != nil { + d.Set("integration_runtime_name", connectVia.ReferenceName) + } + } + + return nil +} + +func resourceArmDataFactoryLinkedServicePostgreSQLDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["linkedservices"] + + response, err := client.Delete(ctx, resourceGroup, dataFactoryName, name) + if err != nil { + if !utils.ResponseWasNotFound(response) { + return fmt.Errorf("Error deleting Data Factory Linked Service PostgreSQL %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_data_factory_linked_service_postgresql_test.go b/azurerm/resource_arm_data_factory_linked_service_postgresql_test.go new file mode 100644 index 000000000000..22ec38f661d9 --- /dev/null +++ b/azurerm/resource_arm_data_factory_linked_service_postgresql_test.go @@ -0,0 +1,233 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactoryLinkedServicePostgreSQL_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryLinkedServicePostgreSQL_basic(ri, testLocation()) + resourceName := "azurerm_data_factory_linked_service_postgresql.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryLinkedServicePostgreSQLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServicePostgreSQLExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // returned as ***** from the api + "connection_string", + }, + }, + }, + }) +} + +func TestAccAzureRMDataFactoryLinkedServicePostgreSQL_update(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryLinkedServicePostgreSQL_update1(ri, testLocation()) + config2 := testAccAzureRMDataFactoryLinkedServicePostgreSQL_update2(ri, testLocation()) + resourceName := "azurerm_data_factory_linked_service_postgresql.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryLinkedServicePostgreSQLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServicePostgreSQLExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "2"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "3"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "2"), + resource.TestCheckResourceAttr(resourceName, "description", "test description"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServicePostgreSQLExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "3"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "1"), + resource.TestCheckResourceAttr(resourceName, "description", "test description 2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // returned as ***** from the api + "connection_string", + }, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryLinkedServicePostgreSQLExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.LinkedServiceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on dataFactoryLinkedServiceClient: %+v", err) + } + + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory Linked Service PostgreSQL %q (data factory name: %q / resource group: %q) does not exist", name, dataFactoryName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDataFactoryLinkedServicePostgreSQLDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.LinkedServiceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory_linked_service_postgresql" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Data Factory Linked Service PostgreSQL still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testAccAzureRMDataFactoryLinkedServicePostgreSQL_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_postgresql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Host=example;Port=5432;Database=example;UID=example;EncryptionMethod=0;Password=example" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryLinkedServicePostgreSQL_update1(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_postgresql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Host=example;Port=5432;Database=example;UID=example;EncryptionMethod=0;Password=example" + annotations = ["test1", "test2", "test3"] + description = "test description" + + parameters = { + foo = "test1" + bar = "test2" + } + + additional_properties = { + foo = "test1" + bar = "test2" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryLinkedServicePostgreSQL_update2(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_postgresql" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Host=example;Port=5432;Database=example;UID=example;EncryptionMethod=0;Password=example" + annotations = ["test1", "test2"] + description = "test description 2" + + parameters = { + foo = "test1" + bar = "test2" + buzz = "test3" + } + + additional_properties = { + foo = "test1" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_factory_linked_service_sql_server.go b/azurerm/resource_arm_data_factory_linked_service_sql_server.go new file mode 100644 index 000000000000..65009ba51d99 --- /dev/null +++ b/azurerm/resource_arm_data_factory_linked_service_sql_server.go @@ -0,0 +1,252 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactoryLinkedServiceSQLServer() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryLinkedServiceSQLServerCreateOrUpdate, + Read: resourceArmDataFactoryLinkedServiceSQLServerRead, + Update: resourceArmDataFactoryLinkedServiceSQLServerCreateOrUpdate, + Delete: resourceArmDataFactoryLinkedServiceSQLServerDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMDataFactoryLinkedServiceDatasetName, + }, + + "data_factory_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid name for Data Factory, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "connection_string": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: azureRmDataFactoryLinkedServiceConnectionStringDiff, + ValidateFunc: validate.NoEmptyStrings, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "integration_runtime_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "parameters": { + Type: schema.TypeMap, + Optional: true, + }, + + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "additional_properties": { + Type: schema.TypeMap, + Optional: true, + }, + }, + } +} + +func resourceArmDataFactoryLinkedServiceSQLServerCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + dataFactoryName := d.Get("data_factory_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory Linked Service SQL Server %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory_linked_service_sql_server", *existing.ID) + } + } + + sqlServerProperties := &datafactory.SQLServerLinkedServiceTypeProperties{ + ConnectionString: d.Get("connection_string").(string), + } + + description := d.Get("description").(string) + + sqlServerLinkedService := &datafactory.SQLServerLinkedService{ + Description: &description, + SQLServerLinkedServiceTypeProperties: sqlServerProperties, + Type: datafactory.TypeSQLServer, + } + + if v, ok := d.GetOk("parameters"); ok { + sqlServerLinkedService.Parameters = expandDataFactoryParameters(v.(map[string]interface{})) + } + + if v, ok := d.GetOk("integration_runtime_name"); ok { + sqlServerLinkedService.ConnectVia = expandDataFactoryLinkedServiceIntegrationRuntime(v.(string)) + } + + if v, ok := d.GetOk("additional_properties"); ok { + sqlServerLinkedService.AdditionalProperties = v.(map[string]interface{}) + } + + if v, ok := d.GetOk("annotations"); ok { + annotations := v.([]interface{}) + sqlServerLinkedService.Annotations = &annotations + } + + linkedService := datafactory.LinkedServiceResource{ + Properties: sqlServerLinkedService, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, dataFactoryName, name, linkedService, ""); err != nil { + return fmt.Errorf("Error creating/updating Data Factory Linked Service SQL Server %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory Linked Service SQL Server %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Data Factory Linked Service SQL Server %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmDataFactoryLinkedServiceSQLServerRead(d, meta) +} + +func resourceArmDataFactoryLinkedServiceSQLServerRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["linkedservices"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Data Factory Linked Service SQL Server %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("data_factory_name", dataFactoryName) + + sqlServer, ok := resp.Properties.AsSQLServerLinkedService() + if !ok { + return fmt.Errorf("Error classifiying Data Factory Linked Service SQL Server %q (Data Factory %q / Resource Group %q): Expected: %q Received: %q", name, dataFactoryName, resourceGroup, datafactory.TypeSQLServer, *resp.Type) + } + + d.Set("additional_properties", sqlServer.AdditionalProperties) + + if sqlServer.Description != nil { + d.Set("description", *sqlServer.Description) + } + + annotations := flattenDataFactoryAnnotations(sqlServer.Annotations) + if err := d.Set("annotations", annotations); err != nil { + return fmt.Errorf("Error setting `annotations`: %+v", err) + } + + parameters := flattenDataFactoryParameters(sqlServer.Parameters) + if err := d.Set("parameters", parameters); err != nil { + return fmt.Errorf("Error setting `parameters`: %+v", err) + } + + if connectVia := sqlServer.ConnectVia; connectVia != nil { + if connectVia.ReferenceName != nil { + d.Set("integration_runtime_name", connectVia.ReferenceName) + } + } + + connectionString := "" + if properties := sqlServer.SQLServerLinkedServiceTypeProperties; properties != nil { + if properties.ConnectionString != nil { + val, ok := properties.ConnectionString.(string) + if ok { + connectionString = val + } else { + log.Printf("[DEBUG] Skipping connection string %q since it's not a string", val) + } + } + } + d.Set("connection_string", connectionString) + + return nil +} + +func resourceArmDataFactoryLinkedServiceSQLServerDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.LinkedServiceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + dataFactoryName := id.Path["factories"] + name := id.Path["linkedservices"] + + response, err := client.Delete(ctx, resourceGroup, dataFactoryName, name) + if err != nil { + if !utils.ResponseWasNotFound(response) { + return fmt.Errorf("Error deleting Data Factory Linked Service SQL Server %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_data_factory_linked_service_sql_server_test.go b/azurerm/resource_arm_data_factory_linked_service_sql_server_test.go new file mode 100644 index 000000000000..6ea40b5cf842 --- /dev/null +++ b/azurerm/resource_arm_data_factory_linked_service_sql_server_test.go @@ -0,0 +1,180 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactoryLinkedServiceSQLServer_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactoryLinkedServiceSQLServer_basic(ri, testLocation()) + config2 := testAccAzureRMDataFactoryLinkedServiceSQLServer_update(ri, testLocation()) + resourceName := "azurerm_data_factory_linked_service_sql_server.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryLinkedServiceSQLServerDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServiceSQLServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "2"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "3"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "2"), + resource.TestCheckResourceAttr(resourceName, "description", "test description"), + resource.TestCheckResourceAttrSet(resourceName, "connection_string"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryLinkedServiceSQLServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "3"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "additional_properties.%", "1"), + resource.TestCheckResourceAttr(resourceName, "description", "test description 2"), + resource.TestCheckResourceAttrSet(resourceName, "connection_string"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryLinkedServiceSQLServerExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.LinkedServiceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on dataFactoryLinkedServiceClient: %+v", err) + } + + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory Linked Service SQL Server %q (data factory name: %q / resource group: %q) does not exist", name, dataFactoryName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDataFactoryLinkedServiceSQLServerDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.LinkedServiceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory_linked_service_sql_server" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Data Factory Linked Service SQL Server still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testAccAzureRMDataFactoryLinkedServiceSQLServer_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_sql_server" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test" + annotations = ["test1", "test2", "test3"] + description = "test description" + + parameters = { + foo = "test1" + bar = "test2" + } + + additional_properties = { + foo = "test1" + bar = "test2" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryLinkedServiceSQLServer_update(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_linked_service_sql_server" "test" { + name = "acctestlssql%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test" + annotations = ["test1", "test2"] + description = "test description 2" + + parameters = { + foo = "test1" + bar = "test2" + buzz = "test3" + } + + additional_properties = { + foo = "test1" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_factory_pipeline.go b/azurerm/resource_arm_data_factory_pipeline.go new file mode 100644 index 000000000000..d146c3dad554 --- /dev/null +++ b/azurerm/resource_arm_data_factory_pipeline.go @@ -0,0 +1,209 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDataFactoryPipeline() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDataFactoryPipelineCreateUpdate, + Read: resourceArmDataFactoryPipelineRead, + Update: resourceArmDataFactoryPipelineCreateUpdate, + Delete: resourceArmDataFactoryPipelineDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMDataFactoryPipelineName, + }, + + "data_factory_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$`), + `Invalid data_factory_name, see https://docs.microsoft.com/en-us/azure/data-factory/naming-rules`, + ), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "parameters": { + Type: schema.TypeMap, + Optional: true, + }, + + "variables": { + Type: schema.TypeMap, + Optional: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "annotations": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +func resourceArmDataFactoryPipelineCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.PipelinesClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Data Factory Pipeline creation.") + + resourceGroupName := d.Get("resource_group_name").(string) + name := d.Get("name").(string) + dataFactoryName := d.Get("data_factory_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroupName, dataFactoryName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Data Factory Pipeline %q (Resource Group %q / Data Factory %q): %s", name, resourceGroupName, dataFactoryName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_data_factory_pipeline", *existing.ID) + } + } + + description := d.Get("description").(string) + pipeline := &datafactory.Pipeline{ + Parameters: expandDataFactoryParameters(d.Get("parameters").(map[string]interface{})), + Variables: expandDataFactoryVariables(d.Get("variables").(map[string]interface{})), + Description: &description, + } + + if v, ok := d.GetOk("annotations"); ok { + annotations := v.([]interface{}) + pipeline.Annotations = &annotations + } else { + annotations := make([]interface{}, 0) + pipeline.Annotations = &annotations + } + + config := datafactory.PipelineResource{ + Pipeline: pipeline, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroupName, dataFactoryName, name, config, ""); err != nil { + return fmt.Errorf("Error creating Data Factory Pipeline %q (Resource Group %q / Data Factory %q): %+v", name, resourceGroupName, dataFactoryName, err) + } + + read, err := client.Get(ctx, resourceGroupName, dataFactoryName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Data Factory Pipeline %q (Resource Group %q / Data Factory %q): %+v", name, resourceGroupName, dataFactoryName, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read Data Factory Pipeline %q (Resource Group %q / Data Factory %q) ID", name, resourceGroupName, dataFactoryName) + } + + d.SetId(*read.ID) + + return resourceArmDataFactoryPipelineRead(d, meta) +} + +func resourceArmDataFactoryPipelineRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.PipelinesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + dataFactoryName := id.Path["factories"] + name := id.Path["pipelines"] + + resp, err := client.Get(ctx, id.ResourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + log.Printf("[DEBUG] Data Factory Pipeline %q was not found in Resource Group %q - removing from state!", name, id.ResourceGroup) + return nil + } + return fmt.Errorf("Error reading the state of Data Factory Pipeline %q: %+v", name, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", id.ResourceGroup) + d.Set("data_factory_name", dataFactoryName) + + if props := resp.Pipeline; props != nil { + d.Set("description", props.Description) + + parameters := flattenDataFactoryParameters(props.Parameters) + if err := d.Set("parameters", parameters); err != nil { + return fmt.Errorf("Error setting `parameters`: %+v", err) + } + + annotations := flattenDataFactoryAnnotations(props.Annotations) + if err := d.Set("annotations", annotations); err != nil { + return fmt.Errorf("Error setting `annotations`: %+v", err) + } + + variables := flattenDataFactoryVariables(props.Variables) + if err := d.Set("variables", variables); err != nil { + return fmt.Errorf("Error setting `variables`: %+v", err) + } + + } + + return nil +} + +func resourceArmDataFactoryPipelineDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).dataFactory.PipelinesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + dataFactoryName := id.Path["factories"] + name := id.Path["pipelines"] + resourceGroupName := id.ResourceGroup + + if _, err = client.Delete(ctx, resourceGroupName, dataFactoryName, name); err != nil { + return fmt.Errorf("Error deleting Data Factory Pipeline %q (Resource Group %q / Data Factory %q): %+v", name, resourceGroupName, dataFactoryName, err) + } + + return nil +} + +func validateAzureRMDataFactoryPipelineName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + if regexp.MustCompile(`^[.+?/<>*%&:\\]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf("any of '.', '+', '?', '/', '<', '>', '*', '%%', '&', ':', '\\', are not allowed in %q: %q", k, value)) + } + + return warnings, errors +} diff --git a/azurerm/resource_arm_data_factory_pipeline_test.go b/azurerm/resource_arm_data_factory_pipeline_test.go new file mode 100644 index 000000000000..8c587ffe068e --- /dev/null +++ b/azurerm/resource_arm_data_factory_pipeline_test.go @@ -0,0 +1,215 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactoryPipeline_basic(t *testing.T) { + resourceName := "azurerm_data_factory_pipeline.test" + ri := tf.AccRandTimeInt() + location := testLocation() + config := testAccAzureRMDataFactoryPipeline_basic(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryPipelineExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactoryPipeline_update(t *testing.T) { + resourceName := "azurerm_data_factory_pipeline.test" + ri := tf.AccRandTimeInt() + location := testLocation() + config := testAccAzureRMDataFactoryPipeline_update1(ri, location) + config2 := testAccAzureRMDataFactoryPipeline_update2(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "1"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "3"), + resource.TestCheckResourceAttr(resourceName, "description", "test description"), + resource.TestCheckResourceAttr(resourceName, "variables.%", "2"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "parameters.%", "2"), + resource.TestCheckResourceAttr(resourceName, "annotations.#", "2"), + resource.TestCheckResourceAttr(resourceName, "description", "test description2"), + resource.TestCheckResourceAttr(resourceName, "variables.%", "3"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryPipelineDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.PipelinesClient + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory_pipeline" { + continue + } + + name := rs.Primary.Attributes["name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + return nil +} + +func testCheckAzureRMDataFactoryPipelineExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + dataFactoryName := rs.Primary.Attributes["data_factory_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + client := testAccProvider.Meta().(*ArmClient).dataFactory.PipelinesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory Pipeline %q (Resource Group %q / Data Factory %q) does not exist", name, resourceGroup, dataFactoryName) + } + return fmt.Errorf("Bad: Get on DataFactoryPipelineClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMDataFactoryPipeline_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdfv2%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_pipeline" "test" { + name = "acctest%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryPipeline_update1(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdfv2%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_pipeline" "test" { + name = "acctest%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + annotations = ["test1", "test2", "test3"] + description = "test description" + + parameters = { + test = "testparameter" + } + + variables = { + foo = "test1" + bar = "test2" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactoryPipeline_update2(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdfv2%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_data_factory_pipeline" "test" { + name = "acctest%d" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + annotations = ["test1", "test2"] + description = "test description2" + + parameters = { + test = "testparameter" + test2 = "testparameter2" + } + + variables = { + foo = "test1" + bar = "test2" + baz = "test3" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_factory_test.go b/azurerm/resource_arm_data_factory_test.go new file mode 100644 index 000000000000..630127c4d148 --- /dev/null +++ b/azurerm/resource_arm_data_factory_test.go @@ -0,0 +1,397 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMDataFactory_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactory_basic(ri, testLocation()) + resourceName := "azurerm_data_factory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactory_tags(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactory_tags(ri, testLocation()) + resourceName := "azurerm_data_factory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "production"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactory_tagsUpdated(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactory_tags(ri, testLocation()) + updatedConfig := testAccAzureRMDataFactory_tagsUpdated(ri, testLocation()) + resourceName := "azurerm_data_factory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "production"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "production"), + resource.TestCheckResourceAttr(resourceName, "tags.updated", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactory_identity(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactory_identity(ri, testLocation()) + resourceName := "azurerm_data_factory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "identity.#"), + resource.TestCheckResourceAttrSet(resourceName, "identity.0.type"), + resource.TestCheckResourceAttrSet(resourceName, "identity.0.principal_id"), + resource.TestCheckResourceAttrSet(resourceName, "identity.0.tenant_id"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactory_disappears(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactory_basic(ri, testLocation()) + resourceName := "azurerm_data_factory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryExists(resourceName), + testCheckAzureRMDataFactoryDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAzureRMDataFactory_github(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMDataFactory_github(ri, testLocation()) + config2 := testAccAzureRMDataFactory_githubUpdated(ri, testLocation()) + resourceName := "azurerm_data_factory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDataFactoryDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.account_name", fmt.Sprintf("acctestGH-%d", ri)), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.git_url", "https://github.com/terraform-providers/"), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.repository_name", "terraform-provider-azurerm"), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.branch_name", "master"), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.root_folder", "/"), + ), + }, + { + Config: config2, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDataFactoryExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.account_name", fmt.Sprintf("acctestGitHub-%d", ri)), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.git_url", "https://github.com/terraform-providers/"), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.repository_name", "terraform-provider-azuread"), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.branch_name", "stable-website"), + resource.TestCheckResourceAttr(resourceName, "github_configuration.0.root_folder", "/azuread"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMDataFactoryExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.FactoriesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on dataFactoryClient: %+v", err) + } + + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Data Factory %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDataFactoryDisappears(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Data Factory: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).dataFactory.FactoriesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(resp) { + return fmt.Errorf("Bad: Delete on dataFactoryClient: %+v", err) + } + } + + return nil + } +} + +func testCheckAzureRMDataFactoryDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).dataFactory.FactoriesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_data_factory" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Data Factory still exists:\n%#v", resp.FactoryProperties) + } + } + + return nil +} + +func testAccAzureRMDataFactory_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rInt) +} + +func testAccAzureRMDataFactory_tags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "production" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMDataFactory_tagsUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "production" + updated = "true" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMDataFactory_identity(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + identity { + type = "SystemAssigned" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMDataFactory_github(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + github_configuration { + git_url = "https://github.com/terraform-providers/" + repository_name = "terraform-provider-azurerm" + branch_name = "master" + root_folder = "/" + account_name = "acctestGH-%d" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMDataFactory_githubUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + github_configuration { + git_url = "https://github.com/terraform-providers/" + repository_name = "terraform-provider-azuread" + branch_name = "stable-website" + root_folder = "/azuread" + account_name = "acctestGitHub-%d" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_data_lake_analytics_account.go b/azurerm/resource_arm_data_lake_analytics_account.go index c038b5f9cf03..bddcffbf49bd 100644 --- a/azurerm/resource_arm_data_lake_analytics_account.go +++ b/azurerm/resource_arm_data_lake_analytics_account.go @@ -6,6 +6,8 @@ import ( "github.com/Azure/azure-sdk-for-go/services/datalake/analytics/mgmt/2016-11-01/account" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" @@ -35,9 +37,9 @@ func resourceArmDataLakeAnalyticsAccount() *schema.Resource { ValidateFunc: azure.ValidateDataLakeAccountName(), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "tier": { Type: schema.TypeString, @@ -64,19 +66,19 @@ func resourceArmDataLakeAnalyticsAccount() *schema.Resource { ValidateFunc: azure.ValidateDataLakeAccountName(), }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDateLakeAnalyticsAccountCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeAnalyticsAccountClient + client := meta.(*ArmClient).datalake.AnalyticsAccountsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -89,16 +91,16 @@ func resourceArmDateLakeAnalyticsAccountCreate(d *schema.ResourceData, meta inte } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) storeAccountName := d.Get("default_store_account_name").(string) tier := d.Get("tier").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) log.Printf("[INFO] preparing arguments for Azure ARM Date Lake Store creation %q (Resource Group %q)", name, resourceGroup) dateLakeAnalyticsAccount := account.CreateDataLakeAnalyticsAccountParameters{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), CreateDataLakeAnalyticsAccountProperties: &account.CreateDataLakeAnalyticsAccountProperties{ NewTier: account.TierType(tier), DefaultDataLakeStoreAccount: &storeAccountName, @@ -133,7 +135,7 @@ func resourceArmDateLakeAnalyticsAccountCreate(d *schema.ResourceData, meta inte } func resourceArmDateLakeAnalyticsAccountUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeAnalyticsAccountClient + client := meta.(*ArmClient).datalake.AnalyticsAccountsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -143,7 +145,7 @@ func resourceArmDateLakeAnalyticsAccountUpdate(d *schema.ResourceData, meta inte newTags := d.Get("tags").(map[string]interface{}) props := &account.UpdateDataLakeAnalyticsAccountParameters{ - Tags: expandTags(newTags), + Tags: tags.Expand(newTags), UpdateDataLakeAnalyticsAccountProperties: &account.UpdateDataLakeAnalyticsAccountProperties{ NewTier: account.TierType(newTier), DataLakeStoreAccounts: &[]account.UpdateDataLakeStoreWithAccountParameters{ @@ -167,10 +169,10 @@ func resourceArmDateLakeAnalyticsAccountUpdate(d *schema.ResourceData, meta inte } func resourceArmDateLakeAnalyticsAccountRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeAnalyticsAccountClient + client := meta.(*ArmClient).datalake.AnalyticsAccountsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -191,7 +193,7 @@ func resourceArmDateLakeAnalyticsAccountRead(d *schema.ResourceData, meta interf d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if properties := resp.DataLakeAnalyticsAccountProperties; properties != nil { @@ -199,16 +201,14 @@ func resourceArmDateLakeAnalyticsAccountRead(d *schema.ResourceData, meta interf d.Set("default_store_account_name", properties.DefaultDataLakeStoreAccount) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmDateLakeAnalyticsAccountDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeAnalyticsAccountClient + client := meta.(*ArmClient).datalake.AnalyticsAccountsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_data_lake_analytics_account_test.go b/azurerm/resource_arm_data_lake_analytics_account_test.go index b9a3bf3ce3da..66245a39c189 100644 --- a/azurerm/resource_arm_data_lake_analytics_account_test.go +++ b/azurerm/resource_arm_data_lake_analytics_account_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDataLakeAnalyticsAccount_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDataLakeAnalyticsAccount_basic(t *testing.T) { } func TestAccAzureRMDataLakeAnalyticsAccount_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -136,7 +137,7 @@ func testCheckAzureRMDataLakeAnalyticsAccountExists(resourceName string) resourc return fmt.Errorf("Bad: no resource group found in state for data lake store: %s", accountName) } - conn := testAccProvider.Meta().(*ArmClient).dataLakeAnalyticsAccountClient + conn := testAccProvider.Meta().(*ArmClient).datalake.AnalyticsAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accountName) @@ -153,7 +154,7 @@ func testCheckAzureRMDataLakeAnalyticsAccountExists(resourceName string) resourc } func testCheckAzureRMDataLakeAnalyticsAccountDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dataLakeAnalyticsAccountClient + conn := testAccProvider.Meta().(*ArmClient).datalake.AnalyticsAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -191,7 +192,7 @@ resource "azurerm_data_lake_analytics_account" "test" { default_store_account_name = "${azurerm_data_lake_store.test.name}" } -`, template, strconv.Itoa(rInt)[0:15]) +`, template, strconv.Itoa(rInt)[2:17]) } func testAccAzureRMDataLakeAnalyticsAccount_requiresImport(rInt int, location string) string { @@ -222,7 +223,7 @@ resource "azurerm_data_lake_analytics_account" "test" { default_store_account_name = "${azurerm_data_lake_store.test.name}" } -`, template, strconv.Itoa(rInt)[0:15]) +`, template, strconv.Itoa(rInt)[2:17]) } func testAccAzureRMDataLakeAnalyticsAccount_withTags(rInt int, location string) string { @@ -242,7 +243,7 @@ resource "azurerm_data_lake_analytics_account" "test" { cost_center = "MSFT" } } -`, template, strconv.Itoa(rInt)[0:15]) +`, template, strconv.Itoa(rInt)[2:17]) } func testAccAzureRMDataLakeAnalyticsAccount_withTagsUpdate(rInt int, location string) string { @@ -261,5 +262,5 @@ resource "azurerm_data_lake_analytics_account" "test" { environment = "staging" } } -`, template, strconv.Itoa(rInt)[0:15]) +`, template, strconv.Itoa(rInt)[2:17]) } diff --git a/azurerm/resource_arm_data_lake_analytics_firewall_rule.go b/azurerm/resource_arm_data_lake_analytics_firewall_rule.go index b53e4067de6a..7adc52bdb59a 100644 --- a/azurerm/resource_arm_data_lake_analytics_firewall_rule.go +++ b/azurerm/resource_arm_data_lake_analytics_firewall_rule.go @@ -6,6 +6,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/datalake/analytics/mgmt/2016-11-01/account" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/hashicorp/terraform/helper/schema" @@ -41,7 +42,7 @@ func resourceArmDataLakeAnalyticsFirewallRule() *schema.Resource { ValidateFunc: azure.ValidateDataLakeAccountName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "start_ip_address": { Type: schema.TypeString, @@ -59,14 +60,14 @@ func resourceArmDataLakeAnalyticsFirewallRule() *schema.Resource { } func resourceArmDateLakeAnalyticsFirewallRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeAnalyticsFirewallRulesClient + client := meta.(*ArmClient).datalake.AnalyticsFirewallRulesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) accountName := d.Get("account_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, accountName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -109,10 +110,10 @@ func resourceArmDateLakeAnalyticsFirewallRuleCreateUpdate(d *schema.ResourceData } func resourceArmDateLakeAnalyticsFirewallRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeAnalyticsFirewallRulesClient + client := meta.(*ArmClient).datalake.AnalyticsFirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -143,10 +144,10 @@ func resourceArmDateLakeAnalyticsFirewallRuleRead(d *schema.ResourceData, meta i } func resourceArmDateLakeAnalyticsFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeAnalyticsFirewallRulesClient + client := meta.(*ArmClient).datalake.AnalyticsFirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_data_lake_analytics_firewall_rule_test.go b/azurerm/resource_arm_data_lake_analytics_firewall_rule_test.go index 1dab7a958427..d9474104cd5b 100644 --- a/azurerm/resource_arm_data_lake_analytics_firewall_rule_test.go +++ b/azurerm/resource_arm_data_lake_analytics_firewall_rule_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDataLakeAnalyticsFirewallRule_basic(t *testing.T) { @@ -41,7 +42,7 @@ func TestAccAzureRMDataLakeAnalyticsFirewallRule_basic(t *testing.T) { } func TestAccAzureRMDataLakeAnalyticsFirewallRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -144,7 +145,7 @@ func testCheckAzureRMDataLakeAnalyticsFirewallRuleExists(resourceName string) re return fmt.Errorf("Bad: no resource group found in state for data lake store firewall rule: %s", firewallRuleName) } - conn := testAccProvider.Meta().(*ArmClient).dataLakeAnalyticsFirewallRulesClient + conn := testAccProvider.Meta().(*ArmClient).datalake.AnalyticsFirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accountName, firewallRuleName) @@ -161,7 +162,7 @@ func testCheckAzureRMDataLakeAnalyticsFirewallRuleExists(resourceName string) re } func testCheckAzureRMDataLakeAnalyticsFirewallRuleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dataLakeAnalyticsFirewallRulesClient + conn := testAccProvider.Meta().(*ArmClient).datalake.AnalyticsFirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -216,7 +217,7 @@ resource "azurerm_data_lake_analytics_firewall_rule" "test" { start_ip_address = "%[4]s" end_ip_address = "%[5]s" } -`, rInt, location, strconv.Itoa(rInt)[0:10], startIP, endIP) +`, rInt, location, strconv.Itoa(rInt)[10:17], startIP, endIP) } func testAccAzureRMDataLakeAnalyticsFirewallRule_requiresImport(rInt int, location, startIP, endIP string) string { diff --git a/azurerm/resource_arm_data_lake_store.go b/azurerm/resource_arm_data_lake_store.go index 40128af8c759..c9aeb17a335a 100644 --- a/azurerm/resource_arm_data_lake_store.go +++ b/azurerm/resource_arm_data_lake_store.go @@ -11,6 +11,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -33,9 +35,9 @@ func resourceArmDataLakeStore() *schema.Resource { ValidateFunc: azure.ValidateDataLakeAccountName(), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "tier": { Type: schema.TypeString, @@ -103,19 +105,19 @@ func resourceArmDataLakeStore() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDateLakeStoreCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreAccountClient + client := meta.(*ArmClient).datalake.StoreAccountsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -128,20 +130,20 @@ func resourceArmDateLakeStoreCreate(d *schema.ResourceData, meta interface{}) er } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) tier := d.Get("tier").(string) encryptionState := account.EncryptionState(d.Get("encryption_state").(string)) encryptionType := account.EncryptionConfigType(d.Get("encryption_type").(string)) firewallState := account.FirewallState(d.Get("firewall_state").(string)) firewallAllowAzureIPs := account.FirewallAllowAzureIpsState(d.Get("firewall_allow_azure_ips").(string)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) log.Printf("[INFO] preparing arguments for Data Lake Store creation %q (Resource Group %q)", name, resourceGroup) dateLakeStore := account.CreateDataLakeStoreAccountParameters{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), CreateDataLakeStoreAccountProperties: &account.CreateDataLakeStoreAccountProperties{ NewTier: account.TierType(tier), FirewallState: firewallState, @@ -176,7 +178,7 @@ func resourceArmDateLakeStoreCreate(d *schema.ResourceData, meta interface{}) er } func resourceArmDateLakeStoreUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreAccountClient + client := meta.(*ArmClient).datalake.StoreAccountsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -184,7 +186,7 @@ func resourceArmDateLakeStoreUpdate(d *schema.ResourceData, meta interface{}) er tier := d.Get("tier").(string) firewallState := account.FirewallState(d.Get("firewall_state").(string)) firewallAllowAzureIPs := account.FirewallAllowAzureIpsState(d.Get("firewall_allow_azure_ips").(string)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) props := account.UpdateDataLakeStoreAccountParameters{ UpdateDataLakeStoreAccountProperties: &account.UpdateDataLakeStoreAccountProperties{ @@ -192,7 +194,7 @@ func resourceArmDateLakeStoreUpdate(d *schema.ResourceData, meta interface{}) er FirewallState: firewallState, FirewallAllowAzureIps: firewallAllowAzureIPs, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.Update(ctx, resourceGroup, name, props) @@ -208,10 +210,10 @@ func resourceArmDateLakeStoreUpdate(d *schema.ResourceData, meta interface{}) er } func resourceArmDateLakeStoreRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreAccountClient + client := meta.(*ArmClient).datalake.StoreAccountsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -232,7 +234,7 @@ func resourceArmDateLakeStoreRead(d *schema.ResourceData, meta interface{}) erro d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if properties := resp.DataLakeStoreAccountProperties; properties != nil { @@ -249,16 +251,14 @@ func resourceArmDateLakeStoreRead(d *schema.ResourceData, meta interface{}) erro d.Set("endpoint", properties.Endpoint) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmDateLakeStoreDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreAccountClient + client := meta.(*ArmClient).datalake.StoreAccountsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_data_lake_store_file.go b/azurerm/resource_arm_data_lake_store_file.go index 182cdcad436b..3093b3ae288f 100644 --- a/azurerm/resource_arm_data_lake_store_file.go +++ b/azurerm/resource_arm_data_lake_store_file.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -39,7 +40,7 @@ func resourceArmDataLakeStoreFile() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validateFilePath(), + ValidateFunc: validateDataLakeStoreRemoteFilePath(), }, "local_file_path": { @@ -52,7 +53,7 @@ func resourceArmDataLakeStoreFile() *schema.Resource { } func resourceArmDataLakeStoreFileCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreFilesClient + client := meta.(*ArmClient).datalake.StoreFilesClient ctx := meta.(*ArmClient).StopContext chunkSize := 4 * 1024 * 1024 @@ -65,7 +66,7 @@ func resourceArmDataLakeStoreFileCreate(d *schema.ResourceData, meta interface{} // example.azuredatalakestore.net/test/example.txt id := fmt.Sprintf("%s.%s%s", accountName, client.AdlsFileSystemDNSSuffix, remoteFilePath) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.GetFileStatus(ctx, accountName, remoteFilePath, utils.Bool(true)) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -111,7 +112,7 @@ func resourceArmDataLakeStoreFileCreate(d *schema.ResourceData, meta interface{} } func resourceArmDataLakeStoreFileRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreFilesClient + client := meta.(*ArmClient).datalake.StoreFilesClient ctx := meta.(*ArmClient).StopContext id, err := parseDataLakeStoreFileId(d.Id(), client.AdlsFileSystemDNSSuffix) @@ -137,7 +138,7 @@ func resourceArmDataLakeStoreFileRead(d *schema.ResourceData, meta interface{}) } func resourceArmDataLakeStoreFileDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreFilesClient + client := meta.(*ArmClient).datalake.StoreFilesClient ctx := meta.(*ArmClient).StopContext id, err := parseDataLakeStoreFileId(d.Id(), client.AdlsFileSystemDNSSuffix) @@ -179,3 +180,15 @@ func parseDataLakeStoreFileId(input string, suffix string) (*dataLakeStoreFileId } return &file, nil } + +func validateDataLakeStoreRemoteFilePath() schema.SchemaValidateFunc { + return func(v interface{}, k string) (warnings []string, errors []error) { + val := v.(string) + + if !strings.HasPrefix(val, "/") { + errors = append(errors, fmt.Errorf("%q must start with `/`", k)) + } + + return warnings, errors + } +} diff --git a/azurerm/resource_arm_data_lake_store_file_migration.go b/azurerm/resource_arm_data_lake_store_file_migration.go index 61d6fd25c87e..0d8d0f52e4fc 100644 --- a/azurerm/resource_arm_data_lake_store_file_migration.go +++ b/azurerm/resource_arm_data_lake_store_file_migration.go @@ -25,7 +25,7 @@ func resourceDataLakeStoreFileStateV0toV1(is *terraform.InstanceState, meta inte log.Printf("[DEBUG] ARM Data Lake Store File Attributes before Migration: %#v", is.Attributes) - client := meta.(*ArmClient).dataLakeStoreFilesClient + client := meta.(*ArmClient).datalake.StoreFilesClient storageAccountName := is.Attributes["account_name"] filePath := is.Attributes["remote_file_path"] diff --git a/azurerm/resource_arm_data_lake_store_file_migration_test.go b/azurerm/resource_arm_data_lake_store_file_migration_test.go index d0bfb71e9f32..1373037f0f68 100644 --- a/azurerm/resource_arm_data_lake_store_file_migration_test.go +++ b/azurerm/resource_arm_data_lake_store_file_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMDataLakeStoreFileMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false, "") + client, err := getArmClient(config, false, "", true) if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return @@ -24,7 +24,7 @@ func TestAccAzureRMDataLakeStoreFileMigrateState(t *testing.T) { client.StopContext = testAccProvider.StopContext() - filesClient := client.dataLakeStoreFilesClient + filesClient := client.datalake.StoreFilesClient cases := map[string]struct { StateVersion int diff --git a/azurerm/resource_arm_data_lake_store_file_test.go b/azurerm/resource_arm_data_lake_store_file_test.go index 72ad93d63664..49c2b88a9115 100644 --- a/azurerm/resource_arm_data_lake_store_file_test.go +++ b/azurerm/resource_arm_data_lake_store_file_test.go @@ -12,9 +12,34 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +func TestValidateAzureDataLakeStoreRemoteFilePath(t *testing.T) { + cases := []struct { + Value string + Errors int + }{ + { + Value: "bad", + Errors: 1, + }, + { + Value: "/good/file/path", + Errors: 0, + }, + } + + for _, tc := range cases { + _, errors := validateDataLakeStoreRemoteFilePath()(tc.Value, "unittest") + + if len(errors) != tc.Errors { + t.Fatalf("Expected validateDataLakeStoreRemoteFilePath to trigger '%d' errors for '%s' - got '%d'", tc.Errors, tc.Value, len(errors)) + } + } +} + func TestAccAzureRMDataLakeStoreFile_basic(t *testing.T) { resourceName := "azurerm_data_lake_store_file.test" @@ -87,7 +112,7 @@ func TestAccAzureRMDataLakeStoreFile_largefiles(t *testing.T) { } func TestAccAzureRMDataLakeStoreFile_requiresimport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -128,7 +153,7 @@ func testCheckAzureRMDataLakeStoreFileExists(resourceName string) resource.TestC remoteFilePath := rs.Primary.Attributes["remote_file_path"] accountName := rs.Primary.Attributes["account_name"] - conn := testAccProvider.Meta().(*ArmClient).dataLakeStoreFilesClient + conn := testAccProvider.Meta().(*ArmClient).datalake.StoreFilesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.GetFileStatus(ctx, accountName, remoteFilePath, utils.Bool(true)) @@ -145,7 +170,7 @@ func testCheckAzureRMDataLakeStoreFileExists(resourceName string) resource.TestC } func testCheckAzureRMDataLakeStoreFileDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dataLakeStoreFilesClient + conn := testAccProvider.Meta().(*ArmClient).datalake.StoreFilesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_data_lake_store_firewall_rule.go b/azurerm/resource_arm_data_lake_store_firewall_rule.go index a563b09db343..346ca26b8999 100644 --- a/azurerm/resource_arm_data_lake_store_firewall_rule.go +++ b/azurerm/resource_arm_data_lake_store_firewall_rule.go @@ -10,6 +10,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +39,7 @@ func resourceArmDataLakeStoreFirewallRule() *schema.Resource { ValidateFunc: azure.ValidateDataLakeAccountName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "start_ip_address": { Type: schema.TypeString, @@ -56,14 +57,14 @@ func resourceArmDataLakeStoreFirewallRule() *schema.Resource { } func resourceArmDateLakeStoreAccountFirewallRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreFirewallRulesClient + client := meta.(*ArmClient).datalake.StoreFirewallRulesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) accountName := d.Get("account_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, accountName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -106,10 +107,10 @@ func resourceArmDateLakeStoreAccountFirewallRuleCreateUpdate(d *schema.ResourceD } func resourceArmDateLakeStoreAccountFirewallRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreFirewallRulesClient + client := meta.(*ArmClient).datalake.StoreFirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -140,10 +141,10 @@ func resourceArmDateLakeStoreAccountFirewallRuleRead(d *schema.ResourceData, met } func resourceArmDateLakeStoreAccountFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dataLakeStoreFirewallRulesClient + client := meta.(*ArmClient).datalake.StoreFirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_data_lake_store_firewall_rule_test.go b/azurerm/resource_arm_data_lake_store_firewall_rule_test.go index 1569a33465fa..6b8e5d61a6a1 100644 --- a/azurerm/resource_arm_data_lake_store_firewall_rule_test.go +++ b/azurerm/resource_arm_data_lake_store_firewall_rule_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDataLakeStoreFirewallRule_basic(t *testing.T) { @@ -43,7 +44,7 @@ func TestAccAzureRMDataLakeStoreFirewallRule_basic(t *testing.T) { // func TestAccAzureRMDataLakeStoreFirewallRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -144,7 +145,7 @@ func testCheckAzureRMDataLakeStoreFirewallRuleExists(resourceName string) resour return fmt.Errorf("Bad: no resource group found in state for data lake store firewall rule: %s", firewallRuleName) } - conn := testAccProvider.Meta().(*ArmClient).dataLakeStoreFirewallRulesClient + conn := testAccProvider.Meta().(*ArmClient).datalake.StoreFirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accountName, firewallRuleName) @@ -161,7 +162,7 @@ func testCheckAzureRMDataLakeStoreFirewallRuleExists(resourceName string) resour } func testCheckAzureRMDataLakeStoreFirewallRuleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dataLakeStoreFirewallRulesClient + conn := testAccProvider.Meta().(*ArmClient).datalake.StoreFirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -208,7 +209,7 @@ resource "azurerm_data_lake_store_firewall_rule" "test" { start_ip_address = "%s" end_ip_address = "%s" } -`, rInt, location, strconv.Itoa(rInt)[0:15], startIP, endIP) +`, rInt, location, strconv.Itoa(rInt)[2:17], startIP, endIP) } func testAccAzureRMDataLakeStoreFirewallRule_requiresImport(rInt int, location, startIP, endIP string) string { diff --git a/azurerm/resource_arm_data_lake_store_test.go b/azurerm/resource_arm_data_lake_store_test.go index b8c1a4da4bec..20de58b1e2d1 100644 --- a/azurerm/resource_arm_data_lake_store_test.go +++ b/azurerm/resource_arm_data_lake_store_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDataLakeStore_basic(t *testing.T) { @@ -38,7 +39,7 @@ func TestAccAzureRMDataLakeStore_basic(t *testing.T) { }) } func TestAccAzureRMDataLakeStore_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -209,7 +210,7 @@ func testCheckAzureRMDataLakeStoreExists(resourceName string) resource.TestCheck return fmt.Errorf("Bad: no resource group found in state for data lake store: %s", accountName) } - conn := testAccProvider.Meta().(*ArmClient).dataLakeStoreAccountClient + conn := testAccProvider.Meta().(*ArmClient).datalake.StoreAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, accountName) @@ -226,7 +227,7 @@ func testCheckAzureRMDataLakeStoreExists(resourceName string) resource.TestCheck } func testCheckAzureRMDataLakeStoreDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dataLakeStoreAccountClient + conn := testAccProvider.Meta().(*ArmClient).datalake.StoreAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -264,7 +265,7 @@ resource "azurerm_data_lake_store" "test" { resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" } -`, rInt, location, strconv.Itoa(rInt)[0:15]) +`, rInt, location, strconv.Itoa(rInt)[2:17]) } func testAccAzureRMDataLakeStore_requiresImport(rInt int, location string) string { @@ -293,7 +294,7 @@ resource "azurerm_data_lake_store" "test" { location = "${azurerm_resource_group.test.location}" tier = "Commitment_1TB" } -`, rInt, location, strconv.Itoa(rInt)[0:15]) +`, rInt, location, strconv.Itoa(rInt)[2:17]) } func testAccAzureRMDataLakeStore_encryptionDisabled(rInt int, location string) string { @@ -309,7 +310,7 @@ resource "azurerm_data_lake_store" "test" { location = "${azurerm_resource_group.test.location}" encryption_state = "Disabled" } -`, rInt, location, strconv.Itoa(rInt)[0:15]) +`, rInt, location, strconv.Itoa(rInt)[2:17]) } func testAccAzureRMDataLakeStore_firewall(rInt int, location string, firewallState string, firewallAllowAzureIPs string) string { @@ -326,7 +327,7 @@ resource "azurerm_data_lake_store" "test" { firewall_state = "%s" firewall_allow_azure_ips = "%s" } -`, rInt, location, strconv.Itoa(rInt)[0:15], firewallState, firewallAllowAzureIPs) +`, rInt, location, strconv.Itoa(rInt)[2:17], firewallState, firewallAllowAzureIPs) } func testAccAzureRMDataLakeStore_withTags(rInt int, location string) string { @@ -346,7 +347,7 @@ resource "azurerm_data_lake_store" "test" { cost_center = "MSFT" } } -`, rInt, location, strconv.Itoa(rInt)[0:15]) +`, rInt, location, strconv.Itoa(rInt)[2:17]) } func testAccAzureRMDataLakeStore_withTagsUpdate(rInt int, location string) string { @@ -365,5 +366,5 @@ resource "azurerm_data_lake_store" "test" { environment = "staging" } } -`, rInt, location, strconv.Itoa(rInt)[0:15]) +`, rInt, location, strconv.Itoa(rInt)[2:17]) } diff --git a/azurerm/resource_arm_databricks_workspace.go b/azurerm/resource_arm_databricks_workspace.go index fe1777148018..894fff81b32d 100644 --- a/azurerm/resource_arm_databricks_workspace.go +++ b/azurerm/resource_arm_databricks_workspace.go @@ -8,9 +8,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/databricks/mgmt/2018-04-01/databricks" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,9 +35,9 @@ func resourceArmDatabricksWorkspace() *schema.Resource { ValidateFunc: validateDatabricksWorkspaceName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeString, @@ -46,7 +49,7 @@ func resourceArmDatabricksWorkspace() *schema.Resource { }, false), }, - "tags": tagsSchema(), + "tags": tags.Schema(), "managed_resource_group_name": { Type: schema.TypeString, @@ -65,7 +68,7 @@ func resourceArmDatabricksWorkspace() *schema.Resource { } func resourceArmDatabricksWorkspaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).databricksWorkspacesClient + client := meta.(*ArmClient).databricks.WorkspacesClient ctx := meta.(*ArmClient).StopContext subscriptionID := meta.(*ArmClient).subscriptionId @@ -74,7 +77,7 @@ func resourceArmDatabricksWorkspaceCreateUpdate(d *schema.ResourceData, meta int name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -91,9 +94,9 @@ func resourceArmDatabricksWorkspaceCreateUpdate(d *schema.ResourceData, meta int managedResourceGroupName := d.Get("managed_resource_group_name").(string) var managedResourceGroupID string - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) if managedResourceGroupName == "" { //no managed resource group name was provided, we use the default pattern @@ -138,10 +141,10 @@ func resourceArmDatabricksWorkspaceCreateUpdate(d *schema.ResourceData, meta int } func resourceArmDatabricksWorkspaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).databricksWorkspacesClient + client := meta.(*ArmClient).databricks.WorkspacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -164,7 +167,7 @@ func resourceArmDatabricksWorkspaceRead(d *schema.ResourceData, meta interface{} d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { @@ -172,7 +175,7 @@ func resourceArmDatabricksWorkspaceRead(d *schema.ResourceData, meta interface{} } if props := resp.WorkspaceProperties; props != nil { - managedResourceGroupID, err := parseAzureResourceID(*props.ManagedResourceGroupID) + managedResourceGroupID, err := azure.ParseAzureResourceID(*props.ManagedResourceGroupID) if err != nil { return err } @@ -180,16 +183,14 @@ func resourceArmDatabricksWorkspaceRead(d *schema.ResourceData, meta interface{} d.Set("managed_resource_group_name", managedResourceGroupID.ResourceGroup) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmDatabricksWorkspaceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).databricksWorkspacesClient + client := meta.(*ArmClient).databricks.WorkspacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_databricks_workspace_test.go b/azurerm/resource_arm_databricks_workspace_test.go index 0cb96624f957..8fcd4c65479e 100644 --- a/azurerm/resource_arm_databricks_workspace_test.go +++ b/azurerm/resource_arm_databricks_workspace_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAzureRMDatabrickWorkspaceName(t *testing.T) { @@ -93,7 +94,7 @@ func TestAccAzureRMDatabricksWorkspace_basic(t *testing.T) { } func TestAccAzureRMDatabricksWorkspace_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -174,7 +175,7 @@ func testCheckAzureRMDatabricksWorkspaceExists(resourceName string) resource.Tes return fmt.Errorf("Bad: No resource group found in state for Databricks Workspace: %s", workspaceName) } - conn := testAccProvider.Meta().(*ArmClient).databricksWorkspacesClient + conn := testAccProvider.Meta().(*ArmClient).databricks.WorkspacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, workspaceName) if err != nil { @@ -190,7 +191,7 @@ func testCheckAzureRMDatabricksWorkspaceExists(resourceName string) resource.Tes } func testCheckAzureRMDatabricksWorkspaceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).databricksWorkspacesClient + conn := testAccProvider.Meta().(*ArmClient).databricks.WorkspacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_ddos_protection_plan.go b/azurerm/resource_arm_ddos_protection_plan.go index 925c5089c30b..514a0be0587a 100644 --- a/azurerm/resource_arm_ddos_protection_plan.go +++ b/azurerm/resource_arm_ddos_protection_plan.go @@ -4,9 +4,13 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -18,10 +22,17 @@ func resourceArmDDoSProtectionPlan() *schema.Resource { Read: resourceArmDDoSProtectionPlanRead, Update: resourceArmDDoSProtectionPlanCreateUpdate, Delete: resourceArmDDoSProtectionPlanDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, + DeprecationMessage: `The 'azurerm_ddos_protection_plan' resource is deprecated in favour of the renamed version 'azurerm_network_ddos_protection_plan'. + +Information on migrating to the renamed resource can be found here: https://terraform.io/docs/providers/azurerm/guides/migrating-between-renamed-resources.html + +As such the existing 'azurerm_ddos_protection_plan' resource is deprecated and will be removed in the next major version of the AzureRM Provider (2.0). +`, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -29,9 +40,9 @@ func resourceArmDDoSProtectionPlan() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "virtual_network_ids": { Type: schema.TypeList, @@ -41,13 +52,13 @@ func resourceArmDDoSProtectionPlan() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDDoSProtectionPlanCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ddosProtectionPlanClient + client := meta.(*ArmClient).network.DDOSProtectionPlansClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for DDoS protection plan creation") @@ -55,7 +66,7 @@ func resourceArmDDoSProtectionPlanCreateUpdate(d *schema.ResourceData, meta inte name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -68,23 +79,23 @@ func resourceArmDDoSProtectionPlanCreateUpdate(d *schema.ResourceData, meta inte } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) vnetsToLock, err := extractVnetNames(d) if err != nil { return fmt.Errorf("Error extracting names of Virtual Network: %+v", err) } - azureRMLockByName(name, azureDDoSProtectionPlanResourceName) - defer azureRMUnlockByName(name, azureDDoSProtectionPlanResourceName) + locks.ByName(name, azureDDoSProtectionPlanResourceName) + defer locks.UnlockByName(name, azureDDoSProtectionPlanResourceName) - azureRMLockMultipleByName(vnetsToLock, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(vnetsToLock, virtualNetworkResourceName) + locks.MultipleByName(vnetsToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(vnetsToLock, virtualNetworkResourceName) parameters := network.DdosProtectionPlan{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resourceGroup, name, parameters) @@ -111,10 +122,10 @@ func resourceArmDDoSProtectionPlanCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmDDoSProtectionPlanRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ddosProtectionPlanClient + client := meta.(*ArmClient).network.DDOSProtectionPlansClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -135,7 +146,7 @@ func resourceArmDDoSProtectionPlanRead(d *schema.ResourceData, meta interface{}) d.Set("name", plan.Name) d.Set("resource_group_name", resourceGroup) if location := plan.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := plan.DdosProtectionPlanPropertiesFormat; props != nil { @@ -145,16 +156,14 @@ func resourceArmDDoSProtectionPlanRead(d *schema.ResourceData, meta interface{}) } } - flattenAndSetTags(d, plan.Tags) - - return nil + return tags.FlattenAndSet(d, plan.Tags) } func resourceArmDDoSProtectionPlanDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ddosProtectionPlanClient + client := meta.(*ArmClient).network.DDOSProtectionPlansClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -177,11 +186,11 @@ func resourceArmDDoSProtectionPlanDelete(d *schema.ResourceData, meta interface{ return fmt.Errorf("Error extracting names of Virtual Network: %+v", err) } - azureRMLockByName(name, azureDDoSProtectionPlanResourceName) - defer azureRMUnlockByName(name, azureDDoSProtectionPlanResourceName) + locks.ByName(name, azureDDoSProtectionPlanResourceName) + defer locks.UnlockByName(name, azureDDoSProtectionPlanResourceName) - azureRMLockMultipleByName(vnetsToLock, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(vnetsToLock, virtualNetworkResourceName) + locks.MultipleByName(vnetsToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(vnetsToLock, virtualNetworkResourceName) future, err := client.Delete(ctx, resourceGroup, name) if err != nil { @@ -200,7 +209,7 @@ func extractVnetNames(d *schema.ResourceData) (*[]string, error) { vnetNames := make([]string, 0) for _, vnetID := range vnetIDs { - vnetResourceID, err := parseAzureResourceID(vnetID.(string)) + vnetResourceID, err := azure.ParseAzureResourceID(vnetID.(string)) if err != nil { return nil, err } diff --git a/azurerm/resource_arm_ddos_protection_plan_test.go b/azurerm/resource_arm_ddos_protection_plan_test.go index 178215139eed..7b19915e7e67 100644 --- a/azurerm/resource_arm_ddos_protection_plan_test.go +++ b/azurerm/resource_arm_ddos_protection_plan_test.go @@ -7,32 +7,10 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -// NOTE: this is a test group to avoid each test case to run in parallel, since Azure only allows one DDoS Protection -// Plan per region. -func TestAccAzureRMDDoSProtectionPlan(t *testing.T) { - testCases := map[string]map[string]func(t *testing.T){ - "normal": { - "basic": testAccAzureRMDDoSProtectionPlan_basic, - "requiresImport": testAccAzureRMDDoSProtectionPlan_requiresImport, - "withTags": testAccAzureRMDDoSProtectionPlan_withTags, - "disappears": testAccAzureRMDDoSProtectionPlan_disappears, - }, - } - - for group, steps := range testCases { - t.Run(group, func(t *testing.T) { - for name, tc := range steps { - t.Run(name, func(t *testing.T) { - tc(t) - }) - } - }) - } -} - func testAccAzureRMDDoSProtectionPlan_basic(t *testing.T) { resourceName := "azurerm_ddos_protection_plan.test" ri := tf.AccRandTimeInt() @@ -60,7 +38,7 @@ func testAccAzureRMDDoSProtectionPlan_basic(t *testing.T) { } func testAccAzureRMDDoSProtectionPlan_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -160,7 +138,7 @@ func testCheckAzureRMDDoSProtectionPlanExists(resourceName string) resource.Test return fmt.Errorf("Bad: no resource group found in state for DDoS Protection Plan: %q", name) } - client := testAccProvider.Meta().(*ArmClient).ddosProtectionPlanClient + client := testAccProvider.Meta().(*ArmClient).network.DDOSProtectionPlansClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) if err != nil { @@ -189,7 +167,7 @@ func testCheckAzureRMDDoSProtectionPlanDisappears(resourceName string) resource. return fmt.Errorf("Bad: no resource group found in state for DDoS Protection Plan: %q", name) } - client := testAccProvider.Meta().(*ArmClient).ddosProtectionPlanClient + client := testAccProvider.Meta().(*ArmClient).network.DDOSProtectionPlansClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, name) if err != nil { @@ -205,7 +183,7 @@ func testCheckAzureRMDDoSProtectionPlanDisappears(resourceName string) resource. } func testCheckAzureRMDDoSProtectionPlanDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).ddosProtectionPlanClient + client := testAccProvider.Meta().(*ArmClient).network.DDOSProtectionPlansClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dev_test_lab.go b/azurerm/resource_arm_dev_test_lab.go index e20c863b40c1..19c4dd230bf9 100644 --- a/azurerm/resource_arm_dev_test_lab.go +++ b/azurerm/resource_arm_dev_test_lab.go @@ -7,8 +7,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,11 +33,11 @@ func resourceArmDevTestLab() *schema.Resource { ValidateFunc: validate.DevTestLabName(), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), // There's a bug in the Azure API where this is returned in lower-case // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3964 - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), "storage_type": { Type: schema.TypeString, @@ -46,7 +49,7 @@ func resourceArmDevTestLab() *schema.Resource { }, false), }, - "tags": tagsSchema(), + "tags": tags.Schema(), "artifacts_storage_account_id": { Type: schema.TypeString, @@ -82,7 +85,7 @@ func resourceArmDevTestLab() *schema.Resource { } func resourceArmDevTestLabCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestLabsClient + client := meta.(*ArmClient).devTestLabs.LabsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for DevTest Lab creation") @@ -90,7 +93,7 @@ func resourceArmDevTestLabCreateUpdate(d *schema.ResourceData, meta interface{}) name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -103,13 +106,13 @@ func resourceArmDevTestLabCreateUpdate(d *schema.ResourceData, meta interface{}) } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) storageType := d.Get("storage_type").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dtl.Lab{ Location: utils.String(location), - Tags: expandTags(tags), + Tags: tags.Expand(t), LabProperties: &dtl.LabProperties{ LabStorageType: dtl.StorageType(storageType), }, @@ -139,10 +142,10 @@ func resourceArmDevTestLabCreateUpdate(d *schema.ResourceData, meta interface{}) } func resourceArmDevTestLabRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestLabsClient + client := meta.(*ArmClient).devTestLabs.LabsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -163,7 +166,7 @@ func resourceArmDevTestLabRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", read.Name) d.Set("resource_group_name", resourceGroup) if location := read.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := read.LabProperties; props != nil { @@ -178,16 +181,14 @@ func resourceArmDevTestLabRead(d *schema.ResourceData, meta interface{}) error { d.Set("unique_identifier", props.UniqueIdentifier) } - flattenAndSetTags(d, read.Tags) - - return nil + return tags.FlattenAndSet(d, read.Tags) } func resourceArmDevTestLabDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestLabsClient + client := meta.(*ArmClient).devTestLabs.LabsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dev_test_lab_schedule.go b/azurerm/resource_arm_dev_test_lab_schedule.go new file mode 100644 index 000000000000..8709df4f47b3 --- /dev/null +++ b/azurerm/resource_arm_dev_test_lab_schedule.go @@ -0,0 +1,453 @@ +package azurerm + +import ( + "fmt" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" + "github.com/Azure/azure-sdk-for-go/services/scheduler/mgmt/2016-03-01/scheduler" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDevTestLabSchedules() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDevTestLabSchedulesCreateUpdate, + Read: resourceArmDevTestLabSchedulesRead, + Update: resourceArmDevTestLabSchedulesCreateUpdate, + Delete: resourceArmDevTestLabSchedulesDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "location": azure.SchemaLocation(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "lab_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.DevTestLabName(), + }, + + "status": { + Type: schema.TypeString, + Optional: true, + Default: dtl.EnableStatusDisabled, + ValidateFunc: validation.StringInSlice([]string{ + string(dtl.EnableStatusEnabled), + string(dtl.EnableStatusDisabled), + }, false), + }, + + "task_type": { + Type: schema.TypeString, + Required: true, + }, + + "weekly_recurrence": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "time": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile("^(0[0-9]|1[0-9]|2[0-3]|[0-9])[0-5][0-9]$"), + "Time of day must match the format HHmm where HH is 00-23 and mm is 00-59", + ), + }, + + "week_days": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(scheduler.Monday), + string(scheduler.Tuesday), + string(scheduler.Wednesday), + string(scheduler.Thursday), + string(scheduler.Friday), + string(scheduler.Saturday), + string(scheduler.Sunday), + }, false), + }, + }, + }, + }, + }, + + "daily_recurrence": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "time": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile("^(0[0-9]|1[0-9]|2[0-3]|[0-9])[0-5][0-9]$"), + "Time of day must match the format HHmm where HH is 00-23 and mm is 00-59", + ), + }, + }, + }, + }, + + "hourly_recurrence": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "minute": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(0, 59), + }, + }, + }, + }, + + "time_zone_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.VirtualMachineTimeZone(), + }, + + "notification_settings": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "status": { + Type: schema.TypeString, + Optional: true, + Default: dtl.NotificationStatusDisabled, + ValidateFunc: validation.StringInSlice([]string{ + string(dtl.NotificationStatusEnabled), + string(dtl.NotificationStatusDisabled), + }, false), + }, + "time_in_minutes": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(1), + }, + "webhook_url": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmDevTestLabSchedulesCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestLabs.LabSchedulesClient + + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + devTestLabName := d.Get("lab_name").(string) + resGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resGroup, devTestLabName, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Schedule %q (Dev Test Lab %q / Resource Group %q): %s", name, devTestLabName, resGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_dev_test_schedule", *existing.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) + + schedule := dtl.Schedule{ + Location: &location, + ScheduleProperties: &dtl.ScheduleProperties{}, + Tags: tags.Expand(t), + } + + switch status := d.Get("status"); status { + case string(dtl.EnableStatusEnabled): + schedule.ScheduleProperties.Status = dtl.EnableStatusEnabled + case string(dtl.EnableStatusDisabled): + schedule.ScheduleProperties.Status = dtl.EnableStatusDisabled + default: + } + + if taskType := d.Get("task_type").(string); taskType != "" { + schedule.ScheduleProperties.TaskType = &taskType + } + + if timeZoneId := d.Get("time_zone_id").(string); timeZoneId != "" { + schedule.ScheduleProperties.TimeZoneID = &timeZoneId + } + + if v, ok := d.GetOk("weekly_recurrence"); ok { + weekRecurrence := expandArmDevTestLabScheduleRecurrenceWeekly(v) + + schedule.WeeklyRecurrence = weekRecurrence + } + + if v, ok := d.GetOk("daily_recurrence"); ok { + dailyRecurrence := expandArmDevTestLabScheduleRecurrenceDaily(v) + schedule.DailyRecurrence = dailyRecurrence + } + + if v, ok := d.GetOk("hourly_recurrence"); ok { + hourlyRecurrence := expandArmDevTestLabScheduleRecurrenceHourly(v) + + schedule.HourlyRecurrence = hourlyRecurrence + } + + if _, ok := d.GetOk("notification_settings"); ok { + notificationSettings := expandArmDevTestLabScheduleNotificationSettings(d) + schedule.NotificationSettings = notificationSettings + } + + if _, err := client.CreateOrUpdate(ctx, resGroup, devTestLabName, name, schedule); err != nil { + return err + } + + read, err := client.Get(ctx, resGroup, devTestLabName, name, "") + if err != nil { + return err + } + + if read.ID == nil { + return fmt.Errorf("Cannot read Dev Test Lab Schedule %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmDevTestLabSchedulesRead(d, meta) +} + +func resourceArmDevTestLabSchedulesRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestLabs.LabSchedulesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + devTestLabName := id.Path["labs"] + name := id.Path["schedules"] + + resp, err := client.Get(ctx, resGroup, devTestLabName, name, "") + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on Dev Test Lab Schedule %s: %s", name, err) + } + + d.Set("name", resp.Name) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + d.Set("lab_name", devTestLabName) + d.Set("resource_group_name", resGroup) + d.Set("task_type", resp.TaskType) + + if props := resp.ScheduleProperties; props != nil { + + d.Set("time_zone_id", props.TimeZoneID) + + d.Set("status", string(props.Status)) + + if err := d.Set("weekly_recurrence", flattenAzureRmDevTestLabScheduleRecurrenceWeekly(props.WeeklyRecurrence)); err != nil { + return fmt.Errorf("Error setting `weeklyRecurrence`: %#v", err) + } + + if err := d.Set("daily_recurrence", flattenAzureRmDevTestLabScheduleRecurrenceDaily(props.DailyRecurrence)); err != nil { + return fmt.Errorf("Error setting `dailyRecurrence`: %#v", err) + } + + if err := d.Set("hourly_recurrence", flattenAzureRmDevTestLabScheduleRecurrenceHourly(props.HourlyRecurrence)); err != nil { + return fmt.Errorf("Error setting `dailyRecurrence`: %#v", err) + } + + if err := d.Set("notification_settings", flattenAzureRmDevTestLabScheduleNotificationSettings(props.NotificationSettings)); err != nil { + return fmt.Errorf("Error setting `notificationSettings`: %#v", err) + } + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmDevTestLabSchedulesDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).compute.VMExtensionClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["schedules"] + devTestLabName := id.Path["labs"] + + future, err := client.Delete(ctx, resGroup, devTestLabName, name) + if err != nil { + return err + } + + return future.WaitForCompletionRef(ctx, client.Client) +} + +func expandArmDevTestLabScheduleRecurrenceDaily(recurrence interface{}) *dtl.DayDetails { + dailyRecurrenceConfigs := recurrence.([]interface{}) + dailyRecurrenceConfig := dailyRecurrenceConfigs[0].(map[string]interface{}) + dailyTime := dailyRecurrenceConfig["time"].(string) + + return &dtl.DayDetails{ + Time: &dailyTime, + } +} + +func flattenAzureRmDevTestLabScheduleRecurrenceDaily(dailyRecurrence *dtl.DayDetails) []interface{} { + if dailyRecurrence == nil { + return []interface{}{} + } + + result := make(map[string]interface{}) + + if dailyRecurrence.Time != nil { + result["time"] = *dailyRecurrence.Time + } + + return []interface{}{result} +} + +func expandArmDevTestLabScheduleRecurrenceWeekly(recurrence interface{}) *dtl.WeekDetails { + weeklyRecurrenceConfigs := recurrence.([]interface{}) + weeklyRecurrenceConfig := weeklyRecurrenceConfigs[0].(map[string]interface{}) + weeklyTime := weeklyRecurrenceConfig["time"].(string) + + weekDays := make([]string, 0) + for _, dayItem := range weeklyRecurrenceConfig["week_days"].([]interface{}) { + weekDays = append(weekDays, dayItem.(string)) + } + + return &dtl.WeekDetails{ + Time: &weeklyTime, + Weekdays: &weekDays, + } +} + +func flattenAzureRmDevTestLabScheduleRecurrenceWeekly(weeklyRecurrence *dtl.WeekDetails) []interface{} { + if weeklyRecurrence == nil { + return []interface{}{} + } + + result := make(map[string]interface{}) + + if weeklyRecurrence.Time != nil { + result["time"] = *weeklyRecurrence.Time + } + + weekDays := make([]string, 0) + if w := weeklyRecurrence.Weekdays; w != nil { + weekDays = *w + } + result["week_days"] = weekDays + + return []interface{}{result} +} + +func expandArmDevTestLabScheduleRecurrenceHourly(recurrence interface{}) *dtl.HourDetails { + hourlyRecurrenceConfigs := recurrence.([]interface{}) + hourlyRecurrenceConfig := hourlyRecurrenceConfigs[0].(map[string]interface{}) + hourlyMinute := int32(hourlyRecurrenceConfig["minute"].(int)) + + return &dtl.HourDetails{ + Minute: &hourlyMinute, + } +} + +func flattenAzureRmDevTestLabScheduleRecurrenceHourly(hourlyRecurrence *dtl.HourDetails) []interface{} { + if hourlyRecurrence == nil { + return []interface{}{} + } + + result := make(map[string]interface{}) + + if hourlyRecurrence.Minute != nil { + result["minute"] = *hourlyRecurrence.Minute + } + + return []interface{}{result} +} + +func expandArmDevTestLabScheduleNotificationSettings(d *schema.ResourceData) *dtl.NotificationSettings { + + notificationSettingsConfigs := d.Get("notification_settings").([]interface{}) + notificationSettingsConfig := notificationSettingsConfigs[0].(map[string]interface{}) + webhookUrl := notificationSettingsConfig["webhook_url"].(string) + timeInMinutes := int32(notificationSettingsConfig["time_in_minutes"].(int)) + + notificationStatus := dtl.NotificationStatus(notificationSettingsConfig["status"].(string)) + + return &dtl.NotificationSettings{ + WebhookURL: &webhookUrl, + TimeInMinutes: &timeInMinutes, + Status: notificationStatus, + } +} + +func flattenAzureRmDevTestLabScheduleNotificationSettings(notificationSettings *dtl.NotificationSettings) []interface{} { + if notificationSettings == nil { + return []interface{}{} + } + + result := make(map[string]interface{}) + + if notificationSettings.WebhookURL != nil { + result["webhook_url"] = *notificationSettings.WebhookURL + } + + if notificationSettings.TimeInMinutes != nil { + result["time_in_minutes"] = *notificationSettings.TimeInMinutes + } + + if string(notificationSettings.Status) != "" { + result["status"] = string(notificationSettings.Status) + } + + return []interface{}{result} +} diff --git a/azurerm/resource_arm_dev_test_lab_schedule_test.go b/azurerm/resource_arm_dev_test_lab_schedule_test.go new file mode 100644 index 000000000000..f1dd60ce587b --- /dev/null +++ b/azurerm/resource_arm_dev_test_lab_schedule_test.go @@ -0,0 +1,383 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMDevTestLabSchedule_autoShutdownBasic(t *testing.T) { + resourceName := "azurerm_dev_test_schedule.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMDevTestLabSchedule_autoShutdownBasic(ri, location) + postConfig := testAccAzureRMDevTestLabSchedule_autoShutdownBasicUpdate(ri, location) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestLabScheduleDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLabScheduleExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "status", "Disabled"), + resource.TestCheckResourceAttr(resourceName, "notification_settings.#", "1"), + resource.TestCheckResourceAttr(resourceName, "notification_settings.0.status", "Disabled"), + resource.TestCheckResourceAttr(resourceName, "daily_recurrence.#", "1"), + resource.TestCheckResourceAttr(resourceName, "daily_recurrence.0.time", "0100"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLabScheduleExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "status", "Enabled"), + resource.TestCheckResourceAttr(resourceName, "notification_settings.#", "1"), + resource.TestCheckResourceAttr(resourceName, "notification_settings.0.status", "Enabled"), + resource.TestCheckResourceAttr(resourceName, "notification_settings.0.time_in_minutes", "30"), + resource.TestCheckResourceAttr(resourceName, "notification_settings.0.webhook_url", "https://www.bing.com/2/4"), + resource.TestCheckResourceAttr(resourceName, "daily_recurrence.#", "1"), + resource.TestCheckResourceAttr(resourceName, "daily_recurrence.0.time", "0900"), + ), + }, + }, + }) +} + +func TestAccAzureRMDevTestLabSchedule_autoStartupBasic(t *testing.T) { + resourceName := "azurerm_dev_test_schedule.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMDevTestLabSchedule_autoStartupBasic(ri, location) + postConfig := testAccAzureRMDevTestLabSchedule_autoStartupBasicUpdate(ri, location) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestLabScheduleDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLabScheduleExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "status", "Disabled"), + resource.TestCheckResourceAttr(resourceName, "weekly_recurrence.#", "1"), + resource.TestCheckResourceAttr(resourceName, "weekly_recurrence.0.time", "1100"), + resource.TestCheckResourceAttr(resourceName, "weekly_recurrence.0.week_days.#", "2"), + resource.TestCheckResourceAttr(resourceName, "weekly_recurrence.0.week_days.1", "Tuesday"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"task_type"}, + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLabScheduleExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "status", "Enabled"), + resource.TestCheckResourceAttr(resourceName, "weekly_recurrence.#", "1"), + resource.TestCheckResourceAttr(resourceName, "weekly_recurrence.0.time", "1000"), + resource.TestCheckResourceAttr(resourceName, "weekly_recurrence.0.week_days.#", "3"), + resource.TestCheckResourceAttr(resourceName, "weekly_recurrence.0.week_days.1", "Thursday"), + ), + }, + }, + }) +} + +func TestAccAzureRMDevTestLabSchedule_concurrent(t *testing.T) { + firstResourceName := "azurerm_dev_test_schedule.test" + secondResourceName := "azurerm_dev_test_schedule.test2" + ri := tf.AccRandTimeInt() + config := testAccAzureRMDevTestLabSchedule_concurrent(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestLabScheduleDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLabScheduleExists(firstResourceName), + testCheckAzureRMDevTestLabScheduleExists(secondResourceName), + ), + }, + }, + }) +} + +func testCheckAzureRMDevTestLabScheduleExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + devTestLabName := rs.Primary.Attributes["lab_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + client := testAccProvider.Meta().(*ArmClient).devTestLabs.LabSchedulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, devTestLabName, name, "") + if err != nil { + return fmt.Errorf("Bad: Get on devTestLabSchedulesClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Dev Test Lab Schedule %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDevTestLabScheduleDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).devTestLabs.LabSchedulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_dev_test_schedule" { + continue + } + + name := rs.Primary.Attributes["name"] + devTestLabName := rs.Primary.Attributes["azurerm_dev_test_lab"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, devTestLabName, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Dev Test Lab Schedule still exists:\n%#v", resp.ScheduleProperties) + } + } + + return nil +} + +func testAccAzureRMDevTestLabSchedule_autoShutdownBasic(rInt int, location string) string { + return fmt.Sprintf(` + resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" + } + + resource "azurerm_dev_test_lab" "test" { + name = "acctdtl-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + } + + resource "azurerm_dev_test_schedule" "test" { + name = "LabVmsShutdown" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + lab_name = "${azurerm_dev_test_lab.test.name}" + daily_recurrence { + time = "0100" + } + time_zone_id = "India Standard Time" + task_type = "LabVmsShutdownTask" + notification_settings { + + } + + tags = { + environment = "Production" + } + } +`, rInt, location, rInt) +} + +func testAccAzureRMDevTestLabSchedule_autoShutdownBasicUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" +} + +resource "azurerm_dev_test_lab" "test" { + name = "acctdtl-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + +} + +resource "azurerm_dev_test_schedule" "test" { + name = "LabVmsShutdown" + status = "Enabled" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + lab_name = "${azurerm_dev_test_lab.test.name}" + daily_recurrence { + time = "0900" + } + time_zone_id = "India Standard Time" + task_type = "LabVmsShutdownTask" + notification_settings { + time_in_minutes = 30 + webhook_url = "https://www.bing.com/2/4" + status = "Enabled" + } +tags = { + environment = "Production" + } +} + +`, rInt, location, rInt) +} + +func testAccAzureRMDevTestLabSchedule_autoStartupBasic(rInt int, location string) string { + return fmt.Sprintf(` + resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" + } + + resource "azurerm_dev_test_lab" "test" { + name = "acctdtl-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + } + + resource "azurerm_dev_test_schedule" "test" { + name = "LabVmAutoStart" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + lab_name = "${azurerm_dev_test_lab.test.name}" + weekly_recurrence { + time = "1100" + week_days = ["Monday", "Tuesday"] + } + + time_zone_id = "India Standard Time" + task_type = "LabVmsStartupTask" + + notification_settings { + + } + + tags = { + environment = "Production" + } + } +`, rInt, location, rInt) +} + +func testAccAzureRMDevTestLabSchedule_autoStartupBasicUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" +} + +resource "azurerm_dev_test_lab" "test" { + name = "acctdtl-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + +} + +resource "azurerm_dev_test_schedule" "test" { + name = "LabVmAutoStart" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + lab_name = "${azurerm_dev_test_lab.test.name}" + weekly_recurrence { + time = "1000" + week_days = ["Wednesday", "Thursday", "Friday"] + } + + time_zone_id = "India Standard Time" + task_type = "LabVmsStartupTask" + + notification_settings { + + } + + status = "Enabled" + + tags = { + environment = "Production" + } +} + +`, rInt, location, rInt) +} + +func testAccAzureRMDevTestLabSchedule_concurrent(rInt int, location string) string { + return fmt.Sprintf(` + resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" + } + + resource "azurerm_dev_test_lab" "test" { + name = "acctdtl-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + } + + resource "azurerm_dev_test_schedule" "test" { + name = "LabVmAutoStart" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + lab_name = "${azurerm_dev_test_lab.test.name}" + weekly_recurrence { + time = "1100" + week_days = ["Monday", "Tuesday"] + } + + time_zone_id = "India Standard Time" + task_type = "LabVmsStartupTask" + + notification_settings { + + } + + tags = { + environment = "Production" + } + } + + resource "azurerm_dev_test_schedule" "test2" { + name = "LabVmsShutdown" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + lab_name = "${azurerm_dev_test_lab.test.name}" + daily_recurrence { + time = "0100" + } + time_zone_id = "India Standard Time" + task_type = "LabVmsShutdownTask" + notification_settings { + + } + + tags = { + environment = "Production" + } + } +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_dev_test_lab_test.go b/azurerm/resource_arm_dev_test_lab_test.go index 0e2b9d4002ff..8e87662f61bf 100644 --- a/azurerm/resource_arm_dev_test_lab_test.go +++ b/azurerm/resource_arm_dev_test_lab_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDevTestLab_basic(t *testing.T) { @@ -38,7 +39,7 @@ func TestAccAzureRMDevTestLab_basic(t *testing.T) { } func TestAccAzureRMDevTestLab_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -108,7 +109,7 @@ func testCheckAzureRMDevTestLabExists(resourceName string) resource.TestCheckFun return fmt.Errorf("Bad: no resource group found in state for DevTest Lab: %s", labName) } - conn := testAccProvider.Meta().(*ArmClient).devTestLabsClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.LabsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, labName, "") if err != nil { @@ -124,7 +125,7 @@ func testCheckAzureRMDevTestLabExists(resourceName string) resource.TestCheckFun } func testCheckAzureRMDevTestLabDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).devTestLabsClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.LabsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -193,7 +194,7 @@ resource "azurerm_dev_test_lab" "test" { storage_type = "Standard" tags = { - "Hello" = "World" + Hello = "World" } } `, rInt, location, rInt) diff --git a/azurerm/resource_arm_dev_test_linux_virtual_machine.go b/azurerm/resource_arm_dev_test_linux_virtual_machine.go index f5ef66263acf..50f0e013f2da 100644 --- a/azurerm/resource_arm_dev_test_linux_virtual_machine.go +++ b/azurerm/resource_arm_dev_test_linux_virtual_machine.go @@ -10,6 +10,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,9 +42,9 @@ func resourceArmDevTestLinuxVirtualMachine() *schema.Resource { // There's a bug in the Azure API where this is returned in lower-case // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3964 - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "size": { Type: schema.TypeString, @@ -116,7 +118,7 @@ func resourceArmDevTestLinuxVirtualMachine() *schema.Resource { Optional: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), "fqdn": { Type: schema.TypeString, @@ -132,7 +134,7 @@ func resourceArmDevTestLinuxVirtualMachine() *schema.Resource { } func resourceArmDevTestLinuxVirtualMachineCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualMachinesClient + client := meta.(*ArmClient).devTestLabs.VirtualMachinesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for DevTest Linux Virtual Machine creation") @@ -141,7 +143,7 @@ func resourceArmDevTestLinuxVirtualMachineCreateUpdate(d *schema.ResourceData, m labName := d.Get("lab_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, labName, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -154,13 +156,13 @@ func resourceArmDevTestLinuxVirtualMachineCreateUpdate(d *schema.ResourceData, m } } - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) allowClaim := d.Get("allow_claim").(bool) disallowPublicIPAddress := d.Get("disallow_public_ip_address").(bool) labSubnetName := d.Get("lab_subnet_name").(string) labVirtualNetworkId := d.Get("lab_virtual_network_id").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) notes := d.Get("notes").(string) password := d.Get("password").(string) sshKey := d.Get("ssh_key").(string) @@ -204,7 +206,7 @@ func resourceArmDevTestLinuxVirtualMachineCreateUpdate(d *schema.ResourceData, m StorageType: utils.String(storageType), UserName: utils.String(username), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resourceGroup, labName, name, parameters) @@ -231,10 +233,10 @@ func resourceArmDevTestLinuxVirtualMachineCreateUpdate(d *schema.ResourceData, m } func resourceArmDevTestLinuxVirtualMachineRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualMachinesClient + client := meta.(*ArmClient).devTestLabs.VirtualMachinesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -257,7 +259,7 @@ func resourceArmDevTestLinuxVirtualMachineRead(d *schema.ResourceData, meta inte d.Set("lab_name", labName) d.Set("resource_group_name", resourceGroup) if location := read.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := read.LabVirtualMachineProperties; props != nil { @@ -278,16 +280,14 @@ func resourceArmDevTestLinuxVirtualMachineRead(d *schema.ResourceData, meta inte d.Set("unique_identifier", props.UniqueIdentifier) } - flattenAndSetTags(d, read.Tags) - - return nil + return tags.FlattenAndSet(d, read.Tags) } func resourceArmDevTestLinuxVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualMachinesClient + client := meta.(*ArmClient).devTestLabs.VirtualMachinesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dev_test_linux_virtual_machine_test.go b/azurerm/resource_arm_dev_test_linux_virtual_machine_test.go index 0059198f8c76..30c7e4e8efd4 100644 --- a/azurerm/resource_arm_dev_test_linux_virtual_machine_test.go +++ b/azurerm/resource_arm_dev_test_linux_virtual_machine_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDevTestLinuxVirtualMachine_basic(t *testing.T) { @@ -44,7 +45,7 @@ func TestAccAzureRMDevTestLinuxVirtualMachine_basic(t *testing.T) { } func TestAccAzureRMDevTestLinuxVirtualMachine_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -185,7 +186,7 @@ func testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName string) resou labName := rs.Primary.Attributes["lab_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - conn := testAccProvider.Meta().(*ArmClient).devTestVirtualMachinesClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.VirtualMachinesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, labName, virtualMachineName, "") @@ -202,7 +203,7 @@ func testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName string) resou } func testCheckAzureRMDevTestLinuxVirtualMachineDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).devTestVirtualMachinesClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.VirtualMachinesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dev_test_policy.go b/azurerm/resource_arm_dev_test_policy.go index 1867c0fd37f8..e900d12786f8 100644 --- a/azurerm/resource_arm_dev_test_policy.go +++ b/azurerm/resource_arm_dev_test_policy.go @@ -7,8 +7,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -54,7 +57,7 @@ func resourceArmDevTestPolicy() *schema.Resource { // There's a bug in the Azure API where this is returned in lower-case // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3964 - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), "threshold": { Type: schema.TypeString, @@ -82,13 +85,13 @@ func resourceArmDevTestPolicy() *schema.Resource { Optional: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDevTestPolicyCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestPoliciesClient + client := meta.(*ArmClient).devTestLabs.PoliciesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for DevTest Policy creation") @@ -98,7 +101,7 @@ func resourceArmDevTestPolicyCreateUpdate(d *schema.ResourceData, meta interface labName := d.Get("lab_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, labName, policySetName, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -116,10 +119,10 @@ func resourceArmDevTestPolicyCreateUpdate(d *schema.ResourceData, meta interface evaluatorType := d.Get("evaluator_type").(string) description := d.Get("description").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dtl.Policy{ - Tags: expandTags(tags), + Tags: tags.Expand(t), PolicyProperties: &dtl.PolicyProperties{ FactName: dtl.PolicyFactName(name), FactData: utils.String(factData), @@ -148,10 +151,10 @@ func resourceArmDevTestPolicyCreateUpdate(d *schema.ResourceData, meta interface } func resourceArmDevTestPolicyRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestPoliciesClient + client := meta.(*ArmClient).devTestLabs.PoliciesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -183,16 +186,14 @@ func resourceArmDevTestPolicyRead(d *schema.ResourceData, meta interface{}) erro d.Set("threshold", props.Threshold) } - flattenAndSetTags(d, read.Tags) - - return nil + return tags.FlattenAndSet(d, read.Tags) } func resourceArmDevTestPolicyDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestPoliciesClient + client := meta.(*ArmClient).devTestLabs.PoliciesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dev_test_policy_test.go b/azurerm/resource_arm_dev_test_policy_test.go index 8b1c899ecd93..667c6476436e 100644 --- a/azurerm/resource_arm_dev_test_policy_test.go +++ b/azurerm/resource_arm_dev_test_policy_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDevTestPolicy_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDevTestPolicy_basic(t *testing.T) { } func TestAccAzureRMDevTestPolicy_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -106,7 +107,7 @@ func testCheckAzureRMDevTestPolicyExists(resourceName string) resource.TestCheck labName := rs.Primary.Attributes["lab_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - conn := testAccProvider.Meta().(*ArmClient).devTestPoliciesClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.PoliciesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, labName, policySetName, policyName, "") @@ -123,7 +124,7 @@ func testCheckAzureRMDevTestPolicyExists(resourceName string) resource.TestCheck } func testCheckAzureRMDevTestPolicyDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).devTestPoliciesClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.PoliciesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dev_test_virtual_network.go b/azurerm/resource_arm_dev_test_virtual_network.go index 4c4c1fd4c990..f0c5c82e8451 100644 --- a/azurerm/resource_arm_dev_test_virtual_network.go +++ b/azurerm/resource_arm_dev_test_virtual_network.go @@ -8,16 +8,19 @@ import ( "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func resourceArmDevTestVirtualNetwork() *schema.Resource { return &schema.Resource{ - Create: resourceArmDevTestVirtualNetworkCreateUpdate, + Create: resourceArmDevTestVirtualNetworkCreate, Read: resourceArmDevTestVirtualNetworkRead, - Update: resourceArmDevTestVirtualNetworkCreateUpdate, + Update: resourceArmDevTestVirtualNetworkUpdate, Delete: resourceArmDevTestVirtualNetworkDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -40,7 +43,7 @@ func resourceArmDevTestVirtualNetwork() *schema.Resource { // There's a bug in the Azure API where this is returned in lower-case // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3964 - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), "description": { Type: schema.TypeString, @@ -77,7 +80,7 @@ func resourceArmDevTestVirtualNetwork() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), "unique_identifier": { Type: schema.TypeString, @@ -87,8 +90,8 @@ func resourceArmDevTestVirtualNetwork() *schema.Resource { } } -func resourceArmDevTestVirtualNetworkCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualNetworksClient +func resourceArmDevTestVirtualNetworkCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestLabs.VirtualNetworksClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for DevTest Virtual Network creation") @@ -97,7 +100,7 @@ func resourceArmDevTestVirtualNetworkCreateUpdate(d *schema.ResourceData, meta i labName := d.Get("lab_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, labName, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -111,14 +114,14 @@ func resourceArmDevTestVirtualNetworkCreateUpdate(d *schema.ResourceData, meta i } description := d.Get("description").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) subscriptionId := meta.(*ArmClient).subscriptionId subnetsRaw := d.Get("subnet").([]interface{}) - subnets := expandDevTestVirtualNetworkSubnets(subnetsRaw, subscriptionId, resourceGroup, labName, name) + subnets := expandDevTestVirtualNetworkSubnets(subnetsRaw, subscriptionId, resourceGroup, name) parameters := dtl.VirtualNetwork{ - Tags: expandTags(tags), + Tags: tags.Expand(t), VirtualNetworkProperties: &dtl.VirtualNetworkProperties{ Description: utils.String(description), SubnetOverrides: subnets, @@ -127,11 +130,11 @@ func resourceArmDevTestVirtualNetworkCreateUpdate(d *schema.ResourceData, meta i future, err := client.CreateOrUpdate(ctx, resourceGroup, labName, name, parameters) if err != nil { - return fmt.Errorf("Error creating/updating DevTest Virtual Network %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + return fmt.Errorf("Error creating DevTest Virtual Network %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) } if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting for creation/update of DevTest Virtual Network %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + return fmt.Errorf("Error waiting for creation of DevTest Virtual Network %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) } read, err := client.Get(ctx, resourceGroup, labName, name, "") @@ -145,14 +148,14 @@ func resourceArmDevTestVirtualNetworkCreateUpdate(d *schema.ResourceData, meta i d.SetId(*read.ID) - return resourceArmDevTestVirtualNetworkRead(d, meta) + return resourceArmDevTestVirtualNetworkUpdate(d, meta) } func resourceArmDevTestVirtualNetworkRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualNetworksClient + client := meta.(*ArmClient).devTestLabs.VirtualNetworksClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -187,16 +190,62 @@ func resourceArmDevTestVirtualNetworkRead(d *schema.ResourceData, meta interface d.Set("unique_identifier", props.UniqueIdentifier) } - flattenAndSetTags(d, read.Tags) + return tags.FlattenAndSet(d, read.Tags) +} + +func resourceArmDevTestVirtualNetworkUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestLabs.VirtualNetworksClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for DevTest Virtual Network creation") - return nil + name := d.Get("name").(string) + labName := d.Get("lab_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + description := d.Get("description").(string) + t := d.Get("tags").(map[string]interface{}) + + subscriptionId := meta.(*ArmClient).subscriptionId + subnetsRaw := d.Get("subnet").([]interface{}) + subnets := expandDevTestVirtualNetworkSubnets(subnetsRaw, subscriptionId, resourceGroup, name) + + parameters := dtl.VirtualNetwork{ + Tags: tags.Expand(t), + VirtualNetworkProperties: &dtl.VirtualNetworkProperties{ + Description: utils.String(description), + SubnetOverrides: subnets, + }, + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, labName, name, parameters) + if err != nil { + return fmt.Errorf("Error updating DevTest Virtual Network %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for update of DevTest Virtual Network %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, labName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving DevTest Virtual Network %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read DevTest Virtual Network %q (Lab %q / Resource Group %q) ID", name, labName, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmDevTestVirtualNetworkRead(d, meta) } func resourceArmDevTestVirtualNetworkDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualNetworksClient + client := meta.(*ArmClient).devTestLabs.VirtualNetworksClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -233,12 +282,12 @@ func validateDevTestVirtualNetworkName() schema.SchemaValidateFunc { "Virtual Network Name can only include alphanumeric characters, underscores, hyphens.") } -func expandDevTestVirtualNetworkSubnets(input []interface{}, subscriptionId, resourceGroupName, labName, virtualNetworkName string) *[]dtl.SubnetOverride { +func expandDevTestVirtualNetworkSubnets(input []interface{}, subscriptionId, resourceGroupName, virtualNetworkName string) *[]dtl.SubnetOverride { results := make([]dtl.SubnetOverride, 0) // default found from the Portal name := fmt.Sprintf("%sSubnet", virtualNetworkName) - idFmt := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.DevTestLab/labs/%s/virtualnetworks/%s/subnets/%s" - subnetId := fmt.Sprintf(idFmt, subscriptionId, resourceGroupName, labName, virtualNetworkName, name) + idFmt := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s" + subnetId := fmt.Sprintf(idFmt, subscriptionId, resourceGroupName, virtualNetworkName, name) if len(input) == 0 { result := dtl.SubnetOverride{ ResourceID: utils.String(subnetId), diff --git a/azurerm/resource_arm_dev_test_virtual_network_test.go b/azurerm/resource_arm_dev_test_virtual_network_test.go index d97298749cf4..28ad72394fe5 100644 --- a/azurerm/resource_arm_dev_test_virtual_network_test.go +++ b/azurerm/resource_arm_dev_test_virtual_network_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestValidateDevTestVirtualNetworkName(t *testing.T) { @@ -65,7 +66,7 @@ func TestAccAzureRMDevTestVirtualNetwork_basic(t *testing.T) { } func TestAccAzureRMDevTestVirtualNetwork_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -109,7 +110,7 @@ func TestAccAzureRMDevTestVirtualNetwork_subnet(t *testing.T) { Check: resource.ComposeTestCheckFunc( testCheckAzureRMDevTestVirtualNetworkExists(resourceName), resource.TestCheckResourceAttr(resourceName, "subnet.#", "1"), - resource.TestCheckResourceAttr(resourceName, "subnet.0.use_public_ip_address", "Allow"), + resource.TestCheckResourceAttr(resourceName, "subnet.0.use_public_ip_address", "Deny"), resource.TestCheckResourceAttr(resourceName, "subnet.0.use_in_virtual_machine_creation", "Allow"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), @@ -135,7 +136,7 @@ func testCheckAzureRMDevTestVirtualNetworkExists(resourceName string) resource.T labName := rs.Primary.Attributes["lab_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - conn := testAccProvider.Meta().(*ArmClient).devTestVirtualNetworksClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.VirtualNetworksClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, labName, virtualNetworkName, "") @@ -152,7 +153,7 @@ func testCheckAzureRMDevTestVirtualNetworkExists(resourceName string) resource.T } func testCheckAzureRMDevTestVirtualNetworkDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).devTestVirtualNetworksClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.VirtualNetworksClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -233,7 +234,7 @@ resource "azurerm_dev_test_virtual_network" "test" { resource_group_name = "${azurerm_resource_group.test.name}" subnet { - use_public_ip_address = "Allow" + use_public_ip_address = "Deny" use_in_virtual_machine_creation = "Allow" } } diff --git a/azurerm/resource_arm_dev_test_windows_virtual_machine.go b/azurerm/resource_arm_dev_test_windows_virtual_machine.go index 6060197fe5b8..76cc14da02ca 100644 --- a/azurerm/resource_arm_dev_test_windows_virtual_machine.go +++ b/azurerm/resource_arm_dev_test_windows_virtual_machine.go @@ -10,6 +10,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,9 +42,9 @@ func resourceArmDevTestWindowsVirtualMachine() *schema.Resource { // There's a bug in the Azure API where this is returned in lower-case // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3964 - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "size": { Type: schema.TypeString, @@ -108,7 +110,7 @@ func resourceArmDevTestWindowsVirtualMachine() *schema.Resource { Optional: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), "fqdn": { Type: schema.TypeString, @@ -124,7 +126,7 @@ func resourceArmDevTestWindowsVirtualMachine() *schema.Resource { } func resourceArmDevTestWindowsVirtualMachineCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualMachinesClient + client := meta.(*ArmClient).devTestLabs.VirtualMachinesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for DevTest Windows Virtual Machine creation") @@ -133,7 +135,7 @@ func resourceArmDevTestWindowsVirtualMachineCreateUpdate(d *schema.ResourceData, labName := d.Get("lab_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, labName, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -146,13 +148,13 @@ func resourceArmDevTestWindowsVirtualMachineCreateUpdate(d *schema.ResourceData, } } - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) allowClaim := d.Get("allow_claim").(bool) disallowPublicIPAddress := d.Get("disallow_public_ip_address").(bool) labSubnetName := d.Get("lab_subnet_name").(string) labVirtualNetworkId := d.Get("lab_virtual_network_id").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) notes := d.Get("notes").(string) password := d.Get("password").(string) size := d.Get("size").(string) @@ -193,7 +195,7 @@ func resourceArmDevTestWindowsVirtualMachineCreateUpdate(d *schema.ResourceData, StorageType: utils.String(storageType), UserName: utils.String(username), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resourceGroup, labName, name, parameters) @@ -220,10 +222,10 @@ func resourceArmDevTestWindowsVirtualMachineCreateUpdate(d *schema.ResourceData, } func resourceArmDevTestWindowsVirtualMachineRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualMachinesClient + client := meta.(*ArmClient).devTestLabs.VirtualMachinesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -246,7 +248,7 @@ func resourceArmDevTestWindowsVirtualMachineRead(d *schema.ResourceData, meta in d.Set("lab_name", labName) d.Set("resource_group_name", resourceGroup) if location := read.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := read.LabVirtualMachineProperties; props != nil { @@ -267,16 +269,14 @@ func resourceArmDevTestWindowsVirtualMachineRead(d *schema.ResourceData, meta in d.Set("unique_identifier", props.UniqueIdentifier) } - flattenAndSetTags(d, read.Tags) - - return nil + return tags.FlattenAndSet(d, read.Tags) } func resourceArmDevTestWindowsVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devTestVirtualMachinesClient + client := meta.(*ArmClient).devTestLabs.VirtualMachinesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dev_test_windows_virtual_machine_test.go b/azurerm/resource_arm_dev_test_windows_virtual_machine_test.go index b05f5fe1f35f..d5f990175132 100644 --- a/azurerm/resource_arm_dev_test_windows_virtual_machine_test.go +++ b/azurerm/resource_arm_dev_test_windows_virtual_machine_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDevTestVirtualMachine_basic(t *testing.T) { @@ -44,7 +45,7 @@ func TestAccAzureRMDevTestVirtualMachine_basic(t *testing.T) { } func TestAccAzureRMDevTestVirtualMachine_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -152,7 +153,7 @@ func testCheckAzureRMDevTestWindowsVirtualMachineExists(resourceName string) res labName := rs.Primary.Attributes["lab_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - conn := testAccProvider.Meta().(*ArmClient).devTestVirtualMachinesClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.VirtualMachinesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, labName, virtualMachineName, "") @@ -169,7 +170,7 @@ func testCheckAzureRMDevTestWindowsVirtualMachineExists(resourceName string) res } func testCheckAzureRMDevTestWindowsVirtualMachineDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).devTestVirtualMachinesClient + conn := testAccProvider.Meta().(*ArmClient).devTestLabs.VirtualMachinesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_devspace_controller.go b/azurerm/resource_arm_devspace_controller.go index 848058f3a96b..ed6d16dd95a5 100644 --- a/azurerm/resource_arm_devspace_controller.go +++ b/azurerm/resource_arm_devspace_controller.go @@ -10,6 +10,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -31,9 +33,9 @@ func resourceArmDevSpaceController() *schema.Resource { ValidateFunc: validate.DevSpaceName(), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeList, @@ -84,7 +86,7 @@ func resourceArmDevSpaceController() *schema.Resource { ValidateFunc: validate.Base64String(), }, - "tags": tagsSchema(), + "tags": tags.Schema(), "data_plane_fqdn": { Type: schema.TypeString, @@ -95,7 +97,7 @@ func resourceArmDevSpaceController() *schema.Resource { } func resourceArmDevSpaceControllerCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devSpaceControllerClient + client := meta.(*ArmClient).devSpace.ControllersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for DevSpace Controller creation") @@ -103,7 +105,7 @@ func resourceArmDevSpaceControllerCreate(d *schema.ResourceData, meta interface{ name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -116,8 +118,8 @@ func resourceArmDevSpaceControllerCreate(d *schema.ResourceData, meta interface{ } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) sku := expandDevSpaceControllerSku(d) @@ -127,7 +129,7 @@ func resourceArmDevSpaceControllerCreate(d *schema.ResourceData, meta interface{ controller := devspaces.Controller{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), Sku: sku, ControllerProperties: &devspaces.ControllerProperties{ HostSuffix: &hostSuffix, @@ -159,10 +161,10 @@ func resourceArmDevSpaceControllerCreate(d *schema.ResourceData, meta interface{ } func resourceArmDevSpaceControllerRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devSpaceControllerClient + client := meta.(*ArmClient).devSpace.ControllersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -183,7 +185,7 @@ func resourceArmDevSpaceControllerRead(d *schema.ResourceData, meta interface{}) d.Set("name", result.Name) d.Set("resource_group_name", resGroupName) if location := result.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if err := d.Set("sku", flattenDevSpaceControllerSku(result.Sku)); err != nil { @@ -196,23 +198,21 @@ func resourceArmDevSpaceControllerRead(d *schema.ResourceData, meta interface{}) d.Set("target_container_host_resource_id", props.TargetContainerHostResourceID) } - flattenAndSetTags(d, result.Tags) - - return nil + return tags.FlattenAndSet(d, result.Tags) } func resourceArmDevSpaceControllerUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devSpaceControllerClient + client := meta.(*ArmClient).devSpace.ControllersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for DevSpace Controller updating") name := d.Get("name").(string) resGroupName := d.Get("resource_group_name").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) params := devspaces.ControllerUpdateParameters{ - Tags: expandTags(tags), + Tags: tags.Expand(t), } result, err := client.Update(ctx, resGroupName, name, params) @@ -229,10 +229,10 @@ func resourceArmDevSpaceControllerUpdate(d *schema.ResourceData, meta interface{ } func resourceArmDevSpaceControllerDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).devSpaceControllerClient + client := meta.(*ArmClient).devSpace.ControllersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_devspace_controller_test.go b/azurerm/resource_arm_devspace_controller_test.go index ccfcb817479d..654f1113125f 100644 --- a/azurerm/resource_arm_devspace_controller_test.go +++ b/azurerm/resource_arm_devspace_controller_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDevSpaceController_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDevSpaceController_basic(t *testing.T) { } func TestAccAzureRMDevSpaceController_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -81,7 +82,7 @@ func testCheckAzureRMDevSpaceControllerExists(resourceName string) resource.Test return fmt.Errorf("Bad: no resource group found in state for DevSpace Controller: %s", ctrlName) } - client := testAccProvider.Meta().(*ArmClient).devSpaceControllerClient + client := testAccProvider.Meta().(*ArmClient).devSpace.ControllersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext result, err := client.Get(ctx, resGroupName, ctrlName) @@ -98,7 +99,7 @@ func testCheckAzureRMDevSpaceControllerExists(resourceName string) resource.Test } func testCheckAzureRMDevSpaceControllerDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).devSpaceControllerClient + client := testAccProvider.Meta().(*ArmClient).devSpace.ControllersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_a_record.go b/azurerm/resource_arm_dns_a_record.go index 9de48978f8d5..5bea1ee2b4d4 100644 --- a/azurerm/resource_arm_dns_a_record.go +++ b/azurerm/resource_arm_dns_a_record.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,7 +30,7 @@ func resourceArmDnsARecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -46,20 +49,20 @@ func resourceArmDnsARecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsARecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.A) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -73,12 +76,12 @@ func resourceArmDnsARecordCreateUpdate(d *schema.ResourceData, meta interface{}) } ttl := int64(d.Get("ttl").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ Name: &name, RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, ARecords: expandAzureRmDnsARecords(d), }, @@ -105,10 +108,10 @@ func resourceArmDnsARecordCreateUpdate(d *schema.ResourceData, meta interface{}) } func resourceArmDnsARecordRead(d *schema.ResourceData, meta interface{}) error { - dnsClient := meta.(*ArmClient).dnsClient + dnsClient := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -134,16 +137,14 @@ func resourceArmDnsARecordRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("records", flattenAzureRmDnsARecords(resp.ARecords)); err != nil { return err } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsARecordDelete(d *schema.ResourceData, meta interface{}) error { - dnsClient := meta.(*ArmClient).dnsClient + dnsClient := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_a_record_test.go b/azurerm/resource_arm_dns_a_record_test.go index 4db1381db701..d2f869ecbf74 100644 --- a/azurerm/resource_arm_dns_a_record_test.go +++ b/azurerm/resource_arm_dns_a_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsARecord_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDnsARecord_basic(t *testing.T) { } func TestAccAzureRMDnsARecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -145,7 +146,7 @@ func testCheckAzureRMDnsARecordExists(resourceName string) resource.TestCheckFun return fmt.Errorf("Bad: no resource group found in state for DNS A record: %s", aName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, aName, dns.A) if err != nil { @@ -161,7 +162,7 @@ func testCheckAzureRMDnsARecordExists(resourceName string) resource.TestCheckFun } func testCheckAzureRMDnsARecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_aaaa_record.go b/azurerm/resource_arm_dns_aaaa_record.go index 819b8b5b5503..7dc20aac5fce 100644 --- a/azurerm/resource_arm_dns_aaaa_record.go +++ b/azurerm/resource_arm_dns_aaaa_record.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,7 +30,7 @@ func resourceArmDnsAAAARecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -46,20 +49,20 @@ func resourceArmDnsAAAARecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsAaaaRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.AAAA) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -73,12 +76,12 @@ func resourceArmDnsAaaaRecordCreateUpdate(d *schema.ResourceData, meta interface } ttl := int64(d.Get("ttl").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ Name: &name, RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, AaaaRecords: expandAzureRmDnsAaaaRecords(d), }, @@ -105,10 +108,10 @@ func resourceArmDnsAaaaRecordCreateUpdate(d *schema.ResourceData, meta interface } func resourceArmDnsAaaaRecordRead(d *schema.ResourceData, meta interface{}) error { - dnsClient := meta.(*ArmClient).dnsClient + dnsClient := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -134,16 +137,14 @@ func resourceArmDnsAaaaRecordRead(d *schema.ResourceData, meta interface{}) erro if err := d.Set("records", flattenAzureRmDnsAaaaRecords(resp.AaaaRecords)); err != nil { return err } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsAaaaRecordDelete(d *schema.ResourceData, meta interface{}) error { - dnsClient := meta.(*ArmClient).dnsClient + dnsClient := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_aaaa_record_test.go b/azurerm/resource_arm_dns_aaaa_record_test.go index a89d18af7497..f761331859f8 100644 --- a/azurerm/resource_arm_dns_aaaa_record_test.go +++ b/azurerm/resource_arm_dns_aaaa_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsAAAARecord_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDnsAAAARecord_basic(t *testing.T) { } func TestAccAzureRMDnsAAAARecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -145,7 +146,7 @@ func testCheckAzureRMDnsAaaaRecordExists(resourceName string) resource.TestCheck return fmt.Errorf("Bad: no resource group found in state for DNS AAAA record: %s", aaaaName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, aaaaName, dns.AAAA) if err != nil { @@ -161,7 +162,7 @@ func testCheckAzureRMDnsAaaaRecordExists(resourceName string) resource.TestCheck } func testCheckAzureRMDnsAaaaRecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_caa_record.go b/azurerm/resource_arm_dns_caa_record.go index 9068ac6320cd..210f7d727751 100644 --- a/azurerm/resource_arm_dns_caa_record.go +++ b/azurerm/resource_arm_dns_caa_record.go @@ -9,7 +9,11 @@ import ( "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,7 +34,7 @@ func resourceArmDnsCaaRecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -55,7 +59,7 @@ func resourceArmDnsCaaRecord() *schema.Resource { "issuewild", "iodef", }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "value": { @@ -72,20 +76,20 @@ func resourceArmDnsCaaRecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsCaaRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.CAA) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -99,12 +103,12 @@ func resourceArmDnsCaaRecordCreateUpdate(d *schema.ResourceData, meta interface{ } ttl := int64(d.Get("ttl").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ Name: &name, RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, CaaRecords: expandAzureRmDnsCaaRecords(d), }, @@ -131,10 +135,10 @@ func resourceArmDnsCaaRecordCreateUpdate(d *schema.ResourceData, meta interface{ } func resourceArmDnsCaaRecordRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -160,16 +164,14 @@ func resourceArmDnsCaaRecordRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("record", flattenAzureRmDnsCaaRecords(resp.CaaRecords)); err != nil { return err } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsCaaRecordDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_caa_record_test.go b/azurerm/resource_arm_dns_caa_record_test.go index d4aece83a91c..c68323d1a725 100644 --- a/azurerm/resource_arm_dns_caa_record_test.go +++ b/azurerm/resource_arm_dns_caa_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsCaaRecord_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDnsCaaRecord_basic(t *testing.T) { } func TestAccAzureRMDnsCaaRecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -145,7 +146,7 @@ func testCheckAzureRMDnsCaaRecordExists(resourceName string) resource.TestCheckF return fmt.Errorf("Bad: no resource group found in state for DNS CAA record: %s", caaName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, caaName, dns.CAA) if err != nil { @@ -161,7 +162,7 @@ func testCheckAzureRMDnsCaaRecordExists(resourceName string) resource.TestCheckF } func testCheckAzureRMDnsCaaRecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_cname_record.go b/azurerm/resource_arm_dns_cname_record.go index e80e3832de18..601d24fbd976 100644 --- a/azurerm/resource_arm_dns_cname_record.go +++ b/azurerm/resource_arm_dns_cname_record.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,7 +30,7 @@ func resourceArmDnsCNameRecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -52,20 +55,20 @@ func resourceArmDnsCNameRecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsCNameRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.CNAME) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -80,12 +83,12 @@ func resourceArmDnsCNameRecordCreateUpdate(d *schema.ResourceData, meta interfac ttl := int64(d.Get("ttl").(int)) record := d.Get("record").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ Name: &name, RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, CnameRecord: &dns.CnameRecord{ Cname: &record, @@ -114,10 +117,10 @@ func resourceArmDnsCNameRecordCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmDnsCNameRecordRead(d *schema.ResourceData, meta interface{}) error { - dnsClient := meta.(*ArmClient).dnsClient + dnsClient := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -146,16 +149,14 @@ func resourceArmDnsCNameRecordRead(d *schema.ResourceData, meta interface{}) err } } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsCNameRecordDelete(d *schema.ResourceData, meta interface{}) error { - dnsClient := meta.(*ArmClient).dnsClient + dnsClient := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_cname_record_test.go b/azurerm/resource_arm_dns_cname_record_test.go index a681c8617cd7..88b4e8093edb 100644 --- a/azurerm/resource_arm_dns_cname_record_test.go +++ b/azurerm/resource_arm_dns_cname_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsCNameRecord_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDnsCNameRecord_basic(t *testing.T) { } func TestAccAzureRMDnsCNameRecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -169,7 +170,7 @@ func testCheckAzureRMDnsCNameRecordExists(resourceName string) resource.TestChec return fmt.Errorf("Bad: no resource group found in state for DNS CNAME record: %s", cnameName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, cnameName, dns.CNAME) if err != nil { @@ -185,7 +186,7 @@ func testCheckAzureRMDnsCNameRecordExists(resourceName string) resource.TestChec } func testCheckAzureRMDnsCNameRecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_mx_record.go b/azurerm/resource_arm_dns_mx_record.go index 549c045b90e9..02f940d0ca5e 100644 --- a/azurerm/resource_arm_dns_mx_record.go +++ b/azurerm/resource_arm_dns_mx_record.go @@ -9,7 +9,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,7 +33,7 @@ func resourceArmDnsMxRecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -62,20 +65,20 @@ func resourceArmDnsMxRecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsMxRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.MX) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -89,12 +92,12 @@ func resourceArmDnsMxRecordCreateUpdate(d *schema.ResourceData, meta interface{} } ttl := int64(d.Get("ttl").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ Name: &name, RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, MxRecords: expandAzureRmDnsMxRecords(d), }, @@ -121,10 +124,10 @@ func resourceArmDnsMxRecordCreateUpdate(d *schema.ResourceData, meta interface{} } func resourceArmDnsMxRecordRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -150,16 +153,14 @@ func resourceArmDnsMxRecordRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("record", flattenAzureRmDnsMxRecords(resp.MxRecords)); err != nil { return err } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsMxRecordDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_mx_record_test.go b/azurerm/resource_arm_dns_mx_record_test.go index 2ae058a1215e..3114371a3a8e 100644 --- a/azurerm/resource_arm_dns_mx_record_test.go +++ b/azurerm/resource_arm_dns_mx_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsMxRecord_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDnsMxRecord_basic(t *testing.T) { } func TestAccAzureRMDnsMxRecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -145,7 +146,7 @@ func testCheckAzureRMDnsMxRecordExists(resourceName string) resource.TestCheckFu return fmt.Errorf("Bad: no resource group found in state for DNS MX record: %s", mxName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, mxName, dns.MX) if err != nil { @@ -161,7 +162,7 @@ func testCheckAzureRMDnsMxRecordExists(resourceName string) resource.TestCheckFu } func testCheckAzureRMDnsMxRecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_ns_record.go b/azurerm/resource_arm_dns_ns_record.go index c401407966b2..a46fb141b171 100644 --- a/azurerm/resource_arm_dns_ns_record.go +++ b/azurerm/resource_arm_dns_ns_record.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,7 +30,7 @@ func resourceArmDnsNsRecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -64,20 +67,20 @@ func resourceArmDnsNsRecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsNsRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.NS) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -91,12 +94,12 @@ func resourceArmDnsNsRecordCreateUpdate(d *schema.ResourceData, meta interface{} } ttl := int64(d.Get("ttl").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ Name: &name, RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, NsRecords: expandAzureRmDnsNsRecords(d), }, @@ -123,10 +126,10 @@ func resourceArmDnsNsRecordCreateUpdate(d *schema.ResourceData, meta interface{} } func resourceArmDnsNsRecordRead(d *schema.ResourceData, meta interface{}) error { - dnsClient := meta.(*ArmClient).dnsClient + dnsClient := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -158,16 +161,14 @@ func resourceArmDnsNsRecordRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error settings `record`: %+v", err) } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsNsRecordDelete(d *schema.ResourceData, meta interface{}) error { - dnsClient := meta.(*ArmClient).dnsClient + dnsClient := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_ns_record_test.go b/azurerm/resource_arm_dns_ns_record_test.go index 8ef81256abbc..10c3debae48d 100644 --- a/azurerm/resource_arm_dns_ns_record_test.go +++ b/azurerm/resource_arm_dns_ns_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) //TODO: remove this once we remove the `record` attribute @@ -58,7 +59,7 @@ func TestAccAzureRMDnsNsRecord_basic(t *testing.T) { } func TestAccAzureRMDnsNsRecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -259,7 +260,7 @@ func testCheckAzureRMDnsNsRecordExists(resourceName string) resource.TestCheckFu return fmt.Errorf("Bad: no resource group found in state for DNS NS record: %s", nsName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, nsName, dns.NS) if err != nil { @@ -275,7 +276,7 @@ func testCheckAzureRMDnsNsRecordExists(resourceName string) resource.TestCheckFu } func testCheckAzureRMDnsNsRecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_ptr_record.go b/azurerm/resource_arm_dns_ptr_record.go index d3caa2abfbab..406d35758da7 100644 --- a/azurerm/resource_arm_dns_ptr_record.go +++ b/azurerm/resource_arm_dns_ptr_record.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,7 +30,7 @@ func resourceArmDnsPtrRecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -46,20 +49,20 @@ func resourceArmDnsPtrRecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsPtrRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.PTR) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -73,11 +76,11 @@ func resourceArmDnsPtrRecordCreateUpdate(d *schema.ResourceData, meta interface{ } ttl := int64(d.Get("ttl").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, PtrRecords: expandAzureRmDnsPtrRecords(d), }, @@ -105,10 +108,10 @@ func resourceArmDnsPtrRecordCreateUpdate(d *schema.ResourceData, meta interface{ func resourceArmDnsPtrRecordRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) - dnsClient := client.dnsClient + dnsClient := client.dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -135,17 +138,15 @@ func resourceArmDnsPtrRecordRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("records", flattenAzureRmDnsPtrRecords(resp.PtrRecords)); err != nil { return err } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsPtrRecordDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) - dnsClient := client.dnsClient + dnsClient := client.dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_ptr_record_test.go b/azurerm/resource_arm_dns_ptr_record_test.go index 919bf0f15e16..d9785f1d5dce 100644 --- a/azurerm/resource_arm_dns_ptr_record_test.go +++ b/azurerm/resource_arm_dns_ptr_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsPtrRecord_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDnsPtrRecord_basic(t *testing.T) { } func TestAccAzureRMDnsPtrRecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -146,7 +147,7 @@ func testCheckAzureRMDnsPtrRecordExists(resourceName string) resource.TestCheckF return fmt.Errorf("Bad: no resource group found in state for DNS PTR record: %s", ptrName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, ptrName, dns.PTR) if err != nil { @@ -162,7 +163,7 @@ func testCheckAzureRMDnsPtrRecordExists(resourceName string) resource.TestCheckF } func testCheckAzureRMDnsPtrRecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_srv_record.go b/azurerm/resource_arm_dns_srv_record.go index c652c100b591..c4b92bb8f107 100644 --- a/azurerm/resource_arm_dns_srv_record.go +++ b/azurerm/resource_arm_dns_srv_record.go @@ -8,7 +8,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -29,7 +32,7 @@ func resourceArmDnsSrvRecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -70,20 +73,20 @@ func resourceArmDnsSrvRecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsSrvRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.SRV) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -97,12 +100,12 @@ func resourceArmDnsSrvRecordCreateUpdate(d *schema.ResourceData, meta interface{ } ttl := int64(d.Get("ttl").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ Name: &name, RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, SrvRecords: expandAzureRmDnsSrvRecords(d), }, @@ -129,10 +132,10 @@ func resourceArmDnsSrvRecordCreateUpdate(d *schema.ResourceData, meta interface{ } func resourceArmDnsSrvRecordRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -158,16 +161,14 @@ func resourceArmDnsSrvRecordRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("record", flattenAzureRmDnsSrvRecords(resp.SrvRecords)); err != nil { return err } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsSrvRecordDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_srv_record_test.go b/azurerm/resource_arm_dns_srv_record_test.go index 9b7665585b00..ca5ffb4b8bdc 100644 --- a/azurerm/resource_arm_dns_srv_record_test.go +++ b/azurerm/resource_arm_dns_srv_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsSrvRecord_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDnsSrvRecord_basic(t *testing.T) { } func TestAccAzureRMDnsSrvRecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -145,7 +146,7 @@ func testCheckAzureRMDnsSrvRecordExists(resourceName string) resource.TestCheckF return fmt.Errorf("Bad: no resource group found in state for DNS SRV record: %s", srvName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, srvName, dns.SRV) if err != nil { @@ -161,7 +162,7 @@ func testCheckAzureRMDnsSrvRecordExists(resourceName string) resource.TestCheckF } func testCheckAzureRMDnsSrvRecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_txt_record.go b/azurerm/resource_arm_dns_txt_record.go index 753b780d2ecf..40a4d90c7bd5 100644 --- a/azurerm/resource_arm_dns_txt_record.go +++ b/azurerm/resource_arm_dns_txt_record.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,7 +30,7 @@ func resourceArmDnsTxtRecord() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "zone_name": { Type: schema.TypeString, @@ -52,20 +55,20 @@ func resourceArmDnsTxtRecord() *schema.Resource { Required: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsTxtRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) zoneName := d.Get("zone_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, zoneName, name, dns.TXT) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -79,12 +82,12 @@ func resourceArmDnsTxtRecordCreateUpdate(d *schema.ResourceData, meta interface{ } ttl := int64(d.Get("ttl").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := dns.RecordSet{ Name: &name, RecordSetProperties: &dns.RecordSetProperties{ - Metadata: expandTags(tags), + Metadata: tags.Expand(t), TTL: &ttl, TxtRecords: expandAzureRmDnsTxtRecords(d), }, @@ -111,10 +114,10 @@ func resourceArmDnsTxtRecordCreateUpdate(d *schema.ResourceData, meta interface{ } func resourceArmDnsTxtRecordRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -140,16 +143,14 @@ func resourceArmDnsTxtRecordRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("record", flattenAzureRmDnsTxtRecords(resp.TxtRecords)); err != nil { return err } - flattenAndSetTags(d, resp.Metadata) - - return nil + return tags.FlattenAndSet(d, resp.Metadata) } func resourceArmDnsTxtRecordDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).dnsClient + client := meta.(*ArmClient).dns.RecordSetsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_txt_record_test.go b/azurerm/resource_arm_dns_txt_record_test.go index 366f2d5a4373..0a717ff1dbb8 100644 --- a/azurerm/resource_arm_dns_txt_record_test.go +++ b/azurerm/resource_arm_dns_txt_record_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsTxtRecord_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMDnsTxtRecord_basic(t *testing.T) { } func TestAccAzureRMDnsTxtRecord_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -143,7 +144,7 @@ func testCheckAzureRMDnsTxtRecordExists(resourceName string) resource.TestCheckF return fmt.Errorf("Bad: no resource group found in state for DNS TXT record: %s", txtName) } - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, zoneName, txtName, dns.TXT) if err != nil { @@ -159,7 +160,7 @@ func testCheckAzureRMDnsTxtRecordExists(resourceName string) resource.TestCheckF } func testCheckAzureRMDnsTxtRecordDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).dnsClient + conn := testAccProvider.Meta().(*ArmClient).dns.RecordSetsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_dns_zone.go b/azurerm/resource_arm_dns_zone.go index 54d66984c98a..48fb2b0c8d17 100644 --- a/azurerm/resource_arm_dns_zone.go +++ b/azurerm/resource_arm_dns_zone.go @@ -6,8 +6,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -28,7 +31,7 @@ func resourceArmDnsZone() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), "number_of_record_sets": { Type: schema.TypeInt, @@ -48,9 +51,10 @@ func resourceArmDnsZone() *schema.Resource { }, "zone_type": { - Type: schema.TypeString, - Default: string(dns.Public), - Optional: true, + Type: schema.TypeString, + Default: string(dns.Public), + Optional: true, + Deprecated: "Use the `azurerm_private_dns_zone` resource instead.", ValidateFunc: validation.StringInSlice([]string{ string(dns.Private), string(dns.Public), @@ -69,19 +73,19 @@ func resourceArmDnsZone() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmDnsZoneCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).zonesClient + client := meta.(*ArmClient).dns.ZonesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -96,14 +100,14 @@ func resourceArmDnsZoneCreateUpdate(d *schema.ResourceData, meta interface{}) er location := "global" zoneType := d.Get("zone_type").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) registrationVirtualNetworkIds := expandDnsZoneRegistrationVirtualNetworkIds(d) resolutionVirtualNetworkIds := expandDnsZoneResolutionVirtualNetworkIds(d) parameters := dns.Zone{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), ZoneProperties: &dns.ZoneProperties{ ZoneType: dns.ZoneType(zoneType), RegistrationVirtualNetworks: registrationVirtualNetworkIds, @@ -133,10 +137,10 @@ func resourceArmDnsZoneCreateUpdate(d *schema.ResourceData, meta interface{}) er } func resourceArmDnsZoneRead(d *schema.ResourceData, meta interface{}) error { - zonesClient := meta.(*ArmClient).zonesClient + zonesClient := meta.(*ArmClient).dns.ZonesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -177,16 +181,14 @@ func resourceArmDnsZoneRead(d *schema.ResourceData, meta interface{}) error { return err } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmDnsZoneDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).zonesClient + client := meta.(*ArmClient).dns.ZonesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_dns_zone_test.go b/azurerm/resource_arm_dns_zone_test.go index a1e46541c44e..f32c5674a904 100644 --- a/azurerm/resource_arm_dns_zone_test.go +++ b/azurerm/resource_arm_dns_zone_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMDnsZone_basic(t *testing.T) { @@ -36,7 +37,7 @@ func TestAccAzureRMDnsZone_basic(t *testing.T) { } func TestAccAzureRMDnsZone_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -138,7 +139,7 @@ func testCheckAzureRMDnsZoneExists(resourceName string) resource.TestCheckFunc { return fmt.Errorf("Bad: no resource group found in state for DNS zone: %s", zoneName) } - client := testAccProvider.Meta().(*ArmClient).zonesClient + client := testAccProvider.Meta().(*ArmClient).dns.ZonesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, zoneName) if err != nil { @@ -154,7 +155,7 @@ func testCheckAzureRMDnsZoneExists(resourceName string) resource.TestCheckFunc { } func testCheckAzureRMDnsZoneDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).zonesClient + conn := testAccProvider.Meta().(*ArmClient).dns.ZonesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_eventgrid_domain.go b/azurerm/resource_arm_eventgrid_domain.go index cd76037a8d82..92327196307c 100644 --- a/azurerm/resource_arm_eventgrid_domain.go +++ b/azurerm/resource_arm_eventgrid_domain.go @@ -7,8 +7,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/eventgrid/mgmt/2018-09-15-preview/eventgrid" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -29,11 +32,11 @@ func resourceArmEventGridDomain() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "tags": tagsSchema(), + "tags": tags.Schema(), "input_schema": { Type: schema.TypeString, @@ -123,13 +126,13 @@ func resourceArmEventGridDomain() *schema.Resource { } func resourceArmEventGridDomainCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridDomainsClient + client := meta.(*ArmClient).eventGrid.DomainsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -142,8 +145,8 @@ func resourceArmEventGridDomainCreateUpdate(d *schema.ResourceData, meta interfa } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) domainProperties := &eventgrid.DomainProperties{ InputSchemaMapping: expandAzureRmEventgridDomainInputMapping(d), @@ -153,7 +156,7 @@ func resourceArmEventGridDomainCreateUpdate(d *schema.ResourceData, meta interfa domain := eventgrid.Domain{ Location: &location, DomainProperties: domainProperties, - Tags: expandTags(tags), + Tags: tags.Expand(t), } log.Printf("[INFO] preparing arguments for AzureRM EventGrid Domain creation with Properties: %+v", domain) @@ -181,10 +184,10 @@ func resourceArmEventGridDomainCreateUpdate(d *schema.ResourceData, meta interfa } func resourceArmEventGridDomainRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridDomainsClient + client := meta.(*ArmClient).eventGrid.DomainsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -205,7 +208,7 @@ func resourceArmEventGridDomainRead(d *schema.ResourceData, meta interface{}) er d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.DomainProperties; props != nil { @@ -230,16 +233,14 @@ func resourceArmEventGridDomainRead(d *schema.ResourceData, meta interface{}) er } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmEventGridDomainDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridDomainsClient + client := meta.(*ArmClient).eventGrid.DomainsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_eventgrid_domain_test.go b/azurerm/resource_arm_eventgrid_domain_test.go index d0de859bb68e..2670641374fe 100644 --- a/azurerm/resource_arm_eventgrid_domain_test.go +++ b/azurerm/resource_arm_eventgrid_domain_test.go @@ -94,7 +94,7 @@ func TestAccAzureRMEventGridDomain_basicWithTags(t *testing.T) { } func testCheckAzureRMEventGridDomainDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).eventGridDomainsClient + client := testAccProvider.Meta().(*ArmClient).eventGrid.DomainsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -136,7 +136,7 @@ func testCheckAzureRMEventGridDomainExists(resourceName string) resource.TestChe return fmt.Errorf("Bad: no resource group found in state for EventGrid Domain: %s", name) } - client := testAccProvider.Meta().(*ArmClient).eventGridDomainsClient + client := testAccProvider.Meta().(*ArmClient).eventGrid.DomainsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) if err != nil { @@ -179,14 +179,15 @@ resource "azurerm_eventgrid_domain" "test" { resource_group_name = "${azurerm_resource_group.test.name}" input_schema = "CustomEventSchema" + input_mapping_fields { - topic = "test" - event_type = "test" + topic = "test" + event_type = "test" } input_mapping_default_values { - data_version = "1.0" - subject = "DefaultSubject" + data_version = "1.0" + subject = "DefaultSubject" } } `, rInt, location, rInt) diff --git a/azurerm/resource_arm_eventgrid_event_subscription.go b/azurerm/resource_arm_eventgrid_event_subscription.go index 2855e1b31a3e..578de8b1e140 100644 --- a/azurerm/resource_arm_eventgrid_event_subscription.go +++ b/azurerm/resource_arm_eventgrid_event_subscription.go @@ -12,6 +12,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -211,13 +212,13 @@ func resourceArmEventGridEventSubscription() *schema.Resource { } func resourceArmEventGridEventSubscriptionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridEventSubscriptionsClient + client := meta.(*ArmClient).eventGrid.EventSubscriptionsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) scope := d.Get("scope").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, scope, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -240,7 +241,7 @@ func resourceArmEventGridEventSubscriptionCreateUpdate(d *schema.ResourceData, m Filter: expandEventGridEventSubscriptionFilter(d), DeadLetterDestination: expandEventGridEventSubscriptionStorageBlobDeadLetterDestination(d), RetryPolicy: expandEventGridEventSubscriptionRetryPolicy(d), - Labels: utils.ExpandStringArray(d.Get("labels").([]interface{})), + Labels: utils.ExpandStringSlice(d.Get("labels").([]interface{})), EventDeliverySchema: eventgrid.EventDeliverySchema(d.Get("event_delivery_schema").(string)), } @@ -277,7 +278,7 @@ func resourceArmEventGridEventSubscriptionCreateUpdate(d *schema.ResourceData, m } func resourceArmEventGridEventSubscriptionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridEventSubscriptionsClient + client := meta.(*ArmClient).eventGrid.EventSubscriptionsClient ctx := meta.(*ArmClient).StopContext id, err := parseAzureEventGridEventSubscriptionID(d.Id()) @@ -323,8 +324,12 @@ func resourceArmEventGridEventSubscriptionRead(d *schema.ResourceData, meta inte return fmt.Errorf("Error setting `hybrid_connection_endpoint` for EventGrid Event Subscription %q (Scope %q): %s", name, scope, err) } } - if webhookEndpoint, ok := props.Destination.AsWebHookEventSubscriptionDestination(); ok { - if err := d.Set("webhook_endpoint", flattenEventGridEventSubscriptionWebhookEndpoint(webhookEndpoint)); err != nil { + if _, ok := props.Destination.AsWebHookEventSubscriptionDestination(); ok { + fullURL, err := client.GetFullURL(ctx, scope, name) + if err != nil { + return fmt.Errorf("Error making Read request on EventGrid Event Subscription full URL '%s': %+v", name, err) + } + if err := d.Set("webhook_endpoint", flattenEventGridEventSubscriptionWebhookEndpoint(&fullURL)); err != nil { return fmt.Errorf("Error setting `webhook_endpoint` for EventGrid Event Subscription %q (Scope %q): %s", name, scope, err) } } @@ -361,7 +366,7 @@ func resourceArmEventGridEventSubscriptionRead(d *schema.ResourceData, meta inte } func resourceArmEventGridEventSubscriptionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridEventSubscriptionsClient + client := meta.(*ArmClient).eventGrid.EventSubscriptionsClient ctx := meta.(*ArmClient).StopContext id, err := parseAzureEventGridEventSubscriptionID(d.Id()) @@ -487,7 +492,7 @@ func expandEventGridEventSubscriptionFilter(d *schema.ResourceData) *eventgrid.E filter := &eventgrid.EventSubscriptionFilter{} if includedEvents, ok := d.GetOk("included_event_types"); ok { - filter.IncludedEventTypes = utils.ExpandStringArray(includedEvents.([]interface{})) + filter.IncludedEventTypes = utils.ExpandStringSlice(includedEvents.([]interface{})) } if subjectFilter, ok := d.GetOk("subject_filter"); ok { @@ -575,7 +580,7 @@ func flattenEventGridEventSubscriptionHybridConnectionEndpoint(input *eventgrid. return []interface{}{result} } -func flattenEventGridEventSubscriptionWebhookEndpoint(input *eventgrid.WebHookEventSubscriptionDestination) []interface{} { +func flattenEventGridEventSubscriptionWebhookEndpoint(input *eventgrid.EventSubscriptionFullURL) []interface{} { if input == nil { return nil } diff --git a/azurerm/resource_arm_eventgrid_event_subscription_test.go b/azurerm/resource_arm_eventgrid_event_subscription_test.go index 5d19985de392..5a57033d436b 100644 --- a/azurerm/resource_arm_eventgrid_event_subscription_test.go +++ b/azurerm/resource_arm_eventgrid_event_subscription_test.go @@ -151,7 +151,7 @@ func TestAccAzureRMEventGridEventSubscription_filter(t *testing.T) { } func testCheckAzureRMEventGridEventSubscriptionDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).eventGridEventSubscriptionsClient + client := testAccProvider.Meta().(*ArmClient).eventGrid.EventSubscriptionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -193,7 +193,7 @@ func testCheckAzureRMEventGridEventSubscriptionExists(resourceName string) resou return fmt.Errorf("Bad: no scope found in state for EventGrid Event Subscription: %s", name) } - client := testAccProvider.Meta().(*ArmClient).eventGridEventSubscriptionsClient + client := testAccProvider.Meta().(*ArmClient).eventGrid.EventSubscriptionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, scope, name) if err != nil { @@ -221,12 +221,12 @@ resource "azurerm_storage_account" "test" { location = "${azurerm_resource_group.test.location}" account_tier = "Standard" account_replication_type = "LRS" - + tags = { environment = "staging" } } - + resource "azurerm_storage_queue" "test" { name = "mysamplequeue-%d" resource_group_name = "${azurerm_resource_group.test.name}" @@ -252,21 +252,22 @@ resource "azurerm_storage_blob" "test" { } resource "azurerm_eventgrid_event_subscription" "test" { - name = "acctesteg-%d" + name = "acctesteg-%d" scope = "${azurerm_resource_group.test.id}" + storage_queue_endpoint { - storage_account_id = "${azurerm_storage_account.test.id}" - queue_name = "${azurerm_storage_queue.test.name}" + storage_account_id = "${azurerm_storage_account.test.id}" + queue_name = "${azurerm_storage_queue.test.name}" } storage_blob_dead_letter_destination { - storage_account_id = "${azurerm_storage_account.test.id}" - storage_blob_container_name = "${azurerm_storage_container.test.name}" + storage_account_id = "${azurerm_storage_account.test.id}" + storage_blob_container_name = "${azurerm_storage_container.test.name}" } retry_policy { - event_time_to_live = 11 - max_delivery_attempts = 11 + event_time_to_live = 11 + max_delivery_attempts = 11 } labels = ["test", "test1", "test2"] @@ -287,12 +288,12 @@ resource "azurerm_storage_account" "test" { location = "${azurerm_resource_group.test.location}" account_tier = "Standard" account_replication_type = "LRS" - + tags = { environment = "staging" } } - + resource "azurerm_storage_queue" "test" { name = "mysamplequeue-%d" resource_group_name = "${azurerm_resource_group.test.name}" @@ -318,30 +319,31 @@ resource "azurerm_storage_blob" "test" { } resource "azurerm_eventgrid_event_subscription" "test" { - name = "acctesteg-%d" + name = "acctesteg-%d" scope = "${azurerm_resource_group.test.id}" + storage_queue_endpoint { - storage_account_id = "${azurerm_storage_account.test.id}" - queue_name = "${azurerm_storage_queue.test.name}" + storage_account_id = "${azurerm_storage_account.test.id}" + queue_name = "${azurerm_storage_queue.test.name}" } storage_blob_dead_letter_destination { - storage_account_id = "${azurerm_storage_account.test.id}" - storage_blob_container_name = "${azurerm_storage_container.test.name}" + storage_account_id = "${azurerm_storage_account.test.id}" + storage_blob_container_name = "${azurerm_storage_container.test.name}" } retry_policy { - event_time_to_live = 12 - max_delivery_attempts = 10 + event_time_to_live = 12 + max_delivery_attempts = 10 } subject_filter { - subject_begins_with = "test/test" - subject_ends_with = ".jpg" + subject_begins_with = "test/test" + subject_ends_with = ".jpg" } included_event_types = ["Microsoft.Storage.BlobCreated", "Microsoft.Storage.BlobDeleted"] - labels = ["test4", "test5", "test6"] + labels = ["test4", "test5", "test6"] } `, rInt, location, rString, rInt, rInt) } @@ -369,11 +371,12 @@ resource "azurerm_eventhub" "test" { } resource "azurerm_eventgrid_event_subscription" "test" { - name = "acctesteg-%d" - scope = "${azurerm_resource_group.test.id}" + name = "acctesteg-%d" + scope = "${azurerm_resource_group.test.id}" event_delivery_schema = "CloudEventV01Schema" + eventhub_endpoint { - eventhub_id = "${azurerm_eventhub.test.id}" + eventhub_id = "${azurerm_eventhub.test.id}" } } `, rInt, location, rInt, rInt, rInt) @@ -392,12 +395,12 @@ resource "azurerm_storage_account" "test" { location = "${azurerm_resource_group.test.location}" account_tier = "Standard" account_replication_type = "LRS" - + tags = { environment = "staging" } } - + resource "azurerm_storage_queue" "test" { name = "mysamplequeue-%d" resource_group_name = "${azurerm_resource_group.test.name}" @@ -405,18 +408,19 @@ resource "azurerm_storage_queue" "test" { } resource "azurerm_eventgrid_event_subscription" "test" { - name = "acctesteg-%d" + name = "acctesteg-%d" scope = "${azurerm_resource_group.test.id}" + storage_queue_endpoint { - storage_account_id = "${azurerm_storage_account.test.id}" - queue_name = "${azurerm_storage_queue.test.name}" + storage_account_id = "${azurerm_storage_account.test.id}" + queue_name = "${azurerm_storage_queue.test.name}" } included_event_types = ["Microsoft.Storage.BlobCreated", "Microsoft.Storage.BlobDeleted"] subject_filter { - subject_begins_with = "test/test" - subject_ends_with = ".jpg" + subject_begins_with = "test/test" + subject_ends_with = ".jpg" } } `, rInt, location, rString, rInt, rInt) diff --git a/azurerm/resource_arm_eventgrid_topic.go b/azurerm/resource_arm_eventgrid_topic.go index dbbb69483a3e..6790d07c7279 100644 --- a/azurerm/resource_arm_eventgrid_topic.go +++ b/azurerm/resource_arm_eventgrid_topic.go @@ -6,8 +6,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/eventgrid/mgmt/2018-09-15-preview/eventgrid" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -28,11 +31,11 @@ func resourceArmEventGridTopic() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "tags": tagsSchema(), + "tags": tags.Schema(), "endpoint": { Type: schema.TypeString, @@ -55,13 +58,13 @@ func resourceArmEventGridTopic() *schema.Resource { } func resourceArmEventGridTopicCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridTopicsClient + client := meta.(*ArmClient).eventGrid.TopicsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -74,13 +77,13 @@ func resourceArmEventGridTopicCreateUpdate(d *schema.ResourceData, meta interfac } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) properties := eventgrid.Topic{ Location: &location, TopicProperties: &eventgrid.TopicProperties{}, - Tags: expandTags(tags), + Tags: tags.Expand(t), } log.Printf("[INFO] preparing arguments for AzureRM EventGrid Topic creation with Properties: %+v.", properties) @@ -108,10 +111,10 @@ func resourceArmEventGridTopicCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmEventGridTopicRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridTopicsClient + client := meta.(*ArmClient).eventGrid.TopicsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -137,7 +140,7 @@ func resourceArmEventGridTopicRead(d *schema.ResourceData, meta interface{}) err d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.TopicProperties; props != nil { @@ -147,16 +150,14 @@ func resourceArmEventGridTopicRead(d *schema.ResourceData, meta interface{}) err d.Set("primary_access_key", keys.Key1) d.Set("secondary_access_key", keys.Key2) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmEventGridTopicDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventGridTopicsClient + client := meta.(*ArmClient).eventGrid.TopicsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_eventgrid_topic_test.go b/azurerm/resource_arm_eventgrid_topic_test.go index c8e5b639bfdf..66a5cfb71975 100644 --- a/azurerm/resource_arm_eventgrid_topic_test.go +++ b/azurerm/resource_arm_eventgrid_topic_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -39,7 +40,7 @@ func TestAccAzureRMEventGridTopic_basic(t *testing.T) { } func TestAccAzureRMEventGridTopic_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -96,7 +97,7 @@ func TestAccAzureRMEventGridTopic_basicWithTags(t *testing.T) { } func testCheckAzureRMEventGridTopicDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).eventGridTopicsClient + client := testAccProvider.Meta().(*ArmClient).eventGrid.TopicsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -138,7 +139,7 @@ func testCheckAzureRMEventGridTopicExists(resourceName string) resource.TestChec return fmt.Errorf("Bad: no resource group found in state for EventGrid Topic: %s", name) } - client := testAccProvider.Meta().(*ArmClient).eventGridTopicsClient + client := testAccProvider.Meta().(*ArmClient).eventGrid.TopicsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) if err != nil { diff --git a/azurerm/resource_arm_eventhub.go b/azurerm/resource_arm_eventhub.go index 68b1778c71b0..2dbd6ee127d6 100644 --- a/azurerm/resource_arm_eventhub.go +++ b/azurerm/resource_arm_eventhub.go @@ -12,6 +12,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,10 +41,10 @@ func resourceArmEventHub() *schema.Resource { ValidateFunc: azure.ValidateEventHubNamespaceName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), // TODO: remove me in the next major version - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), "partition_count": { Type: schema.TypeInt, @@ -68,6 +69,11 @@ func resourceArmEventHub() *schema.Resource { Type: schema.TypeBool, Required: true, }, + "skip_empty_archives": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "encoding": { Type: schema.TypeString, Required: true, @@ -137,7 +143,7 @@ func resourceArmEventHub() *schema.Resource { } func resourceArmEventHubCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubClient + client := meta.(*ArmClient).eventhub.EventHubsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ARM EventHub creation.") @@ -145,7 +151,7 @@ func resourceArmEventHubCreateUpdate(d *schema.ResourceData, meta interface{}) e namespaceName := d.Get("namespace_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, namespaceName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -196,10 +202,10 @@ func resourceArmEventHubCreateUpdate(d *schema.ResourceData, meta interface{}) e } func resourceArmEventHubRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubClient + client := meta.(*ArmClient).eventhub.EventHubsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -235,9 +241,9 @@ func resourceArmEventHubRead(d *schema.ResourceData, meta interface{}) error { } func resourceArmEventHubDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubClient + client := meta.(*ArmClient).eventhub.EventHubsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -261,8 +267,8 @@ func resourceArmEventHubDelete(d *schema.ResourceData, meta interface{}) error { func validateEventHubPartitionCount(v interface{}, _ string) (warnings []string, errors []error) { value := v.(int) - if !(32 >= value && value >= 2) { - errors = append(errors, fmt.Errorf("EventHub Partition Count has to be between 2 and 32")) + if !(32 >= value && value >= 1) { + errors = append(errors, fmt.Errorf("EventHub Partition Count has to be between 1 and 32")) } return warnings, errors @@ -310,12 +316,14 @@ func expandEventHubCaptureDescription(d *schema.ResourceData) (*eventhub.Capture encoding := input["encoding"].(string) intervalInSeconds := input["interval_in_seconds"].(int) sizeLimitInBytes := input["size_limit_in_bytes"].(int) + skipEmptyArchives := input["skip_empty_archives"].(bool) captureDescription := eventhub.CaptureDescription{ Enabled: utils.Bool(enabled), Encoding: eventhub.EncodingCaptureDescription(encoding), IntervalInSeconds: utils.Int32(int32(intervalInSeconds)), SizeLimitInBytes: utils.Int32(int32(sizeLimitInBytes)), + SkipEmptyArchives: utils.Bool(skipEmptyArchives), } if v, ok := input["destination"]; ok { @@ -352,6 +360,10 @@ func flattenEventHubCaptureDescription(description *eventhub.CaptureDescription) output["enabled"] = *enabled } + if skipEmptyArchives := description.SkipEmptyArchives; skipEmptyArchives != nil { + output["skip_empty_archives"] = *skipEmptyArchives + } + output["encoding"] = string(description.Encoding) if interval := description.IntervalInSeconds; interval != nil { diff --git a/azurerm/resource_arm_eventhub_authorization_rule.go b/azurerm/resource_arm_eventhub_authorization_rule.go index 713f87ce17b5..c0a812241de4 100644 --- a/azurerm/resource_arm_eventhub_authorization_rule.go +++ b/azurerm/resource_arm_eventhub_authorization_rule.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -45,9 +46,9 @@ func resourceArmEventHubAuthorizationRule() *schema.Resource { ValidateFunc: azure.ValidateEventHubName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), }), CustomizeDiff: azure.EventHubAuthorizationRuleCustomizeDiff, @@ -55,7 +56,7 @@ func resourceArmEventHubAuthorizationRule() *schema.Resource { } func resourceArmEventHubAuthorizationRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubClient + client := meta.(*ArmClient).eventhub.EventHubsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM EventHub Authorization Rule creation.") @@ -65,7 +66,7 @@ func resourceArmEventHubAuthorizationRuleCreateUpdate(d *schema.ResourceData, me eventHubName := d.Get("eventhub_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.GetAuthorizationRule(ctx, resourceGroup, namespaceName, eventHubName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -104,10 +105,10 @@ func resourceArmEventHubAuthorizationRuleCreateUpdate(d *schema.ResourceData, me } func resourceArmEventHubAuthorizationRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubClient + client := meta.(*ArmClient).eventhub.EventHubsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -152,10 +153,10 @@ func resourceArmEventHubAuthorizationRuleRead(d *schema.ResourceData, meta inter } func resourceArmEventHubAuthorizationRuleDelete(d *schema.ResourceData, meta interface{}) error { - eventhubClient := meta.(*ArmClient).eventHubClient + eventhubClient := meta.(*ArmClient).eventhub.EventHubsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_eventhub_authorization_rule_test.go b/azurerm/resource_arm_eventhub_authorization_rule_test.go index caf253376782..13a47b9c4d93 100644 --- a/azurerm/resource_arm_eventhub_authorization_rule_test.go +++ b/azurerm/resource_arm_eventhub_authorization_rule_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -61,7 +62,7 @@ func testAccAzureRMEventHubAuthorizationRule(t *testing.T, listen, send, manage } func TestAccAzureRMEventHubAuthorizationRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -132,7 +133,7 @@ func TestAccAzureRMEventHubAuthorizationRule_rightsUpdate(t *testing.T) { } func testCheckAzureRMEventHubAuthorizationRuleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).eventHubClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.EventHubsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -172,7 +173,7 @@ func testCheckAzureRMEventHubAuthorizationRuleExists(resourceName string) resour return fmt.Errorf("Bad: no resource group found in state for Event Hub: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).eventHubClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.EventHubsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.GetAuthorizationRule(ctx, resourceGroup, namespaceName, eventHubName, name) if err != nil { diff --git a/azurerm/resource_arm_eventhub_consumer_group.go b/azurerm/resource_arm_eventhub_consumer_group.go index f88d1d581967..41871b6d53ff 100644 --- a/azurerm/resource_arm_eventhub_consumer_group.go +++ b/azurerm/resource_arm_eventhub_consumer_group.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -44,9 +45,9 @@ func resourceArmEventHubConsumerGroup() *schema.Resource { ValidateFunc: azure.ValidateEventHubName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), "user_metadata": { Type: schema.TypeString, @@ -58,7 +59,7 @@ func resourceArmEventHubConsumerGroup() *schema.Resource { } func resourceArmEventHubConsumerGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubConsumerGroupClient + client := meta.(*ArmClient).eventhub.ConsumerGroupClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM EventHub Consumer Group creation.") @@ -67,7 +68,7 @@ func resourceArmEventHubConsumerGroupCreateUpdate(d *schema.ResourceData, meta i eventHubName := d.Get("eventhub_name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, namespaceName, eventHubName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -109,10 +110,10 @@ func resourceArmEventHubConsumerGroupCreateUpdate(d *schema.ResourceData, meta i } func resourceArmEventHubConsumerGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubConsumerGroupClient + client := meta.(*ArmClient).eventhub.ConsumerGroupClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -140,10 +141,10 @@ func resourceArmEventHubConsumerGroupRead(d *schema.ResourceData, meta interface } func resourceArmEventHubConsumerGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubConsumerGroupClient + client := meta.(*ArmClient).eventhub.ConsumerGroupClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_eventhub_consumer_group_test.go b/azurerm/resource_arm_eventhub_consumer_group_test.go index 4c4918710a71..f45f005644e7 100644 --- a/azurerm/resource_arm_eventhub_consumer_group_test.go +++ b/azurerm/resource_arm_eventhub_consumer_group_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +36,7 @@ func TestAccAzureRMEventHubConsumerGroup_basic(t *testing.T) { } func TestAccAzureRMEventHubConsumerGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -120,7 +121,7 @@ func TestAccAzureRMEventHubConsumerGroup_userMetadataUpdate(t *testing.T) { } func testCheckAzureRMEventHubConsumerGroupDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).eventHubConsumerGroupClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.ConsumerGroupClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -159,7 +160,7 @@ func testCheckAzureRMEventHubConsumerGroupExists(resourceName string) resource.T return fmt.Errorf("Bad: no resource group found in state for Event Hub Consumer Group: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).eventHubConsumerGroupClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.ConsumerGroupClient ctx := testAccProvider.Meta().(*ArmClient).StopContext namespaceName := rs.Primary.Attributes["namespace_name"] diff --git a/azurerm/resource_arm_eventhub_namespace.go b/azurerm/resource_arm_eventhub_namespace.go index 45c7db7cab49..6e0a09d2d418 100644 --- a/azurerm/resource_arm_eventhub_namespace.go +++ b/azurerm/resource_arm_eventhub_namespace.go @@ -15,6 +15,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,9 +42,9 @@ func resourceArmEventHubNamespace() *schema.Resource { ValidateFunc: azure.ValidateEventHubNamespaceName(), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeString, @@ -58,7 +60,7 @@ func resourceArmEventHubNamespace() *schema.Resource { Type: schema.TypeInt, Optional: true, Default: 1, - ValidateFunc: validation.IntBetween(1, 100), + ValidateFunc: validation.IntBetween(1, 20), }, "auto_inflate_enabled": { @@ -77,7 +79,7 @@ func resourceArmEventHubNamespace() *schema.Resource { Type: schema.TypeInt, Optional: true, Computed: true, - ValidateFunc: validation.IntBetween(0, 100), + ValidateFunc: validation.IntBetween(0, 20), }, "default_primary_connection_string": { @@ -104,20 +106,20 @@ func resourceArmEventHubNamespace() *schema.Resource { Sensitive: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubNamespacesClient + client := meta.(*ArmClient).eventhub.NamespacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM EventHub Namespace creation.") name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -130,10 +132,10 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) sku := d.Get("sku").(string) capacity := int32(d.Get("capacity").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) autoInflateEnabled := d.Get("auto_inflate_enabled").(bool) kafkaEnabled := d.Get("kafka_enabled").(bool) @@ -148,7 +150,7 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter IsAutoInflateEnabled: utils.Bool(autoInflateEnabled), KafkaEnabled: utils.Bool(kafkaEnabled), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if v, ok := d.GetOk("maximum_throughput_units"); ok { @@ -179,10 +181,10 @@ func resourceArmEventHubNamespaceCreateUpdate(d *schema.ResourceData, meta inter } func resourceArmEventHubNamespaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubNamespacesClient + client := meta.(*ArmClient).eventhub.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -201,7 +203,7 @@ func resourceArmEventHubNamespaceRead(d *schema.ResourceData, meta interface{}) d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("sku", string(resp.Sku.Name)) @@ -223,16 +225,14 @@ func resourceArmEventHubNamespaceRead(d *schema.ResourceData, meta interface{}) d.Set("maximum_throughput_units", int(*props.MaximumThroughputUnits)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmEventHubNamespaceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubNamespacesClient + client := meta.(*ArmClient).eventhub.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -250,7 +250,7 @@ func resourceArmEventHubNamespaceDelete(d *schema.ResourceData, meta interface{} return waitForEventHubNamespaceToBeDeleted(ctx, client, resGroup, name) } -func waitForEventHubNamespaceToBeDeleted(ctx context.Context, client eventhub.NamespacesClient, resourceGroup, name string) error { +func waitForEventHubNamespaceToBeDeleted(ctx context.Context, client *eventhub.NamespacesClient, resourceGroup, name string) error { // we can't use the Waiter here since the API returns a 200 once it's deleted which is considered a polling status code.. log.Printf("[DEBUG] Waiting for EventHub Namespace (%q in Resource Group %q) to be deleted", name, resourceGroup) stateConf := &resource.StateChangeConf{ @@ -266,7 +266,7 @@ func waitForEventHubNamespaceToBeDeleted(ctx context.Context, client eventhub.Na return nil } -func eventHubNamespaceStateStatusCodeRefreshFunc(ctx context.Context, client eventhub.NamespacesClient, resourceGroup, name string) resource.StateRefreshFunc { +func eventHubNamespaceStateStatusCodeRefreshFunc(ctx context.Context, client *eventhub.NamespacesClient, resourceGroup, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_eventhub_namespace_authorization_rule.go b/azurerm/resource_arm_eventhub_namespace_authorization_rule.go index 509dc835c62c..0df33ef1c6d0 100644 --- a/azurerm/resource_arm_eventhub_namespace_authorization_rule.go +++ b/azurerm/resource_arm_eventhub_namespace_authorization_rule.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,9 +39,9 @@ func resourceArmEventHubNamespaceAuthorizationRule() *schema.Resource { ValidateFunc: azure.ValidateEventHubNamespaceName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), }), CustomizeDiff: azure.EventHubAuthorizationRuleCustomizeDiff, @@ -48,7 +49,7 @@ func resourceArmEventHubNamespaceAuthorizationRule() *schema.Resource { } func resourceArmEventHubNamespaceAuthorizationRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubNamespacesClient + client := meta.(*ArmClient).eventhub.NamespacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM EventHub Namespace Authorization Rule creation.") @@ -57,7 +58,7 @@ func resourceArmEventHubNamespaceAuthorizationRuleCreateUpdate(d *schema.Resourc namespaceName := d.Get("namespace_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.GetAuthorizationRule(ctx, resourceGroup, namespaceName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -96,10 +97,10 @@ func resourceArmEventHubNamespaceAuthorizationRuleCreateUpdate(d *schema.Resourc } func resourceArmEventHubNamespaceAuthorizationRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).eventHubNamespacesClient + client := meta.(*ArmClient).eventhub.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -142,10 +143,10 @@ func resourceArmEventHubNamespaceAuthorizationRuleRead(d *schema.ResourceData, m } func resourceArmEventHubNamespaceAuthorizationRuleDelete(d *schema.ResourceData, meta interface{}) error { - eventhubClient := meta.(*ArmClient).eventHubNamespacesClient + eventhubClient := meta.(*ArmClient).eventhub.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_eventhub_namespace_authorization_rule_test.go b/azurerm/resource_arm_eventhub_namespace_authorization_rule_test.go index ee887f8d9af4..c800ce6dd9ba 100644 --- a/azurerm/resource_arm_eventhub_namespace_authorization_rule_test.go +++ b/azurerm/resource_arm_eventhub_namespace_authorization_rule_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -60,7 +61,7 @@ func testAccAzureRMEventHubNamespaceAuthorizationRule(t *testing.T, listen, send } func TestAccAzureRMEventHubNamespaceAuthorizationRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -131,7 +132,7 @@ func TestAccAzureRMEventHubNamespaceAuthorizationRule_rightsUpdate(t *testing.T) } func testCheckAzureRMEventHubNamespaceAuthorizationRuleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).eventHubNamespacesClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -169,7 +170,7 @@ func testCheckAzureRMEventHubNamespaceAuthorizationRuleExists(resourceName strin return fmt.Errorf("Bad: no resource group found in state for Event Hub: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).eventHubNamespacesClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.GetAuthorizationRule(ctx, resourceGroup, namespaceName, name) if err != nil { diff --git a/azurerm/resource_arm_eventhub_namespace_test.go b/azurerm/resource_arm_eventhub_namespace_test.go index b5a8cce01a9a..a730c9226f1c 100644 --- a/azurerm/resource_arm_eventhub_namespace_test.go +++ b/azurerm/resource_arm_eventhub_namespace_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMEventHubNamespace_basic(t *testing.T) { } func TestAccAzureRMEventHubNamespace_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -217,7 +218,7 @@ func TestAccAzureRMEventHubNamespace_BasicWithTagsUpdate(t *testing.T) { func TestAccAzureRMEventHubNamespace_BasicWithCapacity(t *testing.T) { resourceName := "azurerm_eventhub_namespace.test" ri := tf.AccRandTimeInt() - config := testAccAzureRMEventHubNamespace_capacity(ri, testLocation(), 100) + config := testAccAzureRMEventHubNamespace_capacity(ri, testLocation(), 20) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -228,7 +229,7 @@ func TestAccAzureRMEventHubNamespace_BasicWithCapacity(t *testing.T) { Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMEventHubNamespaceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "capacity", "100"), + resource.TestCheckResourceAttr(resourceName, "capacity", "20"), ), }, }, @@ -238,7 +239,7 @@ func TestAccAzureRMEventHubNamespace_BasicWithCapacity(t *testing.T) { func TestAccAzureRMEventHubNamespace_BasicWithCapacityUpdate(t *testing.T) { resourceName := "azurerm_eventhub_namespace.test" ri := tf.AccRandTimeInt() - preConfig := testAccAzureRMEventHubNamespace_capacity(ri, testLocation(), 100) + preConfig := testAccAzureRMEventHubNamespace_capacity(ri, testLocation(), 20) postConfig := testAccAzureRMEventHubNamespace_capacity(ri, testLocation(), 2) resource.ParallelTest(t, resource.TestCase{ @@ -250,7 +251,7 @@ func TestAccAzureRMEventHubNamespace_BasicWithCapacityUpdate(t *testing.T) { Config: preConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMEventHubNamespaceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "capacity", "100"), + resource.TestCheckResourceAttr(resourceName, "capacity", "20"), ), }, { @@ -311,7 +312,7 @@ func TestAccAzureRMEventHubNamespace_maximumThroughputUnitsUpdate(t *testing.T) testCheckAzureRMEventHubNamespaceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "sku", "Standard"), resource.TestCheckResourceAttr(resourceName, "capacity", "2"), - resource.TestCheckResourceAttr(resourceName, "maximum_throughput_units", "100"), + resource.TestCheckResourceAttr(resourceName, "maximum_throughput_units", "20"), ), }, { @@ -347,7 +348,7 @@ func TestAccAzureRMEventHubNamespace_autoInfalteDisabledWithAutoInflateUnits(t * } func testCheckAzureRMEventHubNamespaceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).eventHubNamespacesClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -384,7 +385,7 @@ func testCheckAzureRMEventHubNamespaceExists(resourceName string) resource.TestC return fmt.Errorf("Bad: no resource group found in state for Event Hub Namespace: %s", namespaceName) } - conn := testAccProvider.Meta().(*ArmClient).eventHubNamespacesClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, namespaceName) @@ -441,7 +442,7 @@ resource "azurerm_eventhub_namespace" "test" { name = "acctesteventhubnamespace-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - sku = "Basic" + sku = "Standard" kafka_enabled = true } `, rInt, location, rInt) @@ -494,7 +495,7 @@ resource "azurerm_eventhub_namespace" "test" { sku = "Standard" capacity = "2" auto_inflate_enabled = true - maximum_throughput_units = 100 + maximum_throughput_units = 20 } `, rInt, location, rInt) } diff --git a/azurerm/resource_arm_eventhub_test.go b/azurerm/resource_arm_eventhub_test.go index 2c281135fa7b..230a58dd1896 100644 --- a/azurerm/resource_arm_eventhub_test.go +++ b/azurerm/resource_arm_eventhub_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMEventHubPartitionCount_validation(t *testing.T) { @@ -19,9 +20,13 @@ func TestAccAzureRMEventHubPartitionCount_validation(t *testing.T) { ErrCount int }{ { - Value: 1, + Value: 0, ErrCount: 1, }, + { + Value: 1, + ErrCount: 0, + }, { Value: 2, ErrCount: 0, @@ -175,9 +180,34 @@ func TestAccAzureRMEventHub_basic(t *testing.T) { CheckDestroy: testCheckAzureRMEventHubDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMEventHub_basic(ri, testLocation()), + Config: testAccAzureRMEventHub_basic(ri, testLocation(), 2), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMEventHubExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMEventHub_basicOnePartition(t *testing.T) { + resourceName := "azurerm_eventhub.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMEventHubDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMEventHub_basic(ri, testLocation(), 1), Check: resource.ComposeTestCheckFunc( testCheckAzureRMEventHubExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "partition_count", "1"), ), }, { @@ -190,7 +220,7 @@ func TestAccAzureRMEventHub_basic(t *testing.T) { } func TestAccAzureRMEventHub_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -206,7 +236,7 @@ func TestAccAzureRMEventHub_requiresImport(t *testing.T) { CheckDestroy: testCheckAzureRMEventHubDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMEventHub_basic(ri, location), + Config: testAccAzureRMEventHub_basic(ri, location, 2), Check: resource.ComposeTestCheckFunc( testCheckAzureRMEventHubExists(resourceName), ), @@ -222,7 +252,7 @@ func TestAccAzureRMEventHub_requiresImport(t *testing.T) { func TestAccAzureRMEventHub_partitionCountUpdate(t *testing.T) { resourceName := "azurerm_eventhub.test" ri := tf.AccRandTimeInt() - preConfig := testAccAzureRMEventHub_basic(ri, testLocation()) + preConfig := testAccAzureRMEventHub_basic(ri, testLocation(), 2) postConfig := testAccAzureRMEventHub_partitionCountUpdate(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ @@ -287,6 +317,7 @@ func TestAccAzureRMEventHub_captureDescription(t *testing.T) { Check: resource.ComposeTestCheckFunc( testCheckAzureRMEventHubExists(resourceName), resource.TestCheckResourceAttr(resourceName, "capture_description.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "capture_description.0.skip_empty_archives", "true"), ), }, { @@ -360,7 +391,7 @@ func TestAccAzureRMEventHub_messageRetentionUpdate(t *testing.T) { } func testCheckAzureRMEventHubDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).eventHubClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.EventHubsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -401,7 +432,7 @@ func testCheckAzureRMEventHubExists(resourceName string) resource.TestCheckFunc return fmt.Errorf("Bad: no resource group found in state for Event Hub: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).eventHubClient + conn := testAccProvider.Meta().(*ArmClient).eventhub.EventHubsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, namespaceName, name) @@ -417,7 +448,7 @@ func testCheckAzureRMEventHubExists(resourceName string) resource.TestCheckFunc } } -func testAccAzureRMEventHub_basic(rInt int, location string) string { +func testAccAzureRMEventHub_basic(rInt int, location string, partitionCount int) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -435,14 +466,14 @@ resource "azurerm_eventhub" "test" { name = "acctesteventhub-%d" namespace_name = "${azurerm_eventhub_namespace.test.name}" resource_group_name = "${azurerm_resource_group.test.name}" - partition_count = 2 + partition_count = %d message_retention = 1 } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt, rInt, partitionCount) } func testAccAzureRMEventHub_requiresImport(rInt int, location string) string { - template := testAccAzureRMEventHub_basic(rInt, location) + template := testAccAzureRMEventHub_basic(rInt, location, 2) return fmt.Sprintf(` %s @@ -546,6 +577,7 @@ resource "azurerm_eventhub" "test" { encoding = "Avro" interval_in_seconds = 60 size_limit_in_bytes = 10485760 + skip_empty_archives = true destination { name = "EventHubArchive.AzureBlockBlob" diff --git a/azurerm/resource_arm_express_route_circuit.go b/azurerm/resource_arm_express_route_circuit.go index 3759e292cea3..e4656b80a9b8 100644 --- a/azurerm/resource_arm_express_route_circuit.go +++ b/azurerm/resource_arm_express_route_circuit.go @@ -4,10 +4,15 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,22 +35,22 @@ func resourceArmExpressRouteCircuit() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "service_provider_name": { Type: schema.TypeString, Required: true, ForceNew: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "peering_location": { Type: schema.TypeString, Required: true, ForceNew: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "bandwidth_in_mbps": { @@ -66,7 +71,7 @@ func resourceArmExpressRouteCircuit() *schema.Resource { string(network.ExpressRouteCircuitSkuTierStandard), string(network.ExpressRouteCircuitSkuTierPremium), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "family": { @@ -76,7 +81,7 @@ func resourceArmExpressRouteCircuit() *schema.Resource { string(network.MeteredData), string(network.UnlimitedData), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, }, @@ -99,13 +104,13 @@ func resourceArmExpressRouteCircuit() *schema.Resource { Sensitive: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmExpressRouteCircuitCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).expressRouteCircuitClient + client := meta.(*ArmClient).network.ExpressRouteCircuitsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ARM ExpressRoute Circuit creation.") @@ -113,7 +118,10 @@ func resourceArmExpressRouteCircuitCreateUpdate(d *schema.ResourceData, meta int name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + locks.ByName(name, expressRouteCircuitResourceName) + defer locks.UnlockByName(name, expressRouteCircuitResourceName) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -126,33 +134,62 @@ func resourceArmExpressRouteCircuitCreateUpdate(d *schema.ResourceData, meta int } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) serviceProviderName := d.Get("service_provider_name").(string) peeringLocation := d.Get("peering_location").(string) bandwidthInMbps := int32(d.Get("bandwidth_in_mbps").(int)) sku := expandExpressRouteCircuitSku(d) allowRdfeOps := d.Get("allow_classic_operations").(bool) - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) - - erc := network.ExpressRouteCircuit{ - Name: &name, - Location: &location, - Sku: sku, - ExpressRouteCircuitPropertiesFormat: &network.ExpressRouteCircuitPropertiesFormat{ + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) + + // There is the potential for the express route circuit to become out of sync when the service provider updates + // the express route circuit. We'll get and update the resource in place as per https://aka.ms/erRefresh + // We also want to keep track of the resource obtained from the api and pass down any attributes not + // managed by Terraform. + erc := network.ExpressRouteCircuit{} + if !d.IsNewResource() { + existing, err := client.Get(ctx, resGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(erc.Response) { + return fmt.Errorf("Error checking for presence of existing ExpressRoute Circuit %q (Resource Group %q): %s", name, resGroup, err) + } + } + + future, err := client.CreateOrUpdate(ctx, resGroup, name, existing) + if err != nil { + return fmt.Errorf("Error Creating/Updating ExpressRouteCircuit %q (Resource Group %q): %+v", name, resGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error Creating/Updating ExpressRouteCircuit %q (Resource Group %q): %+v", name, resGroup, err) + } + erc = existing + } + + erc.Name = &name + erc.Location = &location + erc.Sku = sku + erc.Tags = expandedTags + + if erc.ExpressRouteCircuitPropertiesFormat != nil { + erc.ExpressRouteCircuitPropertiesFormat.AllowClassicOperations = &allowRdfeOps + if erc.ExpressRouteCircuitPropertiesFormat.ServiceProviderProperties != nil { + erc.ExpressRouteCircuitPropertiesFormat.ServiceProviderProperties.ServiceProviderName = &serviceProviderName + erc.ExpressRouteCircuitPropertiesFormat.ServiceProviderProperties.PeeringLocation = &peeringLocation + erc.ExpressRouteCircuitPropertiesFormat.ServiceProviderProperties.BandwidthInMbps = &bandwidthInMbps + } + } else { + erc.ExpressRouteCircuitPropertiesFormat = &network.ExpressRouteCircuitPropertiesFormat{ AllowClassicOperations: &allowRdfeOps, ServiceProviderProperties: &network.ExpressRouteCircuitServiceProviderProperties{ ServiceProviderName: &serviceProviderName, PeeringLocation: &peeringLocation, BandwidthInMbps: &bandwidthInMbps, }, - }, - Tags: expandedTags, + } } - azureRMLockByName(name, expressRouteCircuitResourceName) - defer azureRMUnlockByName(name, expressRouteCircuitResourceName) - future, err := client.CreateOrUpdate(ctx, resGroup, name, erc) if err != nil { return fmt.Errorf("Error Creating/Updating ExpressRouteCircuit %q (Resource Group %q): %+v", name, resGroup, err) @@ -176,21 +213,32 @@ func resourceArmExpressRouteCircuitCreateUpdate(d *schema.ResourceData, meta int } func resourceArmExpressRouteCircuitRead(d *schema.ResourceData, meta interface{}) error { - resp, resourceGroup, err := retrieveErcByResourceId(d.Id(), meta) + ercClient := meta.(*ArmClient).network.ExpressRouteCircuitsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { - return err + return fmt.Errorf("Error Parsing Azure Resource ID -: %+v", err) } - if resp == nil { - log.Printf("[INFO] Express Route Circuit %q not found. Removing from state", d.Get("name").(string)) - d.SetId("") - return nil + resourceGroup := id.ResourceGroup + name := id.Path["expressRouteCircuits"] + + resp, err := ercClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Express Route Circuit %q (Resource Group %q) was not found - removing from state", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Express Route Circuit %q (Resource Group %q): %+v", name, resourceGroup, err) } d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if resp.Sku != nil { @@ -210,22 +258,23 @@ func resourceArmExpressRouteCircuitRead(d *schema.ResourceData, meta interface{} d.Set("service_key", resp.ServiceKey) d.Set("allow_classic_operations", resp.AllowClassicOperations) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmExpressRouteCircuitDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).expressRouteCircuitClient + client := meta.(*ArmClient).network.ExpressRouteCircuitsClient ctx := meta.(*ArmClient).StopContext - resourceGroup, name, err := extractResourceGroupAndErcName(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { - return fmt.Errorf("Error Parsing Azure Resource ID: %+v", err) + return fmt.Errorf("Error Parsing Azure Resource ID -: %+v", err) } - azureRMLockByName(name, expressRouteCircuitResourceName) - defer azureRMUnlockByName(name, expressRouteCircuitResourceName) + resourceGroup := id.ResourceGroup + name := id.Path["expressRouteCircuits"] + + locks.ByName(name, expressRouteCircuitResourceName) + defer locks.UnlockByName(name, expressRouteCircuitResourceName) future, err := client.Delete(ctx, resourceGroup, name) if err != nil { diff --git a/azurerm/resource_arm_express_route_circuit_authorization.go b/azurerm/resource_arm_express_route_circuit_authorization.go index 7cffbe27d015..cd623bef2bc7 100644 --- a/azurerm/resource_arm_express_route_circuit_authorization.go +++ b/azurerm/resource_arm_express_route_circuit_authorization.go @@ -3,10 +3,13 @@ package azurerm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -26,7 +29,7 @@ func resourceArmExpressRouteCircuitAuthorization() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "express_route_circuit_name": { Type: schema.TypeString, @@ -49,14 +52,17 @@ func resourceArmExpressRouteCircuitAuthorization() *schema.Resource { } func resourceArmExpressRouteCircuitAuthorizationCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).expressRouteAuthsClient + client := meta.(*ArmClient).network.ExpressRouteAuthsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) circuitName := d.Get("express_route_circuit_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + locks.ByName(circuitName, expressRouteCircuitResourceName) + defer locks.UnlockByName(circuitName, expressRouteCircuitResourceName) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, circuitName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -73,9 +79,6 @@ func resourceArmExpressRouteCircuitAuthorizationCreate(d *schema.ResourceData, m AuthorizationPropertiesFormat: &network.AuthorizationPropertiesFormat{}, } - azureRMLockByName(circuitName, expressRouteCircuitResourceName) - defer azureRMUnlockByName(circuitName, expressRouteCircuitResourceName) - future, err := client.CreateOrUpdate(ctx, resourceGroup, circuitName, name, properties) if err != nil { return fmt.Errorf("Error Creating/Updating Express Route Circuit Authorization %q (Circuit %q / Resource Group %q): %+v", name, circuitName, resourceGroup, err) @@ -96,10 +99,10 @@ func resourceArmExpressRouteCircuitAuthorizationCreate(d *schema.ResourceData, m } func resourceArmExpressRouteCircuitAuthorizationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).expressRouteAuthsClient + client := meta.(*ArmClient).network.ExpressRouteAuthsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -130,10 +133,10 @@ func resourceArmExpressRouteCircuitAuthorizationRead(d *schema.ResourceData, met } func resourceArmExpressRouteCircuitAuthorizationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).expressRouteAuthsClient + client := meta.(*ArmClient).network.ExpressRouteAuthsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -142,8 +145,8 @@ func resourceArmExpressRouteCircuitAuthorizationDelete(d *schema.ResourceData, m circuitName := id.Path["expressRouteCircuits"] name := id.Path["authorizations"] - azureRMLockByName(circuitName, expressRouteCircuitResourceName) - defer azureRMUnlockByName(circuitName, expressRouteCircuitResourceName) + locks.ByName(circuitName, expressRouteCircuitResourceName) + defer locks.UnlockByName(circuitName, expressRouteCircuitResourceName) future, err := client.Delete(ctx, resourceGroup, circuitName, name) if err != nil { diff --git a/azurerm/resource_arm_express_route_circuit_authorization_test.go b/azurerm/resource_arm_express_route_circuit_authorization_test.go index 2c5f24dac49f..1af4768e440c 100644 --- a/azurerm/resource_arm_express_route_circuit_authorization_test.go +++ b/azurerm/resource_arm_express_route_circuit_authorization_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func testAccAzureRMExpressRouteCircuitAuthorization_basic(t *testing.T) { } func testAccAzureRMExpressRouteCircuitAuthorization_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -104,7 +105,7 @@ func testCheckAzureRMExpressRouteCircuitAuthorizationExists(resourceName string) return fmt.Errorf("Bad: no resource group found in state for Express Route Circuit Authorization: %s", expressRouteCircuitName) } - client := testAccProvider.Meta().(*ArmClient).expressRouteAuthsClient + client := testAccProvider.Meta().(*ArmClient).network.ExpressRouteAuthsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, expressRouteCircuitName, authorizationName) @@ -121,7 +122,7 @@ func testCheckAzureRMExpressRouteCircuitAuthorizationExists(resourceName string) } func testCheckAzureRMExpressRouteCircuitAuthorizationDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).expressRouteAuthsClient + client := testAccProvider.Meta().(*ArmClient).network.ExpressRouteAuthsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_express_route_circuit_peering.go b/azurerm/resource_arm_express_route_circuit_peering.go index 52e5c3af1ace..a77336a4e352 100644 --- a/azurerm/resource_arm_express_route_circuit_peering.go +++ b/azurerm/resource_arm_express_route_circuit_peering.go @@ -5,11 +5,14 @@ import ( "log" "strings" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -41,7 +44,7 @@ func resourceArmExpressRouteCircuitPeering() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "primary_peer_address_prefix": { Type: schema.TypeString, @@ -105,7 +108,7 @@ func resourceArmExpressRouteCircuitPeering() *schema.Resource { } func resourceArmExpressRouteCircuitPeeringCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).expressRoutePeeringsClient + client := meta.(*ArmClient).network.ExpressRoutePeeringsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Express Route Peering create/update.") @@ -114,7 +117,10 @@ func resourceArmExpressRouteCircuitPeeringCreateUpdate(d *schema.ResourceData, m circuitName := d.Get("express_route_circuit_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + locks.ByName(circuitName, expressRouteCircuitResourceName) + defer locks.UnlockByName(circuitName, expressRouteCircuitResourceName) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, circuitName, peeringType) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -156,9 +162,6 @@ func resourceArmExpressRouteCircuitPeeringCreateUpdate(d *schema.ResourceData, m parameters.ExpressRouteCircuitPeeringPropertiesFormat.MicrosoftPeeringConfig = peeringConfig } - azureRMLockByName(circuitName, expressRouteCircuitResourceName) - defer azureRMUnlockByName(circuitName, expressRouteCircuitResourceName) - future, err := client.CreateOrUpdate(ctx, resourceGroup, circuitName, peeringType, parameters) if err != nil { return err @@ -179,10 +182,10 @@ func resourceArmExpressRouteCircuitPeeringCreateUpdate(d *schema.ResourceData, m } func resourceArmExpressRouteCircuitPeeringRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).expressRoutePeeringsClient + client := meta.(*ArmClient).network.ExpressRoutePeeringsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -222,10 +225,10 @@ func resourceArmExpressRouteCircuitPeeringRead(d *schema.ResourceData, meta inte } func resourceArmExpressRouteCircuitPeeringDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).expressRoutePeeringsClient + client := meta.(*ArmClient).network.ExpressRoutePeeringsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -234,8 +237,8 @@ func resourceArmExpressRouteCircuitPeeringDelete(d *schema.ResourceData, meta in circuitName := id.Path["expressRouteCircuits"] peeringType := id.Path["peerings"] - azureRMLockByName(circuitName, expressRouteCircuitResourceName) - defer azureRMUnlockByName(circuitName, expressRouteCircuitResourceName) + locks.ByName(circuitName, expressRouteCircuitResourceName) + defer locks.UnlockByName(circuitName, expressRouteCircuitResourceName) future, err := client.Delete(ctx, resourceGroup, circuitName, peeringType) if err != nil { diff --git a/azurerm/resource_arm_express_route_circuit_peering_test.go b/azurerm/resource_arm_express_route_circuit_peering_test.go index e7b89e911c71..73648259cff7 100644 --- a/azurerm/resource_arm_express_route_circuit_peering_test.go +++ b/azurerm/resource_arm_express_route_circuit_peering_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,7 +41,7 @@ func testAccAzureRMExpressRouteCircuitPeering_azurePrivatePeering(t *testing.T) } func testAccAzureRMExpressRouteCircuitPeering_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -96,6 +97,42 @@ func testAccAzureRMExpressRouteCircuitPeering_microsoftPeering(t *testing.T) { }) } +func testAccAzureRMExpressRouteCircuitPeering_azurePrivatePeeringWithCircuitUpdate(t *testing.T) { + resourceName := "azurerm_express_route_circuit_peering.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMExpressRouteCircuitPeeringDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMExpressRouteCircuitPeering_privatePeering(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMExpressRouteCircuitPeeringExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "peering_type", "AzurePrivatePeering"), + resource.TestCheckResourceAttr(resourceName, "microsoft_peering_config.#", "0"), + ), + }, + { + Config: testAccAzureRMExpressRouteCircuitPeering_privatePeeringWithCircuitUpdate(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMExpressRouteCircuitPeeringExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "peering_type", "AzurePrivatePeering"), + resource.TestCheckResourceAttr(resourceName, "microsoft_peering_config.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"shared_key"}, //is not returned by the API + }, + }, + }) +} + func testCheckAzureRMExpressRouteCircuitPeeringExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] @@ -110,7 +147,7 @@ func testCheckAzureRMExpressRouteCircuitPeeringExists(resourceName string) resou return fmt.Errorf("Bad: no resource group found in state for Express Route Circuit Peering: %s", peeringType) } - client := testAccProvider.Meta().(*ArmClient).expressRoutePeeringsClient + client := testAccProvider.Meta().(*ArmClient).network.ExpressRoutePeeringsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, circuitName, peeringType) @@ -127,7 +164,7 @@ func testCheckAzureRMExpressRouteCircuitPeeringExists(resourceName string) resou } func testCheckAzureRMExpressRouteCircuitPeeringDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).expressRoutePeeringsClient + client := testAccProvider.Meta().(*ArmClient).network.ExpressRoutePeeringsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -183,7 +220,7 @@ resource "azurerm_express_route_circuit_peering" "test" { peering_type = "AzurePrivatePeering" express_route_circuit_name = "${azurerm_express_route_circuit.test.name}" resource_group_name = "${azurerm_resource_group.test.name}" - shared_key = "ABCdefGHIJklm@nOPqrsTU!!" + shared_key = "SSSSsssssshhhhhItsASecret" peer_asn = 100 primary_peer_address_prefix = "192.168.1.0/30" secondary_peer_address_prefix = "192.168.2.0/30" @@ -251,3 +288,42 @@ resource "azurerm_express_route_circuit_peering" "test" { } `, rInt, location, rInt) } + +func testAccAzureRMExpressRouteCircuitPeering_privatePeeringWithCircuitUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_express_route_circuit" "test" { + name = "acctest-erc-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + service_provider_name = "Equinix" + peering_location = "Silicon Valley" + bandwidth_in_mbps = 50 + + sku { + tier = "Standard" + family = "MeteredData" + } + + tags = { + Environment = "prod" + Purpose = "AcceptanceTests" + } +} + +resource "azurerm_express_route_circuit_peering" "test" { + peering_type = "AzurePrivatePeering" + express_route_circuit_name = "${azurerm_express_route_circuit.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + shared_key = "SSSSsssssshhhhhItsASecret" + peer_asn = 100 + primary_peer_address_prefix = "192.168.1.0/30" + secondary_peer_address_prefix = "192.168.2.0/30" + vlan_id = 100 +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_express_route_circuit_test.go b/azurerm/resource_arm_express_route_circuit_test.go index e6a43e03653c..632adaf70cee 100644 --- a/azurerm/resource_arm_express_route_circuit_test.go +++ b/azurerm/resource_arm_express_route_circuit_test.go @@ -5,10 +5,11 @@ import ( "net/http" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -25,10 +26,12 @@ func TestAccAzureRMExpressRouteCircuit(t *testing.T) { "premiumUnlimited": testAccAzureRMExpressRouteCircuit_premiumUnlimited, "allowClassicOperationsUpdate": testAccAzureRMExpressRouteCircuit_allowClassicOperationsUpdate, "requiresImport": testAccAzureRMExpressRouteCircuit_requiresImport, + "data_basic": testAccDataSourceAzureRMExpressRoute_basicMetered, }, "PrivatePeering": { - "azurePrivatePeering": testAccAzureRMExpressRouteCircuitPeering_azurePrivatePeering, - "requiresImport": testAccAzureRMExpressRouteCircuitPeering_requiresImport, + "azurePrivatePeering": testAccAzureRMExpressRouteCircuitPeering_azurePrivatePeering, + "azurePrivatePeeringWithUpdate": testAccAzureRMExpressRouteCircuitPeering_azurePrivatePeeringWithCircuitUpdate, + "requiresImport": testAccAzureRMExpressRouteCircuitPeering_requiresImport, }, "MicrosoftPeering": { "microsoftPeering": testAccAzureRMExpressRouteCircuitPeering_microsoftPeering, @@ -79,7 +82,7 @@ func testAccAzureRMExpressRouteCircuit_basicMetered(t *testing.T) { } func testAccAzureRMExpressRouteCircuit_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -285,7 +288,7 @@ func testCheckAzureRMExpressRouteCircuitExists(resourceName string, erc *network return fmt.Errorf("Bad: no resource group found in state for Express Route Circuit: %s", expressRouteCircuitName) } - client := testAccProvider.Meta().(*ArmClient).expressRouteCircuitClient + client := testAccProvider.Meta().(*ArmClient).network.ExpressRouteCircuitsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, expressRouteCircuitName) @@ -304,7 +307,7 @@ func testCheckAzureRMExpressRouteCircuitExists(resourceName string, erc *network } func testCheckAzureRMExpressRouteCircuitDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).expressRouteCircuitClient + client := testAccProvider.Meta().(*ArmClient).network.ExpressRouteCircuitsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_firewall.go b/azurerm/resource_arm_firewall.go index 2ae9fc37a087..b4022de4d0ba 100644 --- a/azurerm/resource_arm_firewall.go +++ b/azurerm/resource_arm_firewall.go @@ -5,11 +5,14 @@ import ( "log" "regexp" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -33,9 +36,9 @@ func resourceArmFirewall() *schema.Resource { ValidateFunc: validateAzureFirewallName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "ip_configuration": { Type: schema.TypeList, @@ -51,7 +54,8 @@ func resourceArmFirewall() *schema.Resource { "subnet_id": { Type: schema.TypeString, Required: true, - ValidateFunc: azure.ValidateResourceID, + ForceNew: true, + ValidateFunc: validateAzureFirewallSubnetName, }, "internal_public_ip_address_id": { Type: schema.TypeString, @@ -76,13 +80,13 @@ func resourceArmFirewall() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmFirewallCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Azure Firewall creation") @@ -90,7 +94,7 @@ func resourceArmFirewallCreateUpdate(d *schema.ResourceData, meta interface{}) e name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -103,25 +107,25 @@ func resourceArmFirewallCreateUpdate(d *schema.ResourceData, meta interface{}) e } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) ipConfigs, subnetToLock, vnetToLock, err := expandArmFirewallIPConfigurations(d) if err != nil { return fmt.Errorf("Error Building list of Azure Firewall IP Configurations: %+v", err) } - azureRMLockByName(name, azureFirewallResourceName) - defer azureRMUnlockByName(name, azureFirewallResourceName) + locks.ByName(name, azureFirewallResourceName) + defer locks.UnlockByName(name, azureFirewallResourceName) - azureRMLockMultipleByName(subnetToLock, subnetResourceName) - defer azureRMUnlockMultipleByName(subnetToLock, subnetResourceName) + locks.MultipleByName(subnetToLock, subnetResourceName) + defer locks.UnlockMultipleByName(subnetToLock, subnetResourceName) - azureRMLockMultipleByName(vnetToLock, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(vnetToLock, virtualNetworkResourceName) + locks.MultipleByName(vnetToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(vnetToLock, virtualNetworkResourceName) parameters := network.AzureFirewall{ Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), AzureFirewallPropertiesFormat: &network.AzureFirewallPropertiesFormat{ IPConfigurations: ipConfigs, }, @@ -168,10 +172,10 @@ func resourceArmFirewallCreateUpdate(d *schema.ResourceData, meta interface{}) e } func resourceArmFirewallRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -192,7 +196,7 @@ func resourceArmFirewallRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", read.Name) d.Set("resource_group_name", resourceGroup) if location := read.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := read.AzureFirewallPropertiesFormat; props != nil { @@ -202,16 +206,14 @@ func resourceArmFirewallRead(d *schema.ResourceData, meta interface{}) error { } } - flattenAndSetTags(d, read.Tags) - - return nil + return tags.FlattenAndSet(d, read.Tags) } func resourceArmFirewallDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -238,7 +240,7 @@ func resourceArmFirewallDelete(d *schema.ResourceData, meta interface{}) error { continue } - parsedSubnetId, err2 := parseAzureResourceID(*config.Subnet.ID) + parsedSubnetId, err2 := azure.ParseAzureResourceID(*config.Subnet.ID) if err2 != nil { return err2 } @@ -256,14 +258,14 @@ func resourceArmFirewallDelete(d *schema.ResourceData, meta interface{}) error { } } - azureRMLockByName(name, azureFirewallResourceName) - defer azureRMUnlockByName(name, azureFirewallResourceName) + locks.ByName(name, azureFirewallResourceName) + defer locks.UnlockByName(name, azureFirewallResourceName) - azureRMLockMultipleByName(&subnetNamesToLock, subnetResourceName) - defer azureRMUnlockMultipleByName(&subnetNamesToLock, subnetResourceName) + locks.MultipleByName(&subnetNamesToLock, subnetResourceName) + defer locks.UnlockMultipleByName(&subnetNamesToLock, subnetResourceName) - azureRMLockMultipleByName(&virtualNetworkNamesToLock, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(&virtualNetworkNamesToLock, virtualNetworkResourceName) + locks.MultipleByName(&virtualNetworkNamesToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(&virtualNetworkNamesToLock, virtualNetworkResourceName) future, err := client.Delete(ctx, resourceGroup, name) if err != nil { @@ -297,7 +299,7 @@ func expandArmFirewallIPConfigurations(d *schema.ResourceData) (*[]network.Azure return nil, nil, nil, fmt.Errorf("one of `ip_configuration.0.internal_public_ip_address_id` or `ip_configuration.0.public_ip_address_id` must be set") } - subnetID, err := parseAzureResourceID(subnetId) + subnetID, err := azure.ParseAzureResourceID(subnetId) if err != nil { return nil, nil, nil, err } @@ -379,3 +381,18 @@ func validateAzureFirewallName(v interface{}, k string) (warnings []string, erro return warnings, errors } + +func validateAzureFirewallSubnetName(v interface{}, k string) (warnings []string, errors []error) { + parsed, err := azure.ParseAzureResourceID(v.(string)) + if err != nil { + errors = append(errors, fmt.Errorf("Error parsing Azure Resource ID %q", v.(string))) + return warnings, errors + } + subnetName := parsed.Path["subnets"] + if subnetName != "AzureFirewallSubnet" { + errors = append(errors, fmt.Errorf("The name of the Subnet for %q must be exactly 'AzureFirewallSubnet' to be used for the Azure Firewall resource", k)) + + } + + return warnings, errors +} diff --git a/azurerm/resource_arm_firewall_application_rule_collection.go b/azurerm/resource_arm_firewall_application_rule_collection.go index bb04e181e08e..36427fdf379c 100644 --- a/azurerm/resource_arm_firewall_application_rule_collection.go +++ b/azurerm/resource_arm_firewall_application_rule_collection.go @@ -4,10 +4,13 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" @@ -39,7 +42,7 @@ func resourceArmFirewallApplicationRuleCollection() *schema.Resource { ValidateFunc: validateAzureFirewallName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "priority": { Type: schema.TypeInt, @@ -119,7 +122,7 @@ func resourceArmFirewallApplicationRuleCollection() *schema.Resource { } func resourceArmFirewallApplicationRuleCollectionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -130,8 +133,8 @@ func resourceArmFirewallApplicationRuleCollectionCreateUpdate(d *schema.Resource return fmt.Errorf("Error expanding Firewall Application Rules: %+v", err) } - azureRMLockByName(firewallName, azureFirewallResourceName) - defer azureRMUnlockByName(firewallName, azureFirewallResourceName) + locks.ByName(firewallName, azureFirewallResourceName) + defer locks.UnlockByName(firewallName, azureFirewallResourceName) firewall, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { @@ -181,7 +184,7 @@ func resourceArmFirewallApplicationRuleCollectionCreateUpdate(d *schema.Resource ruleCollections[index] = newRuleCollection } else { - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { if index != -1 { return tf.ImportAsExistsError("azurerm_firewall_application_rule_collection", id) } @@ -231,10 +234,10 @@ func resourceArmFirewallApplicationRuleCollectionCreateUpdate(d *schema.Resource } func resourceArmFirewallApplicationRuleCollectionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -303,10 +306,10 @@ func resourceArmFirewallApplicationRuleCollectionRead(d *schema.ResourceData, me } func resourceArmFirewallApplicationRuleCollectionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -315,8 +318,8 @@ func resourceArmFirewallApplicationRuleCollectionDelete(d *schema.ResourceData, firewallName := id.Path["azureFirewalls"] name := id.Path["applicationRuleCollections"] - azureRMLockByName(firewallName, azureFirewallResourceName) - defer azureRMUnlockByName(firewallName, azureFirewallResourceName) + locks.ByName(firewallName, azureFirewallResourceName) + defer locks.UnlockByName(firewallName, azureFirewallResourceName) firewall, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { @@ -375,9 +378,9 @@ func expandArmFirewallApplicationRules(inputs []interface{}) ([]network.AzureFir output := network.AzureFirewallApplicationRule{ Name: utils.String(ruleName), Description: utils.String(ruleDescription), - SourceAddresses: utils.ExpandStringArray(ruleSourceAddresses), - FqdnTags: utils.ExpandStringArray(ruleFqdnTags), - TargetFqdns: utils.ExpandStringArray(ruleTargetFqdns), + SourceAddresses: utils.ExpandStringSlice(ruleSourceAddresses), + FqdnTags: utils.ExpandStringSlice(ruleFqdnTags), + TargetFqdns: utils.ExpandStringSlice(ruleTargetFqdns), } ruleProtocols := make([]network.AzureFirewallApplicationRuleProtocol, 0) diff --git a/azurerm/resource_arm_firewall_application_rule_collection_test.go b/azurerm/resource_arm_firewall_application_rule_collection_test.go index 61018058e75c..a8d836ff84a4 100644 --- a/azurerm/resource_arm_firewall_application_rule_collection_test.go +++ b/azurerm/resource_arm_firewall_application_rule_collection_test.go @@ -5,8 +5,9 @@ import ( "testing" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) @@ -48,7 +49,7 @@ func TestAccAzureRMFirewallApplicationRuleCollection_basic(t *testing.T) { } func TestAccAzureRMFirewallApplicationRuleCollection_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -428,7 +429,7 @@ func testCheckAzureRMFirewallApplicationRuleCollectionExists(resourceName string firewallName := rs.Primary.Attributes["azure_firewall_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { @@ -462,7 +463,7 @@ func testCheckAzureRMFirewallApplicationRuleCollectionDoesNotExist(resourceName firewallName := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { @@ -491,7 +492,7 @@ func testCheckAzureRMFirewallApplicationRuleCollectionDisappears(resourceName st firewallName := rs.Primary.Attributes["azure_firewall_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { @@ -843,6 +844,7 @@ resource "azurerm_firewall_application_rule_collection" "test" { port = 9000 type = "Https" } + protocol { port = 9001 type = "Http" diff --git a/azurerm/resource_arm_firewall_nat_rule_collection.go b/azurerm/resource_arm_firewall_nat_rule_collection.go new file mode 100644 index 000000000000..62ada1504571 --- /dev/null +++ b/azurerm/resource_arm_firewall_nat_rule_collection.go @@ -0,0 +1,453 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmFirewallNatRuleCollection() *schema.Resource { + return &schema.Resource{ + Create: resourceArmFirewallNatRuleCollectionCreateUpdate, + Read: resourceArmFirewallNatRuleCollectionRead, + Update: resourceArmFirewallNatRuleCollectionCreateUpdate, + Delete: resourceArmFirewallNatRuleCollectionDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureFirewallName, + }, + + "azure_firewall_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureFirewallName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "priority": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(100, 65000), + }, + + "action": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.Dnat), + string(network.Snat), + }, false), + }, + + "rule": { + Type: schema.TypeSet, + Required: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "translated_address": { + Type: schema.TypeString, + Required: true, + }, + "translated_port": { + Type: schema.TypeString, + Required: true, + }, + "source_addresses": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "destination_addresses": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "destination_ports": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "protocols": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(network.Any), + string(network.ICMP), + string(network.TCP), + string(network.UDP), + }, false), + }, + Set: schema.HashString, + }, + }, + }, + }, + }, + } +} + +func resourceArmFirewallNatRuleCollectionCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.AzureFirewallsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + firewallName := d.Get("azure_firewall_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + locks.ByName(firewallName, azureFirewallResourceName) + defer locks.UnlockByName(firewallName, azureFirewallResourceName) + + firewall, err := client.Get(ctx, resourceGroup, firewallName) + if err != nil { + return fmt.Errorf("Error retrieving Firewall %q (Resource Group %q): %+v", firewallName, resourceGroup, err) + } + + if firewall.AzureFirewallPropertiesFormat == nil { + return fmt.Errorf("Error expanding Firewall %q (Resource Group %q): `properties` was nil.", firewallName, resourceGroup) + } + props := *firewall.AzureFirewallPropertiesFormat + + if props.NatRuleCollections == nil { + return fmt.Errorf("Error expanding Firewall %q (Resource Group %q): `properties.NatRuleCollections` was nil.", firewallName, resourceGroup) + } + + ruleCollections := *props.NatRuleCollections + natRules := expandArmFirewallNatRules(d.Get("rule").(*schema.Set)) + priority := d.Get("priority").(int) + newRuleCollection := network.AzureFirewallNatRuleCollection{ + Name: utils.String(name), + AzureFirewallNatRuleCollectionProperties: &network.AzureFirewallNatRuleCollectionProperties{ + Action: &network.AzureFirewallNatRCAction{ + Type: network.AzureFirewallNatRCActionType(d.Get("action").(string)), + }, + Priority: utils.Int32(int32(priority)), + Rules: &natRules, + }, + } + + index := -1 + var id string + // determine if this already exists + for i, v := range ruleCollections { + if v.Name == nil || v.ID == nil { + continue + } + + if *v.Name == name { + index = i + id = *v.ID + break + } + } + + if !d.IsNewResource() { + if index == -1 { + return fmt.Errorf("Error locating NAT Rule Collection %q (Firewall %q / Resource Group %q)", name, firewallName, resourceGroup) + } + + ruleCollections[index] = newRuleCollection + } else { + if features.ShouldResourcesBeImported() && d.IsNewResource() { + if index != -1 { + return tf.ImportAsExistsError("azurerm_firewall_nat_rule_collection", id) + } + } + + // first double check it doesn't already exist + ruleCollections = append(ruleCollections, newRuleCollection) + } + + firewall.AzureFirewallPropertiesFormat.NatRuleCollections = &ruleCollections + future, err := client.CreateOrUpdate(ctx, resourceGroup, firewallName, firewall) + if err != nil { + return fmt.Errorf("Error creating/updating NAT Rule Collection %q in Firewall %q (Resource Group %q): %+v", name, firewallName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation/update of NAT Rule Collection %q of Firewall %q (Resource Group %q): %+v", name, firewallName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, firewallName) + if err != nil { + return fmt.Errorf("Error retrieving Firewall %q (Resource Group %q): %+v", firewallName, resourceGroup, err) + } + + var collectionID string + if props := read.AzureFirewallPropertiesFormat; props != nil { + if collections := props.NatRuleCollections; collections != nil { + for _, collection := range *collections { + if collection.Name == nil { + continue + } + + if *collection.Name == name { + collectionID = *collection.ID + break + } + } + } + } + + if collectionID == "" { + return fmt.Errorf("Cannot find ID for NAT Rule Collection %q (Azure Firewall %q / Resource Group %q)", name, firewallName, resourceGroup) + } + d.SetId(collectionID) + + return resourceArmFirewallNatRuleCollectionRead(d, meta) +} + +func resourceArmFirewallNatRuleCollectionRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.AzureFirewallsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + firewallName := id.Path["azureFirewalls"] + name := id.Path["natRuleCollections"] + + read, err := client.Get(ctx, resourceGroup, firewallName) + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] Azure Firewall %q (Resource Group %q) was not found - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error retrieving Azure Firewall %q (Resource Group %q): %+v", name, resourceGroup, err) + } + if read.AzureFirewallPropertiesFormat == nil { + return fmt.Errorf("Error retrieving NAT Rule Collection %q (Firewall %q / Resource Group %q): `props` was nil", name, firewallName, resourceGroup) + } + + props := *read.AzureFirewallPropertiesFormat + + if props.NatRuleCollections == nil { + return fmt.Errorf("Error retrieving NAT Rule Collection %q (Firewall %q / Resource Group %q): `props.NetworkRuleCollections` was nil", name, firewallName, resourceGroup) + } + + var rule *network.AzureFirewallNatRuleCollection + for _, r := range *props.NatRuleCollections { + if r.Name == nil { + continue + } + + if *r.Name == name { + rule = &r + break + } + } + + if rule == nil { + log.Printf("[DEBUG] NAT Rule Collection %q was not found on Firewall %q (Resource Group %q) - removing from state!", name, firewallName, resourceGroup) + d.SetId("") + return nil + } + + d.Set("name", rule.Name) + d.Set("azure_firewall_name", firewallName) + d.Set("resource_group_name", resourceGroup) + + if props := rule.AzureFirewallNatRuleCollectionProperties; props != nil { + if action := props.Action; action != nil { + d.Set("action", string(action.Type)) + } + + if priority := props.Priority; priority != nil { + d.Set("priority", int(*priority)) + } + + flattenedRules := flattenFirewallNatRuleCollectionRules(props.Rules) + if err := d.Set("rule", flattenedRules); err != nil { + return fmt.Errorf("Error setting `rule`: %+v", err) + } + } + + return nil +} + +func resourceArmFirewallNatRuleCollectionDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.AzureFirewallsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + firewallName := id.Path["azureFirewalls"] + name := id.Path["natRuleCollections"] + + locks.ByName(firewallName, azureFirewallResourceName) + defer locks.UnlockByName(firewallName, azureFirewallResourceName) + + firewall, err := client.Get(ctx, resourceGroup, firewallName) + if err != nil { + if utils.ResponseWasNotFound(firewall.Response) { + // assume deleted + return nil + } + + return fmt.Errorf("Error making Read request on Azure Firewall %q (Resource Group %q): %+v", firewallName, resourceGroup, err) + } + + props := firewall.AzureFirewallPropertiesFormat + if props == nil { + return fmt.Errorf("Error retrieving NAT Rule Collection %q (Firewall %q / Resource Group %q): `props` was nil", name, firewallName, resourceGroup) + } + if props.NetworkRuleCollections == nil { + return fmt.Errorf("Error retrieving NAT Rule Collection %q (Firewall %q / Resource Group %q): `props.NatRuleCollections` was nil", name, firewallName, resourceGroup) + } + + natRules := make([]network.AzureFirewallNatRuleCollection, 0) + for _, rule := range *props.NatRuleCollections { + if rule.Name == nil { + continue + } + + if *rule.Name != name { + natRules = append(natRules, rule) + } + } + props.NatRuleCollections = &natRules + + future, err := client.CreateOrUpdate(ctx, resourceGroup, firewallName, firewall) + if err != nil { + return fmt.Errorf("Error deleting NAT Rule Collection %q from Firewall %q (Resource Group %q): %+v", name, firewallName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of NAT Rule Collection %q from Firewall %q (Resource Group %q): %+v", name, firewallName, resourceGroup, err) + } + + return nil +} + +func expandArmFirewallNatRules(input *schema.Set) []network.AzureFirewallNatRule { + nwRules := input.List() + rules := make([]network.AzureFirewallNatRule, 0) + + for _, nwRule := range nwRules { + rule := nwRule.(map[string]interface{}) + + name := rule["name"].(string) + description := rule["description"].(string) + + sourceAddresses := make([]string, 0) + for _, v := range rule["source_addresses"].(*schema.Set).List() { + sourceAddresses = append(sourceAddresses, v.(string)) + } + + destinationAddresses := make([]string, 0) + for _, v := range rule["destination_addresses"].(*schema.Set).List() { + destinationAddresses = append(destinationAddresses, v.(string)) + } + + destinationPorts := make([]string, 0) + for _, v := range rule["destination_ports"].(*schema.Set).List() { + destinationPorts = append(destinationPorts, v.(string)) + } + + translatedAddress := rule["translated_address"].(string) + translatedPort := rule["translated_port"].(string) + + ruleToAdd := network.AzureFirewallNatRule{ + Name: utils.String(name), + Description: utils.String(description), + SourceAddresses: &sourceAddresses, + DestinationAddresses: &destinationAddresses, + DestinationPorts: &destinationPorts, + TranslatedAddress: &translatedAddress, + TranslatedPort: &translatedPort, + } + + nrProtocols := make([]network.AzureFirewallNetworkRuleProtocol, 0) + protocols := rule["protocols"].(*schema.Set) + for _, v := range protocols.List() { + s := network.AzureFirewallNetworkRuleProtocol(v.(string)) + nrProtocols = append(nrProtocols, s) + } + ruleToAdd.Protocols = &nrProtocols + rules = append(rules, ruleToAdd) + } + + return rules +} + +func flattenFirewallNatRuleCollectionRules(rules *[]network.AzureFirewallNatRule) []map[string]interface{} { + outputs := make([]map[string]interface{}, 0) + if rules == nil { + return outputs + } + + for _, rule := range *rules { + output := make(map[string]interface{}) + if rule.Name != nil { + output["name"] = *rule.Name + } + if rule.Description != nil { + output["description"] = *rule.Description + } + if rule.TranslatedAddress != nil { + output["translated_address"] = *rule.TranslatedAddress + } + if rule.TranslatedPort != nil { + output["translated_port"] = *rule.TranslatedPort + } + if rule.SourceAddresses != nil { + output["source_addresses"] = set.FromStringSlice(*rule.SourceAddresses) + } + if rule.DestinationAddresses != nil { + output["destination_addresses"] = set.FromStringSlice(*rule.DestinationAddresses) + } + if rule.DestinationPorts != nil { + output["destination_ports"] = set.FromStringSlice(*rule.DestinationPorts) + } + protocols := make([]string, 0) + if rule.Protocols != nil { + for _, protocol := range *rule.Protocols { + protocols = append(protocols, string(protocol)) + } + } + output["protocols"] = set.FromStringSlice(protocols) + outputs = append(outputs, output) + } + return outputs +} diff --git a/azurerm/resource_arm_firewall_nat_rule_collection_test.go b/azurerm/resource_arm_firewall_nat_rule_collection_test.go new file mode 100644 index 000000000000..fbf0bfb08639 --- /dev/null +++ b/azurerm/resource_arm_firewall_nat_rule_collection_test.go @@ -0,0 +1,753 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMFirewallNatRuleCollection_basic(t *testing.T) { + resourceName := "azurerm_firewall_nat_rule_collection.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMFirewallNatRuleCollection_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_firewall_nat_rule_collection.test" + ri := tf.AccRandTimeInt() + + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + Config: testAccAzureRMFirewallNatRuleCollection_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_firewall_nat_rule_collection"), + }, + }, + }) +} + +func TestAccAzureRMFirewallNatRuleCollection_updatedName(t *testing.T) { + resourceName := "azurerm_firewall_nat_rule_collection.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMFirewallNatRuleCollection_updatedName(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMFirewallNatRuleCollection_multipleRuleCollections(t *testing.T) { + firstRule := "azurerm_firewall_nat_rule_collection.test" + secondRule := "azurerm_firewall_nat_rule_collection.test_add" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(firstRule), + ), + }, + { + ResourceName: firstRule, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMFirewallNatRuleCollection_multiple(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(firstRule), + testCheckAzureRMFirewallNatRuleCollectionExists(secondRule), + ), + }, + { + ResourceName: firstRule, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(firstRule), + testCheckAzureRMFirewallNatRuleCollectionDoesNotExist("azurerm_firewall.test", "acctestnrc_add"), + ), + }, + { + ResourceName: firstRule, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMFirewallNatRuleCollection_update(t *testing.T) { + firstResourceName := "azurerm_firewall_nat_rule_collection.test" + secondResourceName := "azurerm_firewall_nat_rule_collection.test_add" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFirewallNatRuleCollection_multiple(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(firstResourceName), + testCheckAzureRMFirewallNatRuleCollectionExists(secondResourceName), + ), + }, + { + ResourceName: firstResourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMFirewallNatRuleCollection_multipleUpdate(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(firstResourceName), + testCheckAzureRMFirewallNatRuleCollectionExists(secondResourceName), + ), + }, + { + ResourceName: firstResourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMFirewallNatRuleCollection_disappears(t *testing.T) { + resourceName := "azurerm_firewall_nat_rule_collection.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + testCheckAzureRMFirewallNatRuleCollectionDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAzureRMFirewallNatRuleCollection_multipleRules(t *testing.T) { + resourceName := "azurerm_firewall_nat_rule_collection.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMFirewallNatRuleCollection_multipleRules(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMFirewallNatRuleCollection_updateFirewallTags(t *testing.T) { + resourceName := "azurerm_firewall_nat_rule_collection.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFirewallDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMFirewallNatRuleCollection_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMFirewallNatRuleCollection_updateFirewallTags(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFirewallNatRuleCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMFirewallNatRuleCollectionExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + firewallName := rs.Primary.Attributes["azure_firewall_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + read, err := client.Get(ctx, resourceGroup, firewallName) + if err != nil { + return err + } + + found := false + for _, collection := range *read.AzureFirewallPropertiesFormat.NatRuleCollections { + if *collection.Name == name { + found = true + break + } + } + + if !found { + return fmt.Errorf("Expected NAT Rule Collection %q (Firewall %q / Resource Group %q) to exist but it didn't", name, firewallName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMFirewallNatRuleCollectionDoesNotExist(resourceName string, collectionName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + firewallName := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + read, err := client.Get(ctx, resourceGroup, firewallName) + if err != nil { + return err + } + + for _, collection := range *read.AzureFirewallPropertiesFormat.NatRuleCollections { + if *collection.Name == collectionName { + return fmt.Errorf("NAT Rule Collection %q exists in Firewall %q: %+v", collectionName, firewallName, collection) + } + } + + return nil + } +} + +func testCheckAzureRMFirewallNatRuleCollectionDisappears(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + firewallName := rs.Primary.Attributes["azure_firewall_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + read, err := client.Get(ctx, resourceGroup, firewallName) + if err != nil { + return err + } + + rules := make([]network.AzureFirewallNatRuleCollection, 0) + for _, collection := range *read.AzureFirewallPropertiesFormat.NatRuleCollections { + if *collection.Name != name { + rules = append(rules, collection) + } + } + + read.AzureFirewallPropertiesFormat.NatRuleCollections = &rules + + future, err := client.CreateOrUpdate(ctx, resourceGroup, firewallName, read) + if err != nil { + return fmt.Errorf("Error removing NAT Rule Collection from Firewall: %+v", err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for the removal of NAT Rule Collection from Firewall: %+v", err) + } + + _, err = client.Get(ctx, resourceGroup, firewallName) + return err + } +} + +func testAccAzureRMFirewallNatRuleCollection_basic(rInt int, location string) string { + template := testAccAzureRMFirewall_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_firewall_nat_rule_collection" "test" { + name = "acctestnrc-%d" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 100 + action = "Dnat" + + rule { + name = "rule1" + + source_addresses = [ + "10.0.0.0/16", + ] + + destination_ports = [ + "53", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "Any", + ] + + translated_port = 53 + translated_address = "8.8.8.8" + } +} +`, template, rInt) +} + +func testAccAzureRMFirewallNatRuleCollection_requiresImport(rInt int, location string) string { + template := testAccAzureRMFirewallNatRuleCollection_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_firewall_nat_rule_collection" "import" { + name = "${azurerm_firewall_nat_rule_collection.test.name}" + azure_firewall_name = "${azurerm_firewall_nat_rule_collection.test.azure_firewall_name}" + resource_group_name = "${azurerm_firewall_nat_rule_collection.test.resource_group_name}" + priority = 100 + action = "Dnat" + + rule { + name = "rule1" + + source_addresses = [ + "10.0.0.0/16", + ] + + destination_ports = [ + "53", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "Any", + ] + + translated_port = 53 + translated_address = "8.8.8.8" + } +} +`, template) +} + +func testAccAzureRMFirewallNatRuleCollection_updatedName(rInt int, location string) string { + template := testAccAzureRMFirewall_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_firewall_nat_rule_collection" "test" { + name = "acctestnrc-%d" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 100 + action = "Dnat" + + rule { + name = "rule2" + + source_addresses = [ + "10.0.0.0/16", + ] + + destination_ports = [ + "53", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "TCP", + ] + + translated_port = 53 + translated_address = "8.8.8.8" + } +} +`, template, rInt) +} + +func testAccAzureRMFirewallNatRuleCollection_multiple(rInt int, location string) string { + template := testAccAzureRMFirewall_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_firewall_nat_rule_collection" "test" { + name = "acctestnrc-%d" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 100 + action = "Dnat" + + rule { + name = "acctestrule" + + source_addresses = [ + "10.0.0.0/16", + ] + + destination_ports = [ + "53", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "TCP", + ] + + translated_port = 53 + translated_address = "8.8.8.8" + } +} + +resource "azurerm_firewall_nat_rule_collection" "test_add" { + name = "acctestnrc_add-%d" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 200 + action = "Dnat" + + rule { + name = "acctestruleadd" + + source_addresses = [ + "10.0.0.0/8", + ] + + destination_ports = [ + "8080", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "TCP", + ] + + translated_port = 8080 + translated_address = "8.8.4.4" + } +} +`, template, rInt, rInt) +} + +func testAccAzureRMFirewallNatRuleCollection_multipleUpdate(rInt int, location string) string { + template := testAccAzureRMFirewall_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_firewall_nat_rule_collection" "test" { + name = "acctestnrc-%d" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 300 + action = "Dnat" + + rule { + name = "acctestrule" + + source_addresses = [ + "10.0.0.0/16", + ] + + destination_ports = [ + "53", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "TCP", + ] + + translated_port = 53 + translated_address = "10.0.0.1" + } +} + +resource "azurerm_firewall_nat_rule_collection" "test_add" { + name = "acctestnrc_add-%d" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 400 + action = "Dnat" + + rule { + name = "acctestruleadd" + + source_addresses = [ + "10.0.0.0/8", + ] + + destination_ports = [ + "8080", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "TCP", + ] + + translated_port = 8080 + translated_address = "10.0.0.1" + } +} +`, template, rInt, rInt) +} + +func testAccAzureRMFirewallNatRuleCollection_multipleRules(rInt int, location string) string { + template := testAccAzureRMFirewall_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_firewall_nat_rule_collection" "test" { + name = "acctestnrc-%d" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 100 + action = "Dnat" + + rule { + name = "acctestrule" + + source_addresses = [ + "10.0.0.0/16", + ] + + destination_ports = [ + "53", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "TCP", + ] + + translated_port = 53 + translated_address = "10.0.0.1" + } + + rule { + name = "acctestrule_add" + + source_addresses = [ + "192.168.0.1", + ] + + destination_ports = [ + "8888", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "TCP", + ] + + translated_port = 8888 + translated_address = "192.168.0.1" + } +} +`, template, rInt) +} + +func testAccAzureRMFirewallNatRuleCollection_updateFirewallTags(rInt int, location string) string { + template := testAccAzureRMFirewall_withTags(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_firewall_nat_rule_collection" "test" { + name = "acctestnrc-%d" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 100 + action = "Dnat" + + rule { + name = "rule1" + + source_addresses = [ + "10.0.0.0/16", + ] + + destination_ports = [ + "53", + ] + + destination_addresses = [ + "${azurerm_public_ip.test.ip_address}", + ] + + protocols = [ + "TCP", + ] + + translated_port = 53 + translated_address = "10.0.0.1" + } +} +`, template, rInt) +} diff --git a/azurerm/resource_arm_firewall_network_rule_collection.go b/azurerm/resource_arm_firewall_network_rule_collection.go index 6b29374a6521..589020846611 100644 --- a/azurerm/resource_arm_firewall_network_rule_collection.go +++ b/azurerm/resource_arm_firewall_network_rule_collection.go @@ -4,12 +4,15 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +41,7 @@ func resourceArmFirewallNetworkRuleCollection() *schema.Resource { ValidateFunc: validateAzureFirewallName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "priority": { Type: schema.TypeInt, @@ -110,15 +113,15 @@ func resourceArmFirewallNetworkRuleCollection() *schema.Resource { } func resourceArmFirewallNetworkRuleCollectionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) firewallName := d.Get("azure_firewall_name").(string) resourceGroup := d.Get("resource_group_name").(string) - azureRMLockByName(firewallName, azureFirewallResourceName) - defer azureRMUnlockByName(firewallName, azureFirewallResourceName) + locks.ByName(firewallName, azureFirewallResourceName) + defer locks.UnlockByName(firewallName, azureFirewallResourceName) firewall, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { @@ -170,7 +173,7 @@ func resourceArmFirewallNetworkRuleCollectionCreateUpdate(d *schema.ResourceData ruleCollections[index] = newRuleCollection } else { - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { if index != -1 { return tf.ImportAsExistsError("azurerm_firewall_network_rule_collection", id) } @@ -221,10 +224,10 @@ func resourceArmFirewallNetworkRuleCollectionCreateUpdate(d *schema.ResourceData } func resourceArmFirewallNetworkRuleCollectionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -293,10 +296,10 @@ func resourceArmFirewallNetworkRuleCollectionRead(d *schema.ResourceData, meta i } func resourceArmFirewallNetworkRuleCollectionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).azureFirewallsClient + client := meta.(*ArmClient).network.AzureFirewallsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -305,8 +308,8 @@ func resourceArmFirewallNetworkRuleCollectionDelete(d *schema.ResourceData, meta firewallName := id.Path["azureFirewalls"] name := id.Path["networkRuleCollections"] - azureRMLockByName(firewallName, azureFirewallResourceName) - defer azureRMUnlockByName(firewallName, azureFirewallResourceName) + locks.ByName(firewallName, azureFirewallResourceName) + defer locks.UnlockByName(firewallName, azureFirewallResourceName) firewall, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { diff --git a/azurerm/resource_arm_firewall_network_rule_collection_test.go b/azurerm/resource_arm_firewall_network_rule_collection_test.go index 592ae30c2380..38834df7b1eb 100644 --- a/azurerm/resource_arm_firewall_network_rule_collection_test.go +++ b/azurerm/resource_arm_firewall_network_rule_collection_test.go @@ -4,10 +4,11 @@ import ( "fmt" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMFirewallNetworkRuleCollection_basic(t *testing.T) { @@ -40,7 +41,7 @@ func TestAccAzureRMFirewallNetworkRuleCollection_basic(t *testing.T) { } func TestAccAzureRMFirewallNetworkRuleCollection_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -317,7 +318,7 @@ func testCheckAzureRMFirewallNetworkRuleCollectionExists(resourceName string) re firewallName := rs.Primary.Attributes["azure_firewall_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { @@ -351,7 +352,7 @@ func testCheckAzureRMFirewallNetworkRuleCollectionDoesNotExist(resourceName stri firewallName := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { @@ -380,7 +381,7 @@ func testCheckAzureRMFirewallNetworkRuleCollectionDisappears(resourceName string firewallName := rs.Primary.Attributes["azure_firewall_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, firewallName) if err != nil { diff --git a/azurerm/resource_arm_firewall_test.go b/azurerm/resource_arm_firewall_test.go index 134cb607a1ec..67908dc910b0 100644 --- a/azurerm/resource_arm_firewall_test.go +++ b/azurerm/resource_arm_firewall_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -110,7 +111,7 @@ func TestAccAzureRMFirewall_basic(t *testing.T) { } func TestAccAzureRMFirewall_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -211,7 +212,7 @@ func testCheckAzureRMFirewallExists(resourceName string) resource.TestCheckFunc return fmt.Errorf("Bad: no resource group found in state for Azure Firewall: %q", name) } - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) if err != nil { @@ -240,7 +241,7 @@ func testCheckAzureRMFirewallDisappears(resourceName string) resource.TestCheckF return fmt.Errorf("Bad: no resource group found in state for Azure Firewall: %q", name) } - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, name) if err != nil { @@ -255,7 +256,7 @@ func testCheckAzureRMFirewallDisappears(resourceName string) resource.TestCheckF } func testCheckAzureRMFirewallDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).azureFirewallsClient + client := testAccProvider.Meta().(*ArmClient).network.AzureFirewallsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_function_app.go b/azurerm/resource_arm_function_app.go index dd171f88312f..cc3a0f315ae5 100644 --- a/azurerm/resource_arm_function_app.go +++ b/azurerm/resource_arm_function_app.go @@ -9,7 +9,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -33,9 +37,9 @@ func resourceArmFunctionApp() *schema.Resource { ValidateFunc: validateAppServiceName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "kind": { Type: schema.TypeString, @@ -109,7 +113,7 @@ func resourceArmFunctionApp() *schema.Resource { string(web.SQLAzure), string(web.SQLServer), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, }, @@ -125,9 +129,9 @@ func resourceArmFunctionApp() *schema.Resource { "type": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ - string(web.SystemAssigned), + string(web.ManagedServiceIdentityTypeSystemAssigned), }, true), }, "principal_id": { @@ -142,7 +146,7 @@ func resourceArmFunctionApp() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), "default_hostname": { Type: schema.TypeString, @@ -198,10 +202,18 @@ func resourceArmFunctionApp() *schema.Resource { Optional: true, Computed: true, }, + "virtual_network_name": { + Type: schema.TypeString, + Optional: true, + Computed: false, + }, + "cors": azure.SchemaWebCorsSettings(), }, }, }, + "auth_settings": azure.SchemaAppServiceAuthSettings(), + "site_credential": { Type: schema.TypeList, Computed: true, @@ -225,7 +237,7 @@ func resourceArmFunctionApp() *schema.Resource { } func resourceArmFunctionAppCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Function App creation.") @@ -233,7 +245,7 @@ func resourceArmFunctionAppCreate(d *schema.ResourceData, meta interface{}) erro name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -259,13 +271,13 @@ func resourceArmFunctionAppCreate(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("The name %q used for the Function App needs to be globally unique and isn't available: %s", name, *available.Message) } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) kind := "functionapp" appServicePlanID := d.Get("app_service_plan_id").(string) enabled := d.Get("enabled").(bool) clientAffinityEnabled := d.Get("client_affinity_enabled").(bool) httpsOnly := d.Get("https_only").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) appServiceTier, err := getFunctionAppServiceTier(ctx, appServicePlanID, meta) if err != nil { return err @@ -279,7 +291,7 @@ func resourceArmFunctionAppCreate(d *schema.ResourceData, meta interface{}) erro siteEnvelope := web.Site{ Kind: &kind, Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), SiteProperties: &web.SiteProperties{ ServerFarmID: utils.String(appServicePlanID), Enabled: utils.Bool(enabled), @@ -315,14 +327,25 @@ func resourceArmFunctionAppCreate(d *schema.ResourceData, meta interface{}) erro d.SetId(*read.ID) + authSettingsRaw := d.Get("auth_settings").([]interface{}) + authSettings := azure.ExpandAppServiceAuthSettings(authSettingsRaw) + + auth := web.SiteAuthSettings{ + ID: read.ID, + SiteAuthSettingsProperties: &authSettings} + + if _, err := client.UpdateAuthSettings(ctx, resourceGroup, name, auth); err != nil { + return fmt.Errorf("Error updating auth settings for Function App %q (resource group %q): %+s", name, resourceGroup, err) + } + return resourceArmFunctionAppUpdate(d, meta) } func resourceArmFunctionAppUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -330,13 +353,13 @@ func resourceArmFunctionAppUpdate(d *schema.ResourceData, meta interface{}) erro resGroup := id.ResourceGroup name := id.Path["sites"] - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) kind := "functionapp" appServicePlanID := d.Get("app_service_plan_id").(string) enabled := d.Get("enabled").(bool) clientAffinityEnabled := d.Get("client_affinity_enabled").(bool) httpsOnly := d.Get("https_only").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) appServiceTier, err := getFunctionAppServiceTier(ctx, appServicePlanID, meta) @@ -345,12 +368,13 @@ func resourceArmFunctionAppUpdate(d *schema.ResourceData, meta interface{}) erro } basicAppSettings := getBasicFunctionAppAppSettings(d, appServiceTier) siteConfig := expandFunctionAppSiteConfig(d) + siteConfig.AppSettings = &basicAppSettings siteEnvelope := web.Site{ Kind: &kind, Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), SiteProperties: &web.SiteProperties{ ServerFarmID: utils.String(appServicePlanID), Enabled: utils.Bool(enabled), @@ -395,6 +419,20 @@ func resourceArmFunctionAppUpdate(d *schema.ResourceData, meta interface{}) erro } } + if d.HasChange("auth_settings") { + authSettingsRaw := d.Get("auth_settings").([]interface{}) + authSettingsProperties := azure.ExpandAppServiceAuthSettings(authSettingsRaw) + id := d.Id() + authSettings := web.SiteAuthSettings{ + ID: &id, + SiteAuthSettingsProperties: &authSettingsProperties, + } + + if _, err := client.UpdateAuthSettings(ctx, resGroup, name, authSettings); err != nil { + return fmt.Errorf("Error updating Authentication Settings for Function App %q: %+v", name, err) + } + } + if d.HasChange("connection_string") { // update the ConnectionStrings connectionStrings := expandFunctionAppConnectionStrings(d) @@ -411,10 +449,10 @@ func resourceArmFunctionAppUpdate(d *schema.ResourceData, meta interface{}) erro } func resourceArmFunctionAppRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -455,17 +493,21 @@ func resourceArmFunctionAppRead(d *schema.ResourceData, meta interface{}) error if err != nil { return err } - siteCredResp, err := siteCredFuture.Result(client) + siteCredResp, err := siteCredFuture.Result(*client) if err != nil { return fmt.Errorf("Error making Read request on AzureRM App Service Site Credential %q: %+v", name, err) } + authResp, err := client.GetAuthSettings(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving the AuthSettings for Function App %q (Resource Group %q): %+v", name, resGroup, err) + } d.Set("name", name) d.Set("resource_group_name", resGroup) d.Set("kind", resp.Kind) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.SiteProperties; props != nil { @@ -513,20 +555,23 @@ func resourceArmFunctionAppRead(d *schema.ResourceData, meta interface{}) error return err } + authSettings := azure.FlattenAppServiceAuthSettings(authResp.SiteAuthSettingsProperties) + if err := d.Set("auth_settings", authSettings); err != nil { + return fmt.Errorf("Error setting `auth_settings`: %s", err) + } + siteCred := flattenFunctionAppSiteCredential(siteCredResp.UserProperties) if err = d.Set("site_credential", siteCred); err != nil { return err } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmFunctionAppDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).appServicesClient + client := meta.(*ArmClient).web.AppServicesClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -586,14 +631,14 @@ func getBasicFunctionAppAppSettings(d *schema.ResourceData, appServiceTier strin } func getFunctionAppServiceTier(ctx context.Context, appServicePlanId string, meta interface{}) (string, error) { - id, err := parseAzureResourceID(appServicePlanId) + id, err := azure.ParseAzureResourceID(appServicePlanId) if err != nil { return "", fmt.Errorf("[ERROR] Unable to parse App Service Plan ID %q: %+v", appServicePlanId, err) } log.Printf("[DEBUG] Retrieving App Server Plan %s", id.Path["serverfarms"]) - appServicePlansClient := meta.(*ArmClient).appServicePlansClient + appServicePlansClient := meta.(*ArmClient).web.AppServicePlansClient appServicePlan, err := appServicePlansClient.Get(ctx, id.ResourceGroup, id.Path["serverfarms"]) if err != nil { return "", fmt.Errorf("[ERROR] Could not retrieve App Service Plan ID %q: %+v", appServicePlanId, err) @@ -644,6 +689,16 @@ func expandFunctionAppSiteConfig(d *schema.ResourceData) web.SiteConfig { siteConfig.LinuxFxVersion = utils.String(v.(string)) } + if v, ok := config["cors"]; ok { + corsSettings := v.(interface{}) + expand := azure.ExpandWebCorsSettings(corsSettings) + siteConfig.Cors = &expand + } + + if v, ok := config["virtual_network_name"]; ok { + siteConfig.VnetName = utils.String(v.(string)) + } + return siteConfig } @@ -672,6 +727,12 @@ func flattenFunctionAppSiteConfig(input *web.SiteConfig) []interface{} { result["linux_fx_version"] = *input.LinuxFxVersion } + if input.VnetName != nil { + result["virtual_network_name"] = *input.VnetName + } + + result["cors"] = azure.FlattenWebCorsSettings(input.Cors) + results = append(results, result) return results } diff --git a/azurerm/resource_arm_function_app_test.go b/azurerm/resource_arm_function_app_test.go index 3e7853789f9a..9c0f71afdd73 100644 --- a/azurerm/resource_arm_function_app_test.go +++ b/azurerm/resource_arm_function_app_test.go @@ -2,10 +2,12 @@ package azurerm import ( "fmt" + "os" "strings" "testing" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" @@ -45,7 +47,7 @@ func TestAccAzureRMFunctionApp_basic(t *testing.T) { } func TestAccAzureRMFunctionApp_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -596,8 +598,104 @@ func TestAccAzureRMFunctionApp_updateLogging(t *testing.T) { }) } +func TestAccAzureRMFunctionApp_authSettings(t *testing.T) { + resourceName := "azurerm_function_app.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + tenantID := os.Getenv("ARM_TENANT_ID") + config := testAccAzureRMFunctionApp_authSettings(ri, rs, testLocation(), tenantID) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFunctionAppDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAppServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.issuer", fmt.Sprintf("https://sts.windows.net/%s", tenantID)), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.runtime_version", "1.0"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.unauthenticated_client_action", "RedirectToLoginPage"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.token_refresh_extension_hours", "75"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.token_store_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.additional_login_params.test_key", "test_value"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.allowed_external_redirect_urls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.allowed_external_redirect_urls.0", "https://terra.form"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_id", "aadclientid"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.client_secret", "aadsecret"), + resource.TestCheckResourceAttr(resourceName, "auth_settings.0.active_directory.0.allowed_audiences.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMFunctionApp_corsSettings(t *testing.T) { + resourceName := "azurerm_function_app.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + config := testAccAzureRMFunctionApp_corsSettings(ri, rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFunctionAppDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFunctionAppExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.#", "1"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.0.support_credentials", "true"), + resource.TestCheckResourceAttr(resourceName, "site_config.0.cors.0.allowed_origins.#", "4"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMFunctionApp_vnetName(t *testing.T) { + resourceName := "azurerm_function_app.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + vnetName := strings.ToLower(acctest.RandString(11)) + config := testAccAzureRMFunctionApp_vnetName(ri, rs, testLocation(), vnetName) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMFunctionAppDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMFunctionAppExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "site_config.0.virtual_network_name", vnetName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMFunctionAppDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).appServicesClient + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_function_app" { @@ -636,7 +734,7 @@ func testCheckAzureRMFunctionAppExists(resourceName string) resource.TestCheckFu return fmt.Errorf("Bad: no resource group found in state for Function App: %s", functionAppName) } - client := testAccProvider.Meta().(*ArmClient).appServicesClient + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, functionAppName) if err != nil { @@ -665,7 +763,7 @@ func testCheckAzureRMFunctionAppHasContentShare(resourceName string) resource.Te return fmt.Errorf("Bad: no resource group found in state for Function App: %s", functionAppName) } - client := testAccProvider.Meta().(*ArmClient).appServicesClient + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext appSettingsResp, err := client.ListApplicationSettings(ctx, resourceGroup, functionAppName) @@ -697,7 +795,7 @@ func testCheckAzureRMFunctionAppHasNoContentShare(resourceName string) resource. return fmt.Errorf("Bad: no resource group found in state for Function App: %s", functionAppName) } - client := testAccProvider.Meta().(*ArmClient).appServicesClient + client := testAccProvider.Meta().(*ArmClient).web.AppServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext appSettingsResp, err := client.ListApplicationSettings(ctx, resourceGroup, functionAppName) @@ -989,10 +1087,8 @@ resource "azurerm_app_service_plan" "test" { tier = "Standard" size = "S1" } - - properties { - reserved = true - } + + reserved = true } resource "azurerm_function_app" "test" { @@ -1002,7 +1098,7 @@ resource "azurerm_function_app" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}" - + site_config { linux_fx_version = "DOCKER|(golang:latest)" } @@ -1121,10 +1217,8 @@ resource "azurerm_app_service_plan" "test" { tier = "Standard" size = "S1" } - - properties { - reserved = true - } + + reserved = true } resource "azurerm_function_app" "test" { @@ -1134,7 +1228,7 @@ resource "azurerm_function_app" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}" - + app_settings = { "hello" = "world" } @@ -1173,9 +1267,7 @@ resource "azurerm_app_service_plan" "test" { size = "S1" } - properties { - reserved = true - } + reserved = true } resource "azurerm_function_app" "test" { @@ -1185,7 +1277,7 @@ resource "azurerm_function_app" "test" { resource_group_name = "${azurerm_resource_group.test.name}" app_service_plan_id = "${azurerm_app_service_plan.test.id}" storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}" - + app_settings = { "hello" = "world" } @@ -1431,3 +1523,154 @@ resource "azurerm_function_app" "test" { } `, rInt, location, storage) } + +func testAccAzureRMFunctionApp_authSettings(rInt int, storage string, location string, tenantID string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%[3]s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%[1]d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_function_app" "test" { + name = "acctest-%[1]d-func" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}" + + auth_settings { + enabled = true + issuer = "https://sts.windows.net/%[4]s" + runtime_version = "1.0" + unauthenticated_client_action = "RedirectToLoginPage" + token_refresh_extension_hours = 75 + token_store_enabled = true + + additional_login_params = { + test_key = "test_value" + } + + allowed_external_redirect_urls = [ + "https://terra.form", + ] + + active_directory { + client_id = "aadclientid" + client_secret = "aadsecret" + + allowed_audiences = [ + "activedirectorytokenaudiences", + ] + } + } +} +`, rInt, location, storage, tenantID) +} + +func testAccAzureRMFunctionApp_corsSettings(rInt int, storage string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%[3]s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%[1]d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_function_app" "test" { + name = "acctest-%[1]d-func" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}" + + site_config { + cors { + allowed_origins = [ + "http://www.contoso.com", + "www.contoso.com", + "contoso.com", + "http://localhost:4201", + ] + + support_credentials = true + } + } +} +`, rInt, location, storage) +} + +func testAccAzureRMFunctionApp_vnetName(rInt int, storage, location, vnetName string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%[3]s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_app_service_plan" "test" { + name = "acctestASP-%[1]d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + tier = "Standard" + size = "S1" + } +} + +resource "azurerm_function_app" "test" { + name = "acctest-%[1]d-func" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + app_service_plan_id = "${azurerm_app_service_plan.test.id}" + storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}" + + site_config { + virtual_network_name = "%[4]s" + } +} +`, rInt, location, storage, vnetName) +} diff --git a/azurerm/resource_arm_hdinsight_hadoop_cluster.go b/azurerm/resource_arm_hdinsight_hadoop_cluster.go new file mode 100644 index 000000000000..3ce3d2d1d988 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_hadoop_cluster.go @@ -0,0 +1,291 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this isn't a recommended way of building resources in Terraform +// this pattern is used to work around a generic but pedantic API endpoint +var hdInsightHadoopClusterHeadNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 2, + MaxInstanceCount: 2, + CanSpecifyDisks: false, + FixedMinInstanceCount: utils.Int32(int32(1)), + FixedTargetInstanceCount: utils.Int32(int32(2)), +} + +var hdInsightHadoopClusterWorkerNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: true, + MinInstanceCount: 1, + MaxInstanceCount: 25, + CanSpecifyDisks: false, +} + +var hdInsightHadoopClusterZookeeperNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 3, + MaxInstanceCount: 3, + CanSpecifyDisks: false, + FixedMinInstanceCount: utils.Int32(int32(1)), + FixedTargetInstanceCount: utils.Int32(int32(3)), +} + +func resourceArmHDInsightHadoopCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmHDInsightHadoopClusterCreate, + Read: resourceArmHDInsightHadoopClusterRead, + Update: hdinsightClusterUpdate("Hadoop", resourceArmHDInsightHadoopClusterRead), + Delete: hdinsightClusterDelete("Hadoop"), + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "cluster_version": azure.SchemaHDInsightClusterVersion(), + + "tier": azure.SchemaHDInsightTier(), + + "component_version": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "hadoop": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + }, + + "gateway": azure.SchemaHDInsightsGateway(), + + "storage_account": azure.SchemaHDInsightsStorageAccounts(), + + "roles": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "head_node": azure.SchemaHDInsightNodeDefinition("roles.0.head_node", hdInsightHadoopClusterHeadNodeDefinition), + + "worker_node": azure.SchemaHDInsightNodeDefinition("roles.0.worker_node", hdInsightHadoopClusterWorkerNodeDefinition), + + "zookeeper_node": azure.SchemaHDInsightNodeDefinition("roles.0.zookeeper_node", hdInsightHadoopClusterZookeeperNodeDefinition), + }, + }, + }, + + "tags": tags.Schema(), + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmHDInsightHadoopClusterCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + clusterVersion := d.Get("cluster_version").(string) + t := d.Get("tags").(map[string]interface{}) + tier := hdinsight.Tier(d.Get("tier").(string)) + + componentVersionsRaw := d.Get("component_version").([]interface{}) + componentVersions := expandHDInsightHadoopComponentVersion(componentVersionsRaw) + + gatewayRaw := d.Get("gateway").([]interface{}) + gateway := azure.ExpandHDInsightsConfigurations(gatewayRaw) + + storageAccountsRaw := d.Get("storage_account").([]interface{}) + storageAccounts, err := azure.ExpandHDInsightsStorageAccounts(storageAccountsRaw) + if err != nil { + return fmt.Errorf("Error expanding `storage_account`: %s", err) + } + + rolesRaw := d.Get("roles").([]interface{}) + hadoopRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightHadoopClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightHadoopClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightHadoopClusterZookeeperNodeDefinition, + } + roles, err := expandHDInsightRoles(rolesRaw, hadoopRoles) + if err != nil { + return fmt.Errorf("Error expanding `roles`: %+v", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing HDInsight Hadoop Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_hdinsight_hadoop_cluster", *existing.ID) + } + } + + params := hdinsight.ClusterCreateParametersExtended{ + Location: utils.String(location), + Properties: &hdinsight.ClusterCreateProperties{ + Tier: tier, + OsType: hdinsight.Linux, + ClusterVersion: utils.String(clusterVersion), + ClusterDefinition: &hdinsight.ClusterDefinition{ + Kind: utils.String("Hadoop"), + ComponentVersion: componentVersions, + Configurations: gateway, + }, + StorageProfile: &hdinsight.StorageProfile{ + Storageaccounts: storageAccounts, + }, + ComputeProfile: &hdinsight.ComputeProfile{ + Roles: roles, + }, + }, + Tags: tags.Expand(t), + } + future, err := client.Create(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error creating HDInsight Hadoop Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of HDInsight Hadoop Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving HDInsight Hadoop Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Error reading ID for HDInsight Hadoop Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmHDInsightHadoopClusterRead(d, meta) +} + +func resourceArmHDInsightHadoopClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight Hadoop Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight Hadoop Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Configuration for HDInsight Hadoop Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + // storage_account isn't returned so I guess we just leave it ¯\_(ツ)_/¯ + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + if err := d.Set("component_version", flattenHDInsightHadoopComponentVersion(def.ComponentVersion)); err != nil { + return fmt.Errorf("Error flattening `component_version`: %+v", err) + } + + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + } + + hadoopRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightHadoopClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightHadoopClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightHadoopClusterZookeeperNodeDefinition, + } + flattenedRoles := flattenHDInsightRoles(d, props.ComputeProfile, hadoopRoles) + if err := d.Set("roles", flattenedRoles); err != nil { + return fmt.Errorf("Error flattening `roles`: %+v", err) + } + + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func expandHDInsightHadoopComponentVersion(input []interface{}) map[string]*string { + vs := input[0].(map[string]interface{}) + return map[string]*string{ + "Hadoop": utils.String(vs["hadoop"].(string)), + } +} + +func flattenHDInsightHadoopComponentVersion(input map[string]*string) []interface{} { + hadoopVersion := "" + if v, ok := input["Hadoop"]; ok { + if v != nil { + hadoopVersion = *v + } + } + return []interface{}{ + map[string]interface{}{ + "hadoop": hadoopVersion, + }, + } +} diff --git a/azurerm/resource_arm_hdinsight_hadoop_cluster_test.go b/azurerm/resource_arm_hdinsight_hadoop_cluster_test.go new file mode 100644 index 000000000000..5c5bc2d1440a --- /dev/null +++ b/azurerm/resource_arm_hdinsight_hadoop_cluster_test.go @@ -0,0 +1,606 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMHDInsightHadoopCluster_basic(t *testing.T) { + resourceName := "azurerm_hdinsight_hadoop_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hadoop_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHadoopCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightHadoopCluster_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_hdinsight_hadoop_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hadoop_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHadoopCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + Config: testAccAzureRMHDInsightHadoopCluster_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_hdinsight_hadoop_cluster"), + }, + }, + }) +} + +func TestAccAzureRMHDInsightHadoopCluster_update(t *testing.T) { + resourceName := "azurerm_hdinsight_hadoop_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hadoop_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHadoopCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + { + Config: testAccAzureRMHDInsightHadoopCluster_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightHadoopCluster_sshKeys(t *testing.T) { + resourceName := "azurerm_hdinsight_hadoop_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hadoop_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHadoopCluster_sshKeys(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "storage_account", + "roles.0.head_node.0.ssh_keys", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.ssh_keys", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.ssh_keys", + "roles.0.zookeeper_node.0.vm_size", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightHadoopCluster_virtualNetwork(t *testing.T) { + resourceName := "azurerm_hdinsight_hadoop_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hadoop_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHadoopCluster_virtualNetwork(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightHadoopCluster_complete(t *testing.T) { + resourceName := "azurerm_hdinsight_hadoop_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hadoop_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHadoopCluster_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func testAccAzureRMHDInsightHadoopCluster_basic(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHadoopCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_hadoop_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hadoop = "2.7" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 2 + } + + zookeeper_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightHadoopCluster_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHadoopCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_hadoop_cluster" "import" { + name = "${azurerm_hdinsight_hadoop_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_hadoop_cluster.test.resource_group_name}" + location = "${azurerm_hdinsight_hadoop_cluster.test.location}" + cluster_version = "${azurerm_hdinsight_hadoop_cluster.test.cluster_version}" + tier = "${azurerm_hdinsight_hadoop_cluster.test.tier}" + component_version = "${azurerm_hdinsight_hadoop_cluster.test.component_version}" + gateway = "${azurerm_hdinsight_hadoop_cluster.test.gateway}" + storage_account = "${azurerm_hdinsight_hadoop_cluster.test.storage_account}" + roles = "${azurerm_hdinsight_hadoop_cluster.test.roles}" +} +`, template) +} + +func testAccAzureRMHDInsightHadoopCluster_sshKeys(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHadoopCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +variable "ssh_key" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" +} + +resource "azurerm_hdinsight_hadoop_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hadoop = "2.7" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + worker_node { + vm_size = "Standard_D4_v2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightHadoopCluster_updated(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHadoopCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_hadoop_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hadoop = "2.7" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D4_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 5 + } + + zookeeper_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightHadoopCluster_virtualNetwork(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHadoopCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_hadoop_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hadoop = "2.7" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D4_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightHadoopCluster_complete(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHadoopCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_hadoop_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hadoop = "2.7" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D4_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightHadoopCluster_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_hdinsight_hbase_cluster.go b/azurerm/resource_arm_hdinsight_hbase_cluster.go new file mode 100644 index 000000000000..f73c0ff3ccb9 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_hbase_cluster.go @@ -0,0 +1,289 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this isn't a recommended way of building resources in Terraform +// this pattern is used to work around a generic but pedantic API endpoint +var hdInsightHBaseClusterHeadNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 2, + MaxInstanceCount: 2, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(2)), +} + +var hdInsightHBaseClusterWorkerNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: true, + MinInstanceCount: 1, + MaxInstanceCount: 23, + CanSpecifyDisks: false, +} + +var hdInsightHBaseClusterZookeeperNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 3, + MaxInstanceCount: 3, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(3)), +} + +func resourceArmHDInsightHBaseCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmHDInsightHBaseClusterCreate, + Read: resourceArmHDInsightHBaseClusterRead, + Update: hdinsightClusterUpdate("HBase", resourceArmHDInsightHBaseClusterRead), + Delete: hdinsightClusterDelete("HBase"), + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "cluster_version": azure.SchemaHDInsightClusterVersion(), + + "tier": azure.SchemaHDInsightTier(), + + "component_version": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "hbase": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + }, + + "gateway": azure.SchemaHDInsightsGateway(), + + "storage_account": azure.SchemaHDInsightsStorageAccounts(), + + "roles": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "head_node": azure.SchemaHDInsightNodeDefinition("roles.0.head_node", hdInsightHBaseClusterHeadNodeDefinition), + + "worker_node": azure.SchemaHDInsightNodeDefinition("roles.0.worker_node", hdInsightHBaseClusterWorkerNodeDefinition), + + "zookeeper_node": azure.SchemaHDInsightNodeDefinition("roles.0.zookeeper_node", hdInsightHBaseClusterZookeeperNodeDefinition), + }, + }, + }, + + "tags": tags.Schema(), + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmHDInsightHBaseClusterCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + clusterVersion := d.Get("cluster_version").(string) + t := d.Get("tags").(map[string]interface{}) + tier := hdinsight.Tier(d.Get("tier").(string)) + + componentVersionsRaw := d.Get("component_version").([]interface{}) + componentVersions := expandHDInsightHBaseComponentVersion(componentVersionsRaw) + + gatewayRaw := d.Get("gateway").([]interface{}) + gateway := azure.ExpandHDInsightsConfigurations(gatewayRaw) + + storageAccountsRaw := d.Get("storage_account").([]interface{}) + storageAccounts, err := azure.ExpandHDInsightsStorageAccounts(storageAccountsRaw) + if err != nil { + return fmt.Errorf("Error expanding `storage_account`: %s", err) + } + + hbaseRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightHBaseClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightHBaseClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightHBaseClusterZookeeperNodeDefinition, + } + rolesRaw := d.Get("roles").([]interface{}) + roles, err := expandHDInsightRoles(rolesRaw, hbaseRoles) + if err != nil { + return fmt.Errorf("Error expanding `roles`: %+v", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing HDInsight HBase Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_hdinsight_hbase_cluster", *existing.ID) + } + } + + params := hdinsight.ClusterCreateParametersExtended{ + Location: utils.String(location), + Properties: &hdinsight.ClusterCreateProperties{ + Tier: tier, + OsType: hdinsight.Linux, + ClusterVersion: utils.String(clusterVersion), + ClusterDefinition: &hdinsight.ClusterDefinition{ + Kind: utils.String("HBase"), + ComponentVersion: componentVersions, + Configurations: gateway, + }, + StorageProfile: &hdinsight.StorageProfile{ + Storageaccounts: storageAccounts, + }, + ComputeProfile: &hdinsight.ComputeProfile{ + Roles: roles, + }, + }, + Tags: tags.Expand(t), + } + future, err := client.Create(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error creating HDInsight HBase Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of HDInsight HBase Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving HDInsight HBase Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Error reading ID for HDInsight HBase Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmHDInsightHBaseClusterRead(d, meta) +} + +func resourceArmHDInsightHBaseClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight HBase Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight HBase Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Configuration for HDInsight HBase Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + // storage_account isn't returned so I guess we just leave it ¯\_(ツ)_/¯ + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + if err := d.Set("component_version", flattenHDInsightHBaseComponentVersion(def.ComponentVersion)); err != nil { + return fmt.Errorf("Error flattening `component_version`: %+v", err) + } + + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + } + + hbaseRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightHBaseClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightHBaseClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightHBaseClusterZookeeperNodeDefinition, + } + flattenedRoles := flattenHDInsightRoles(d, props.ComputeProfile, hbaseRoles) + if err := d.Set("roles", flattenedRoles); err != nil { + return fmt.Errorf("Error flattening `roles`: %+v", err) + } + + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func expandHDInsightHBaseComponentVersion(input []interface{}) map[string]*string { + vs := input[0].(map[string]interface{}) + return map[string]*string{ + "hbase": utils.String(vs["hbase"].(string)), + } +} + +func flattenHDInsightHBaseComponentVersion(input map[string]*string) []interface{} { + hbaseVersion := "" + if v, ok := input["hbase"]; ok { + if v != nil { + hbaseVersion = *v + } + } + return []interface{}{ + map[string]interface{}{ + "hbase": hbaseVersion, + }, + } +} diff --git a/azurerm/resource_arm_hdinsight_hbase_cluster_test.go b/azurerm/resource_arm_hdinsight_hbase_cluster_test.go new file mode 100644 index 000000000000..7a1f86ad45a7 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_hbase_cluster_test.go @@ -0,0 +1,606 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMHDInsightHBaseCluster_basic(t *testing.T) { + resourceName := "azurerm_hdinsight_hbase_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hbase_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHBaseCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightHBaseCluster_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_hdinsight_hbase_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hbase_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHBaseCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + Config: testAccAzureRMHDInsightHBaseCluster_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_hdinsight_hbase_cluster"), + }, + }, + }) +} + +func TestAccAzureRMHDInsightHBaseCluster_update(t *testing.T) { + resourceName := "azurerm_hdinsight_hbase_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hbase_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHBaseCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + { + Config: testAccAzureRMHDInsightHBaseCluster_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightHBaseCluster_sshKeys(t *testing.T) { + resourceName := "azurerm_hdinsight_hbase_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hbase_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHBaseCluster_sshKeys(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "storage_account", + "roles.0.head_node.0.ssh_keys", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.ssh_keys", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.ssh_keys", + "roles.0.zookeeper_node.0.vm_size", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightHBaseCluster_virtualNetwork(t *testing.T) { + resourceName := "azurerm_hdinsight_hbase_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hbase_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHBaseCluster_virtualNetwork(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightHBaseCluster_complete(t *testing.T) { + resourceName := "azurerm_hdinsight_hbase_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_hbase_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightHBaseCluster_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func testAccAzureRMHDInsightHBaseCluster_basic(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHBaseCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_hbase_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hbase = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 2 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightHBaseCluster_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHBaseCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_hbase_cluster" "import" { + name = "${azurerm_hdinsight_hbase_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_hbase_cluster.test.resource_group_name}" + location = "${azurerm_hdinsight_hbase_cluster.test.location}" + cluster_version = "${azurerm_hdinsight_hbase_cluster.test.cluster_version}" + tier = "${azurerm_hdinsight_hbase_cluster.test.tier}" + component_version = "${azurerm_hdinsight_hbase_cluster.test.component_version}" + gateway = "${azurerm_hdinsight_hbase_cluster.test.gateway}" + storage_account = "${azurerm_hdinsight_hbase_cluster.test.storage_account}" + roles = "${azurerm_hdinsight_hbase_cluster.test.roles}" +} +`, template) +} + +func testAccAzureRMHDInsightHBaseCluster_sshKeys(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHBaseCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +variable "ssh_key" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" +} + +resource "azurerm_hdinsight_hbase_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hbase = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightHBaseCluster_updated(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHBaseCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_hbase_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hbase = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 5 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightHBaseCluster_virtualNetwork(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHBaseCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_hbase_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hbase = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightHBaseCluster_complete(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightHBaseCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_hbase_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hbase = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightHBaseCluster_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_hdinsight_interactive_query_cluster.go b/azurerm/resource_arm_hdinsight_interactive_query_cluster.go new file mode 100644 index 000000000000..55edeece0951 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_interactive_query_cluster.go @@ -0,0 +1,289 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this isn't a recommended way of building resources in Terraform +// this pattern is used to work around a generic but pedantic API endpoint +var hdInsightInteractiveQueryClusterHeadNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 2, + MaxInstanceCount: 2, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(2)), +} + +var hdInsightInteractiveQueryClusterWorkerNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: true, + MinInstanceCount: 1, + MaxInstanceCount: 9, + CanSpecifyDisks: false, +} + +var hdInsightInteractiveQueryClusterZookeeperNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 3, + MaxInstanceCount: 3, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(3)), +} + +func resourceArmHDInsightInteractiveQueryCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmHDInsightInteractiveQueryClusterCreate, + Read: resourceArmHDInsightInteractiveQueryClusterRead, + Update: hdinsightClusterUpdate("Interactive Query", resourceArmHDInsightInteractiveQueryClusterRead), + Delete: hdinsightClusterDelete("Interactive Query"), + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "cluster_version": azure.SchemaHDInsightClusterVersion(), + + "tier": azure.SchemaHDInsightTier(), + + "component_version": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "interactive_hive": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + }, + + "gateway": azure.SchemaHDInsightsGateway(), + + "storage_account": azure.SchemaHDInsightsStorageAccounts(), + + "roles": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "head_node": azure.SchemaHDInsightNodeDefinition("roles.0.head_node", hdInsightInteractiveQueryClusterHeadNodeDefinition), + + "worker_node": azure.SchemaHDInsightNodeDefinition("roles.0.worker_node", hdInsightInteractiveQueryClusterWorkerNodeDefinition), + + "zookeeper_node": azure.SchemaHDInsightNodeDefinition("roles.0.zookeeper_node", hdInsightInteractiveQueryClusterZookeeperNodeDefinition), + }, + }, + }, + + "tags": tags.Schema(), + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmHDInsightInteractiveQueryClusterCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + clusterVersion := d.Get("cluster_version").(string) + t := d.Get("tags").(map[string]interface{}) + tier := hdinsight.Tier(d.Get("tier").(string)) + + componentVersionsRaw := d.Get("component_version").([]interface{}) + componentVersions := expandHDInsightInteractiveQueryComponentVersion(componentVersionsRaw) + + gatewayRaw := d.Get("gateway").([]interface{}) + gateway := azure.ExpandHDInsightsConfigurations(gatewayRaw) + + storageAccountsRaw := d.Get("storage_account").([]interface{}) + storageAccounts, err := azure.ExpandHDInsightsStorageAccounts(storageAccountsRaw) + if err != nil { + return fmt.Errorf("Error expanding `storage_account`: %s", err) + } + + interactiveQueryRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightInteractiveQueryClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightInteractiveQueryClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightInteractiveQueryClusterZookeeperNodeDefinition, + } + rolesRaw := d.Get("roles").([]interface{}) + roles, err := expandHDInsightRoles(rolesRaw, interactiveQueryRoles) + if err != nil { + return fmt.Errorf("Error expanding `roles`: %+v", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing HDInsight InteractiveQuery Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_hdinsight_interactive_query_cluster", *existing.ID) + } + } + + params := hdinsight.ClusterCreateParametersExtended{ + Location: utils.String(location), + Properties: &hdinsight.ClusterCreateProperties{ + Tier: tier, + OsType: hdinsight.Linux, + ClusterVersion: utils.String(clusterVersion), + ClusterDefinition: &hdinsight.ClusterDefinition{ + Kind: utils.String("INTERACTIVEHIVE"), + ComponentVersion: componentVersions, + Configurations: gateway, + }, + StorageProfile: &hdinsight.StorageProfile{ + Storageaccounts: storageAccounts, + }, + ComputeProfile: &hdinsight.ComputeProfile{ + Roles: roles, + }, + }, + Tags: tags.Expand(t), + } + future, err := client.Create(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error creating HDInsight Interactive Query Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of HDInsight Interactive Query Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving HDInsight Interactive Query Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Error reading ID for HDInsight Interactive Query Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmHDInsightInteractiveQueryClusterRead(d, meta) +} + +func resourceArmHDInsightInteractiveQueryClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight Interactive Query Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight Interactive Query Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Configuration for HDInsight Interactive Query Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + // storage_account isn't returned so I guess we just leave it ¯\_(ツ)_/¯ + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + if err := d.Set("component_version", flattenHDInsightInteractiveQueryComponentVersion(def.ComponentVersion)); err != nil { + return fmt.Errorf("Error flattening `component_version`: %+v", err) + } + + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + } + + interactiveQueryRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightInteractiveQueryClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightInteractiveQueryClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightInteractiveQueryClusterZookeeperNodeDefinition, + } + flattenedRoles := flattenHDInsightRoles(d, props.ComputeProfile, interactiveQueryRoles) + if err := d.Set("roles", flattenedRoles); err != nil { + return fmt.Errorf("Error flattening `roles`: %+v", err) + } + + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func expandHDInsightInteractiveQueryComponentVersion(input []interface{}) map[string]*string { + vs := input[0].(map[string]interface{}) + return map[string]*string{ + "InteractiveHive": utils.String(vs["interactive_hive"].(string)), + } +} + +func flattenHDInsightInteractiveQueryComponentVersion(input map[string]*string) []interface{} { + interactiveHiveVersion := "" + if v, ok := input["InteractiveHive"]; ok { + if v != nil { + interactiveHiveVersion = *v + } + } + return []interface{}{ + map[string]interface{}{ + "interactive_hive": interactiveHiveVersion, + }, + } +} diff --git a/azurerm/resource_arm_hdinsight_interactive_query_cluster_test.go b/azurerm/resource_arm_hdinsight_interactive_query_cluster_test.go new file mode 100644 index 000000000000..854f1d618a9a --- /dev/null +++ b/azurerm/resource_arm_hdinsight_interactive_query_cluster_test.go @@ -0,0 +1,606 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMHDInsightInteractiveQueryCluster_basic(t *testing.T) { + resourceName := "azurerm_hdinsight_interactive_query_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_interactive_query_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightInteractiveQueryCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightInteractiveQueryCluster_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_hdinsight_interactive_query_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_interactive_query_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightInteractiveQueryCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + Config: testAccAzureRMHDInsightInteractiveQueryCluster_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_hdinsight_interactive_query_cluster"), + }, + }, + }) +} + +func TestAccAzureRMHDInsightInteractiveQueryCluster_update(t *testing.T) { + resourceName := "azurerm_hdinsight_interactive_query_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_interactive_query_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightInteractiveQueryCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + { + Config: testAccAzureRMHDInsightInteractiveQueryCluster_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightInteractiveQueryCluster_sshKeys(t *testing.T) { + resourceName := "azurerm_hdinsight_interactive_query_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_interactive_query_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightInteractiveQueryCluster_sshKeys(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "storage_account", + "roles.0.head_node.0.ssh_keys", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.ssh_keys", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.ssh_keys", + "roles.0.zookeeper_node.0.vm_size", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightInteractiveQueryCluster_virtualNetwork(t *testing.T) { + resourceName := "azurerm_hdinsight_interactive_query_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_interactive_query_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightInteractiveQueryCluster_virtualNetwork(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightInteractiveQueryCluster_complete(t *testing.T) { + resourceName := "azurerm_hdinsight_interactive_query_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_interactive_query_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightInteractiveQueryCluster_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func testAccAzureRMHDInsightInteractiveQueryCluster_basic(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightInteractiveQueryCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_interactive_query_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + interactive_hive = "2.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D13_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D14_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 2 + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightInteractiveQueryCluster_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightInteractiveQueryCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_interactive_query_cluster" "import" { + name = "${azurerm_hdinsight_interactive_query_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_interactive_query_cluster.test.resource_group_name}" + location = "${azurerm_hdinsight_interactive_query_cluster.test.location}" + cluster_version = "${azurerm_hdinsight_interactive_query_cluster.test.cluster_version}" + tier = "${azurerm_hdinsight_interactive_query_cluster.test.tier}" + component_version = "${azurerm_hdinsight_interactive_query_cluster.test.component_version}" + gateway = "${azurerm_hdinsight_interactive_query_cluster.test.gateway}" + storage_account = "${azurerm_hdinsight_interactive_query_cluster.test.storage_account}" + roles = "${azurerm_hdinsight_interactive_query_cluster.test.roles}" +} +`, template) +} + +func testAccAzureRMHDInsightInteractiveQueryCluster_sshKeys(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightInteractiveQueryCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +variable "ssh_key" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" +} + +resource "azurerm_hdinsight_interactive_query_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + interactive_hive = "2.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D13_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + worker_node { + vm_size = "Standard_D14_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightInteractiveQueryCluster_updated(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightInteractiveQueryCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_interactive_query_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + interactive_hive = "2.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D13_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D14_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 5 + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightInteractiveQueryCluster_virtualNetwork(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightInteractiveQueryCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_interactive_query_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + interactive_hive = "2.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D13_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D14_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightInteractiveQueryCluster_complete(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightInteractiveQueryCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_interactive_query_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + interactive_hive = "2.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D13_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D14_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightInteractiveQueryCluster_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_hdinsight_kafka_cluster.go b/azurerm/resource_arm_hdinsight_kafka_cluster.go new file mode 100644 index 000000000000..9815d5f6b543 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_kafka_cluster.go @@ -0,0 +1,290 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this isn't a recommended way of building resources in Terraform +// this pattern is used to work around a generic but pedantic API endpoint +var hdInsightKafkaClusterHeadNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 2, + MaxInstanceCount: 2, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(2)), +} + +var hdInsightKafkaClusterWorkerNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: true, + MinInstanceCount: 1, + MaxInstanceCount: 57, + CanSpecifyDisks: true, + MaxNumberOfDisksPerNode: utils.Int(8), +} + +var hdInsightKafkaClusterZookeeperNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 3, + MaxInstanceCount: 3, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(3)), +} + +func resourceArmHDInsightKafkaCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmHDInsightKafkaClusterCreate, + Read: resourceArmHDInsightKafkaClusterRead, + Update: hdinsightClusterUpdate("Kafka", resourceArmHDInsightKafkaClusterRead), + Delete: hdinsightClusterDelete("Kafka"), + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "cluster_version": azure.SchemaHDInsightClusterVersion(), + + "tier": azure.SchemaHDInsightTier(), + + "component_version": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "kafka": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + }, + + "gateway": azure.SchemaHDInsightsGateway(), + + "storage_account": azure.SchemaHDInsightsStorageAccounts(), + + "roles": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "head_node": azure.SchemaHDInsightNodeDefinition("roles.0.head_node", hdInsightKafkaClusterHeadNodeDefinition), + + "worker_node": azure.SchemaHDInsightNodeDefinition("roles.0.worker_node", hdInsightKafkaClusterWorkerNodeDefinition), + + "zookeeper_node": azure.SchemaHDInsightNodeDefinition("roles.0.zookeeper_node", hdInsightKafkaClusterZookeeperNodeDefinition), + }, + }, + }, + + "tags": tags.Schema(), + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmHDInsightKafkaClusterCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + clusterVersion := d.Get("cluster_version").(string) + t := d.Get("tags").(map[string]interface{}) + tier := hdinsight.Tier(d.Get("tier").(string)) + + componentVersionsRaw := d.Get("component_version").([]interface{}) + componentVersions := expandHDInsightKafkaComponentVersion(componentVersionsRaw) + + gatewayRaw := d.Get("gateway").([]interface{}) + gateway := azure.ExpandHDInsightsConfigurations(gatewayRaw) + + storageAccountsRaw := d.Get("storage_account").([]interface{}) + storageAccounts, err := azure.ExpandHDInsightsStorageAccounts(storageAccountsRaw) + if err != nil { + return fmt.Errorf("Error expanding `storage_account`: %s", err) + } + + kafkaRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightKafkaClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightKafkaClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightKafkaClusterZookeeperNodeDefinition, + } + rolesRaw := d.Get("roles").([]interface{}) + roles, err := expandHDInsightRoles(rolesRaw, kafkaRoles) + if err != nil { + return fmt.Errorf("Error expanding `roles`: %+v", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing HDInsight Kafka Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_hdinsight_kafka_cluster", *existing.ID) + } + } + + params := hdinsight.ClusterCreateParametersExtended{ + Location: utils.String(location), + Properties: &hdinsight.ClusterCreateProperties{ + Tier: tier, + OsType: hdinsight.Linux, + ClusterVersion: utils.String(clusterVersion), + ClusterDefinition: &hdinsight.ClusterDefinition{ + Kind: utils.String("Kafka"), + ComponentVersion: componentVersions, + Configurations: gateway, + }, + StorageProfile: &hdinsight.StorageProfile{ + Storageaccounts: storageAccounts, + }, + ComputeProfile: &hdinsight.ComputeProfile{ + Roles: roles, + }, + }, + Tags: tags.Expand(t), + } + future, err := client.Create(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error creating HDInsight Kafka Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of HDInsight Kafka Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving HDInsight Kafka Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Error reading ID for HDInsight Kafka Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmHDInsightKafkaClusterRead(d, meta) +} + +func resourceArmHDInsightKafkaClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight Kafka Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight Kafka Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Configuration for HDInsight Kafka Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + // storage_account isn't returned so I guess we just leave it ¯\_(ツ)_/¯ + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + if err := d.Set("component_version", flattenHDInsightKafkaComponentVersion(def.ComponentVersion)); err != nil { + return fmt.Errorf("Error flattening `component_version`: %+v", err) + } + + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + } + + kafkaRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightKafkaClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightKafkaClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightKafkaClusterZookeeperNodeDefinition, + } + flattenedRoles := flattenHDInsightRoles(d, props.ComputeProfile, kafkaRoles) + if err := d.Set("roles", flattenedRoles); err != nil { + return fmt.Errorf("Error flattening `roles`: %+v", err) + } + + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func expandHDInsightKafkaComponentVersion(input []interface{}) map[string]*string { + vs := input[0].(map[string]interface{}) + return map[string]*string{ + "kafka": utils.String(vs["kafka"].(string)), + } +} + +func flattenHDInsightKafkaComponentVersion(input map[string]*string) []interface{} { + kafkaVersion := "" + if v, ok := input["kafka"]; ok { + if v != nil { + kafkaVersion = *v + } + } + return []interface{}{ + map[string]interface{}{ + "kafka": kafkaVersion, + }, + } +} diff --git a/azurerm/resource_arm_hdinsight_kafka_cluster_test.go b/azurerm/resource_arm_hdinsight_kafka_cluster_test.go new file mode 100644 index 000000000000..3ef595fdb477 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_kafka_cluster_test.go @@ -0,0 +1,611 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMHDInsightKafkaCluster_basic(t *testing.T) { + resourceName := "azurerm_hdinsight_kafka_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_kafka_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightKafkaCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightKafkaCluster_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_hdinsight_kafka_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_kafka_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightKafkaCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + Config: testAccAzureRMHDInsightKafkaCluster_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_hdinsight_kafka_cluster"), + }, + }, + }) +} + +func TestAccAzureRMHDInsightKafkaCluster_update(t *testing.T) { + resourceName := "azurerm_hdinsight_kafka_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_kafka_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightKafkaCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + { + Config: testAccAzureRMHDInsightKafkaCluster_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightKafkaCluster_sshKeys(t *testing.T) { + resourceName := "azurerm_hdinsight_kafka_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_kafka_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightKafkaCluster_sshKeys(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "storage_account", + "roles.0.head_node.0.ssh_keys", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.ssh_keys", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.ssh_keys", + "roles.0.zookeeper_node.0.vm_size", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightKafkaCluster_virtualNetwork(t *testing.T) { + resourceName := "azurerm_hdinsight_kafka_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_kafka_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightKafkaCluster_virtualNetwork(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightKafkaCluster_complete(t *testing.T) { + resourceName := "azurerm_hdinsight_kafka_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_kafka_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightKafkaCluster_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func testAccAzureRMHDInsightKafkaCluster_basic(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightKafkaCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_kafka_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + kafka = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + number_of_disks_per_node = 2 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightKafkaCluster_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightKafkaCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_kafka_cluster" "import" { + name = "${azurerm_hdinsight_kafka_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_kafka_cluster.test.resource_group_name}" + location = "${azurerm_hdinsight_kafka_cluster.test.location}" + cluster_version = "${azurerm_hdinsight_kafka_cluster.test.cluster_version}" + tier = "${azurerm_hdinsight_kafka_cluster.test.tier}" + component_version = "${azurerm_hdinsight_kafka_cluster.test.component_version}" + gateway = "${azurerm_hdinsight_kafka_cluster.test.gateway}" + storage_account = "${azurerm_hdinsight_kafka_cluster.test.storage_account}" + roles = "${azurerm_hdinsight_kafka_cluster.test.roles}" +} +`, template) +} + +func testAccAzureRMHDInsightKafkaCluster_sshKeys(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightKafkaCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +variable "ssh_key" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" +} + +resource "azurerm_hdinsight_kafka_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + kafka = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + target_instance_count = 3 + number_of_disks_per_node = 2 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightKafkaCluster_updated(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightKafkaCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_kafka_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + kafka = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 5 + number_of_disks_per_node = 2 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightKafkaCluster_virtualNetwork(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightKafkaCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_kafka_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + kafka = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + number_of_disks_per_node = 2 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightKafkaCluster_complete(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightKafkaCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_kafka_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + kafka = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + number_of_disks_per_node = 2 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightKafkaCluster_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_hdinsight_ml_services_cluster.go b/azurerm/resource_arm_hdinsight_ml_services_cluster.go new file mode 100644 index 000000000000..1dfbe778dd08 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_ml_services_cluster.go @@ -0,0 +1,301 @@ +package azurerm + +import ( + "fmt" + "log" + "strconv" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this isn't a recommended way of building resources in Terraform +// this pattern is used to work around a generic but pedantic API endpoint +var hdInsightMLServicesClusterHeadNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 2, + MaxInstanceCount: 2, + CanSpecifyDisks: false, + FixedMinInstanceCount: utils.Int32(int32(1)), + FixedTargetInstanceCount: utils.Int32(int32(2)), +} + +var hdInsightMLServicesClusterWorkerNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: true, + MinInstanceCount: 1, + MaxInstanceCount: 16, + CanSpecifyDisks: false, +} + +var hdInsightMLServicesClusterZookeeperNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 3, + MaxInstanceCount: 3, + CanSpecifyDisks: false, + FixedMinInstanceCount: utils.Int32(int32(1)), + FixedTargetInstanceCount: utils.Int32(int32(3)), +} + +var hdInsightMLServicesClusterEdgeNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 1, + MaxInstanceCount: 1, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(1)), +} + +func resourceArmHDInsightMLServicesCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmHDInsightMLServicesClusterCreate, + Read: resourceArmHDInsightMLServicesClusterRead, + Update: hdinsightClusterUpdate("MLServices", resourceArmHDInsightMLServicesClusterRead), + Delete: hdinsightClusterDelete("MLServices"), + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "cluster_version": azure.SchemaHDInsightClusterVersion(), + + "tier": azure.SchemaHDInsightTier(), + + "gateway": azure.SchemaHDInsightsGateway(), + + "rstudio": { + Type: schema.TypeBool, + Required: true, + ForceNew: true, + }, + + "storage_account": azure.SchemaHDInsightsStorageAccounts(), + + "roles": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "head_node": azure.SchemaHDInsightNodeDefinition("roles.0.head_node", hdInsightMLServicesClusterHeadNodeDefinition), + + "worker_node": azure.SchemaHDInsightNodeDefinition("roles.0.worker_node", hdInsightMLServicesClusterWorkerNodeDefinition), + + "zookeeper_node": azure.SchemaHDInsightNodeDefinition("roles.0.zookeeper_node", hdInsightMLServicesClusterZookeeperNodeDefinition), + + "edge_node": azure.SchemaHDInsightNodeDefinition("roles.0.edge_node", hdInsightMLServicesClusterEdgeNodeDefinition), + }, + }, + }, + + "tags": tags.Schema(), + + "edge_ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func expandHDInsightsMLServicesConfigurations(gateway []interface{}, rStudio bool) map[string]interface{} { + config := azure.ExpandHDInsightsConfigurations(gateway) + + config["rserver"] = map[string]interface{}{ + "rstudio": rStudio, + } + + return config +} + +func resourceArmHDInsightMLServicesClusterCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + clusterVersion := d.Get("cluster_version").(string) + t := d.Get("tags").(map[string]interface{}) + tier := hdinsight.Tier(d.Get("tier").(string)) + + gatewayRaw := d.Get("gateway").([]interface{}) + rStudio := d.Get("rstudio").(bool) + gateway := expandHDInsightsMLServicesConfigurations(gatewayRaw, rStudio) + + storageAccountsRaw := d.Get("storage_account").([]interface{}) + storageAccounts, err := azure.ExpandHDInsightsStorageAccounts(storageAccountsRaw) + if err != nil { + return fmt.Errorf("Error expanding `storage_account`: %s", err) + } + + mlServicesRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightMLServicesClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightMLServicesClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightMLServicesClusterZookeeperNodeDefinition, + EdgeNodeDef: &hdInsightMLServicesClusterEdgeNodeDefinition, + } + rolesRaw := d.Get("roles").([]interface{}) + roles, err := expandHDInsightRoles(rolesRaw, mlServicesRoles) + if err != nil { + return fmt.Errorf("Error expanding `roles`: %+v", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing HDInsight MLServices Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_hdinsight_ml_server_cluster", *existing.ID) + } + } + + params := hdinsight.ClusterCreateParametersExtended{ + Location: utils.String(location), + Properties: &hdinsight.ClusterCreateProperties{ + Tier: tier, + OsType: hdinsight.Linux, + ClusterVersion: utils.String(clusterVersion), + ClusterDefinition: &hdinsight.ClusterDefinition{ + Kind: utils.String("MLServices"), + Configurations: gateway, + }, + StorageProfile: &hdinsight.StorageProfile{ + Storageaccounts: storageAccounts, + }, + ComputeProfile: &hdinsight.ComputeProfile{ + Roles: roles, + }, + }, + Tags: tags.Expand(t), + } + future, err := client.Create(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error creating HDInsight MLServices Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of HDInsight MLServices Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving HDInsight MLServices Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Error reading ID for HDInsight MLServices Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmHDInsightMLServicesClusterRead(d, meta) +} + +func resourceArmHDInsightMLServicesClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight MLServices Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight MLServices Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Gateway Configuration for HDInsight MLServices Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + rStudioConfig, err := configurationsClient.Get(ctx, resourceGroup, name, "rserver") + if err != nil { + return fmt.Errorf("Error retrieving RStudio Configuration for HDInsight MLServices Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + // storage_account isn't returned so I guess we just leave it ¯\_(ツ)_/¯ + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + + var rStudio bool + if rStudioStr := rStudioConfig.Value["rstudio"]; rStudioStr != nil { + rStudioBool, err := strconv.ParseBool(*rStudioStr) + if err != nil { + return err + } + + rStudio = rStudioBool + } + + d.Set("rstudio", rStudio) + } + + mlServicesRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightMLServicesClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightMLServicesClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightMLServicesClusterZookeeperNodeDefinition, + EdgeNodeDef: &hdInsightMLServicesClusterEdgeNodeDefinition, + } + flattenedRoles := flattenHDInsightRoles(d, props.ComputeProfile, mlServicesRoles) + if err := d.Set("roles", flattenedRoles); err != nil { + return fmt.Errorf("Error flattening `roles`: %+v", err) + } + + edgeSSHEndpoint := azure.FindHDInsightConnectivityEndpoint("EDGESSH", props.ConnectivityEndpoints) + d.Set("edge_ssh_endpoint", edgeSSHEndpoint) + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} diff --git a/azurerm/resource_arm_hdinsight_ml_services_cluster_test.go b/azurerm/resource_arm_hdinsight_ml_services_cluster_test.go new file mode 100644 index 000000000000..dcc59f01eab6 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_ml_services_cluster_test.go @@ -0,0 +1,643 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMHDInsightMLServicesCluster_basic(t *testing.T) { + resourceName := "azurerm_hdinsight_ml_services_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_ml_services_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightMLServicesCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightMLServicesCluster_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_hdinsight_ml_services_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_ml_services_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightMLServicesCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + Config: testAccAzureRMHDInsightMLServicesCluster_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_hdinsight_ml_services_cluster"), + }, + }, + }) +} + +func TestAccAzureRMHDInsightMLServicesCluster_update(t *testing.T) { + resourceName := "azurerm_hdinsight_ml_services_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_ml_services_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightMLServicesCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + { + Config: testAccAzureRMHDInsightMLServicesCluster_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightMLServicesCluster_sshKeys(t *testing.T) { + resourceName := "azurerm_hdinsight_ml_services_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_ml_services_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightMLServicesCluster_sshKeys(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "storage_account", + "roles.0.head_node.0.ssh_keys", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.ssh_keys", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.ssh_keys", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.ssh_keys", + "roles.0.edge_node.0.vm_size", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightMLServicesCluster_virtualNetwork(t *testing.T) { + resourceName := "azurerm_hdinsight_ml_services_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_ml_services_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightMLServicesCluster_virtualNetwork(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightMLServicesCluster_complete(t *testing.T) { + resourceName := "azurerm_hdinsight_ml_services_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_ml_services_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightMLServicesCluster_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func testAccAzureRMHDInsightMLServicesCluster_basic(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightMLServicesCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_ml_services_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 2 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightMLServicesCluster_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightMLServicesCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_ml_services_cluster" "import" { + name = "${azurerm_hdinsight_ml_services_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_ml_services_cluster.test.resource_group_name}" + location = "${azurerm_hdinsight_ml_services_cluster.test.location}" + cluster_version = "${azurerm_hdinsight_ml_services_cluster.test.cluster_version}" + tier = "${azurerm_hdinsight_ml_services_cluster.test.tier}" + gateway = "${azurerm_hdinsight_ml_services_cluster.test.gateway}" + storage_account = "${azurerm_hdinsight_ml_services_cluster.test.storage_account}" + roles = "${azurerm_hdinsight_ml_services_cluster.test.roles}" +} +`, template) +} + +func testAccAzureRMHDInsightMLServicesCluster_sshKeys(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightMLServicesCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +variable "ssh_key" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" +} + +resource "azurerm_hdinsight_ml_services_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightMLServicesCluster_updated(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightMLServicesCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_ml_services_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 5 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightMLServicesCluster_virtualNetwork(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightMLServicesCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_ml_services_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightMLServicesCluster_complete(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightMLServicesCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_ml_services_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightMLServicesCluster_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_hdinsight_rserver_cluster.go b/azurerm/resource_arm_hdinsight_rserver_cluster.go new file mode 100644 index 000000000000..ff829eb0c85f --- /dev/null +++ b/azurerm/resource_arm_hdinsight_rserver_cluster.go @@ -0,0 +1,301 @@ +package azurerm + +import ( + "fmt" + "log" + "strconv" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this isn't a recommended way of building resources in Terraform +// this pattern is used to work around a generic but pedantic API endpoint +var hdInsightRServerClusterHeadNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 2, + MaxInstanceCount: 2, + CanSpecifyDisks: false, + FixedMinInstanceCount: utils.Int32(int32(1)), + FixedTargetInstanceCount: utils.Int32(int32(2)), +} + +var hdInsightRServerClusterWorkerNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: true, + MinInstanceCount: 1, + MaxInstanceCount: 16, + CanSpecifyDisks: false, +} + +var hdInsightRServerClusterZookeeperNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 3, + MaxInstanceCount: 3, + CanSpecifyDisks: false, + FixedMinInstanceCount: utils.Int32(int32(1)), + FixedTargetInstanceCount: utils.Int32(int32(3)), +} + +var hdInsightRServerClusterEdgeNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 1, + MaxInstanceCount: 1, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(1)), +} + +func resourceArmHDInsightRServerCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmHDInsightRServerClusterCreate, + Read: resourceArmHDInsightRServerClusterRead, + Update: hdinsightClusterUpdate("RServer", resourceArmHDInsightRServerClusterRead), + Delete: hdinsightClusterDelete("RServer"), + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "cluster_version": azure.SchemaHDInsightClusterVersion(), + + "tier": azure.SchemaHDInsightTier(), + + "gateway": azure.SchemaHDInsightsGateway(), + + "rstudio": { + Type: schema.TypeBool, + Required: true, + ForceNew: true, + }, + + "storage_account": azure.SchemaHDInsightsStorageAccounts(), + + "roles": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "head_node": azure.SchemaHDInsightNodeDefinition("roles.0.head_node", hdInsightRServerClusterHeadNodeDefinition), + + "worker_node": azure.SchemaHDInsightNodeDefinition("roles.0.worker_node", hdInsightRServerClusterWorkerNodeDefinition), + + "zookeeper_node": azure.SchemaHDInsightNodeDefinition("roles.0.zookeeper_node", hdInsightRServerClusterZookeeperNodeDefinition), + + "edge_node": azure.SchemaHDInsightNodeDefinition("roles.0.edge_node", hdInsightRServerClusterEdgeNodeDefinition), + }, + }, + }, + + "tags": tags.Schema(), + + "edge_ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func expandHDInsightsRServerConfigurations(gateway []interface{}, rStudio bool) map[string]interface{} { + config := azure.ExpandHDInsightsConfigurations(gateway) + + config["rserver"] = map[string]interface{}{ + "rstudio": rStudio, + } + + return config +} + +func resourceArmHDInsightRServerClusterCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + clusterVersion := d.Get("cluster_version").(string) + t := d.Get("tags").(map[string]interface{}) + tier := hdinsight.Tier(d.Get("tier").(string)) + + gatewayRaw := d.Get("gateway").([]interface{}) + rStudio := d.Get("rstudio").(bool) + gateway := expandHDInsightsRServerConfigurations(gatewayRaw, rStudio) + + storageAccountsRaw := d.Get("storage_account").([]interface{}) + storageAccounts, err := azure.ExpandHDInsightsStorageAccounts(storageAccountsRaw) + if err != nil { + return fmt.Errorf("Error expanding `storage_account`: %s", err) + } + + RServerRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightRServerClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightRServerClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightRServerClusterZookeeperNodeDefinition, + EdgeNodeDef: &hdInsightRServerClusterEdgeNodeDefinition, + } + rolesRaw := d.Get("roles").([]interface{}) + roles, err := expandHDInsightRoles(rolesRaw, RServerRoles) + if err != nil { + return fmt.Errorf("Error expanding `roles`: %+v", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing HDInsight RServer Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_hdinsight_rserver_cluster", *existing.ID) + } + } + + params := hdinsight.ClusterCreateParametersExtended{ + Location: utils.String(location), + Properties: &hdinsight.ClusterCreateProperties{ + Tier: tier, + OsType: hdinsight.Linux, + ClusterVersion: utils.String(clusterVersion), + ClusterDefinition: &hdinsight.ClusterDefinition{ + Kind: utils.String("RServer"), + Configurations: gateway, + }, + StorageProfile: &hdinsight.StorageProfile{ + Storageaccounts: storageAccounts, + }, + ComputeProfile: &hdinsight.ComputeProfile{ + Roles: roles, + }, + }, + Tags: tags.Expand(t), + } + future, err := client.Create(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error creating HDInsight RServer Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of HDInsight RServer Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving HDInsight RServer Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Error reading ID for HDInsight RServer Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmHDInsightRServerClusterRead(d, meta) +} + +func resourceArmHDInsightRServerClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight RServer Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight RServer Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Gateway Configuration for HDInsight RServer Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + rStudioConfig, err := configurationsClient.Get(ctx, resourceGroup, name, "rserver") + if err != nil { + return fmt.Errorf("Error retrieving RStudio Configuration for HDInsight RServer Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + // storage_account isn't returned so I guess we just leave it ¯\_(ツ)_/¯ + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + + var rStudio bool + if rStudioStr := rStudioConfig.Value["rstudio"]; rStudioStr != nil { + rStudioBool, err := strconv.ParseBool(*rStudioStr) + if err != nil { + return err + } + + rStudio = rStudioBool + } + + d.Set("rstudio", rStudio) + } + + RServerRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightRServerClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightRServerClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightRServerClusterZookeeperNodeDefinition, + EdgeNodeDef: &hdInsightRServerClusterEdgeNodeDefinition, + } + flattenedRoles := flattenHDInsightRoles(d, props.ComputeProfile, RServerRoles) + if err := d.Set("roles", flattenedRoles); err != nil { + return fmt.Errorf("Error flattening `roles`: %+v", err) + } + + edgeSSHEndpoint := azure.FindHDInsightConnectivityEndpoint("EDGESSH", props.ConnectivityEndpoints) + d.Set("edge_ssh_endpoint", edgeSSHEndpoint) + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} diff --git a/azurerm/resource_arm_hdinsight_rserver_cluster_test.go b/azurerm/resource_arm_hdinsight_rserver_cluster_test.go new file mode 100644 index 000000000000..983bfa626ac2 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_rserver_cluster_test.go @@ -0,0 +1,643 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMHDInsightRServerCluster_basic(t *testing.T) { + resourceName := "azurerm_hdinsight_rserver_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_rserver_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightRServerCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightRServerCluster_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_hdinsight_rserver_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_rserver_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightRServerCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + Config: testAccAzureRMHDInsightRServerCluster_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_hdinsight_rserver_cluster"), + }, + }, + }) +} + +func TestAccAzureRMHDInsightRServerCluster_update(t *testing.T) { + resourceName := "azurerm_hdinsight_rserver_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_rserver_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightRServerCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + { + Config: testAccAzureRMHDInsightRServerCluster_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightRServerCluster_sshKeys(t *testing.T) { + resourceName := "azurerm_hdinsight_rserver_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_rserver_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightRServerCluster_sshKeys(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "storage_account", + "roles.0.head_node.0.ssh_keys", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.ssh_keys", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.ssh_keys", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.ssh_keys", + "roles.0.edge_node.0.vm_size", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightRServerCluster_virtualNetwork(t *testing.T) { + resourceName := "azurerm_hdinsight_rserver_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_rserver_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightRServerCluster_virtualNetwork(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightRServerCluster_complete(t *testing.T) { + resourceName := "azurerm_hdinsight_rserver_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_rserver_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightRServerCluster_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "edge_ssh_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "roles.0.edge_node.0.password", + "roles.0.edge_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func testAccAzureRMHDInsightRServerCluster_basic(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightRServerCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_rserver_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 2 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightRServerCluster_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightRServerCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_rserver_cluster" "import" { + name = "${azurerm_hdinsight_rserver_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_rserver_cluster.test.resource_group_name}" + location = "${azurerm_hdinsight_rserver_cluster.test.location}" + cluster_version = "${azurerm_hdinsight_rserver_cluster.test.cluster_version}" + tier = "${azurerm_hdinsight_rserver_cluster.test.tier}" + gateway = "${azurerm_hdinsight_rserver_cluster.test.gateway}" + storage_account = "${azurerm_hdinsight_rserver_cluster.test.storage_account}" + roles = "${azurerm_hdinsight_rserver_cluster.test.roles}" +} +`, template) +} + +func testAccAzureRMHDInsightRServerCluster_sshKeys(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightRServerCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +variable "ssh_key" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" +} + +resource "azurerm_hdinsight_rserver_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightRServerCluster_updated(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightRServerCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_rserver_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 5 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightRServerCluster_virtualNetwork(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightRServerCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_rserver_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightRServerCluster_complete(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightRServerCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_rserver_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + edge_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightRServerCluster_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_hdinsight_spark_cluster.go b/azurerm/resource_arm_hdinsight_spark_cluster.go new file mode 100644 index 000000000000..7998973a4b96 --- /dev/null +++ b/azurerm/resource_arm_hdinsight_spark_cluster.go @@ -0,0 +1,289 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this isn't a recommended way of building resources in Terraform +// this pattern is used to work around a generic but pedantic API endpoint +var hdInsightSparkClusterHeadNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 2, + MaxInstanceCount: 2, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(2)), +} + +var hdInsightSparkClusterWorkerNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: true, + MinInstanceCount: 1, + MaxInstanceCount: 19, + CanSpecifyDisks: false, +} + +var hdInsightSparkClusterZookeeperNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 3, + MaxInstanceCount: 3, + FixedTargetInstanceCount: utils.Int32(int32(3)), + CanSpecifyDisks: false, +} + +func resourceArmHDInsightSparkCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmHDInsightSparkClusterCreate, + Read: resourceArmHDInsightSparkClusterRead, + Update: hdinsightClusterUpdate("Spark", resourceArmHDInsightSparkClusterRead), + Delete: hdinsightClusterDelete("Spark"), + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "cluster_version": azure.SchemaHDInsightClusterVersion(), + + "tier": azure.SchemaHDInsightTier(), + + "component_version": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "spark": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + }, + + "gateway": azure.SchemaHDInsightsGateway(), + + "storage_account": azure.SchemaHDInsightsStorageAccounts(), + + "roles": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "head_node": azure.SchemaHDInsightNodeDefinition("roles.0.head_node", hdInsightSparkClusterHeadNodeDefinition), + + "worker_node": azure.SchemaHDInsightNodeDefinition("roles.0.worker_node", hdInsightSparkClusterWorkerNodeDefinition), + + "zookeeper_node": azure.SchemaHDInsightNodeDefinition("roles.0.zookeeper_node", hdInsightSparkClusterZookeeperNodeDefinition), + }, + }, + }, + + "tags": tags.Schema(), + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmHDInsightSparkClusterCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + clusterVersion := d.Get("cluster_version").(string) + t := d.Get("tags").(map[string]interface{}) + tier := hdinsight.Tier(d.Get("tier").(string)) + + componentVersionsRaw := d.Get("component_version").([]interface{}) + componentVersions := expandHDInsightSparkComponentVersion(componentVersionsRaw) + + gatewayRaw := d.Get("gateway").([]interface{}) + gateway := azure.ExpandHDInsightsConfigurations(gatewayRaw) + + storageAccountsRaw := d.Get("storage_account").([]interface{}) + storageAccounts, err := azure.ExpandHDInsightsStorageAccounts(storageAccountsRaw) + if err != nil { + return fmt.Errorf("Error expanding `storage_account`: %s", err) + } + + sparkRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightSparkClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightSparkClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightSparkClusterZookeeperNodeDefinition, + } + rolesRaw := d.Get("roles").([]interface{}) + roles, err := expandHDInsightRoles(rolesRaw, sparkRoles) + if err != nil { + return fmt.Errorf("Error expanding `roles`: %+v", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing HDInsight Spark Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_hdinsight_spark_cluster", *existing.ID) + } + } + + params := hdinsight.ClusterCreateParametersExtended{ + Location: utils.String(location), + Properties: &hdinsight.ClusterCreateProperties{ + Tier: tier, + OsType: hdinsight.Linux, + ClusterVersion: utils.String(clusterVersion), + ClusterDefinition: &hdinsight.ClusterDefinition{ + Kind: utils.String("Spark"), + ComponentVersion: componentVersions, + Configurations: gateway, + }, + StorageProfile: &hdinsight.StorageProfile{ + Storageaccounts: storageAccounts, + }, + ComputeProfile: &hdinsight.ComputeProfile{ + Roles: roles, + }, + }, + Tags: tags.Expand(t), + } + future, err := client.Create(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error creating HDInsight Spark Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of HDInsight Spark Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving HDInsight Spark Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Error reading ID for HDInsight Spark Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmHDInsightSparkClusterRead(d, meta) +} + +func resourceArmHDInsightSparkClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight Spark Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight Spark Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Configuration for HDInsight Spark Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + // storage_account isn't returned so I guess we just leave it ¯\_(ツ)_/¯ + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + if err := d.Set("component_version", flattenHDInsightSparkComponentVersion(def.ComponentVersion)); err != nil { + return fmt.Errorf("Error flattening `component_version`: %+v", err) + } + + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + } + + sparkRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightSparkClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightSparkClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightSparkClusterZookeeperNodeDefinition, + } + flattenedRoles := flattenHDInsightRoles(d, props.ComputeProfile, sparkRoles) + if err := d.Set("roles", flattenedRoles); err != nil { + return fmt.Errorf("Error flattening `roles`: %+v", err) + } + + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func expandHDInsightSparkComponentVersion(input []interface{}) map[string]*string { + vs := input[0].(map[string]interface{}) + return map[string]*string{ + "Spark": utils.String(vs["spark"].(string)), + } +} + +func flattenHDInsightSparkComponentVersion(input map[string]*string) []interface{} { + sparkVersion := "" + if v, ok := input["Spark"]; ok { + if v != nil { + sparkVersion = *v + } + } + return []interface{}{ + map[string]interface{}{ + "spark": sparkVersion, + }, + } +} diff --git a/azurerm/resource_arm_hdinsight_spark_cluster_test.go b/azurerm/resource_arm_hdinsight_spark_cluster_test.go new file mode 100644 index 000000000000..977fea952afe --- /dev/null +++ b/azurerm/resource_arm_hdinsight_spark_cluster_test.go @@ -0,0 +1,606 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMHDInsightSparkCluster_basic(t *testing.T) { + resourceName := "azurerm_hdinsight_spark_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_spark_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightSparkCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightSparkCluster_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_hdinsight_spark_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_spark_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightSparkCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + Config: testAccAzureRMHDInsightSparkCluster_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_hdinsight_spark_cluster"), + }, + }, + }) +} + +func TestAccAzureRMHDInsightSparkCluster_update(t *testing.T) { + resourceName := "azurerm_hdinsight_spark_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_spark_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightSparkCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + { + Config: testAccAzureRMHDInsightSparkCluster_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightSparkCluster_sshKeys(t *testing.T) { + resourceName := "azurerm_hdinsight_spark_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_spark_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightSparkCluster_sshKeys(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "storage_account", + "roles.0.head_node.0.ssh_keys", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.ssh_keys", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.ssh_keys", + "roles.0.zookeeper_node.0.vm_size", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightSparkCluster_virtualNetwork(t *testing.T) { + resourceName := "azurerm_hdinsight_spark_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_spark_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightSparkCluster_virtualNetwork(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightSparkCluster_complete(t *testing.T) { + resourceName := "azurerm_hdinsight_spark_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_spark_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightSparkCluster_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func testAccAzureRMHDInsightSparkCluster_basic(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightSparkCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_spark_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + spark = "2.3" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Medium" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightSparkCluster_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightSparkCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_spark_cluster" "import" { + name = "${azurerm_hdinsight_spark_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_spark_cluster.test.resource_group_name}" + location = "${azurerm_hdinsight_spark_cluster.test.location}" + cluster_version = "${azurerm_hdinsight_spark_cluster.test.cluster_version}" + tier = "${azurerm_hdinsight_spark_cluster.test.tier}" + component_version = "${azurerm_hdinsight_spark_cluster.test.component_version}" + gateway = "${azurerm_hdinsight_spark_cluster.test.gateway}" + storage_account = "${azurerm_hdinsight_spark_cluster.test.storage_account}" + roles = "${azurerm_hdinsight_spark_cluster.test.roles}" +} +`, template) +} + +func testAccAzureRMHDInsightSparkCluster_sshKeys(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightSparkCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +variable "ssh_key" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" +} + +resource "azurerm_hdinsight_spark_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + spark = "2.3" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Medium" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightSparkCluster_updated(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightSparkCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_spark_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + spark = "2.3" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 5 + } + + zookeeper_node { + vm_size = "Medium" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightSparkCluster_virtualNetwork(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightSparkCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_spark_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + spark = "2.3" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Medium" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightSparkCluster_complete(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightSparkCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_spark_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + spark = "2.3" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Medium" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightSparkCluster_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_hdinsight_storm_cluster.go b/azurerm/resource_arm_hdinsight_storm_cluster.go new file mode 100644 index 000000000000..f2d1d2a2b8ac --- /dev/null +++ b/azurerm/resource_arm_hdinsight_storm_cluster.go @@ -0,0 +1,290 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this isn't a recommended way of building resources in Terraform +// this pattern is used to work around a generic but pedantic API endpoint +var hdInsightStormClusterHeadNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 4, + MaxInstanceCount: 4, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(2)), +} + +var hdInsightStormClusterWorkerNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: true, + MinInstanceCount: 1, + // can't find a hard limit - appears to be limited by the subscription; setting something sensible for now + MaxInstanceCount: 9999, + CanSpecifyDisks: false, +} + +var hdInsightStormClusterZookeeperNodeDefinition = azure.HDInsightNodeDefinition{ + CanSpecifyInstanceCount: false, + MinInstanceCount: 3, + MaxInstanceCount: 3, + CanSpecifyDisks: false, + FixedTargetInstanceCount: utils.Int32(int32(3)), +} + +func resourceArmHDInsightStormCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmHDInsightStormClusterCreate, + Read: resourceArmHDInsightStormClusterRead, + Update: hdinsightClusterUpdate("Storm", resourceArmHDInsightStormClusterRead), + Delete: hdinsightClusterDelete("Storm"), + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": azure.SchemaHDInsightName(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "cluster_version": azure.SchemaHDInsightClusterVersion(), + + "tier": azure.SchemaHDInsightTier(), + + "component_version": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "storm": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + }, + + "gateway": azure.SchemaHDInsightsGateway(), + + "storage_account": azure.SchemaHDInsightsStorageAccounts(), + + "roles": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "head_node": azure.SchemaHDInsightNodeDefinition("roles.0.head_node", hdInsightStormClusterHeadNodeDefinition), + + "worker_node": azure.SchemaHDInsightNodeDefinition("roles.0.worker_node", hdInsightStormClusterWorkerNodeDefinition), + + "zookeeper_node": azure.SchemaHDInsightNodeDefinition("roles.0.zookeeper_node", hdInsightStormClusterZookeeperNodeDefinition), + }, + }, + }, + + "tags": tags.Schema(), + + "https_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "ssh_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmHDInsightStormClusterCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).hdinsight.ClustersClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + clusterVersion := d.Get("cluster_version").(string) + t := d.Get("tags").(map[string]interface{}) + tier := hdinsight.Tier(d.Get("tier").(string)) + + componentVersionsRaw := d.Get("component_version").([]interface{}) + componentVersions := expandHDInsightStormComponentVersion(componentVersionsRaw) + + gatewayRaw := d.Get("gateway").([]interface{}) + gateway := azure.ExpandHDInsightsConfigurations(gatewayRaw) + + storageAccountsRaw := d.Get("storage_account").([]interface{}) + storageAccounts, err := azure.ExpandHDInsightsStorageAccounts(storageAccountsRaw) + if err != nil { + return fmt.Errorf("Error expanding `storage_account`: %s", err) + } + + stormRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightStormClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightStormClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightStormClusterZookeeperNodeDefinition, + } + rolesRaw := d.Get("roles").([]interface{}) + roles, err := expandHDInsightRoles(rolesRaw, stormRoles) + if err != nil { + return fmt.Errorf("Error expanding `roles`: %+v", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing HDInsight Storm Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_hdinsight_storm_cluster", *existing.ID) + } + } + + params := hdinsight.ClusterCreateParametersExtended{ + Location: utils.String(location), + Properties: &hdinsight.ClusterCreateProperties{ + Tier: tier, + OsType: hdinsight.Linux, + ClusterVersion: utils.String(clusterVersion), + ClusterDefinition: &hdinsight.ClusterDefinition{ + Kind: utils.String("Storm"), + ComponentVersion: componentVersions, + Configurations: gateway, + }, + StorageProfile: &hdinsight.StorageProfile{ + Storageaccounts: storageAccounts, + }, + ComputeProfile: &hdinsight.ComputeProfile{ + Roles: roles, + }, + }, + Tags: tags.Expand(t), + } + future, err := client.Create(ctx, resourceGroup, name, params) + if err != nil { + return fmt.Errorf("Error creating HDInsight Storm Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of HDInsight Storm Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving HDInsight Storm Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Error reading ID for HDInsight Storm Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmHDInsightStormClusterRead(d, meta) +} + +func resourceArmHDInsightStormClusterRead(d *schema.ResourceData, meta interface{}) error { + clustersClient := meta.(*ArmClient).hdinsight.ClustersClient + configurationsClient := meta.(*ArmClient).hdinsight.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["clusters"] + + resp, err := clustersClient.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] HDInsight Storm Cluster %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving HDInsight Storm Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + configuration, err := configurationsClient.Get(ctx, resourceGroup, name, "gateway") + if err != nil { + return fmt.Errorf("Error retrieving Configuration for HDInsight Storm Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + // storage_account isn't returned so I guess we just leave it ¯\_(ツ)_/¯ + if props := resp.Properties; props != nil { + d.Set("cluster_version", props.ClusterVersion) + d.Set("tier", string(props.Tier)) + + if def := props.ClusterDefinition; def != nil { + if err := d.Set("component_version", flattenHDInsightStormComponentVersion(def.ComponentVersion)); err != nil { + return fmt.Errorf("Error flattening `component_version`: %+v", err) + } + + if err := d.Set("gateway", azure.FlattenHDInsightsConfigurations(configuration.Value)); err != nil { + return fmt.Errorf("Error flattening `gateway`: %+v", err) + } + } + + stormRoles := hdInsightRoleDefinition{ + HeadNodeDef: hdInsightStormClusterHeadNodeDefinition, + WorkerNodeDef: hdInsightStormClusterWorkerNodeDefinition, + ZookeeperNodeDef: hdInsightStormClusterZookeeperNodeDefinition, + } + flattenedRoles := flattenHDInsightRoles(d, props.ComputeProfile, stormRoles) + if err := d.Set("roles", flattenedRoles); err != nil { + return fmt.Errorf("Error flattening `roles`: %+v", err) + } + + httpEndpoint := azure.FindHDInsightConnectivityEndpoint("HTTPS", props.ConnectivityEndpoints) + d.Set("https_endpoint", httpEndpoint) + sshEndpoint := azure.FindHDInsightConnectivityEndpoint("SSH", props.ConnectivityEndpoints) + d.Set("ssh_endpoint", sshEndpoint) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func expandHDInsightStormComponentVersion(input []interface{}) map[string]*string { + vs := input[0].(map[string]interface{}) + return map[string]*string{ + "Storm": utils.String(vs["storm"].(string)), + } +} + +func flattenHDInsightStormComponentVersion(input map[string]*string) []interface{} { + stormVersion := "" + if v, ok := input["Storm"]; ok { + if v != nil { + stormVersion = *v + } + } + return []interface{}{ + map[string]interface{}{ + "storm": stormVersion, + }, + } +} diff --git a/azurerm/resource_arm_hdinsight_storm_cluster_test.go b/azurerm/resource_arm_hdinsight_storm_cluster_test.go new file mode 100644 index 000000000000..7aaef8fd79bb --- /dev/null +++ b/azurerm/resource_arm_hdinsight_storm_cluster_test.go @@ -0,0 +1,606 @@ +package azurerm + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMHDInsightStormCluster_basic(t *testing.T) { + resourceName := "azurerm_hdinsight_storm_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_storm_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightStormCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightStormCluster_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_hdinsight_storm_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_storm_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightStormCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + Config: testAccAzureRMHDInsightStormCluster_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_hdinsight_storm_cluster"), + }, + }, + }) +} + +func TestAccAzureRMHDInsightStormCluster_update(t *testing.T) { + resourceName := "azurerm_hdinsight_storm_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_storm_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightStormCluster_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + { + Config: testAccAzureRMHDInsightStormCluster_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightStormCluster_sshKeys(t *testing.T) { + resourceName := "azurerm_hdinsight_storm_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_storm_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightStormCluster_sshKeys(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "storage_account", + "roles.0.head_node.0.ssh_keys", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.ssh_keys", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.ssh_keys", + "roles.0.zookeeper_node.0.vm_size", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightStormCluster_virtualNetwork(t *testing.T) { + resourceName := "azurerm_hdinsight_storm_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_storm_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightStormCluster_virtualNetwork(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func TestAccAzureRMHDInsightStormCluster_complete(t *testing.T) { + resourceName := "azurerm_hdinsight_storm_cluster.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMHDInsightClusterDestroy("azurerm_hdinsight_storm_cluster"), + Steps: []resource.TestStep{ + { + Config: testAccAzureRMHDInsightStormCluster_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMHDInsightClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "https_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "ssh_endpoint"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "roles.0.head_node.0.password", + "roles.0.head_node.0.vm_size", + "roles.0.worker_node.0.password", + "roles.0.worker_node.0.vm_size", + "roles.0.zookeeper_node.0.password", + "roles.0.zookeeper_node.0.vm_size", + "storage_account", + }, + }, + }, + }) +} + +func testAccAzureRMHDInsightStormCluster_basic(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightStormCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_storm_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + storm = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightStormCluster_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightStormCluster_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_storm_cluster" "import" { + name = "${azurerm_hdinsight_storm_cluster.test.name}" + resource_group_name = "${azurerm_hdinsight_storm_cluster.test.resource_group_name}" + location = "${azurerm_hdinsight_storm_cluster.test.location}" + cluster_version = "${azurerm_hdinsight_storm_cluster.test.cluster_version}" + tier = "${azurerm_hdinsight_storm_cluster.test.tier}" + component_version = "${azurerm_hdinsight_storm_cluster.test.component_version}" + gateway = "${azurerm_hdinsight_storm_cluster.test.gateway}" + storage_account = "${azurerm_hdinsight_storm_cluster.test.storage_account}" + roles = "${azurerm_hdinsight_storm_cluster.test.roles}" +} +`, template) +} + +func testAccAzureRMHDInsightStormCluster_sshKeys(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightStormCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +variable "ssh_key" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" +} + +resource "azurerm_hdinsight_storm_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + storm = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + ssh_keys = ["${var.ssh_key}"] + } + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightStormCluster_updated(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightStormCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_hdinsight_storm_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + storm = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 5 + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt) +} + +func testAccAzureRMHDInsightStormCluster_virtualNetwork(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightStormCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_storm_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + storm = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightStormCluster_complete(rInt int, rString string, location string) string { + template := testAccAzureRMHDInsightStormCluster_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_hdinsight_storm_cluster" "test" { + name = "acctesthdi-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + storm = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.test.id}" + storage_account_key = "${azurerm_storage_account.test.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + worker_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + subnet_id = "${azurerm_subnet.test.id}" + virtual_network_id = "${azurerm_virtual_network.test.id}" + } + } + + tags = { + Hello = "World" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMHDInsightStormCluster_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_image.go b/azurerm/resource_arm_image.go index 9d923e211133..25434bc3d872 100644 --- a/azurerm/resource_arm_image.go +++ b/azurerm/resource_arm_image.go @@ -5,7 +5,10 @@ import ( "log" "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" @@ -31,9 +34,16 @@ func resourceArmImage() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), + + "zone_resilient": { + Type: schema.TypeBool, + Optional: true, + Default: false, + ForceNew: true, + }, "source_virtual_machine_id": { Type: schema.TypeString, @@ -51,7 +61,7 @@ func resourceArmImage() *schema.Resource { "os_type": { Type: schema.TypeString, Optional: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(compute.Linux), string(compute.Windows), @@ -61,7 +71,7 @@ func resourceArmImage() *schema.Resource { "os_state": { Type: schema.TypeString, Optional: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(compute.Generalized), string(compute.Specialized), @@ -72,7 +82,7 @@ func resourceArmImage() *schema.Resource { Type: schema.TypeString, Computed: true, Optional: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: azure.ValidateResourceID, }, @@ -88,7 +98,7 @@ func resourceArmImage() *schema.Resource { Type: schema.TypeString, Optional: true, Default: string(compute.None), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(compute.CachingTypesNone), string(compute.CachingTypesReadOnly), @@ -140,7 +150,7 @@ func resourceArmImage() *schema.Resource { string(compute.CachingTypesReadOnly), string(compute.CachingTypesReadWrite), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "size_gb": { @@ -153,21 +163,22 @@ func resourceArmImage() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmImageCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).imageClient + client := meta.(*ArmClient).compute.ImagesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Image creation.") name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) + zoneResilient := d.Get("zone_resilient").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -180,8 +191,8 @@ func resourceArmImageCreateUpdate(d *schema.ResourceData, meta interface{}) erro } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - expandedTags := expandTags(d.Get("tags").(map[string]interface{})) + location := azure.NormalizeLocation(d.Get("location").(string)) + expandedTags := tags.Expand(d.Get("tags").(map[string]interface{})) properties := compute.ImageProperties{} @@ -196,8 +207,9 @@ func resourceArmImageCreateUpdate(d *schema.ResourceData, meta interface{}) erro } storageProfile := compute.ImageStorageProfile{ - OsDisk: osDisk, - DataDisks: &dataDisks, + OsDisk: osDisk, + DataDisks: &dataDisks, + ZoneResilient: utils.Bool(zoneResilient), } sourceVM := compute.SubResource{} @@ -255,10 +267,10 @@ func resourceArmImageCreateUpdate(d *schema.ResourceData, meta interface{}) erro } func resourceArmImageRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).imageClient + client := meta.(*ArmClient).compute.ImagesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -277,7 +289,7 @@ func resourceArmImageRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } //either source VM or storage profile can be specified, but not both @@ -295,18 +307,17 @@ func resourceArmImageRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("[DEBUG] Error setting AzureRM Image Data Disks error: %+v", err) } } + d.Set("zone_resilient", resp.StorageProfile.ZoneResilient) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmImageDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).imageClient + client := meta.(*ArmClient).compute.ImagesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -355,7 +366,9 @@ func flattenAzureRmImageDataDisks(diskImages *[]compute.ImageDataDisk) []interfa if disk.DiskSizeGB != nil { l["size_gb"] = *disk.DiskSizeGB } - l["lun"] = *disk.Lun + if v := disk.Lun; v != nil { + l["lun"] = *v + } if disk.ManagedDisk != nil && disk.ManagedDisk.ID != nil { l["managed_disk_id"] = *disk.ManagedDisk.ID } @@ -383,7 +396,6 @@ func expandAzureRmImageOsDisk(d *schema.ResourceData) (*compute.ImageOSDisk, err osState := compute.OperatingSystemStateTypes(v) osDisk.OsState = osState } - managedDiskID := config["managed_disk_id"].(string) if managedDiskID != "" { managedDisk := &compute.SubResource{ @@ -417,8 +429,9 @@ func expandAzureRmImageDataDisks(d *schema.ResourceData) ([]compute.ImageDataDis for _, diskConfig := range disks { config := diskConfig.(map[string]interface{}) - managedDiskID := d.Get("managed_disk_id").(string) - blobURI := d.Get("blob_uri").(string) + managedDiskID := config["managed_disk_id"].(string) + + blobURI := config["blob_uri"].(string) lun := int32(config["lun"].(int)) dataDisk := compute.ImageDataDisk{ @@ -426,12 +439,12 @@ func expandAzureRmImageDataDisks(d *schema.ResourceData) ([]compute.ImageDataDis BlobURI: &blobURI, } - if size := d.Get("size_gb"); size != 0 { + if size := config["size_gb"]; size != 0 { diskSize := int32(size.(int)) dataDisk.DiskSizeGB = &diskSize } - if v := d.Get("caching").(string); v != "" { + if v := config["caching"].(string); v != "" { caching := compute.CachingTypes(v) dataDisk.Caching = caching } diff --git a/azurerm/resource_arm_image_test.go b/azurerm/resource_arm_image_test.go index f356b3f5c7f2..55f4009b6290 100644 --- a/azurerm/resource_arm_image_test.go +++ b/azurerm/resource_arm_image_test.go @@ -10,7 +10,9 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "golang.org/x/crypto/ssh" ) @@ -22,8 +24,48 @@ func TestAccAzureRMImage_standaloneImage(t *testing.T) { hostName := fmt.Sprintf("tftestcustomimagesrc%d", ri) sshPort := "22" location := testLocation() - preConfig := testAccAzureRMImage_standaloneImage_setup(ri, userName, password, hostName, location) - postConfig := testAccAzureRMImage_standaloneImage_provision(ri, userName, password, hostName, location) + preConfig := testAccAzureRMImage_standaloneImage_setup(ri, userName, password, hostName, location, "LRS") + postConfig := testAccAzureRMImage_standaloneImage_provision(ri, userName, password, hostName, location, "LRS") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMImageDestroy, + Steps: []resource.TestStep{ + { + //need to create a vm and then reference it in the image creation + Config: preConfig, + Destroy: false, + Check: resource.ComposeTestCheckFunc( + testCheckAzureVMExists("azurerm_virtual_machine.testsource", true), + testGeneralizeVMImage(resourceGroup, "testsource", userName, password, hostName, sshPort, location), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMImageExists("azurerm_image.test", true), + ), + }, + { + ResourceName: "azurerm_image.test", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMImage_standaloneImageZoneRedundant(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceGroup := fmt.Sprintf("acctestRG-%d", ri) + userName := "testadmin" + password := "Password1234!" + hostName := fmt.Sprintf("tftestcustomimagesrc%d", ri) + sshPort := "22" + location := testLocation() + preConfig := testAccAzureRMImage_standaloneImage_setup(ri, userName, password, hostName, location, "ZRS") + postConfig := testAccAzureRMImage_standaloneImage_provision(ri, userName, password, hostName, location, "ZRS") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -55,7 +97,7 @@ func TestAccAzureRMImage_standaloneImage(t *testing.T) { } func TestAccAzureRMImage_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -75,7 +117,7 @@ func TestAccAzureRMImage_requiresImport(t *testing.T) { Steps: []resource.TestStep{ { //need to create a vm and then reference it in the image creation - Config: testAccAzureRMImage_standaloneImage_setup(ri, userName, password, hostName, location), + Config: testAccAzureRMImage_standaloneImage_setup(ri, userName, password, hostName, location, "LRS"), Destroy: false, Check: resource.ComposeTestCheckFunc( testCheckAzureVMExists("azurerm_virtual_machine.testsource", true), @@ -83,7 +125,7 @@ func TestAccAzureRMImage_requiresImport(t *testing.T) { ), }, { - Config: testAccAzureRMImage_standaloneImage_provision(ri, userName, password, hostName, location), + Config: testAccAzureRMImage_standaloneImage_provision(ri, userName, password, hostName, location, "LRS"), Check: resource.ComposeTestCheckFunc( testCheckAzureRMImageExists("azurerm_image.test", true), ), @@ -204,10 +246,10 @@ func TestAccAzureRMImageVMSS_customImageVMSSFromVHD(t *testing.T) { func testGeneralizeVMImage(resourceGroup string, vmName string, userName string, password string, hostName string, port string, location string) resource.TestCheckFunc { return func(s *terraform.State) error { armClient := testAccProvider.Meta().(*ArmClient) - vmClient := armClient.vmClient + vmClient := armClient.compute.VMClient ctx := armClient.StopContext - normalizedLocation := azureRMNormalizeLocation(location) + normalizedLocation := azure.NormalizeLocation(location) suffix := armClient.environment.ResourceManagerVMDNSSuffix dnsName := fmt.Sprintf("%s.%s.%s", hostName, normalizedLocation, suffix) @@ -282,7 +324,7 @@ func testCheckAzureRMImageExists(resourceName string, shouldExist bool) resource return fmt.Errorf("Bad: no resource group found in state for image: %s", dName) } - client := testAccProvider.Meta().(*ArmClient).imageClient + client := testAccProvider.Meta().(*ArmClient).compute.ImagesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, dName, "") @@ -305,7 +347,7 @@ func testCheckAzureVMExists(sourceVM string, shouldExist bool) resource.TestChec return func(s *terraform.State) error { log.Printf("[INFO] testing MANAGED IMAGE VM EXISTS - BEGIN.") - client := testAccProvider.Meta().(*ArmClient).vmClient + client := testAccProvider.Meta().(*ArmClient).compute.VMClient ctx := testAccProvider.Meta().(*ArmClient).StopContext vmRs, vmOk := s.RootModule().Resources[sourceVM] if !vmOk { @@ -340,7 +382,7 @@ func testCheckAzureVMSSExists(sourceVMSS string, shouldExist bool) resource.Test return func(s *terraform.State) error { log.Printf("[INFO] testing MANAGED IMAGE VMSS EXISTS - BEGIN.") - vmssClient := testAccProvider.Meta().(*ArmClient).vmScaleSetClient + vmssClient := testAccProvider.Meta().(*ArmClient).compute.VMScaleSetClient ctx := testAccProvider.Meta().(*ArmClient).StopContext vmRs, vmOk := s.RootModule().Resources[sourceVMSS] if !vmOk { @@ -372,7 +414,7 @@ func testCheckAzureVMSSExists(sourceVMSS string, shouldExist bool) resource.Test } func testCheckAzureRMImageDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).diskClient + client := testAccProvider.Meta().(*ArmClient).compute.DisksClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -397,7 +439,7 @@ func testCheckAzureRMImageDestroy(s *terraform.State) error { return nil } -func testAccAzureRMImage_standaloneImage_setup(rInt int, userName string, password string, hostName string, location string) string { +func testAccAzureRMImage_standaloneImage_setup(rInt int, userName string, password string, hostName string, location string, storageType string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -444,7 +486,7 @@ resource "azurerm_storage_account" "test" { resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" account_tier = "Standard" - account_replication_type = "LRS" + account_replication_type = "%s" tags = { environment = "Dev" @@ -463,7 +505,7 @@ resource "azurerm_virtual_machine" "testsource" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" network_interface_ids = ["${azurerm_network_interface.testsource.id}"] - vm_size = "Standard_D1_v2" + vm_size = "Standard_F2" storage_image_reference { publisher = "Canonical" @@ -495,10 +537,10 @@ resource "azurerm_virtual_machine" "testsource" { cost-center = "Ops" } } -`, rInt, location, rInt, rInt, rInt, hostName, rInt, rInt, userName, password) +`, rInt, location, rInt, rInt, rInt, hostName, rInt, rInt, storageType, userName, password) } -func testAccAzureRMImage_standaloneImage_provision(rInt int, userName string, password string, hostName string, location string) string { +func testAccAzureRMImage_standaloneImage_provision(rInt int, userName string, password string, hostName string, location string, storageType string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -545,7 +587,7 @@ resource "azurerm_storage_account" "test" { resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" account_tier = "Standard" - account_replication_type = "LRS" + account_replication_type = "%s" tags = { environment = "Dev" @@ -569,7 +611,7 @@ resource "azurerm_virtual_machine" "testsource" { storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" - sku = "16.04-LTS" + sku = "18.04-LTS" version = "latest" } @@ -601,6 +643,7 @@ resource "azurerm_image" "test" { name = "accteste" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + zone_resilient = %t os_disk { os_type = "Linux" @@ -615,15 +658,14 @@ resource "azurerm_image" "test" { cost-center = "Ops" } } -`, rInt, location, rInt, rInt, rInt, hostName, rInt, rInt, userName, password) +`, rInt, location, rInt, rInt, rInt, hostName, rInt, rInt, storageType, userName, password, storageType == "ZRS") } func testAccAzureRMImage_standaloneImage_requiresImport(rInt int, userName string, password string, hostName string, location string) string { - template := testAccAzureRMImage_standaloneImage_provision(rInt, userName, password, hostName, location) + template := testAccAzureRMImage_standaloneImage_provision(rInt, userName, password, hostName, location, "LRS") return fmt.Sprintf(` %s - resource "azurerm_image" "import" { name = "${azurerm_image.test.name}" location = "${azurerm_image.test.location}" @@ -716,7 +758,7 @@ resource "azurerm_virtual_machine" "testsource" { storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" - sku = "16.04-LTS" + sku = "18.04-LTS" version = "latest" } @@ -817,7 +859,7 @@ resource "azurerm_virtual_machine" "testsource" { storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" - sku = "16.04-LTS" + sku = "18.04-LTS" version = "latest" } @@ -963,7 +1005,7 @@ resource "azurerm_virtual_machine" "testsource" { storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" - sku = "16.04-LTS" + sku = "18.04-LTS" version = "latest" } @@ -1043,7 +1085,7 @@ resource "azurerm_virtual_machine" "testsource" { storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" - sku = "16.04-LTS" + sku = "18.04-LTS" version = "latest" } @@ -1199,7 +1241,7 @@ resource "azurerm_virtual_machine" "testsource" { storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" - sku = "16.04-LTS" + sku = "18.04-LTS" version = "latest" } @@ -1300,7 +1342,7 @@ resource "azurerm_virtual_machine" "testsource" { storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" - sku = "16.04-LTS" + sku = "18.04-LTS" version = "latest" } diff --git a/azurerm/resource_arm_iot_dps.go b/azurerm/resource_arm_iot_dps.go new file mode 100644 index 000000000000..d12fee23a66d --- /dev/null +++ b/azurerm/resource_arm_iot_dps.go @@ -0,0 +1,360 @@ +package azurerm + +import ( + "context" + "fmt" + "log" + "regexp" + "strconv" + "time" + + "github.com/Azure/azure-sdk-for-go/services/preview/iothub/mgmt/2018-12-01-preview/devices" + "github.com/Azure/azure-sdk-for-go/services/provisioningservices/mgmt/2018-01-22/iothub" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmIotDPS() *schema.Resource { + return &schema.Resource{ + Create: resourceArmIotDPSCreateOrUpdate, + Read: resourceArmIotDPSRead, + Update: resourceArmIotDPSCreateOrUpdate, + Delete: resourceArmIotDPSDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.IoTHubName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), // azure.SchemaResourceGroupNameDiffSuppress(), + + "location": azure.SchemaLocation(), + + "sku": { + Type: schema.TypeList, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(devices.B1), + string(devices.B2), + string(devices.B3), + string(devices.F1), + string(devices.S1), + string(devices.S2), + string(devices.S3), + }, true), + }, + + "tier": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(devices.Basic), + string(devices.Free), + string(devices.Standard), + }, true), + }, + + "capacity": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + }, + }, + }, + + "linked_hub": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "connection_string": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + ForceNew: true, + // Azure returns the key as ****. We'll suppress that here. + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + secretKeyRegex := regexp.MustCompile("(SharedAccessKey)=[^;]+") + maskedNew := secretKeyRegex.ReplaceAllString(new, "$1=****") + return (new == d.Get(k).(string)) && (maskedNew == old) + }, + Sensitive: true, + }, + "location": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + StateFunc: azure.NormalizeLocation, + ForceNew: true, + }, + "apply_allocation_policy": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "allocation_weight": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + ValidateFunc: validation.IntBetween(0, 1000), + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmIotDPSCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.DPSResourceClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, name, resourceGroup) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_iot_dps", *existing.ID) + } + } + + iotdps := iothub.ProvisioningServiceDescription{ + Location: utils.String(d.Get("location").(string)), + Name: utils.String(name), + Sku: expandIoTDPSSku(d), + Properties: &iothub.IotDpsPropertiesDescription{ + IotHubs: expandIoTDPSIoTHubs(d.Get("linked_hub").([]interface{})), + }, + Tags: tags.Expand(d.Get("tags").(map[string]interface{})), + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, name, iotdps) + if err != nil { + return fmt.Errorf("Error creating/updating IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for the completion of the creating/updating of IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + resp, err := client.Get(ctx, name, resourceGroup) + if err != nil { + return fmt.Errorf("Error retrieving IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmIotDPSRead(d, meta) +} + +func resourceArmIotDPSRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.DPSResourceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["provisioningServices"] + + resp, err := client.Get(ctx, name, resourceGroup) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + sku := flattenIoTDPSSku(resp.Sku) + if err := d.Set("sku", sku); err != nil { + return fmt.Errorf("Error setting `sku`: %+v", err) + } + + if props := resp.Properties; props != nil { + if err := d.Set("linked_hub", flattenIoTDPSLinkedHub(props.IotHubs)); err != nil { + return fmt.Errorf("Error setting `linked_hub`: %+v", err) + } + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmIotDPSDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.DPSResourceClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["provisioningServices"] + + future, err := client.Delete(ctx, name, resourceGroup) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + return waitForIotDPSToBeDeleted(ctx, client, resourceGroup, name) +} + +func waitForIotDPSToBeDeleted(ctx context.Context, client *iothub.IotDpsResourceClient, resourceGroup, name string) error { + // we can't use the Waiter here since the API returns a 404 once it's deleted which is considered a polling status code.. + log.Printf("[DEBUG] Waiting for IoT Device Provisioning Service %q (Resource Group %q) to be deleted", name, resourceGroup) + stateConf := &resource.StateChangeConf{ + Pending: []string{"200"}, + Target: []string{"404"}, + Refresh: iotdpsStateStatusCodeRefreshFunc(ctx, client, resourceGroup, name), + Timeout: 40 * time.Minute, + } + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for IoT Device Provisioning Service %q (Resource Group %q) to be deleted: %+v", name, resourceGroup, err) + } + + return nil +} + +func iotdpsStateStatusCodeRefreshFunc(ctx context.Context, client *iothub.IotDpsResourceClient, resourceGroup, name string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + res, err := client.Get(ctx, name, resourceGroup) + + log.Printf("Retrieving IoT Device Provisioning Service %q (Resource Group %q) returned Status %d", resourceGroup, name, res.StatusCode) + + if err != nil { + if utils.ResponseWasNotFound(res.Response) { + return res, strconv.Itoa(res.StatusCode), nil + } + return nil, "", fmt.Errorf("Error polling for the status of the IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + return res, strconv.Itoa(res.StatusCode), nil + } +} + +func expandIoTDPSSku(d *schema.ResourceData) *iothub.IotDpsSkuInfo { + skuList := d.Get("sku").([]interface{}) + skuMap := skuList[0].(map[string]interface{}) + capacity := int64(skuMap["capacity"].(int)) + + name := skuMap["name"].(string) + tier := skuMap["tier"].(string) + + return &iothub.IotDpsSkuInfo{ + Name: iothub.IotDpsSku(name), + Tier: utils.String(tier), + Capacity: utils.Int64(capacity), + } +} + +func expandIoTDPSIoTHubs(input []interface{}) *[]iothub.DefinitionDescription { + linkedHubs := make([]iothub.DefinitionDescription, 0) + + for _, attr := range input { + linkedHubConfig := attr.(map[string]interface{}) + linkedHub := iothub.DefinitionDescription{ + ConnectionString: utils.String(linkedHubConfig["connection_string"].(string)), + AllocationWeight: utils.Int32(int32(linkedHubConfig["allocation_weight"].(int))), + ApplyAllocationPolicy: utils.Bool(linkedHubConfig["apply_allocation_policy"].(bool)), + Location: utils.String(linkedHubConfig["location"].(string)), + } + + linkedHubs = append(linkedHubs, linkedHub) + } + + return &linkedHubs +} + +func flattenIoTDPSSku(input *iothub.IotDpsSkuInfo) []interface{} { + output := make(map[string]interface{}) + + output["name"] = string(input.Name) + output["tier"] = input.Tier + if capacity := input.Capacity; capacity != nil { + output["capacity"] = int(*capacity) + } + + return []interface{}{output} +} + +func flattenIoTDPSLinkedHub(input *[]iothub.DefinitionDescription) []interface{} { + linkedHubs := make([]interface{}, 0) + if input == nil { + return linkedHubs + } + + for _, attr := range *input { + linkedHub := make(map[string]interface{}) + + if attr.Name != nil { + linkedHub["hostname"] = *attr.Name + } + if attr.ApplyAllocationPolicy != nil { + linkedHub["apply_allocation_policy"] = *attr.ApplyAllocationPolicy + } + if attr.AllocationWeight != nil { + linkedHub["allocation_weight"] = *attr.AllocationWeight + } + if attr.ConnectionString != nil { + linkedHub["connection_string"] = *attr.ConnectionString + } + if attr.Location != nil { + linkedHub["location"] = *attr.Location + } + + linkedHubs = append(linkedHubs, linkedHub) + } + + return linkedHubs +} diff --git a/azurerm/resource_arm_iot_dps_cerificate.go b/azurerm/resource_arm_iot_dps_cerificate.go new file mode 100644 index 000000000000..65f69005576c --- /dev/null +++ b/azurerm/resource_arm_iot_dps_cerificate.go @@ -0,0 +1,155 @@ +package azurerm + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" + + "github.com/Azure/azure-sdk-for-go/services/provisioningservices/mgmt/2018-01-22/iothub" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmIotDPSCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceArmIotDPSCertificateCreateOrUpdate, + Read: resourceArmIotDPSCertificateRead, + Update: resourceArmIotDPSCertificateCreateOrUpdate, + Delete: resourceArmIotDPSCertificateDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.IoTHubName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "iot_dps_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.IoTHubName, + }, + + "certificate_content": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + Sensitive: true, + }, + }, + } +} + +func resourceArmIotDPSCertificateCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.DPSCertificateClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + iotDPSName := d.Get("iot_dps_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_iot_dps_certificate", *existing.ID) + } + } + + certificate := iothub.CertificateBodyDescription{ + Certificate: utils.String(d.Get("certificate_content").(string)), + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, iotDPSName, name, certificate, ""); err != nil { + return fmt.Errorf("Error creating/updating IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + return fmt.Errorf("Error retrieving IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmIotDPSCertificateRead(d, meta) +} + +func resourceArmIotDPSCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.DPSCertificateClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + iotDPSName := id.Path["provisioningServices"] + name := id.Path["certificates"] + + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error retrieving IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("iot_dps_name", iotDPSName) + // We are unable to set `certificate_content` since it is not returned from the API + + return nil +} + +func resourceArmIotDPSCertificateDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.DPSCertificateClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + iotDPSName := id.Path["provisioningServices"] + name := id.Path["certificates"] + + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return fmt.Errorf("Error retrieving IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + if resp.Etag == nil { + return fmt.Errorf("Error deleting IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q) because Etag is nil", name, iotDPSName, resourceGroup) + } + + // TODO address this delete call if https://github.com/Azure/azure-rest-api-specs/pull/6311 get's merged + if _, err := client.Delete(ctx, resourceGroup, *resp.Etag, iotDPSName, name, "", nil, nil, iothub.ServerAuthentication, nil, nil, nil, ""); err != nil { + return fmt.Errorf("Error deleting IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + return nil +} diff --git a/azurerm/resource_arm_iot_dps_certificate_test.go b/azurerm/resource_arm_iot_dps_certificate_test.go new file mode 100644 index 000000000000..23c474abea97 --- /dev/null +++ b/azurerm/resource_arm_iot_dps_certificate_test.go @@ -0,0 +1,243 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMIotDPSCertificate_basic(t *testing.T) { + resourceName := "azurerm_iot_dps_certificate.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotDPSCertificate_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSCertificateExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "certificate_content", + }, + }, + }, + }) +} + +func TestAccAzureRMIotDPSCertificate_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_iot_dps_certificate.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotDPSCertificate_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSCertificateExists(resourceName), + ), + }, + { + Config: testAccAzureRMIotDPSCertificate_requiresImport(rInt, location), + ExpectError: testRequiresImportError("azurerm_iotdps"), + }, + }, + }) +} + +func TestAccAzureRMIotDPSCertificate_update(t *testing.T) { + resourceName := "azurerm_iot_dps_certificate.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotDPSCertificate_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSCertificateExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "certificate_content", + }, + }, + { + Config: testAccAzureRMIotDPSCertificate_update(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSCertificateExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "certificate_content", + }, + }, + }, + }) +} + +func testCheckAzureRMIotDPSCertificateDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).iothub.DPSCertificateClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_iot_dps_certificate" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + iotDPSName := rs.Primary.Attributes["iot_dps_name"] + + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("IoT Device Provisioning Service Certificate %s still exists in (device provisioning service %s / resource group %s)", name, iotDPSName, resourceGroup) + } + } + return nil +} + +func testCheckAzureRMIotDPSCertificateExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + iotDPSName := rs.Primary.Attributes["iot_dps_name"] + + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for IoT Device Provisioning Service Certificate: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).iothub.DPSCertificateClient + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q) does not exist", name, iotDPSName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on iothubDPSCertificateClient: %+v", err) + } + + return nil + + } +} + +func testAccAzureRMIotDPSCertificate_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iot_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} + +resource "azurerm_iot_dps_certificate" "test" { + name = "acctestIoTDPSCertificate-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + iot_dps_name = "${azurerm_iot_dps.test.name}" + + certificate_content = "${filebase64("testdata/batch_certificate.cer")}" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMIotDPSCertificate_requiresImport(rInt int, location string) string { + template := testAccAzureRMIotDPS_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_iot_dps_certificate" "test" { + name = "${azurerm_iot_dps_certificate.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + iot_dps_name = "${azurerm_iot_dps.test.name}" + + certificate_content = "${filebase64("testdata/batch_certificate.cer")}" +} +`, template) +} + +func testAccAzureRMIotDPSCertificate_update(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iot_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + tags = { + purpose = "testing" + } +} + +resource "azurerm_iot_dps_certificate" "test" { + name = "acctestIoTDPSCertificate-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + iot_dps_name = "${azurerm_iot_dps.test.name}" + + certificate_content = "${filebase64("testdata/application_gateway_test.cer")}" +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_iot_dps_test.go b/azurerm/resource_arm_iot_dps_test.go new file mode 100644 index 000000000000..75c431e4018f --- /dev/null +++ b/azurerm/resource_arm_iot_dps_test.go @@ -0,0 +1,314 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMIotDPS_basic(t *testing.T) { + resourceName := "azurerm_iot_dps.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotDPS_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMIotDPS_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_iot_dps.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotDPS_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSExists(resourceName), + ), + }, + { + Config: testAccAzureRMIotDPS_requiresImport(rInt, location), + ExpectError: testRequiresImportError("azurerm_iotdps"), + }, + }, + }) +} + +func TestAccAzureRMIotDPS_update(t *testing.T) { + resourceName := "azurerm_iot_dps.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotDPS_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMIotDPS_update(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMIotDPS_linkedHubs(t *testing.T) { + resourceName := "azurerm_iot_dps.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotDPS_linkedHubs(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMIotDPS_linkedHubsUpdated(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMIotDPSDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).iothub.DPSResourceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_iotdps" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("IoT Device Provisioning Service %s still exists in resource group %s", name, resourceGroup) + } + } + return nil +} + +func testCheckAzureRMIotDPSExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + iotdpsName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for IoT Device Provisioning Service: %s", iotdpsName) + } + + client := testAccProvider.Meta().(*ArmClient).iothub.DPSResourceClient + resp, err := client.Get(ctx, iotdpsName, resourceGroup) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: IoT Device Provisioning Service %q (Resource Group %q) does not exist", iotdpsName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on iothubDPSResourceClient: %+v", err) + } + + return nil + + } +} + +func testAccAzureRMIotDPS_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iot_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMIotDPS_requiresImport(rInt int, location string) string { + template := testAccAzureRMIotDPS_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_iot_dps" "import" { + name = "${azurerm_iot_dps.test.name}" + resource_group_name = "${azurerm_iot_dps.test.name}" + location = "${azurerm_iot_dps.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} +`, template) +} + +func testAccAzureRMIotDPS_update(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iot_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + tags = { + purpose = "testing" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMIotDPS_linkedHubs(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iot_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + linked_hub { + connection_string = "HostName=test.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=booo" + location = "${azurerm_resource_group.test.location}" + allocation_weight = 15 + apply_allocation_policy = true + } + + linked_hub { + connection_string = "HostName=test2.azure-devices.net;SharedAccessKeyName=iothubowner2;SharedAccessKey=key2" + location = "${azurerm_resource_group.test.location}" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMIotDPS_linkedHubsUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iot_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + linked_hub { + connection_string = "HostName=test.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=booo" + location = "${azurerm_resource_group.test.location}" + allocation_weight = 150 + } +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_iothub.go b/azurerm/resource_arm_iothub.go index d4fb8cee81af..d8da75e1e09e 100755 --- a/azurerm/resource_arm_iothub.go +++ b/azurerm/resource_arm_iothub.go @@ -14,13 +14,38 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +var iothubResourceName = "azurerm_iothub" + +func suppressIfTypeIsNot(t string) schema.SchemaDiffSuppressFunc { + return func(k, old, new string, d *schema.ResourceData) bool { + path := strings.Split(k, ".") + path[len(path)-1] = "type" + return d.Get(strings.Join(path, ".")).(string) != t + } +} + +func supressWhenAll(fs ...schema.SchemaDiffSuppressFunc) schema.SchemaDiffSuppressFunc { + return func(k, old, new string, d *schema.ResourceData) bool { + for _, f := range fs { + if !f(k, old, new, d) { + return false + } + } + return true + } +} + func resourceArmIotHub() *schema.Resource { return &schema.Resource{ Create: resourceArmIotHubCreateUpdate, @@ -39,9 +64,9 @@ func resourceArmIotHub() *schema.Resource { ValidateFunc: validate.IoTHubName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeList, @@ -139,6 +164,64 @@ func resourceArmIotHub() *schema.Resource { }, }, + "file_upload": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "connection_string": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + secretKeyRegex := regexp.MustCompile("(SharedAccessKey|AccountKey)=[^;]+") + sbProtocolRegex := regexp.MustCompile("sb://([^:]+)(:5671)?/;") + + // Azure will always mask the Access Keys and will include the port number in the GET response + // 5671 is the default port for Azure Service Bus connections + maskedNew := sbProtocolRegex.ReplaceAllString(new, "sb://$1:5671/;") + maskedNew = secretKeyRegex.ReplaceAllString(maskedNew, "$1=****") + return (new == d.Get(k).(string)) && (maskedNew == old) + }, + Sensitive: true, + }, + "container_name": { + Type: schema.TypeString, + Required: true, + }, + "notifications": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "max_delivery_count": { + Type: schema.TypeInt, + Optional: true, + Default: 10, + ValidateFunc: validation.IntBetween(1, 100), + }, + "sas_ttl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validate.ISO8601Duration, + }, + "default_ttl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validate.ISO8601Duration, + }, + "lock_duration": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validate.ISO8601Duration, + }, + }, + }, + }, + "endpoint": { Type: schema.TypeList, Optional: true, @@ -158,12 +241,14 @@ func resourceArmIotHub() *schema.Resource { Type: schema.TypeString, Required: true, DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // As Azure API masks the connection string key suppress diff for this property - if old != "" && strings.HasSuffix(old, "****") { - return true - } - - return false + secretKeyRegex := regexp.MustCompile("(SharedAccessKey|AccountKey)=[^;]+") + sbProtocolRegex := regexp.MustCompile("sb://([^:]+)(:5671)?/;") + + // Azure will always mask the Access Keys and will include the port number in the GET response + // 5671 is the default port for Azure Service Bus connections + maskedNew := sbProtocolRegex.ReplaceAllString(new, "sb://$1:5671/;") + maskedNew = secretKeyRegex.ReplaceAllString(maskedNew, "$1=****") + return (new == d.Get(k).(string)) && (maskedNew == old) }, Sensitive: true, }, @@ -173,25 +258,30 @@ func resourceArmIotHub() *schema.Resource { ValidateFunc: validateIoTHubEndpointName, }, "batch_frequency_in_seconds": { - Type: schema.TypeInt, - Optional: true, - Default: 300, - ValidateFunc: validation.IntBetween(60, 720), + Type: schema.TypeInt, + Optional: true, + Default: 300, + DiffSuppressFunc: suppressIfTypeIsNot("AzureIotHub.StorageContainer"), + ValidateFunc: validation.IntBetween(60, 720), }, "max_chunk_size_in_bytes": { - Type: schema.TypeInt, - Optional: true, - Default: 314572800, - ValidateFunc: validation.IntBetween(10485760, 524288000), + Type: schema.TypeInt, + Optional: true, + Default: 314572800, + DiffSuppressFunc: suppressIfTypeIsNot("AzureIotHub.StorageContainer"), + ValidateFunc: validation.IntBetween(10485760, 524288000), }, "container_name": { - Type: schema.TypeString, - Optional: true, - }, - "encoding": { Type: schema.TypeString, Optional: true, - DiffSuppressFunc: suppress.CaseDifference, + DiffSuppressFunc: suppressIfTypeIsNot("AzureIotHub.StorageContainer"), + }, + "encoding": { + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: supressWhenAll( + suppressIfTypeIsNot("AzureIotHub.StorageContainer"), + suppress.CaseDifference), ValidateFunc: validation.StringInSlice([]string{ string(devices.Avro), string(devices.AvroDeflate), @@ -297,21 +387,51 @@ func resourceArmIotHub() *schema.Resource { }, }, - "tags": tagsSchema(), + "ip_filter_rule": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "ip_mask": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.CIDR, + }, + "action": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(devices.Accept), + string(devices.Reject), + }, false), + }, + }, + }, + }, + + "tags": tags.Schema(), }, } } func resourceArmIotHubCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).iothubResourceClient + client := meta.(*ArmClient).iothub.ResourceClient ctx := meta.(*ArmClient).StopContext subscriptionID := meta.(*ArmClient).subscriptionId name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + locks.ByName(name, iothubResourceName) + defer locks.UnlockByName(name, iothubResourceName) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -338,9 +458,9 @@ func resourceArmIotHubCreateUpdate(d *schema.ResourceData, meta interface{}) err } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) skuInfo := expandIoTHubSku(d) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) fallbackRoute := expandIoTHubFallbackRoute(d) endpoints, err := expandIoTHubEndpoints(d, subscriptionID) @@ -348,20 +468,30 @@ func resourceArmIotHubCreateUpdate(d *schema.ResourceData, meta interface{}) err return fmt.Errorf("Error expanding `endpoint`: %+v", err) } + storageEndpoints, messagingEndpoints, enableFileUploadNotifications, err := expandIoTHubFileUpload(d) + if err != nil { + return fmt.Errorf("Error expanding `file_upload`: %+v", err) + } + routes := expandIoTHubRoutes(d) + ipFilterRules := expandIPFilterRules(d) properties := devices.IotHubDescription{ Name: utils.String(name), Location: utils.String(location), Sku: skuInfo, Properties: &devices.IotHubProperties{ + IPFilterRules: ipFilterRules, Routing: &devices.RoutingProperties{ Endpoints: endpoints, Routes: routes, FallbackRoute: fallbackRoute, }, + StorageEndpoints: storageEndpoints, + MessagingEndpoints: messagingEndpoints, + EnableFileUploadNotifications: &enableFileUploadNotifications, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resourceGroup, name, properties, "") @@ -384,10 +514,10 @@ func resourceArmIotHubCreateUpdate(d *schema.ResourceData, meta interface{}) err } func resourceArmIotHubRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).iothubResourceClient + client := meta.(*ArmClient).iothub.ResourceClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -450,35 +580,46 @@ func resourceArmIotHubRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("fallback_route", fallbackRoute); err != nil { return fmt.Errorf("Error setting `fallbackRoute` in IoTHub %q: %+v", name, err) } + + ipFilterRules := flattenIPFilterRules(properties.IPFilterRules) + if err := d.Set("ip_filter_rule", ipFilterRules); err != nil { + return fmt.Errorf("Error setting `ip_filter_rule` in IoTHub %q: %+v", name, err) + } + + fileUpload := flattenIoTHubFileUpload(properties.StorageEndpoints, properties.MessagingEndpoints, properties.EnableFileUploadNotifications) + if err := d.Set("file_upload", fileUpload); err != nil { + return fmt.Errorf("Error setting `file_upload` in IoTHub %q: %+v", name, err) + } } d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := hub.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } sku := flattenIoTHubSku(hub.Sku) if err := d.Set("sku", sku); err != nil { return fmt.Errorf("Error setting `sku`: %+v", err) } d.Set("type", hub.Type) - flattenAndSetTags(d, hub.Tags) - - return nil + return tags.FlattenAndSet(d, hub.Tags) } func resourceArmIotHubDelete(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } - client := meta.(*ArmClient).iothubResourceClient + client := meta.(*ArmClient).iothub.ResourceClient ctx := meta.(*ArmClient).StopContext name := id.Path["IotHubs"] resourceGroup := id.ResourceGroup + locks.ByName(name, iothubResourceName) + defer locks.UnlockByName(name, iothubResourceName) + future, err := client.Delete(ctx, resourceGroup, name) if err != nil { if response.WasNotFound(future.Response()) { @@ -490,7 +631,7 @@ func resourceArmIotHubDelete(d *schema.ResourceData, meta interface{}) error { return waitForIotHubToBeDeleted(ctx, client, resourceGroup, name) } -func waitForIotHubToBeDeleted(ctx context.Context, client devices.IotHubResourceClient, resourceGroup, name string) error { +func waitForIotHubToBeDeleted(ctx context.Context, client *devices.IotHubResourceClient, resourceGroup, name string) error { // we can't use the Waiter here since the API returns a 404 once it's deleted which is considered a polling status code.. log.Printf("[DEBUG] Waiting for IotHub (%q in Resource Group %q) to be deleted", name, resourceGroup) stateConf := &resource.StateChangeConf{ @@ -506,7 +647,7 @@ func waitForIotHubToBeDeleted(ctx context.Context, client devices.IotHubResource return nil } -func iothubStateStatusCodeRefreshFunc(ctx context.Context, client devices.IotHubResourceClient, resourceGroup, name string) resource.StateRefreshFunc { +func iothubStateStatusCodeRefreshFunc(ctx context.Context, client *devices.IotHubResourceClient, resourceGroup, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, resourceGroup, name) @@ -543,7 +684,7 @@ func expandIoTHubRoutes(d *schema.ResourceData) *[]devices.RouteProperties { Name: &name, Source: source, Condition: &condition, - EndpointNames: utils.ExpandStringArray(endpointNamesRaw), + EndpointNames: utils.ExpandStringSlice(endpointNamesRaw), IsEnabled: &isEnabled, }) } @@ -551,6 +692,40 @@ func expandIoTHubRoutes(d *schema.ResourceData) *[]devices.RouteProperties { return &routeProperties } +func expandIoTHubFileUpload(d *schema.ResourceData) (map[string]*devices.StorageEndpointProperties, map[string]*devices.MessagingEndpointProperties, bool, error) { + fileUploadList := d.Get("file_upload").([]interface{}) + + storageEndpointProperties := make(map[string]*devices.StorageEndpointProperties) + messagingEndpointProperties := make(map[string]*devices.MessagingEndpointProperties) + notifications := false + + if len(fileUploadList) > 0 { + fileUploadMap := fileUploadList[0].(map[string]interface{}) + + connectionStr := fileUploadMap["connection_string"].(string) + containerName := fileUploadMap["container_name"].(string) + notifications = fileUploadMap["notifications"].(bool) + maxDeliveryCount := int32(fileUploadMap["max_delivery_count"].(int)) + sasTTL := fileUploadMap["sas_ttl"].(string) + defaultTTL := fileUploadMap["default_ttl"].(string) + lockDuration := fileUploadMap["lock_duration"].(string) + + storageEndpointProperties["$default"] = &devices.StorageEndpointProperties{ + SasTTLAsIso8601: &sasTTL, + ConnectionString: &connectionStr, + ContainerName: &containerName, + } + + messagingEndpointProperties["fileNotifications"] = &devices.MessagingEndpointProperties{ + LockDurationAsIso8601: &lockDuration, + TTLAsIso8601: &defaultTTL, + MaxDeliveryCount: &maxDeliveryCount, + } + } + + return storageEndpointProperties, messagingEndpointProperties, notifications, nil +} + func expandIoTHubEndpoints(d *schema.ResourceData, subscriptionId string) (*devices.RoutingEndpoints, error) { routeEndpointList := d.Get("endpoint").([]interface{}) @@ -641,7 +816,7 @@ func expandIoTHubFallbackRoute(d *schema.ResourceData) *devices.FallbackRoutePro return &devices.FallbackRouteProperties{ Source: &source, Condition: &condition, - EndpointNames: utils.ExpandStringArray(fallbackRouteMap["endpoint_names"].([]interface{})), + EndpointNames: utils.ExpandStringSlice(fallbackRouteMap["endpoint_names"].([]interface{})), IsEnabled: &isEnabled, } } @@ -700,6 +875,43 @@ func flattenIoTHubSharedAccessPolicy(input *[]devices.SharedAccessSignatureAutho return results } +func flattenIoTHubFileUpload(storageEndpoints map[string]*devices.StorageEndpointProperties, messagingEndpoints map[string]*devices.MessagingEndpointProperties, enableFileUploadNotifications *bool) []interface{} { + results := make([]interface{}, 0) + output := make(map[string]interface{}) + + if storageEndpointProperties, ok := storageEndpoints["$default"]; ok { + if connString := storageEndpointProperties.ConnectionString; connString != nil { + output["connection_string"] = *connString + } + if containerName := storageEndpointProperties.ContainerName; containerName != nil { + output["container_name"] = *containerName + } + if sasTTLAsIso8601 := storageEndpointProperties.SasTTLAsIso8601; sasTTLAsIso8601 != nil { + output["sas_ttl"] = *sasTTLAsIso8601 + } + + if messagingEndpointProperties, ok := messagingEndpoints["fileNotifications"]; ok { + if lockDurationAsIso8601 := messagingEndpointProperties.LockDurationAsIso8601; lockDurationAsIso8601 != nil { + output["lock_duration"] = *lockDurationAsIso8601 + } + if ttlAsIso8601 := messagingEndpointProperties.TTLAsIso8601; ttlAsIso8601 != nil { + output["default_ttl"] = *ttlAsIso8601 + } + if maxDeliveryCount := messagingEndpointProperties.MaxDeliveryCount; maxDeliveryCount != nil { + output["max_delivery_count"] = *maxDeliveryCount + } + } + + if enableFileUploadNotifications != nil { + output["notifications"] = *enableFileUploadNotifications + } + + results = append(results, output) + } + + return results +} + func flattenIoTHubEndpoint(input *devices.RoutingProperties) []interface{} { results := make([]interface{}, 0) @@ -836,7 +1048,7 @@ func flattenIoTHubFallbackRoute(input *devices.RoutingProperties) []interface{} output["source"] = *source } - output["endpoint_names"] = utils.FlattenStringArray(route.EndpointNames) + output["endpoint_names"] = utils.FlattenStringSlice(route.EndpointNames) return []interface{}{output} } @@ -881,3 +1093,46 @@ func validateIoTHubFileNameFormat(v interface{}, k string) (warnings []string, e return warnings, errors } +func expandIPFilterRules(d *schema.ResourceData) *[]devices.IPFilterRule { + ipFilterRuleList := d.Get("ip_filter_rule").(*schema.Set).List() + if len(ipFilterRuleList) == 0 { + return nil + } + + rules := make([]devices.IPFilterRule, 0) + + for _, r := range ipFilterRuleList { + rawRule := r.(map[string]interface{}) + rule := &devices.IPFilterRule{ + FilterName: utils.String(rawRule["name"].(string)), + Action: devices.IPFilterActionType(rawRule["action"].(string)), + IPMask: utils.String(rawRule["ip_mask"].(string)), + } + + rules = append(rules, *rule) + } + return &rules +} + +func flattenIPFilterRules(in *[]devices.IPFilterRule) []interface{} { + rules := make([]interface{}, 0) + if in == nil { + return rules + } + + for _, r := range *in { + rawRule := make(map[string]interface{}) + + if r.FilterName != nil { + rawRule["name"] = *r.FilterName + } + + rawRule["action"] = string(r.Action) + + if r.IPMask != nil { + rawRule["ip_mask"] = *r.IPMask + } + rules = append(rules, rawRule) + } + return rules +} diff --git a/azurerm/resource_arm_iothub_consumer_group.go b/azurerm/resource_arm_iothub_consumer_group.go index 1ca0e8c78326..fc00ce1c6440 100644 --- a/azurerm/resource_arm_iothub_consumer_group.go +++ b/azurerm/resource_arm_iothub_consumer_group.go @@ -5,8 +5,10 @@ import ( "log" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,13 +42,13 @@ func resourceArmIotHubConsumerGroup() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), }, } } func resourceArmIotHubConsumerGroupCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).iothubResourceClient + client := meta.(*ArmClient).iothub.ResourceClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM IoTHub Consumer Group creation.") @@ -55,7 +57,7 @@ func resourceArmIotHubConsumerGroupCreate(d *schema.ResourceData, meta interface endpointName := d.Get("eventhub_endpoint_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -87,10 +89,10 @@ func resourceArmIotHubConsumerGroupCreate(d *schema.ResourceData, meta interface } func resourceArmIotHubConsumerGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).iothubResourceClient + client := meta.(*ArmClient).iothub.ResourceClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -118,10 +120,10 @@ func resourceArmIotHubConsumerGroupRead(d *schema.ResourceData, meta interface{} } func resourceArmIotHubConsumerGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).iothubResourceClient + client := meta.(*ArmClient).iothub.ResourceClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_iothub_consumer_group_test.go b/azurerm/resource_arm_iothub_consumer_group_test.go index c24be32ffde3..ddcea40b3aed 100644 --- a/azurerm/resource_arm_iothub_consumer_group_test.go +++ b/azurerm/resource_arm_iothub_consumer_group_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMIotHubConsumerGroup_events(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMIotHubConsumerGroup_events(t *testing.T) { } func TestAccAzureRMIotHubConsumerGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -92,7 +93,7 @@ func TestAccAzureRMIotHubConsumerGroup_operationsMonitoringEvents(t *testing.T) } func testCheckAzureRMIotHubConsumerGroupDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).iothubResourceClient + client := testAccProvider.Meta().(*ArmClient).iothub.ResourceClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -132,7 +133,7 @@ func testCheckAzureRMIotHubConsumerGroupExists(resourceName string) resource.Tes endpointName := rs.Primary.Attributes["eventhub_endpoint_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).iothubResourceClient + client := testAccProvider.Meta().(*ArmClient).iothub.ResourceClient resp, err := client.GetEventHubConsumerGroup(ctx, resourceGroup, iotHubName, endpointName, name) if err != nil { if resp.StatusCode == http.StatusNotFound { @@ -166,7 +167,7 @@ resource "azurerm_iothub" "test" { } tags = { - "purpose" = "testing" + purpose = "testing" } } diff --git a/azurerm/resource_arm_iothub_shared_access_policy.go b/azurerm/resource_arm_iothub_shared_access_policy.go new file mode 100644 index 000000000000..7127ae2a9e79 --- /dev/null +++ b/azurerm/resource_arm_iothub_shared_access_policy.go @@ -0,0 +1,358 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/preview/iothub/mgmt/2018-12-01-preview/devices" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmIotHubSharedAccessPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceArmIotHubSharedAccessPolicyCreateUpdate, + Read: resourceArmIotHubSharedAccessPolicyRead, + Update: resourceArmIotHubSharedAccessPolicyCreateUpdate, + Delete: resourceArmIotHubSharedAccessPolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`[a-zA-Z0-9!._-]{1,64}`), ""+ + "The shared access policy key name must not be empty, and must not exceed 64 characters in length. The shared access policy key name can only contain alphanumeric characters, exclamation marks, periods, underscores and hyphens."), + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "iothub_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.IoTHubName, + }, + + "registry_read": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "registry_write": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "service_connect": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "device_connect": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "primary_key": { + Type: schema.TypeString, + Sensitive: true, + Computed: true, + }, + + "primary_connection_string": { + Type: schema.TypeString, + Sensitive: true, + Computed: true, + }, + + "secondary_key": { + Type: schema.TypeString, + Sensitive: true, + Computed: true, + }, + + "secondary_connection_string": { + Type: schema.TypeString, + Sensitive: true, + Computed: true, + }, + }, + CustomizeDiff: iothubSharedAccessPolicyCustomizeDiff, + } +} + +func iothubSharedAccessPolicyCustomizeDiff(d *schema.ResourceDiff, _ interface{}) (err error) { + registryRead, hasRegistryRead := d.GetOk("registry_read") + registryWrite, hasRegistryWrite := d.GetOk("registry_write") + serviceConnect, hasServieConnect := d.GetOk("service_connect") + deviceConnect, hasDeviceConnect := d.GetOk("device_connect") + + if !hasRegistryRead && !hasRegistryWrite && !hasServieConnect && !hasDeviceConnect { + return fmt.Errorf("One of `registry_read`, `registry_write`, `service_connect` or `device_connect` properties must be set") + } + + if !registryRead.(bool) && !registryWrite.(bool) && !serviceConnect.(bool) && !deviceConnect.(bool) { + err = multierror.Append(err, fmt.Errorf("At least one of `registry_read`, `registry_write`, `service_connect` or `device_connect` properties must be set to true")) + } + + if registryWrite.(bool) && !registryRead.(bool) { + err = multierror.Append(err, fmt.Errorf("If `registry_write` is set to true, `registry_read` must also be set to true")) + } + + return +} + +func resourceArmIotHubSharedAccessPolicyCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.ResourceClient + ctx := meta.(*ArmClient).StopContext + + iothubName := d.Get("iothub_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + locks.ByName(iothubName, iothubResourceName) + defer locks.UnlockByName(iothubName, iothubResourceName) + + iothub, err := client.Get(ctx, resourceGroup, iothubName) + if err != nil { + if utils.ResponseWasNotFound(iothub.Response) { + return fmt.Errorf("IotHub %q (Resource Group %q) was not found", iothubName, resourceGroup) + } + + return fmt.Errorf("Error loading IotHub %q (Resource Group %q): %+v", iothubName, resourceGroup, err) + } + + keyName := d.Get("name").(string) + + resourceId := fmt.Sprintf("%s/IotHubKeys/%s", *iothub.ID, keyName) + + expandedAccessPolicy := devices.SharedAccessSignatureAuthorizationRule{ + KeyName: &keyName, + Rights: devices.AccessRights(expandAccessRights(d)), + } + + accessPolicies := make([]devices.SharedAccessSignatureAuthorizationRule, 0) + + alreadyExists := false + for accessPolicyIterator, err := client.ListKeysComplete(ctx, resourceGroup, iothubName); accessPolicyIterator.NotDone(); err = accessPolicyIterator.NextWithContext(ctx) { + if err != nil { + return fmt.Errorf("Error loading Shared Access Profiles of IotHub %q (Resource Group %q): %+v", iothubName, resourceGroup, err) + } + existingAccessPolicy := accessPolicyIterator.Value() + + if strings.EqualFold(*existingAccessPolicy.KeyName, keyName) { + if features.ShouldResourcesBeImported() && d.IsNewResource() { + return tf.ImportAsExistsError("azurerm_iothub_shared_access_policy", resourceId) + } + accessPolicies = append(accessPolicies, expandedAccessPolicy) + alreadyExists = true + } else { + accessPolicies = append(accessPolicies, existingAccessPolicy) + } + } + + if d.IsNewResource() { + accessPolicies = append(accessPolicies, expandedAccessPolicy) + } else if !alreadyExists { + return fmt.Errorf("Unable to find Shared Access Policy %q defined for IotHub %q (Resource Group %q)", keyName, iothubName, resourceGroup) + } + + iothub.Properties.AuthorizationPolicies = &accessPolicies + + future, err := client.CreateOrUpdate(ctx, resourceGroup, iothubName, iothub, "") + if err != nil { + return fmt.Errorf("Error updating IotHub %q (Resource Group %q) with Shared Access Profile %q: %+v", iothubName, resourceGroup, keyName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for IotHub %q (Resource Group %q) to finish updating Shared Access Profile %q: %+v", iothubName, resourceGroup, keyName, err) + } + + d.SetId(resourceId) + + return resourceArmIotHubSharedAccessPolicyRead(d, meta) +} + +func resourceArmIotHubSharedAccessPolicyRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.ResourceClient + ctx := meta.(*ArmClient).StopContext + + parsedIothubSAPId, err := azure.ParseAzureResourceID(d.Id()) + + if err != nil { + return err + } + + resourceGroup := parsedIothubSAPId.ResourceGroup + iothubName := parsedIothubSAPId.Path["IotHubs"] + keyName := parsedIothubSAPId.Path["IotHubKeys"] + + accessPolicy, err := client.GetKeysForKeyName(ctx, resourceGroup, iothubName, keyName) + if err != nil { + if utils.ResponseWasNotFound(accessPolicy.Response) { + log.Printf("[DEBUG] Shared Access Policy %q was not found on IotHub %q (Resource Group %q) - removing from state", keyName, iothubName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error loading IotHub Shared Access Policy %q (Resource Group %q): %+v", iothubName, resourceGroup, err) + } + + iothub, err := client.Get(ctx, resourceGroup, iothubName) + if err != nil { + return fmt.Errorf("Error loading IotHub %q (Resource Group %q): %+v", iothubName, resourceGroup, err) + } + + d.Set("name", keyName) + d.Set("iothub_name", iothubName) + d.Set("resource_group_name", resourceGroup) + + d.Set("primary_key", accessPolicy.PrimaryKey) + if err := d.Set("primary_connection_string", getSharedAccessPolicyConnectionString(*iothub.Properties.HostName, keyName, *accessPolicy.PrimaryKey)); err != nil { + return fmt.Errorf("error setting `primary_connection_string`: %v", err) + } + d.Set("secondary_key", accessPolicy.SecondaryKey) + if err := d.Set("secondary_connection_string", getSharedAccessPolicyConnectionString(*iothub.Properties.HostName, keyName, *accessPolicy.SecondaryKey)); err != nil { + return fmt.Errorf("error setting `secondary_connection_string`: %v", err) + } + + rights := flattenAccessRights(accessPolicy.Rights) + d.Set("registry_read", rights.registryRead) + d.Set("registry_write", rights.registryWrite) + d.Set("device_connect", rights.deviceConnect) + d.Set("service_connect", rights.serviceConnect) + + return nil +} + +func resourceArmIotHubSharedAccessPolicyDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).iothub.ResourceClient + ctx := meta.(*ArmClient).StopContext + + parsedIothubSAPId, err := azure.ParseAzureResourceID(d.Id()) + + if err != nil { + return err + } + + resourceGroup := parsedIothubSAPId.ResourceGroup + iothubName := parsedIothubSAPId.Path["IotHubs"] + keyName := parsedIothubSAPId.Path["IotHubKeys"] + + locks.ByName(iothubName, iothubResourceName) + defer locks.UnlockByName(iothubName, iothubResourceName) + + iothub, err := client.Get(ctx, resourceGroup, iothubName) + if err != nil { + if utils.ResponseWasNotFound(iothub.Response) { + return fmt.Errorf("IotHub %q (Resource Group %q) was not found", iothubName, resourceGroup) + } + + return fmt.Errorf("Error loading IotHub %q (Resource Group %q): %+v", iothubName, resourceGroup, err) + } + + accessPolicies := make([]devices.SharedAccessSignatureAuthorizationRule, 0) + + for accessPolicyIterator, err := client.ListKeysComplete(ctx, resourceGroup, iothubName); accessPolicyIterator.NotDone(); err = accessPolicyIterator.NextWithContext(ctx) { + if err != nil { + return fmt.Errorf("Error loading Shared Access Profiles of IotHub %q (Resource Group %q): %+v", iothubName, resourceGroup, err) + } + existingAccessPolicy := accessPolicyIterator.Value() + + if !strings.EqualFold(*existingAccessPolicy.KeyName, keyName) { + accessPolicies = append(accessPolicies, existingAccessPolicy) + } + } + + iothub.Properties.AuthorizationPolicies = &accessPolicies + + future, err := client.CreateOrUpdate(ctx, resourceGroup, iothubName, iothub, "") + if err != nil { + return fmt.Errorf("Error updating IotHub %q (Resource Group %q) with Shared Access Profile %q: %+v", iothubName, resourceGroup, keyName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for IotHub %q (Resource Group %q) to finish updating Shared Access Profile %q: %+v", iothubName, resourceGroup, keyName, err) + } + + return nil +} + +type accessRights struct { + registryRead bool + registryWrite bool + serviceConnect bool + deviceConnect bool +} + +func expandAccessRights(d *schema.ResourceData) string { + + var possibleAccessRights = []struct { + schema string + right string + }{ + {"registry_read", "RegistryRead"}, + {"registry_write", "RegistryWrite"}, + {"service_connect", "ServiceConnect"}, + {"device_connect", "DeviceConnect"}, + } + actualRights := make([]string, 0) + // iteration order is important here, so we cannot use a map + for _, possibleRight := range possibleAccessRights { + if d.Get(possibleRight.schema).(bool) { + actualRights = append(actualRights, possibleRight.right) + } + } + strRights := strings.Join(actualRights, ", ") + return strRights +} + +func flattenAccessRights(r devices.AccessRights) accessRights { + rights := accessRights{ + registryRead: false, + registryWrite: false, + deviceConnect: false, + serviceConnect: false, + } + + actualAccessRights := strings.Split(string(r), ",") + + for _, right := range actualAccessRights { + switch strings.ToLower(strings.Trim(right, " ")) { + case "registrywrite": + rights.registryWrite = true + // RegistryWrite implies RegistryRead. + // What's more, creating a Access Policy with both RegistryRead and RegistryWrite + // only really sets RegistryWrite permission, which then also implies RedistryRead + fallthrough + case "registryread": + rights.registryRead = true + case "deviceconnect": + rights.deviceConnect = true + case "serviceconnect": + rights.serviceConnect = true + } + } + + return rights +} + +func getSharedAccessPolicyConnectionString(iothubHostName string, keyName string, key string) string { + return fmt.Sprintf("HostName=%s;SharedAccessKeyName=%s;SharedAccessKey=%s", iothubHostName, keyName, key) +} diff --git a/azurerm/resource_arm_iothub_shared_access_policy_test.go b/azurerm/resource_arm_iothub_shared_access_policy_test.go new file mode 100644 index 000000000000..c347548bac29 --- /dev/null +++ b/azurerm/resource_arm_iothub_shared_access_policy_test.go @@ -0,0 +1,236 @@ +package azurerm + +import ( + "fmt" + "regexp" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMIotHubSharedAccessPolicy_basic(t *testing.T) { + resourceName := "azurerm_iothub_shared_access_policy.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubSharedAccessPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubSharedAccessPolicy_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubSharedAccessPolicyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "registry_read", "true"), + resource.TestCheckResourceAttr(resourceName, "registry_write", "true"), + resource.TestCheckResourceAttr(resourceName, "service_connect", "false"), + resource.TestCheckResourceAttr(resourceName, "device_connect", "false"), + resource.TestCheckResourceAttr(resourceName, "name", "acctest"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMIotHubSharedAccessPolicy_writeWithoutRead(t *testing.T) { + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubSharedAccessPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubSharedAccessPolicy_writeWithoutRead(rInt, testLocation()), + ExpectError: regexp.MustCompile("If `registry_write` is set to true, `registry_read` must also be set to true"), + }, + }, + }) +} + +func TestAccAzureRMIotHubSharedAccessPolicy_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_iothub_shared_access_policy.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubSharedAccessPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubSharedAccessPolicy_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubSharedAccessPolicyExists(resourceName), + ), + }, + { + Config: testAccAzureRMIotHubSharedAccessPolicy_requiresImport(rInt, location), + ExpectError: testRequiresImportError("azurerm_iothub_shared_access_policy"), + }, + }, + }) +} + +func testAccAzureRMIotHubSharedAccessPolicy_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub" "test" { + name = "acctestIoTHub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "B1" + tier = "Basic" + capacity = "1" + } + + tags = { + purpose = "testing" + } +} + +resource "azurerm_iothub_shared_access_policy" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + iothub_name = "${azurerm_iothub.test.name}" + name = "acctest" + + registry_read = true + registry_write = true +} +`, rInt, location, rInt) +} + +func testAccAzureRMIotHubSharedAccessPolicy_requiresImport(rInt int, location string) string { + template := testAccAzureRMIotHubSharedAccessPolicy_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_iothub_shared_access_policy" "import" { + resource_group_name = "${azurerm_resource_group.test.name}" + iothub_name = "${azurerm_iothub.test.name}" + name = "acctest" + + registry_read = true + registry_write = true +} +`, template) +} + +func testAccAzureRMIotHubSharedAccessPolicy_writeWithoutRead(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub" "test" { + name = "acctestIoTHub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "B1" + tier = "Basic" + capacity = "1" + } + + tags = { + purpose = "testing" + } +} + +resource "azurerm_iothub_shared_access_policy" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + iothub_name = "${azurerm_iothub.test.name}" + name = "acctest" + + registry_write = true +} +`, rInt, location, rInt) +} + +func testCheckAzureRMIotHubSharedAccessPolicyExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + parsedIothubId, err := azure.ParseAzureResourceID(rs.Primary.ID) + if err != nil { + return err + } + iothubName := parsedIothubId.Path["IotHubs"] + keyName := parsedIothubId.Path["IotHubKeys"] + resourceGroup := parsedIothubId.ResourceGroup + + client := testAccProvider.Meta().(*ArmClient).iothub.ResourceClient + + for accessPolicyIterator, err := client.ListKeysComplete(ctx, resourceGroup, iothubName); accessPolicyIterator.NotDone(); err = accessPolicyIterator.NextWithContext(ctx) { + if err != nil { + return fmt.Errorf("Error loading Shared Access Profiles of IotHub %q (Resource Group %q): %+v", iothubName, resourceGroup, err) + } + + if strings.EqualFold(*accessPolicyIterator.Value().KeyName, keyName) { + return nil + } + } + + return fmt.Errorf("Bad: No shared access policy %s defined for IotHub %s", keyName, iothubName) + + } +} + +func testCheckAzureRMIotHubSharedAccessPolicyDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).iothub.ResourceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_iothub_shared_access_policy" { + continue + } + + keyName := rs.Primary.Attributes["name"] + iothubName := rs.Primary.Attributes["iothub_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, iothubName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return fmt.Errorf("Bad: Get on iothubResourceClient: %+v", err) + } + + for _, sharedAccessPolicy := range *resp.Properties.AuthorizationPolicies { + if *sharedAccessPolicy.KeyName == keyName { + return fmt.Errorf("Bad: Shared Access Policy %s still exists on IoTHb %s", keyName, iothubName) + } + } + } + return nil +} diff --git a/azurerm/resource_arm_iothub_test.go b/azurerm/resource_arm_iothub_test.go index c89be0f3fd78..475292d90e45 100644 --- a/azurerm/resource_arm_iothub_test.go +++ b/azurerm/resource_arm_iothub_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMIotHub_basic(t *testing.T) { @@ -35,8 +36,32 @@ func TestAccAzureRMIotHub_basic(t *testing.T) { }) } +func TestAccAzureRMIotHub_ipFilterRules(t *testing.T) { + resourceName := "azurerm_iothub.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHub_ipFilterRules(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMIotHub_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -102,6 +127,37 @@ func TestAccAzureRMIotHub_customRoutes(t *testing.T) { Config: testAccAzureRMIotHub_customRoutes(rInt, rStr, testLocation()), Check: resource.ComposeTestCheckFunc( testCheckAzureRMIotHubExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "endpoint.#", "2"), + resource.TestCheckResourceAttr(resourceName, "endpoint.0.type", "AzureIotHub.StorageContainer"), + resource.TestCheckResourceAttr(resourceName, "endpoint.1.type", "AzureIotHub.EventHub"), + resource.TestCheckResourceAttr(resourceName, "route.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMIotHub_fileUpload(t *testing.T) { + resourceName := "azurerm_iothub.test" + rInt := tf.AccRandTimeInt() + rStr := acctest.RandString(5) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHub_fileUpload(rInt, rStr, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "file_upload.#", "1"), + resource.TestCheckResourceAttr(resourceName, "file_upload.0.lock_duration", "PT5M"), ), }, { @@ -141,7 +197,7 @@ func TestAccAzureRMIotHub_fallbackRoute(t *testing.T) { } func testCheckAzureRMIotHubDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).iothubResourceClient + client := testAccProvider.Meta().(*ArmClient).iothub.ResourceClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -179,7 +235,7 @@ func testCheckAzureRMIotHubExists(resourceName string) resource.TestCheckFunc { return fmt.Errorf("Bad: no resource group found in state for IotHub: %s", iothubName) } - client := testAccProvider.Meta().(*ArmClient).iothubResourceClient + client := testAccProvider.Meta().(*ArmClient).iothub.ResourceClient resp, err := client.Get(ctx, resourceGroup, iothubName) if err != nil { if resp.StatusCode == http.StatusNotFound { @@ -213,7 +269,7 @@ resource "azurerm_iothub" "test" { } tags = { - "purpose" = "testing" + purpose = "testing" } } `, rInt, location, rInt) @@ -236,7 +292,7 @@ resource "azurerm_iothub" "import" { } tags = { - "purpose" = "testing" + purpose = "testing" } } `, template) @@ -261,7 +317,38 @@ resource "azurerm_iothub" "test" { } tags = { - "purpose" = "testing" + purpose = "testing" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMIotHub_ipFilterRules(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub" "test" { + name = "acctestIoTHub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + ip_filter_rule { + name = "test" + ip_mask = "10.0.0.0/31" + action = "Accept" + } + + tags = { + purpose = "testing" } } `, rInt, location, rInt) @@ -289,6 +376,29 @@ resource "azurerm_storage_container" "test" { container_access_type = "private" } +resource "azurerm_eventhub_namespace" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + name = "acctest-%d" + sku = "Basic" +} + +resource "azurerm_eventhub" "test" { + name = "acctest" + resource_group_name = "${azurerm_resource_group.test.name}" + namespace_name = "${azurerm_eventhub_namespace.test.name}" + partition_count = 2 + message_retention = 1 +} + +resource "azurerm_eventhub_authorization_rule" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + namespace_name = "${azurerm_eventhub_namespace.test.name}" + eventhub_name = "${azurerm_eventhub.test.name}" + name = "acctest" + send = true +} + resource "azurerm_iothub" "test" { name = "acctestIoTHub-%d" resource_group_name = "${azurerm_resource_group.test.name}" @@ -311,6 +421,12 @@ resource "azurerm_iothub" "test" { file_name_format = "{iothub}/{partition}_{YYYY}_{MM}_{DD}_{HH}_{mm}" } + endpoint { + type = "AzureIotHub.EventHub" + connection_string = "${azurerm_eventhub_authorization_rule.test.primary_connection_string}" + name = "export2" + } + route { name = "export" source = "DeviceMessages" @@ -319,11 +435,19 @@ resource "azurerm_iothub" "test" { enabled = true } + route { + name = "export2" + source = "DeviceMessages" + condition = "true" + endpoint_names = ["export2"] + enabled = true + } + tags = { - "purpose" = "testing" + purpose = "testing" } } -`, rInt, location, rStr, rInt) +`, rInt, location, rStr, rInt, rInt) } func testAccAzureRMIotHub_fallbackRoute(rInt int, location string) string { @@ -334,9 +458,9 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_iothub" "test" { - name = "acctestIoTHub-%d" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" + name = "acctestIoTHub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" sku { name = "S1" @@ -350,9 +474,55 @@ resource "azurerm_iothub" "test" { enabled = true } - tags = { - "purpose" = "testing" + tags = { + purpose = "testing" } } `, rInt, location, rInt) } + +func testAccAzureRMIotHub_fileUpload(rInt int, rStr string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "test" { + name = "test" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} + +resource "azurerm_iothub" "test" { + name = "acctestIoTHub-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + file_upload { + connection_string = "${azurerm_storage_account.test.primary_blob_connection_string}" + container_name = "${azurerm_storage_container.test.name}" + notifications = true + max_delivery_count = 12 + sas_ttl = "PT2H" + default_ttl = "PT3H" + lock_duration = "PT5M" + } +} +`, rInt, location, rStr, rInt) +} diff --git a/azurerm/resource_arm_key_vault.go b/azurerm/resource_arm_key_vault.go index e02881b42292..af3479dd39e5 100644 --- a/azurerm/resource_arm_key_vault.go +++ b/azurerm/resource_arm_key_vault.go @@ -16,6 +16,10 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -48,18 +52,23 @@ func resourceArmKeyVault() *schema.Resource { ValidateFunc: validateKeyVaultName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), + // Remove in 2.0 "sku": { - Type: schema.TypeList, - Required: true, + Type: schema.TypeList, + Optional: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the 'sku_name' property and will be removed in version 2.0 of the provider", + ConflictsWith: []string{"sku_name"}, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, - Required: true, + Optional: true, ValidateFunc: validation.StringInSlice([]string{ string(keyvault.Standard), string(keyvault.Premium), @@ -69,6 +78,16 @@ func resourceArmKeyVault() *schema.Resource { }, }, + "sku_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + string(keyvault.Standard), + string(keyvault.Premium), + }, false), + }, + "vault_uri": { Type: schema.TypeString, Computed: true, @@ -77,34 +96,36 @@ func resourceArmKeyVault() *schema.Resource { "tenant_id": { Type: schema.TypeString, Required: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, "access_policy": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1024, + Type: schema.TypeList, + ConfigMode: schema.SchemaConfigModeAttr, + Optional: true, + Computed: true, + MaxItems: 1024, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "tenant_id": { Type: schema.TypeString, Required: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, "object_id": { Type: schema.TypeString, Required: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, "application_id": { Type: schema.TypeString, Optional: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, "certificate_permissions": azure.SchemaKeyVaultCertificatePermissions(), "key_permissions": azure.SchemaKeyVaultKeyPermissions(), "secret_permissions": azure.SchemaKeyVaultSecretPermissions(), + "storage_permissions": azure.SchemaKeyVaultStoragePermissions(), }, }, }, @@ -162,20 +183,44 @@ func resourceArmKeyVault() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmKeyVaultCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).keyVaultClient + client := meta.(*ArmClient).keyvault.VaultsClient ctx := meta.(*ArmClient).StopContext + + // Remove in 2.0 + var sku keyvault.Sku + + if inputs := d.Get("sku").([]interface{}); len(inputs) != 0 { + input := inputs[0].(map[string]interface{}) + v := input["name"].(string) + + sku = keyvault.Sku{ + Family: &armKeyVaultSkuFamily, + Name: keyvault.SkuName(v), + } + } else { + // Keep in 2.0 + sku = keyvault.Sku{ + Family: &armKeyVaultSkuFamily, + Name: keyvault.SkuName(d.Get("sku_name").(string)), + } + } + + if sku.Name == "" { + return fmt.Errorf("either 'sku_name' or 'sku' must be defined in the configuration file") + } + log.Printf("[INFO] preparing arguments for Azure ARM KeyVault creation.") name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -188,12 +233,12 @@ func resourceArmKeyVaultCreateUpdate(d *schema.ResourceData, meta interface{}) e } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) tenantUUID := uuid.FromStringOrNil(d.Get("tenant_id").(string)) enabledForDeployment := d.Get("enabled_for_deployment").(bool) enabledForDiskEncryption := d.Get("enabled_for_disk_encryption").(bool) enabledForTemplateDeployment := d.Get("enabled_for_template_deployment").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) networkAclsRaw := d.Get("network_acls").([]interface{}) networkAcls, subnetIds := expandKeyVaultNetworkAcls(networkAclsRaw) @@ -208,25 +253,25 @@ func resourceArmKeyVaultCreateUpdate(d *schema.ResourceData, meta interface{}) e Location: &location, Properties: &keyvault.VaultProperties{ TenantID: &tenantUUID, - Sku: expandKeyVaultSku(d), + Sku: &sku, AccessPolicies: accessPolicies, EnabledForDeployment: &enabledForDeployment, EnabledForDiskEncryption: &enabledForDiskEncryption, EnabledForTemplateDeployment: &enabledForTemplateDeployment, NetworkAcls: networkAcls, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } // Locking this resource so we don't make modifications to it at the same time if there is a // key vault access policy trying to update it as well - azureRMLockByName(name, keyVaultResourceName) - defer azureRMUnlockByName(name, keyVaultResourceName) + locks.ByName(name, keyVaultResourceName) + defer locks.UnlockByName(name, keyVaultResourceName) // also lock on the Virtual Network ID's since modifications in the networking stack are exclusive virtualNetworkNames := make([]string, 0) for _, v := range subnetIds { - id, err2 := parseAzureResourceID(v) + id, err2 := azure.ParseAzureResourceID(v) if err2 != nil { return err2 } @@ -237,8 +282,8 @@ func resourceArmKeyVaultCreateUpdate(d *schema.ResourceData, meta interface{}) e } } - azureRMLockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) + locks.MultipleByName(&virtualNetworkNames, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) if _, err = client.CreateOrUpdate(ctx, resourceGroup, name, parameters); err != nil { return fmt.Errorf("Error updating Key Vault %q (Resource Group %q): %+v", name, resourceGroup, err) @@ -279,10 +324,10 @@ func resourceArmKeyVaultCreateUpdate(d *schema.ResourceData, meta interface{}) e } func resourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).keyVaultClient + client := meta.(*ArmClient).keyvault.VaultsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -302,7 +347,7 @@ func resourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.Properties; props != nil { @@ -312,8 +357,17 @@ func resourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { d.Set("enabled_for_template_deployment", props.EnabledForTemplateDeployment) d.Set("vault_uri", props.VaultURI) - if err := d.Set("sku", flattenKeyVaultSku(props.Sku)); err != nil { - return fmt.Errorf("Error setting `sku` for KeyVault %q: %+v", *resp.Name, err) + if sku := props.Sku; sku != nil { + // Remove in 2.0 + if err := d.Set("sku", flattenKeyVaultSku(sku)); err != nil { + return fmt.Errorf("Error setting 'sku' for KeyVault %q: %+v", *resp.Name, err) + } + + if err := d.Set("sku_name", string(sku.Name)); err != nil { + return fmt.Errorf("Error setting 'sku_name' for KeyVault %q: %+v", *resp.Name, err) + } + } else { + return fmt.Errorf("Error making Read request on KeyVault %q (Resource Group %q): Unable to retrieve 'sku' value", name, resourceGroup) } if err := d.Set("network_acls", flattenKeyVaultNetworkAcls(props.NetworkAcls)); err != nil { @@ -326,23 +380,22 @@ func resourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { } } - flattenAndSetTags(d, resp.Tags) - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmKeyVaultDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).keyVaultClient + client := meta.(*ArmClient).keyvault.VaultsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } resourceGroup := id.ResourceGroup name := id.Path["vaults"] - azureRMLockByName(name, keyVaultResourceName) - defer azureRMUnlockByName(name, keyVaultResourceName) + locks.ByName(name, keyVaultResourceName) + defer locks.UnlockByName(name, keyVaultResourceName) read, err := client.Get(ctx, resourceGroup, name) if err != nil { @@ -363,7 +416,7 @@ func resourceArmKeyVaultDelete(d *schema.ResourceData, meta interface{}) error { continue } - id, err2 := parseAzureResourceID(*v.ID) + id, err2 := azure.ParseAzureResourceID(*v.ID) if err2 != nil { return err2 } @@ -377,8 +430,8 @@ func resourceArmKeyVaultDelete(d *schema.ResourceData, meta interface{}) error { } } - azureRMLockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) + locks.MultipleByName(&virtualNetworkNames, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) resp, err := client.Delete(ctx, resourceGroup, name) if err != nil { @@ -390,16 +443,7 @@ func resourceArmKeyVaultDelete(d *schema.ResourceData, meta interface{}) error { return nil } -func expandKeyVaultSku(d *schema.ResourceData) *keyvault.Sku { - skuSets := d.Get("sku").([]interface{}) - sku := skuSets[0].(map[string]interface{}) - - return &keyvault.Sku{ - Family: &armKeyVaultSkuFamily, - Name: keyvault.SkuName(sku["name"].(string)), - } -} - +// Remove in 2.0 func flattenKeyVaultSku(sku *keyvault.Sku) []interface{} { result := map[string]interface{}{ "name": string(sku.Name), diff --git a/azurerm/resource_arm_key_vault_access_policy.go b/azurerm/resource_arm_key_vault_access_policy.go index b4e31181f6f2..67baf77b453e 100644 --- a/azurerm/resource_arm_key_vault_access_policy.go +++ b/azurerm/resource_arm_key_vault_access_policy.go @@ -6,8 +6,10 @@ import ( "regexp" "strings" - "github.com/satori/go.uuid" + uuid "github.com/satori/go.uuid" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2018-02-14/keyvault" "github.com/hashicorp/terraform/helper/schema" @@ -78,21 +80,21 @@ func resourceArmKeyVaultAccessPolicy() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, "object_id": { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, "application_id": { Type: schema.TypeString, Optional: true, ForceNew: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, "certificate_permissions": azure.SchemaKeyVaultCertificatePermissions(), @@ -100,12 +102,14 @@ func resourceArmKeyVaultAccessPolicy() *schema.Resource { "key_permissions": azure.SchemaKeyVaultKeyPermissions(), "secret_permissions": azure.SchemaKeyVaultSecretPermissions(), + + "storage_permissions": azure.SchemaKeyVaultStoragePermissions(), }, } } func resourceArmKeyVaultAccessPolicyCreateOrDelete(d *schema.ResourceData, meta interface{}, action keyvault.AccessPolicyUpdateKind) error { - client := meta.(*ArmClient).keyVaultClient + client := meta.(*ArmClient).keyvault.VaultsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] Preparing arguments for Key Vault Access Policy: %s.", action) @@ -167,10 +171,10 @@ func resourceArmKeyVaultAccessPolicyCreateOrDelete(d *schema.ResourceData, meta } // Locking to prevent parallel changes causing issues - azureRMLockByName(vaultName, keyVaultResourceName) - defer azureRMUnlockByName(vaultName, keyVaultResourceName) + locks.ByName(vaultName, keyVaultResourceName) + defer locks.UnlockByName(vaultName, keyVaultResourceName) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { props := keyVault.Properties if props == nil { return fmt.Errorf("Error parsing Key Vault: `properties` was nil") @@ -208,6 +212,9 @@ func resourceArmKeyVaultAccessPolicyCreateOrDelete(d *schema.ResourceData, meta secretPermissionsRaw := d.Get("secret_permissions").([]interface{}) secretPermissions := azure.ExpandSecretPermissions(secretPermissionsRaw) + storagePermissionsRaw := d.Get("storage_permissions").([]interface{}) + storagePermissions := azure.ExpandStoragePermissions(storagePermissionsRaw) + accessPolicy := keyvault.AccessPolicyEntry{ ObjectID: utils.String(objectId), TenantID: &tenantId, @@ -215,6 +222,7 @@ func resourceArmKeyVaultAccessPolicyCreateOrDelete(d *schema.ResourceData, meta Certificates: certPermissions, Keys: keyPermissions, Secrets: secretPermissions, + Storage: storagePermissions, }, } @@ -269,10 +277,10 @@ func resourceArmKeyVaultAccessPolicyUpdate(d *schema.ResourceData, meta interfac } func resourceArmKeyVaultAccessPolicyRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).keyVaultClient + client := meta.(*ArmClient).keyvault.VaultsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err @@ -332,6 +340,11 @@ func resourceArmKeyVaultAccessPolicyRead(d *schema.ResourceData, meta interface{ if err := d.Set("secret_permissions", secretPermissions); err != nil { return fmt.Errorf("Error setting `secret_permissions`: %+v", err) } + + storagePermissions := azure.FlattenStoragePermissions(permissions.Storage) + if err := d.Set("storage_permissions", storagePermissions); err != nil { + return fmt.Errorf("Error setting `storage_permissions`: %+v", err) + } } return nil diff --git a/azurerm/resource_arm_key_vault_access_policy_test.go b/azurerm/resource_arm_key_vault_access_policy_test.go index 137ad3899e6c..7caa77576ce1 100644 --- a/azurerm/resource_arm_key_vault_access_policy_test.go +++ b/azurerm/resource_arm_key_vault_access_policy_test.go @@ -8,6 +8,8 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -68,7 +70,7 @@ func TestAccAzureRMKeyVaultAccessPolicy_basicClassic(t *testing.T) { } func TestAccAzureRMKeyVaultAccessPolicy_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -196,7 +198,7 @@ func TestAccAzureRMKeyVaultAccessPolicy_nonExistentVault(t *testing.T) { func testCheckAzureRMKeyVaultAccessPolicyExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultClient + client := testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API @@ -205,7 +207,7 @@ func testCheckAzureRMKeyVaultAccessPolicyExists(resourceName string) resource.Te return fmt.Errorf("Not found: %s", resourceName) } - id, err := parseAzureResourceID(rs.Primary.ID) + id, err := azure.ParseAzureResourceID(rs.Primary.ID) if err != nil { return err @@ -290,9 +292,9 @@ func testAccAzureRMKeyVaultAccessPolicy_requiresImport(rString string, location %s resource "azurerm_key_vault_access_policy" "import" { - key_vault_id = "${azurerm_key_vault.test.id}" - tenant_id = "${azurerm_key_vault_access_policy.test.tenant_id}" - object_id = "${azurerm_key_vault_access_policy.test.object_id}" + key_vault_id = "${azurerm_key_vault.test.id}" + tenant_id = "${azurerm_key_vault_access_policy.test.tenant_id}" + object_id = "${azurerm_key_vault_access_policy.test.object_id}" key_permissions = [ "get", @@ -352,6 +354,23 @@ resource "azurerm_key_vault_access_policy" "test_no_application_id" { "delete", ] + storage_permissions = [ + "backup", + "delete", + "deletesas", + "get", + "getsas", + "list", + "listsas", + "purge", + "recover", + "regeneratekey", + "restore", + "set", + "setsas", + "update", + ] + tenant_id = "${data.azurerm_client_config.current.tenant_id}" object_id = "${data.azurerm_client_config.current.service_principal_object_id}" } @@ -395,9 +414,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" tags = { environment = "Production" @@ -421,9 +438,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" tags = { environment = "Production" diff --git a/azurerm/resource_arm_key_vault_certificate.go b/azurerm/resource_arm_key_vault_certificate.go index 4d31a83bd6fc..94c8c2c92579 100644 --- a/azurerm/resource_arm_key_vault_certificate.go +++ b/azurerm/resource_arm_key_vault_certificate.go @@ -16,12 +16,14 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) //todo refactor and find a home for this wayward func func resourceArmKeyVaultChildResourceImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - client := meta.(*ArmClient).keyVaultClient + client := meta.(*ArmClient).keyvault.VaultsClient ctx := meta.(*ArmClient).StopContext id, err := azure.ParseKeyVaultChildID(d.Id()) @@ -328,14 +330,14 @@ func resourceArmKeyVaultCertificate() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmKeyVaultCertificateCreate(d *schema.ResourceData, meta interface{}) error { - vaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + vaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -361,7 +363,7 @@ func resourceArmKeyVaultCertificateCreate(d *schema.ResourceData, meta interface d.Set("key_vault_id", id) } - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.GetCertificate(ctx, keyVaultBaseUrl, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -374,7 +376,7 @@ func resourceArmKeyVaultCertificateCreate(d *schema.ResourceData, meta interface } } - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) policy := expandKeyVaultCertificatePolicy(d) if v, ok := d.GetOk("certificate"); ok { @@ -384,7 +386,7 @@ func resourceArmKeyVaultCertificateCreate(d *schema.ResourceData, meta interface Base64EncodedCertificate: utils.String(certificate.CertificateData), Password: utils.String(certificate.CertificatePassword), CertificatePolicy: &policy, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.ImportCertificate(ctx, keyVaultBaseUrl, name, importParameters); err != nil { return err @@ -393,7 +395,7 @@ func resourceArmKeyVaultCertificateCreate(d *schema.ResourceData, meta interface // Generate new parameters := keyvault.CertificateCreateParameters{ CertificatePolicy: &policy, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.CreateCertificate(ctx, keyVaultBaseUrl, name, parameters); err != nil { return err @@ -422,7 +424,7 @@ func resourceArmKeyVaultCertificateCreate(d *schema.ResourceData, meta interface return resourceArmKeyVaultCertificateRead(d, meta) } -func keyVaultCertificateCreationRefreshFunc(ctx context.Context, client keyvault.BaseClient, keyVaultBaseUrl string, name string) resource.StateRefreshFunc { +func keyVaultCertificateCreationRefreshFunc(ctx context.Context, client *keyvault.BaseClient, keyVaultBaseUrl string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.GetCertificate(ctx, keyVaultBaseUrl, name, "") if err != nil { @@ -438,8 +440,8 @@ func keyVaultCertificateCreationRefreshFunc(ctx context.Context, client keyvault } func resourceArmKeyVaultCertificateRead(d *schema.ResourceData, meta interface{}) error { - keyVaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + keyVaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext id, err := azure.ParseKeyVaultChildID(d.Id()) @@ -502,14 +504,12 @@ func resourceArmKeyVaultCertificateRead(d *schema.ResourceData, meta interface{} d.Set("thumbprint", strings.ToUpper(hex.EncodeToString(x509Thumbprint))) } - flattenAndSetTags(d, cert.Tags) - - return nil + return tags.FlattenAndSet(d, cert.Tags) } func resourceArmKeyVaultCertificateDelete(d *schema.ResourceData, meta interface{}) error { - keyVaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + keyVaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext id, err := azure.ParseKeyVaultChildID(d.Id()) @@ -612,7 +612,7 @@ func expandKeyVaultCertificatePolicy(d *schema.ResourceData) keyvault.Certificat cert := v.(map[string]interface{}) ekus := cert["extended_key_usage"].([]interface{}) - extendedKeyUsage := utils.ExpandStringArray(ekus) + extendedKeyUsage := utils.ExpandStringSlice(ekus) keyUsage := make([]keyvault.KeyUsageType, 0) keys := cert["key_usage"].([]interface{}) @@ -629,17 +629,17 @@ func expandKeyVaultCertificatePolicy(d *schema.ResourceData) keyvault.Certificat emails := san["emails"].([]interface{}) if len(emails) > 0 { - subjectAlternativeNames.Emails = utils.ExpandStringArray(emails) + subjectAlternativeNames.Emails = utils.ExpandStringSlice(emails) } dnsNames := san["dns_names"].([]interface{}) if len(dnsNames) > 0 { - subjectAlternativeNames.DNSNames = utils.ExpandStringArray(dnsNames) + subjectAlternativeNames.DNSNames = utils.ExpandStringSlice(dnsNames) } upns := san["upns"].([]interface{}) if len(upns) > 0 { - subjectAlternativeNames.Upns = utils.ExpandStringArray(upns) + subjectAlternativeNames.Upns = utils.ExpandStringSlice(upns) } } } @@ -726,9 +726,9 @@ func flattenKeyVaultCertificatePolicy(input *keyvault.CertificatePolicy) []inter if san := props.SubjectAlternativeNames; san != nil { sanOutput := make(map[string]interface{}) - sanOutput["emails"] = utils.FlattenStringArray(san.Emails) - sanOutput["dns_names"] = utils.FlattenStringArray(san.DNSNames) - sanOutput["upns"] = utils.FlattenStringArray(san.Upns) + sanOutput["emails"] = utils.FlattenStringSlice(san.Emails) + sanOutput["dns_names"] = utils.FlattenStringSlice(san.DNSNames) + sanOutput["upns"] = utils.FlattenStringSlice(san.Upns) sanOutputs = append(sanOutputs, sanOutput) } diff --git a/azurerm/resource_arm_key_vault_certificate_test.go b/azurerm/resource_arm_key_vault_certificate_test.go index f52ef5c45b9a..4d85e5f23b60 100644 --- a/azurerm/resource_arm_key_vault_certificate_test.go +++ b/azurerm/resource_arm_key_vault_certificate_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" @@ -68,7 +69,7 @@ func TestAccAzureRMKeyVaultCertificate_basicImportPFXClassic(t *testing.T) { } func TestAccAzureRMKeyVaultCertificate_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -245,7 +246,7 @@ func TestAccAzureRMKeyVaultCertificate_basicExtendedKeyUsage(t *testing.T) { } func testCheckAzureRMKeyVaultCertificateDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -257,7 +258,7 @@ func testCheckAzureRMKeyVaultCertificateDestroy(s *terraform.State) error { vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Certificate %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -283,7 +284,7 @@ func testCheckAzureRMKeyVaultCertificateDestroy(s *terraform.State) error { func testCheckAzureRMKeyVaultCertificateExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API @@ -296,7 +297,7 @@ func testCheckAzureRMKeyVaultCertificateExists(resourceName string) resource.Tes vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Certificate %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -320,7 +321,7 @@ func testCheckAzureRMKeyVaultCertificateExists(resourceName string) resource.Tes func testCheckAzureRMKeyVaultCertificateDisappears(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API @@ -332,7 +333,7 @@ func testCheckAzureRMKeyVaultCertificateDisappears(resourceName string) resource vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Certificate %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -369,9 +370,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -394,11 +393,11 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "acctestcert%s" + name = "acctestcert%s" key_vault_id = "${azurerm_key_vault.test.id}" certificate { - contents = "${base64encode(file("testdata/keyvaultcert.pfx"))}" + contents = "${filebase64("testdata/keyvaultcert.pfx")}" password = "" } @@ -437,9 +436,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -458,6 +455,10 @@ resource "azurerm_key_vault" "test" { secret_permissions = [ "set", ] + + storage_permissions = [ + "set", + ] } } @@ -466,7 +467,7 @@ resource "azurerm_key_vault_certificate" "test" { vault_uri = "${azurerm_key_vault.test.vault_uri}" certificate { - contents = "${base64encode(file("testdata/keyvaultcert.pfx"))}" + contents = "${filebase64("testdata/keyvaultcert.pfx")}" password = "" } @@ -500,7 +501,7 @@ resource "azurerm_key_vault_certificate" "import" { key_vault_id = "${azurerm_key_vault.test.id}" certificate { - contents = "${base64encode(file("testdata/keyvaultcert.pfx"))}" + contents = "${filebase64("testdata/keyvaultcert.pfx")}" password = "" } @@ -538,9 +539,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -560,12 +559,16 @@ resource "azurerm_key_vault" "test" { secret_permissions = [ "set", ] + + storage_permissions = [ + "set", + ] } } resource "azurerm_key_vault_certificate" "test" { - name = "acctestcert%s" - key_vault_id = "${azurerm_key_vault.test.id}" + name = "acctestcert%s" + key_vault_id = "${azurerm_key_vault.test.id}" certificate_policy { issuer_parameters { @@ -626,9 +629,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -648,11 +649,15 @@ resource "azurerm_key_vault" "test" { secret_permissions = [ "set", ] + + storage_permissions = [ + "set", + ] } } resource "azurerm_key_vault_certificate" "test" { - name = "acctestcert%s" + name = "acctestcert%s" key_vault_id = "${azurerm_key_vault.test.id}" certificate_policy { @@ -721,9 +726,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -747,7 +750,7 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "acctestcert%s" + name = "acctestcert%s" key_vault_id = "${azurerm_key_vault.test.id}" certificate_policy { @@ -813,9 +816,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -835,6 +836,10 @@ resource "azurerm_key_vault" "test" { secret_permissions = [ "set", ] + + storage_permissions = [ + "set", + ] } } diff --git a/azurerm/resource_arm_key_vault_key.go b/azurerm/resource_arm_key_vault_key.go index df3701fee596..5ea92dc134db 100644 --- a/azurerm/resource_arm_key_vault_key.go +++ b/azurerm/resource_arm_key_vault_key.go @@ -1,6 +1,7 @@ package azurerm import ( + "encoding/base64" "fmt" "log" @@ -10,6 +11,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -61,15 +64,17 @@ func resourceArmKeyVaultKey() *schema.Resource { // TODO: add `oct` back in once this is fixed // https://github.com/Azure/azure-rest-api-specs/issues/1739#issuecomment-332236257 string(keyvault.EC), + string(keyvault.ECHSM), string(keyvault.RSA), string(keyvault.RSAHSM), }, false), }, "key_size": { - Type: schema.TypeInt, - Required: true, - ForceNew: true, + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"curve"}, }, "key_opts": { @@ -90,6 +95,23 @@ func resourceArmKeyVaultKey() *schema.Resource { }, }, + "curve": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(keyvault.P256), + string(keyvault.P384), + string(keyvault.P521), + string(keyvault.SECP256K1), + }, false), + // TODO: the curve name should probably be mandatory for EC in the future, + // but handle the diff so that we don't break existing configurations and + // imported EC keys + ConflictsWith: []string{"key_size"}, + }, + // Computed "version": { Type: schema.TypeString, @@ -106,14 +128,24 @@ func resourceArmKeyVaultKey() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "x": { + Type: schema.TypeString, + Computed: true, + }, + + "y": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tags.Schema(), }, } } func resourceArmKeyVaultKeyCreate(d *schema.ResourceData, meta interface{}) error { - vaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + vaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext log.Print("[INFO] preparing arguments for AzureRM KeyVault Key creation.") @@ -140,7 +172,7 @@ func resourceArmKeyVaultKeyCreate(d *schema.ResourceData, meta interface{}) erro d.Set("key_vault_id", id) } - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.GetKey(ctx, keyVaultBaseUri, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -155,7 +187,7 @@ func resourceArmKeyVaultKeyCreate(d *schema.ResourceData, meta interface{}) erro keyType := d.Get("key_type").(string) keyOptions := expandKeyVaultKeyOptions(d) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) // TODO: support Importing Keys once this is fixed: // https://github.com/Azure/azure-rest-api-specs/issues/1747 @@ -165,10 +197,23 @@ func resourceArmKeyVaultKeyCreate(d *schema.ResourceData, meta interface{}) erro KeyAttributes: &keyvault.KeyAttributes{ Enabled: utils.Bool(true), }, - KeySize: utils.Int32(int32(d.Get("key_size").(int))), - Tags: expandTags(tags), + + Tags: tags.Expand(t), } + if parameters.Kty == keyvault.EC || parameters.Kty == keyvault.ECHSM { + curveName := d.Get("curve").(string) + parameters.Curve = keyvault.JSONWebKeyCurveName(curveName) + } else if parameters.Kty == keyvault.RSA || parameters.Kty == keyvault.RSAHSM { + keySize, ok := d.GetOk("key_size") + if !ok { + return fmt.Errorf("Key size is required when creating an RSA key") + } + parameters.KeySize = utils.Int32(int32(keySize.(int))) + } + // TODO: support `oct` once this is fixed + // https://github.com/Azure/azure-rest-api-specs/issues/1739#issuecomment-332236257 + if _, err := client.CreateKey(ctx, keyVaultBaseUri, name, parameters); err != nil { return fmt.Errorf("Error Creating Key: %+v", err) } @@ -185,8 +230,8 @@ func resourceArmKeyVaultKeyCreate(d *schema.ResourceData, meta interface{}) erro } func resourceArmKeyVaultKeyUpdate(d *schema.ResourceData, meta interface{}) error { - vaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + vaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext id, err := azure.ParseKeyVaultChildID(d.Id()) @@ -213,14 +258,14 @@ func resourceArmKeyVaultKeyUpdate(d *schema.ResourceData, meta interface{}) erro } keyOptions := expandKeyVaultKeyOptions(d) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := keyvault.KeyUpdateParameters{ KeyOps: keyOptions, KeyAttributes: &keyvault.KeyAttributes{ Enabled: utils.Bool(true), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err = client.UpdateKey(ctx, id.KeyVaultBaseUrl, id.Name, id.Version, parameters); err != nil { @@ -231,8 +276,8 @@ func resourceArmKeyVaultKeyUpdate(d *schema.ResourceData, meta interface{}) erro } func resourceArmKeyVaultKeyRead(d *schema.ResourceData, meta interface{}) error { - keyVaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + keyVaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext id, err := azure.ParseKeyVaultChildID(d.Id()) @@ -283,19 +328,28 @@ func resourceArmKeyVaultKeyRead(d *schema.ResourceData, meta interface{}) error d.Set("n", key.N) d.Set("e", key.E) + d.Set("x", key.X) + d.Set("y", key.Y) + if key.N != nil { + nBytes, err := base64.RawURLEncoding.DecodeString(*key.N) + if err != nil { + return fmt.Errorf("Could not decode N: %+v", err) + } + d.Set("key_size", len(nBytes)*8) + } + + d.Set("curve", key.Crv) } // Computed d.Set("version", id.Version) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmKeyVaultKeyDelete(d *schema.ResourceData, meta interface{}) error { - keyVaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + keyVaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext id, err := azure.ParseKeyVaultChildID(d.Id()) diff --git a/azurerm/resource_arm_key_vault_key_test.go b/azurerm/resource_arm_key_vault_key_test.go index b9c37fd56431..272bf3122848 100644 --- a/azurerm/resource_arm_key_vault_key_test.go +++ b/azurerm/resource_arm_key_vault_key_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" @@ -66,7 +67,7 @@ func TestAccAzureRMKeyVaultKey_basicECClassic(t *testing.T) { } func TestAccAzureRMKeyVaultKey_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -94,6 +95,51 @@ func TestAccAzureRMKeyVaultKey_requiresImport(t *testing.T) { }) } +func TestAccAzureRMKeyVaultKey_basicECHSM(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_basicECHSM(rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultKeyExists(resourceName), + ), + }, + }, + }) +} + +func TestAccAzureRMKeyVaultKey_curveEC(t *testing.T) { + resourceName := "azurerm_key_vault_key.test" + rs := acctest.RandString(6) + config := testAccAzureRMKeyVaultKey_curveEC(rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultKeyDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultKeyExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMKeyVaultKey_basicRSA(t *testing.T) { resourceName := "azurerm_key_vault_key.test" rs := acctest.RandString(6) @@ -249,7 +295,7 @@ func TestAccAzureRMKeyVaultKey_disappearsWhenParentKeyVaultDeleted(t *testing.T) } func testCheckAzureRMKeyVaultKeyDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -261,7 +307,7 @@ func testCheckAzureRMKeyVaultKeyDestroy(s *terraform.State) error { vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Secret %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -287,7 +333,7 @@ func testCheckAzureRMKeyVaultKeyDestroy(s *terraform.State) error { func testCheckAzureRMKeyVaultKeyExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API @@ -299,7 +345,7 @@ func testCheckAzureRMKeyVaultKeyExists(resourceName string) resource.TestCheckFu vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Key %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -323,7 +369,7 @@ func testCheckAzureRMKeyVaultKeyExists(resourceName string) resource.TestCheckFu func testCheckAzureRMKeyVaultKeyDisappears(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API @@ -336,7 +382,7 @@ func testCheckAzureRMKeyVaultKeyDisappears(resourceName string) resource.TestChe vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Key %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -373,9 +419,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -428,9 +472,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -474,10 +516,10 @@ func testAccAzureRMKeyVaultKey_requiresImport(rString string, location string) s %s resource "azurerm_key_vault_key" "import" { - name = "${azurerm_key_vault_key.test.name}" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "EC" - key_size = 2048 + name = "${azurerm_key_vault_key.test.name}" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "EC" + key_size = 2048 key_opts = [ "sign", @@ -502,9 +544,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -530,10 +570,10 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "RSA" - key_size = 2048 + name = "key-%s" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "RSA" + key_size = 2048 key_opts = [ "decrypt", @@ -562,9 +602,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -589,10 +627,10 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "RSA-HSM" - key_size = 2048 + name = "key-%s" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "RSA-HSM" + key_size = 2048 key_opts = [ "decrypt", @@ -621,9 +659,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -648,10 +684,10 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_key" "test" { - name = "key-%s" - key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "RSA" - key_size = 2048 + name = "key-%s" + key_vault_id = "${azurerm_key_vault.test.id}" + key_type = "RSA" + key_size = 2048 key_opts = [ "decrypt", @@ -684,9 +720,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -727,3 +761,113 @@ resource "azurerm_key_vault_key" "test" { } `, rString, location, rString, rString) } + +func testAccAzureRMKeyVaultKey_curveEC(rString string, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%s" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "acctestkv-%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku { + name = "premium" + } + + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" + + key_permissions = [ + "create", + "delete", + "get", + ] + + secret_permissions = [ + "get", + "delete", + "set", + ] + } + + tags = { + environment = "Production" + } +} + +resource "azurerm_key_vault_key" "test" { + name = "key-%s" + vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_type = "EC" + curve = "P-521" + + key_opts = [ + "sign", + "verify", + ] +} +`, rString, location, rString, rString) +} + +func testAccAzureRMKeyVaultKey_basicECHSM(rString string, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%s" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "acctestkv-%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku { + name = "premium" + } + + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.service_principal_object_id}" + + key_permissions = [ + "create", + "delete", + "get", + ] + + secret_permissions = [ + "get", + "delete", + "set", + ] + } + + tags = { + environment = "Production" + } +} + +resource "azurerm_key_vault_key" "test" { + name = "key-%s" + vault_uri = "${azurerm_key_vault.test.vault_uri}" + key_type = "EC-HSM" + curve = "P-521" + + key_opts = [ + "sign", + "verify", + ] +} +`, rString, location, rString, rString) +} diff --git a/azurerm/resource_arm_key_vault_migration_test.go b/azurerm/resource_arm_key_vault_migration_test.go index b8ede42dba76..46be91a85535 100644 --- a/azurerm/resource_arm_key_vault_migration_test.go +++ b/azurerm/resource_arm_key_vault_migration_test.go @@ -35,6 +35,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "Get", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, Expected: map[string]string{ "access_policy.#": "1", @@ -47,6 +48,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "Get", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, }, "v0_1_certificates": { @@ -63,6 +65,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "Get", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, Expected: map[string]string{ "access_policy.#": "1", @@ -86,6 +89,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "Get", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, }, "v0_1_certificates_multiple": { @@ -104,6 +108,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "Get", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, Expected: map[string]string{ "access_policy.#": "1", @@ -127,6 +132,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "Get", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, }, "v0_1_keys": { @@ -142,6 +148,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "All", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, Expected: map[string]string{ "access_policy.#": "1", @@ -168,6 +175,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.15": "wrapKey", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, }, "v0_1_keys_multiple": { @@ -185,6 +193,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.1": "create", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, Expected: map[string]string{ "access_policy.#": "1", @@ -211,6 +220,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.15": "wrapKey", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "Get", + "access_policy.0.storage_permissions.#": "0", }, }, "v0_1_secrets": { @@ -226,6 +236,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "create", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "All", + "access_policy.0.storage_permissions.#": "0", }, Expected: map[string]string{ "access_policy.#": "1", @@ -244,6 +255,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.secret_permissions.5": "recover", "access_policy.0.secret_permissions.6": "restore", "access_policy.0.secret_permissions.7": "set", + "access_policy.0.storage_permissions.#": "0", }, }, "v0_1_secrets_multiple": { @@ -261,6 +273,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.secret_permissions.#": "2", "access_policy.0.secret_permissions.0": "backup", "access_policy.0.secret_permissions.1": "all", + "access_policy.0.storage_permissions.#": "0", }, Expected: map[string]string{ "access_policy.#": "1", @@ -279,6 +292,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.secret_permissions.5": "recover", "access_policy.0.secret_permissions.6": "restore", "access_policy.0.secret_permissions.7": "set", + "access_policy.0.storage_permissions.#": "0", }, }, "v0_1_all": { @@ -295,6 +309,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.key_permissions.0": "all", "access_policy.0.secret_permissions.#": "1", "access_policy.0.secret_permissions.0": "all", + "access_policy.0.storage_permissions.#": "0", }, Expected: map[string]string{ "access_policy.#": "1", @@ -340,6 +355,7 @@ func TestAzureRMKeyVaultMigrateState(t *testing.T) { "access_policy.0.secret_permissions.5": "recover", "access_policy.0.secret_permissions.6": "restore", "access_policy.0.secret_permissions.7": "set", + "access_policy.0.storage_permissions.#": "0", }, }, } diff --git a/azurerm/resource_arm_key_vault_secret.go b/azurerm/resource_arm_key_vault_secret.go index cf54c2b1de74..93070146053a 100644 --- a/azurerm/resource_arm_key_vault_secret.go +++ b/azurerm/resource_arm_key_vault_secret.go @@ -9,6 +9,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -66,14 +68,14 @@ func resourceArmKeyVaultSecret() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmKeyVaultSecretCreate(d *schema.ResourceData, meta interface{}) error { - vaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + vaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext log.Print("[INFO] preparing arguments for AzureRM KeyVault Secret creation.") @@ -101,7 +103,7 @@ func resourceArmKeyVaultSecretCreate(d *schema.ResourceData, meta interface{}) e d.Set("key_vault_id", id) } - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.GetSecret(ctx, keyVaultBaseUrl, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -116,12 +118,12 @@ func resourceArmKeyVaultSecretCreate(d *schema.ResourceData, meta interface{}) e value := d.Get("value").(string) contentType := d.Get("content_type").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := keyvault.SecretSetParameters{ Value: utils.String(value), ContentType: utils.String(contentType), - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.SetSecret(ctx, keyVaultBaseUrl, name, parameters); err != nil { @@ -143,8 +145,8 @@ func resourceArmKeyVaultSecretCreate(d *schema.ResourceData, meta interface{}) e } func resourceArmKeyVaultSecretUpdate(d *schema.ResourceData, meta interface{}) error { - keyVaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + keyVaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext log.Print("[INFO] preparing arguments for AzureRM KeyVault Secret update.") @@ -173,14 +175,14 @@ func resourceArmKeyVaultSecretUpdate(d *schema.ResourceData, meta interface{}) e value := d.Get("value").(string) contentType := d.Get("content_type").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) if d.HasChange("value") { // for changing the value of the secret we need to create a new version parameters := keyvault.SecretSetParameters{ Value: utils.String(value), ContentType: utils.String(contentType), - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err = client.SetSecret(ctx, id.KeyVaultBaseUrl, id.Name, parameters); err != nil { @@ -202,7 +204,7 @@ func resourceArmKeyVaultSecretUpdate(d *schema.ResourceData, meta interface{}) e } else { parameters := keyvault.SecretUpdateParameters{ ContentType: utils.String(contentType), - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err = client.UpdateSecret(ctx, id.KeyVaultBaseUrl, id.Name, id.Version, parameters); err != nil { @@ -214,8 +216,8 @@ func resourceArmKeyVaultSecretUpdate(d *schema.ResourceData, meta interface{}) e } func resourceArmKeyVaultSecretRead(d *schema.ResourceData, meta interface{}) error { - keyVaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + keyVaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext id, err := azure.ParseKeyVaultChildID(d.Id()) @@ -266,13 +268,12 @@ func resourceArmKeyVaultSecretRead(d *schema.ResourceData, meta interface{}) err d.Set("version", respID.Version) d.Set("content_type", resp.ContentType) - flattenAndSetTags(d, resp.Tags) - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmKeyVaultSecretDelete(d *schema.ResourceData, meta interface{}) error { - keyVaultClient := meta.(*ArmClient).keyVaultClient - client := meta.(*ArmClient).keyVaultManagementClient + keyVaultClient := meta.(*ArmClient).keyvault.VaultsClient + client := meta.(*ArmClient).keyvault.ManagementClient ctx := meta.(*ArmClient).StopContext id, err := azure.ParseKeyVaultChildID(d.Id()) diff --git a/azurerm/resource_arm_key_vault_secret_test.go b/azurerm/resource_arm_key_vault_secret_test.go index d9c388ed0426..23a686ffe8e4 100644 --- a/azurerm/resource_arm_key_vault_secret_test.go +++ b/azurerm/resource_arm_key_vault_secret_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" @@ -66,7 +67,7 @@ func TestAccAzureRMKeyVaultSecret_basicClassic(t *testing.T) { } func TestAccAzureRMKeyVaultSecret_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -195,7 +196,7 @@ func TestAccAzureRMKeyVaultSecret_update(t *testing.T) { } func testCheckAzureRMKeyVaultSecretDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -207,7 +208,7 @@ func testCheckAzureRMKeyVaultSecretDestroy(s *terraform.State) error { vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Secret %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -233,7 +234,7 @@ func testCheckAzureRMKeyVaultSecretDestroy(s *terraform.State) error { func testCheckAzureRMKeyVaultSecretExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API @@ -245,7 +246,7 @@ func testCheckAzureRMKeyVaultSecretExists(resourceName string) resource.TestChec vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Secret %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -269,7 +270,7 @@ func testCheckAzureRMKeyVaultSecretExists(resourceName string) resource.TestChec func testCheckAzureRMKeyVaultSecretDisappears(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultManagementClient + client := testAccProvider.Meta().(*ArmClient).keyvault.ManagementClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API @@ -281,7 +282,7 @@ func testCheckAzureRMKeyVaultSecretDisappears(resourceName string) resource.Test vaultBaseUrl := rs.Primary.Attributes["vault_uri"] keyVaultId := rs.Primary.Attributes["key_vault_id"] - ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyVaultClient, keyVaultId) + ok, err := azure.KeyVaultExists(ctx, testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient, keyVaultId) if err != nil { return fmt.Errorf("Error checking if key vault %q for Secret %q in Vault at url %q exists: %v", keyVaultId, name, vaultBaseUrl, err) } @@ -318,9 +319,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -343,9 +342,9 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_secret" "test" { - name = "secret-%s" - value = "rick-and-morty" - key_vault_id = "${azurerm_key_vault.test.id}" + name = "secret-%s" + value = "rick-and-morty" + key_vault_id = "${azurerm_key_vault.test.id}" } `, rString, location, rString, rString) } @@ -365,9 +364,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -403,9 +400,9 @@ func testAccAzureRMKeyVaultSecret_requiresImport(rString string, location string %s resource "azurerm_key_vault_secret" "import" { - name = "${azurerm_key_vault_secret.test.name}" - value = "${azurerm_key_vault_secret.test.value}" - key_vault_id = "${azurerm_key_vault_secret.test.key_vault_id}" + name = "${azurerm_key_vault_secret.test.name}" + value = "${azurerm_key_vault_secret.test.value}" + key_vault_id = "${azurerm_key_vault_secret.test.key_vault_id}" } `, template) } @@ -425,9 +422,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -452,7 +447,7 @@ resource "azurerm_key_vault" "test" { resource "azurerm_key_vault_secret" "test" { name = "secret-%s" value = "" - key_vault_id = "${azurerm_key_vault.test.id}" + key_vault_id = "${azurerm_key_vault.test.id}" content_type = "application/xml" tags = { @@ -477,9 +472,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" diff --git a/azurerm/resource_arm_key_vault_test.go b/azurerm/resource_arm_key_vault_test.go index bd25cb25d30c..1a30d261b35b 100644 --- a/azurerm/resource_arm_key_vault_test.go +++ b/azurerm/resource_arm_key_vault_test.go @@ -2,6 +2,7 @@ package azurerm import ( "fmt" + "regexp" "testing" "github.com/hashicorp/terraform/helper/acctest" @@ -9,6 +10,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -85,6 +87,53 @@ func TestAccAzureRMKeyVault_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testCheckAzureRMKeyVaultExists(resourceName), resource.TestCheckResourceAttr(resourceName, "network_acls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "sku_name", "premium"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +// Remove in 2.0 +func TestAccAzureRMKeyVault_basicNotDefined(t *testing.T) { + ri := tf.AccRandTimeInt() + config := testAccAzureRMKeyVault_basicNotDefined(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ExpectError: regexp.MustCompile("either 'sku_name' or 'sku' must be defined in the configuration file"), + }, + }, + }) +} + +// Remove in 2.0 +func TestAccAzureRMKeyVault_basicClassic(t *testing.T) { + resourceName := "azurerm_key_vault.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMKeyVault_basicClassic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_acls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "premium"), ), }, { @@ -97,7 +146,7 @@ func TestAccAzureRMKeyVault_basic(t *testing.T) { } func TestAccAzureRMKeyVault_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -238,6 +287,8 @@ func TestAccAzureRMKeyVault_update(t *testing.T) { resourceName := "azurerm_key_vault.test" preConfig := testAccAzureRMKeyVault_basic(ri, testLocation()) postConfig := testAccAzureRMKeyVault_update(ri, testLocation()) + noAccessPolicyConfig := testAccAzureRMKeyVault_noAccessPolicyBlocks(ri, testLocation()) + forceZeroAccessPolicyConfig := testAccAzureRMKeyVault_accessPolicyExplicitZero(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -264,6 +315,23 @@ func TestAccAzureRMKeyVault_update(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.environment", "Staging"), ), }, + { + Config: noAccessPolicyConfig, + Check: resource.ComposeTestCheckFunc( + // There are no access_policy blocks in this configuration + // at all, which means to ignore any existing policies and + // so the one created in previous steps is still present. + resource.TestCheckResourceAttr(resourceName, "access_policy.#", "1"), + ), + }, + { + Config: forceZeroAccessPolicyConfig, + Check: resource.ComposeTestCheckFunc( + // This config explicitly sets access_policy = [], which + // means to delete any existing policies. + resource.TestCheckResourceAttr(resourceName, "access_policy.#", "0"), + ), + }, }, }) } @@ -294,7 +362,7 @@ func TestAccAzureRMKeyVault_justCert(t *testing.T) { } func testCheckAzureRMKeyVaultDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).keyVaultClient + client := testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -333,7 +401,7 @@ func testCheckAzureRMKeyVaultExists(resourceName string) resource.TestCheckFunc return fmt.Errorf("Bad: no resource group found in state for vault: %s", vaultName) } - client := testAccProvider.Meta().(*ArmClient).keyVaultClient + client := testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, vaultName) @@ -363,7 +431,7 @@ func testCheckAzureRMKeyVaultDisappears(resourceName string) resource.TestCheckF return fmt.Errorf("Bad: no resource group found in state for vault: %s", vaultName) } - client := testAccProvider.Meta().(*ArmClient).keyVaultClient + client := testAccProvider.Meta().(*ArmClient).keyvault.VaultsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Delete(ctx, resourceGroup, vaultName) @@ -388,6 +456,70 @@ resource "azurerm_resource_group" "test" { location = "%s" } +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku_name = "premium" + + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.client_id}" + + key_permissions = [ + "create", + ] + + secret_permissions = [ + "set", + ] + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMKeyVault_basicNotDefined(rInt int, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.client_id}" + + key_permissions = [ + "create", + ] + + secret_permissions = [ + "set", + ] + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMKeyVault_basicClassic(rInt int, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + resource "azurerm_key_vault" "test" { name = "vault%d" location = "${azurerm_resource_group.test.location}" @@ -419,16 +551,13 @@ func testAccAzureRMKeyVault_requiresImport(rInt int, location string) string { return fmt.Sprintf(` %s - resource "azurerm_key_vault" "import" { name = "${azurerm_key_vault.test.name}" location = "${azurerm_key_vault.test.location}" resource_group_name = "${azurerm_key_vault.test.resource_group_name}" tenant_id = "${azurerm_key_vault.test.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -491,9 +620,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -528,9 +655,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -570,9 +695,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -598,7 +721,37 @@ resource "azurerm_key_vault" "test" { `, rInt, location, rInt) } -func testAccAzureRMKeyVault_complete(rInt int, location string) string { +func testAccAzureRMKeyVault_noAccessPolicyBlocks(rInt int, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku { + name = "premium" + } + + enabled_for_deployment = true + enabled_for_disk_encryption = true + enabled_for_template_deployment = true + + tags = { + environment = "Staging" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMKeyVault_accessPolicyExplicitZero(rInt int, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} @@ -617,6 +770,36 @@ resource "azurerm_key_vault" "test" { name = "premium" } + access_policy = [] + + enabled_for_deployment = true + enabled_for_disk_encryption = true + enabled_for_template_deployment = true + + tags = { + environment = "Staging" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMKeyVault_complete(rInt int, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku_name = "premium" + access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" object_id = "${data.azurerm_client_config.current.client_id}" @@ -657,9 +840,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -697,44 +878,43 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" %s } %s + `, rInt, location, rInt, accessPoliciesConfigs, storageAccountConfigs) } func testAccAzureRMKeyVault_generateStorageAccountConfigs(accountNum int, rs string) string { return fmt.Sprintf(` resource "azurerm_storage_account" "testsa%d" { - name = "testsa%s%d" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "GRS" - - identity { - type = "SystemAssigned" - } - - tags = { - environment = "testing" - } + name = "testsa%s%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "GRS" + + identity { + type = "SystemAssigned" + } + + tags = { + environment = "testing" + } } `, accountNum, rs, accountNum) } func testAccAzureRMKeyVault_generateAccessPolicyConfigs(accountNum int) string { return fmt.Sprintf(` - access_policy { - tenant_id = "${data.azurerm_client_config.current.tenant_id}" - object_id = "${azurerm_storage_account.testsa%d.identity.0.principal_id}" - - key_permissions = ["get","create","delete","list","restore","recover","unwrapkey","wrapkey","purge","encrypt","decrypt","sign","verify"] - secret_permissions = ["get"] - } +access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${azurerm_storage_account.testsa%d.identity.0.principal_id}" + + key_permissions = ["get", "create", "delete", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify"] + secret_permissions = ["get"] +} `, accountNum) } diff --git a/azurerm/resource_arm_kubernetes_cluster.go b/azurerm/resource_arm_kubernetes_cluster.go index 6e520657989a..952c12e00fd6 100644 --- a/azurerm/resource_arm_kubernetes_cluster.go +++ b/azurerm/resource_arm_kubernetes_cluster.go @@ -6,7 +6,7 @@ import ( "log" "strings" - "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2018-03-31/containerservice" + "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2019-06-01/containerservice" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" @@ -15,6 +15,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -71,9 +73,9 @@ func resourceArmKubernetesCluster() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "dns_prefix": { Type: schema.TypeString, @@ -92,7 +94,6 @@ func resourceArmKubernetesCluster() *schema.Resource { "agent_pool_profile": { Type: schema.TypeList, Required: true, - MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { @@ -102,6 +103,17 @@ func resourceArmKubernetesCluster() *schema.Resource { ValidateFunc: validate.KubernetesAgentPoolName, }, + "type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: string(containerservice.AvailabilitySet), + ValidateFunc: validation.StringInSlice([]string{ + string(containerservice.AvailabilitySet), + string(containerservice.VirtualMachineScaleSets), + }, false), + }, + "count": { Type: schema.TypeInt, Optional: true, @@ -109,6 +121,31 @@ func resourceArmKubernetesCluster() *schema.Resource { ValidateFunc: validation.IntBetween(1, 100), }, + "max_count": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 100), + }, + + "min_count": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 100), + }, + + "enable_auto_scaling": { + Type: schema.TypeBool, + Optional: true, + }, + + "availability_zones": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + // TODO: remove this field in the next major version "dns_prefix": { Type: schema.TypeString, @@ -163,6 +200,12 @@ func resourceArmKubernetesCluster() *schema.Resource { Computed: true, ForceNew: true, }, + + "node_taints": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, }, }, @@ -258,6 +301,20 @@ func resourceArmKubernetesCluster() *schema.Resource { }, }, }, + + "kube_dashboard": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + }, + }, + }, }, }, }, @@ -278,6 +335,7 @@ func resourceArmKubernetesCluster() *schema.Resource { Type: schema.TypeList, Required: true, ForceNew: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -294,6 +352,26 @@ func resourceArmKubernetesCluster() *schema.Resource { }, }, + "windows_profile": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "admin_username": { + Type: schema.TypeString, + Required: true, + }, + "admin_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + "network_profile": { Type: schema.TypeList, Optional: true, @@ -312,6 +390,17 @@ func resourceArmKubernetesCluster() *schema.Resource { }, false), }, + "network_policy": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(containerservice.NetworkPolicyCalico), + string(containerservice.NetworkPolicyAzure), + }, false), + }, + "dns_service_ip": { Type: schema.TypeString, Optional: true, @@ -343,6 +432,18 @@ func resourceArmKubernetesCluster() *schema.Resource { ForceNew: true, ValidateFunc: validate.CIDR, }, + + "load_balancer_sku": { + Type: schema.TypeString, + Optional: true, + Default: string(containerservice.Basic), + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(containerservice.Basic), + string(containerservice.Standard), + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, }, }, }, @@ -404,7 +505,7 @@ func resourceArmKubernetesCluster() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), "fqdn": { Type: schema.TypeString, @@ -498,6 +599,23 @@ func resourceArmKubernetesCluster() *schema.Resource { "node_resource_group": { Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + "api_server_authorized_ip_ranges": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.CIDR, + }, + }, + + "enable_pod_security_policy": { + Type: schema.TypeBool, + Optional: true, Computed: true, }, }, @@ -505,7 +623,7 @@ func resourceArmKubernetesCluster() *schema.Resource { } func resourceArmKubernetesClusterCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).kubernetesClustersClient + client := meta.(*ArmClient).containers.KubernetesClustersClient ctx := meta.(*ArmClient).StopContext tenantId := meta.(*ArmClient).tenantId @@ -514,7 +632,7 @@ func resourceArmKubernetesClusterCreateUpdate(d *schema.ResourceData, meta inter resGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -527,48 +645,51 @@ func resourceArmKubernetesClusterCreateUpdate(d *schema.ResourceData, meta inter } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) dnsPrefix := d.Get("dns_prefix").(string) kubernetesVersion := d.Get("kubernetes_version").(string) linuxProfile := expandKubernetesClusterLinuxProfile(d) - agentProfiles := expandKubernetesClusterAgentPoolProfiles(d) + agentProfiles, err := expandKubernetesClusterAgentPoolProfiles(d) + if err != nil { + return err + } + windowsProfile := expandKubernetesClusterWindowsProfile(d) servicePrincipalProfile := expandAzureRmKubernetesClusterServicePrincipal(d) networkProfile := expandKubernetesClusterNetworkProfile(d) addonProfiles := expandKubernetesClusterAddonProfiles(d) - tags := d.Get("tags").(map[string]interface{}) - - // we can't do this in the CustomizeDiff since the interpolations aren't evaluated at that point - if networkProfile != nil { - // ensure there's a Subnet ID attached - if networkProfile.NetworkPlugin == containerservice.Azure { - for _, profile := range agentProfiles { - if profile.VnetSubnetID == nil { - return fmt.Errorf("A `vnet_subnet_id` must be specified when the `network_plugin` is set to `azure`.") - } - } - } - } + t := d.Get("tags").(map[string]interface{}) rbacRaw := d.Get("role_based_access_control").([]interface{}) rbacEnabled, azureADProfile := expandKubernetesClusterRoleBasedAccessControl(rbacRaw, tenantId) + apiServerAuthorizedIPRangesRaw := d.Get("api_server_authorized_ip_ranges").(*schema.Set).List() + apiServerAuthorizedIPRanges := utils.ExpandStringSlice(apiServerAuthorizedIPRangesRaw) + + nodeResourceGroup := d.Get("node_resource_group").(string) + + enablePodSecurityPolicy := d.Get("enable_pod_security_policy").(bool) + parameters := containerservice.ManagedCluster{ Name: &name, Location: &location, ManagedClusterProperties: &containerservice.ManagedClusterProperties{ - AadProfile: azureADProfile, - AddonProfiles: addonProfiles, - AgentPoolProfiles: &agentProfiles, - DNSPrefix: utils.String(dnsPrefix), - EnableRBAC: utils.Bool(rbacEnabled), - KubernetesVersion: utils.String(kubernetesVersion), - LinuxProfile: linuxProfile, - NetworkProfile: networkProfile, - ServicePrincipalProfile: servicePrincipalProfile, + APIServerAuthorizedIPRanges: apiServerAuthorizedIPRanges, + AadProfile: azureADProfile, + AddonProfiles: addonProfiles, + AgentPoolProfiles: &agentProfiles, + DNSPrefix: utils.String(dnsPrefix), + EnableRBAC: utils.Bool(rbacEnabled), + KubernetesVersion: utils.String(kubernetesVersion), + LinuxProfile: linuxProfile, + WindowsProfile: windowsProfile, + NetworkProfile: networkProfile, + ServicePrincipalProfile: servicePrincipalProfile, + NodeResourceGroup: utils.String(nodeResourceGroup), + EnablePodSecurityPolicy: utils.Bool(enablePodSecurityPolicy), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resGroup, name, parameters) @@ -595,10 +716,10 @@ func resourceArmKubernetesClusterCreateUpdate(d *schema.ResourceData, meta inter } func resourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).kubernetesClustersClient + client := meta.(*ArmClient).containers.KubernetesClustersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -624,7 +745,7 @@ func resourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}) d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.ManagedClusterProperties; props != nil { @@ -632,6 +753,12 @@ func resourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}) d.Set("fqdn", props.Fqdn) d.Set("kubernetes_version", props.KubernetesVersion) d.Set("node_resource_group", props.NodeResourceGroup) + d.Set("enable_pod_security_policy", props.EnablePodSecurityPolicy) + + apiServerAuthorizedIPRanges := utils.FlattenStringSlice(props.APIServerAuthorizedIPRanges) + if err := d.Set("api_server_authorized_ip_ranges", apiServerAuthorizedIPRanges); err != nil { + return fmt.Errorf("Error setting `api_server_authorized_ip_ranges`: %+v", err) + } addonProfiles := flattenKubernetesClusterAddonProfiles(props.AddonProfiles) if err := d.Set("addon_profile", addonProfiles); err != nil { @@ -648,6 +775,11 @@ func resourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error setting `linux_profile`: %+v", err) } + windowsProfile := flattenKubernetesClusterWindowsProfile(props.WindowsProfile, d) + if err := d.Set("windows_profile", windowsProfile); err != nil { + return fmt.Errorf("Error setting `windows_profile`: %+v", err) + } + networkProfile := flattenKubernetesClusterNetworkProfile(props.NetworkProfile) if err := d.Set("network_profile", networkProfile); err != nil { return fmt.Errorf("Error setting `network_profile`: %+v", err) @@ -687,16 +819,14 @@ func resourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error setting `kube_config`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmKubernetesClusterDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).kubernetesClustersClient + client := meta.(*ArmClient).containers.KubernetesClustersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -784,7 +914,7 @@ func expandKubernetesClusterAddonProfiles(d *schema.ResourceData) map[string]*co enabled := value["enabled"].(bool) if subnetName, ok := value["subnet_name"]; ok { - config["subnetName"] = utils.String(subnetName.(string)) + config["SubnetName"] = utils.String(subnetName.(string)) } addonProfiles["aciConnectorLinux"] = &containerservice.ManagedClusterAddonProfile{ @@ -793,6 +923,17 @@ func expandKubernetesClusterAddonProfiles(d *schema.ResourceData) map[string]*co } } + kubeDashboard := profile["kube_dashboard"].([]interface{}) + if len(kubeDashboard) > 0 { + value := kubeDashboard[0].(map[string]interface{}) + enabled := value["enabled"].(bool) + + addonProfiles["kubeDashboard"] = &containerservice.ManagedClusterAddonProfile{ + Enabled: utils.Bool(enabled), + Config: nil, + } + } + return addonProfiles } @@ -847,7 +988,7 @@ func flattenKubernetesClusterAddonProfiles(profile map[string]*containerservice. } subnetName := "" - if v := aciConnector.Config["subnetName"]; v != nil { + if v := aciConnector.Config["SubnetName"]; v != nil { subnetName = *v } @@ -859,38 +1000,90 @@ func flattenKubernetesClusterAddonProfiles(profile map[string]*containerservice. } values["aci_connector_linux"] = aciConnectors + kubeDashboards := make([]interface{}, 0) + if kubeDashboard := profile["kubeDashboard"]; kubeDashboard != nil { + enabled := false + if enabledVal := kubeDashboard.Enabled; enabledVal != nil { + enabled = *enabledVal + } + + output := map[string]interface{}{ + "enabled": enabled, + } + kubeDashboards = append(kubeDashboards, output) + } + values["kube_dashboard"] = kubeDashboards + return []interface{}{values} } -func expandKubernetesClusterAgentPoolProfiles(d *schema.ResourceData) []containerservice.ManagedClusterAgentPoolProfile { +func expandKubernetesClusterAgentPoolProfiles(d *schema.ResourceData) ([]containerservice.ManagedClusterAgentPoolProfile, error) { + configs := d.Get("agent_pool_profile").([]interface{}) - config := configs[0].(map[string]interface{}) - name := config["name"].(string) - count := int32(config["count"].(int)) - vmSize := config["vm_size"].(string) - osDiskSizeGB := int32(config["os_disk_size_gb"].(int)) - osType := config["os_type"].(string) + profiles := make([]containerservice.ManagedClusterAgentPoolProfile, 0) + for config_id := range configs { + config := configs[config_id].(map[string]interface{}) + + name := config["name"].(string) + poolType := config["type"].(string) + count := int32(config["count"].(int)) + vmSize := config["vm_size"].(string) + osDiskSizeGB := int32(config["os_disk_size_gb"].(int)) + osType := config["os_type"].(string) + + profile := containerservice.ManagedClusterAgentPoolProfile{ + Name: utils.String(name), + Type: containerservice.AgentPoolType(poolType), + Count: utils.Int32(count), + VMSize: containerservice.VMSizeTypes(vmSize), + OsDiskSizeGB: utils.Int32(osDiskSizeGB), + OsType: containerservice.OSType(osType), + } - profile := containerservice.ManagedClusterAgentPoolProfile{ - Name: utils.String(name), - Count: utils.Int32(count), - VMSize: containerservice.VMSizeTypes(vmSize), - OsDiskSizeGB: utils.Int32(osDiskSizeGB), - StorageProfile: containerservice.ManagedDisks, - OsType: containerservice.OSType(osType), - } + if maxPods := int32(config["max_pods"].(int)); maxPods > 0 { + profile.MaxPods = utils.Int32(maxPods) + } - if maxPods := int32(config["max_pods"].(int)); maxPods > 0 { - profile.MaxPods = utils.Int32(maxPods) - } + vnetSubnetID := config["vnet_subnet_id"].(string) + if vnetSubnetID != "" { + profile.VnetSubnetID = utils.String(vnetSubnetID) + } + + if maxCount := int32(config["max_count"].(int)); maxCount > 0 { + profile.MaxCount = utils.Int32(maxCount) + } + + if minCount := int32(config["min_count"].(int)); minCount > 0 { + profile.MinCount = utils.Int32(minCount) + } + + if enableAutoScalingItf := config["enable_auto_scaling"]; enableAutoScalingItf != nil { + profile.EnableAutoScaling = utils.Bool(enableAutoScalingItf.(bool)) + + // Auto scaling will change the number of nodes, but the original count number should not be sent again. + // This avoid the cluster being resized after creation. + if *profile.EnableAutoScaling && !d.IsNewResource() { + profile.Count = nil + } + } + + if availavilityZones := utils.ExpandStringSlice(config["availability_zones"].([]interface{})); len(*availavilityZones) > 0 { + profile.AvailabilityZones = availavilityZones + } + + if *profile.EnableAutoScaling && (profile.MinCount == nil || profile.MaxCount == nil) { + return nil, fmt.Errorf("Can't create an AKS cluster with autoscaling enabled but not setting min_count or max_count") + } + + if nodeTaints := utils.ExpandStringSlice(config["node_taints"].([]interface{})); len(*nodeTaints) > 0 { + profile.NodeTaints = nodeTaints + } - vnetSubnetID := config["vnet_subnet_id"].(string) - if vnetSubnetID != "" { - profile.VnetSubnetID = utils.String(vnetSubnetID) + profiles = append(profiles, profile) } - return []containerservice.ManagedClusterAgentPoolProfile{profile} + return profiles, nil } func flattenKubernetesClusterAgentPoolProfiles(profiles *[]containerservice.ManagedClusterAgentPoolProfile, fqdn *string) []interface{} { @@ -903,10 +1096,28 @@ func flattenKubernetesClusterAgentPoolProfiles(profiles *[]containerservice.Mana for _, profile := range *profiles { agentPoolProfile := make(map[string]interface{}) + if profile.Type != "" { + agentPoolProfile["type"] = string(profile.Type) + } + if profile.Count != nil { agentPoolProfile["count"] = int(*profile.Count) } + if profile.MinCount != nil { + agentPoolProfile["min_count"] = int(*profile.MinCount) + } + + if profile.MaxCount != nil { + agentPoolProfile["max_count"] = int(*profile.MaxCount) + } + + if profile.EnableAutoScaling != nil { + agentPoolProfile["enable_auto_scaling"] = *profile.EnableAutoScaling + } + + agentPoolProfile["availability_zones"] = utils.FlattenStringSlice(profile.AvailabilityZones) + if fqdn != nil { // temporarily persist the parent FQDN here until `fqdn` is removed from the `agent_pool_profile` agentPoolProfile["fqdn"] = *fqdn @@ -936,6 +1147,10 @@ func flattenKubernetesClusterAgentPoolProfiles(profiles *[]containerservice.Mana agentPoolProfile["max_pods"] = int(*profile.MaxPods) } + if profile.NodeTaints != nil { + agentPoolProfile["node_taints"] = *profile.NodeTaints + } + agentPoolProfiles = append(agentPoolProfiles, agentPoolProfile) } @@ -974,6 +1189,26 @@ func expandKubernetesClusterLinuxProfile(d *schema.ResourceData) *containerservi return &profile } +func expandKubernetesClusterWindowsProfile(d *schema.ResourceData) *containerservice.ManagedClusterWindowsProfile { + profiles := d.Get("windows_profile").([]interface{}) + + if len(profiles) == 0 { + return nil + } + + config := profiles[0].(map[string]interface{}) + + adminUsername := config["admin_username"].(string) + adminPassword := config["admin_password"].(string) + + profile := containerservice.ManagedClusterWindowsProfile{ + AdminUsername: &adminUsername, + AdminPassword: &adminPassword, + } + + return &profile +} + func flattenKubernetesClusterLinuxProfile(profile *containerservice.LinuxProfile) []interface{} { if profile == nil { return []interface{}{} @@ -1003,7 +1238,26 @@ func flattenKubernetesClusterLinuxProfile(profile *containerservice.LinuxProfile return []interface{}{values} } -func expandKubernetesClusterNetworkProfile(d *schema.ResourceData) *containerservice.NetworkProfile { +func flattenKubernetesClusterWindowsProfile(profile *containerservice.ManagedClusterWindowsProfile, d *schema.ResourceData) []interface{} { + if profile == nil { + return []interface{}{} + } + + values := make(map[string]interface{}) + + if username := profile.AdminUsername; username != nil { + values["admin_username"] = *username + } + + // admin password isn't returned, so let's look it up + if v, ok := d.GetOk("windows_profile.0.admin_password"); ok { + values["admin_password"] = v.(string) + } + + return []interface{}{values} +} + +func expandKubernetesClusterNetworkProfile(d *schema.ResourceData) *containerservice.NetworkProfileType { configs := d.Get("network_profile").([]interface{}) if len(configs) == 0 { return nil @@ -1013,8 +1267,14 @@ func expandKubernetesClusterNetworkProfile(d *schema.ResourceData) *containerser networkPlugin := config["network_plugin"].(string) - networkProfile := containerservice.NetworkProfile{ - NetworkPlugin: containerservice.NetworkPlugin(networkPlugin), + networkPolicy := config["network_policy"].(string) + + loadBalancerSku := config["load_balancer_sku"].(string) + + networkProfile := containerservice.NetworkProfileType{ + NetworkPlugin: containerservice.NetworkPlugin(networkPlugin), + NetworkPolicy: containerservice.NetworkPolicy(networkPolicy), + LoadBalancerSku: containerservice.LoadBalancerSku(loadBalancerSku), } if v, ok := config["dns_service_ip"]; ok && v.(string) != "" { @@ -1040,7 +1300,7 @@ func expandKubernetesClusterNetworkProfile(d *schema.ResourceData) *containerser return &networkProfile } -func flattenKubernetesClusterNetworkProfile(profile *containerservice.NetworkProfile) []interface{} { +func flattenKubernetesClusterNetworkProfile(profile *containerservice.NetworkProfileType) []interface{} { if profile == nil { return []interface{}{} } @@ -1049,6 +1309,10 @@ func flattenKubernetesClusterNetworkProfile(profile *containerservice.NetworkPro values["network_plugin"] = profile.NetworkPlugin + if profile.NetworkPolicy != "" { + values["network_policy"] = string(profile.NetworkPolicy) + } + if profile.ServiceCidr != nil { values["service_cidr"] = *profile.ServiceCidr } @@ -1065,6 +1329,10 @@ func flattenKubernetesClusterNetworkProfile(profile *containerservice.NetworkPro values["pod_cidr"] = *profile.PodCidr } + if profile.LoadBalancerSku != "" { + values["load_balancer_sku"] = string(profile.LoadBalancerSku) + } + return []interface{}{values} } diff --git a/azurerm/resource_arm_kubernetes_cluster_test.go b/azurerm/resource_arm_kubernetes_cluster_test.go index 964164f9743b..5bdc68749c0a 100644 --- a/azurerm/resource_arm_kubernetes_cluster_test.go +++ b/azurerm/resource_arm_kubernetes_cluster_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMKubernetesCluster_basic(t *testing.T) { @@ -39,6 +40,7 @@ func TestAccAzureRMKubernetesCluster_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "kube_admin_config.#", "0"), resource.TestCheckResourceAttr(resourceName, "kube_admin_config_raw", ""), resource.TestCheckResourceAttrSet(resourceName, "agent_pool_profile.0.max_pods"), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.load_balancer_sku", "basic"), ), }, { @@ -51,7 +53,7 @@ func TestAccAzureRMKubernetesCluster_basic(t *testing.T) { } func TestAccAzureRMKubernetesCluster_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -200,6 +202,44 @@ func TestAccAzureRMKubernetesCluster_linuxProfile(t *testing.T) { }) } +func TestAccAzureRMKubernetesCluster_windowsProfile(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_windowsProfile(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.client_key"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.client_certificate"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.cluster_ca_certificate"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.host"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.username"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.password"), + resource.TestCheckResourceAttrSet(resourceName, "agent_pool_profile.0.max_pods"), + resource.TestCheckResourceAttrSet(resourceName, "agent_pool_profile.1.max_pods"), + resource.TestCheckResourceAttrSet(resourceName, "linux_profile.0.admin_username"), + resource.TestCheckResourceAttrSet(resourceName, "windows_profile.0.admin_username"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"windows_profile.0.admin_password"}, + }, + }, + }) +} + func TestAccAzureRMKubernetesCluster_addAgent(t *testing.T) { resourceName := "azurerm_kubernetes_cluster.test" ri := tf.AccRandTimeInt() @@ -242,17 +282,17 @@ func TestAccAzureRMKubernetesCluster_upgradeConfig(t *testing.T) { CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMKubernetesCluster_upgrade(ri, location, clientId, clientSecret, "1.10.9"), + Config: testAccAzureRMKubernetesCluster_upgrade(ri, location, clientId, clientSecret, "1.12.7"), Check: resource.ComposeTestCheckFunc( testCheckAzureRMKubernetesClusterExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "kubernetes_version", "1.10.9"), + resource.TestCheckResourceAttr(resourceName, "kubernetes_version", "1.12.7"), ), }, { - Config: testAccAzureRMKubernetesCluster_upgrade(ri, location, clientId, clientSecret, "1.11.5"), + Config: testAccAzureRMKubernetesCluster_upgrade(ri, location, clientId, clientSecret, "1.13.5"), Check: resource.ComposeTestCheckFunc( testCheckAzureRMKubernetesClusterExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "kubernetes_version", "1.11.5"), + resource.TestCheckResourceAttr(resourceName, "kubernetes_version", "1.13.5"), ), }, }, @@ -360,6 +400,30 @@ func TestAccAzureRMKubernetesCluster_addonProfileRouting(t *testing.T) { }) } +func TestAccAzureRMKubernetesCluster_addonProfileKubeDashboard(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_addonProfileKubeDashboard(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "addon_profile.0.kube_dashboard.#", "1"), + resource.TestCheckResourceAttr(resourceName, "addon_profile.0.kube_dashboard.0.enabled", "false"), + ), + }, + }, + }) +} + func TestAccAzureRMKubernetesCluster_advancedNetworkingKubenet(t *testing.T) { resourceName := "azurerm_kubernetes_cluster.test" ri := tf.AccRandTimeInt() @@ -452,99 +516,975 @@ func TestAccAzureRMKubernetesCluster_advancedNetworkingAzureComplete(t *testing. }) } -func testCheckAzureRMKubernetesClusterExists(resourceName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - // Ensure we have enough information in state to look up in API - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("Not found: %s", resourceName) - } +func TestAccAzureRMKubernetesCluster_advancedNetworkingAzureCalicoPolicy(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicy(ri, clientId, clientSecret, testLocation(), "azure", "calico") - name := rs.Primary.Attributes["name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for Managed Kubernetes Cluster: %s", name) - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_plugin", "azure"), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_policy", "calico"), + ), + }, + }, + }) +} - client := testAccProvider.Meta().(*ArmClient).kubernetesClustersClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext +func TestAccAzureRMKubernetesCluster_advancedNetworkingAzureCalicoPolicyComplete(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicyComplete(ri, clientId, clientSecret, testLocation(), "azure", "calico") - aks, err := client.Get(ctx, resourceGroup, name) - if err != nil { - return fmt.Errorf("Bad: Get on kubernetesClustersClient: %+v", err) - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_plugin", "azure"), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_policy", "calico"), + ), + }, + }, + }) +} - if aks.StatusCode == http.StatusNotFound { - return fmt.Errorf("Bad: Managed Kubernetes Cluster %q (Resource Group: %q) does not exist", name, resourceGroup) - } +func TestAccAzureRMKubernetesCluster_advancedNetworkingAzureNPMPolicy(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicy(ri, clientId, clientSecret, testLocation(), "azure", "azure") - return nil - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_plugin", "azure"), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_policy", "azure"), + ), + }, + }, + }) } -func testCheckAzureRMKubernetesClusterDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).kubernetesClustersClient - - for _, rs := range s.RootModule().Resources { - if rs.Type != "azurerm_kubernetes_cluster" { - continue - } +func TestAccAzureRMKubernetesCluster_advancedNetworkingAzureNPMPolicyComplete(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicyComplete(ri, clientId, clientSecret, testLocation(), "azure", "azure") - name := rs.Primary.Attributes["name"] - resourceGroup := rs.Primary.Attributes["resource_group_name"] + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_plugin", "azure"), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_policy", "azure"), + ), + }, + }, + }) +} - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := conn.Get(ctx, resourceGroup, name) +func TestAccAzureRMKubernetesCluster_standardLoadBalancer(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_standardLoadBalancer(ri, clientId, clientSecret, testLocation()) - if err != nil { - return nil - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.load_balancer_sku", "standard"), + ), + }, + }, + }) +} - if resp.StatusCode != http.StatusNotFound { - return fmt.Errorf("Managed Kubernetes Cluster still exists:\n%#v", resp) - } - } +func TestAccAzureRMKubernetesCluster_standardLoadBalancerComplete(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_standardLoadBalancerComplete(ri, clientId, clientSecret, testLocation()) - return nil + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_profile.0.load_balancer_sku", "standard"), + ), + }, + }, + }) } -func testAccAzureRMKubernetesCluster_basic(rInt int, clientId string, clientSecret string, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" +func TestAccAzureRMKubernetesCluster_apiServerAuthorizedIPRanges(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_apiServerAuthorizedIPRanges(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "role_based_access_control.#", "1"), + resource.TestCheckResourceAttr(resourceName, "role_based_access_control.0.enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "role_based_access_control.0.azure_active_directory.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.client_key"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.client_certificate"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.cluster_ca_certificate"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.host"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.username"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.password"), + resource.TestCheckResourceAttr(resourceName, "kube_admin_config.#", "0"), + resource.TestCheckResourceAttr(resourceName, "kube_admin_config_raw", ""), + resource.TestCheckResourceAttrSet(resourceName, "agent_pool_profile.0.max_pods"), + resource.TestCheckResourceAttr(resourceName, "api_server_authorized_ip_ranges.#", "3"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) } -resource "azurerm_kubernetes_cluster" "test" { - name = "acctestaks%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - dns_prefix = "acctestaks%d" +func TestAccAzureRMKubernetesCluster_virtualMachineScaleSets(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_virtualMachineScaleSets(ri, clientId, clientSecret, testLocation()) - agent_pool_profile { - name = "default" - count = "1" - vm_size = "Standard_DS2_v2" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "role_based_access_control.#", "1"), + resource.TestCheckResourceAttr(resourceName, "role_based_access_control.0.enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "role_based_access_control.0.azure_active_directory.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.client_key"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.client_certificate"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.cluster_ca_certificate"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.host"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.username"), + resource.TestCheckResourceAttrSet(resourceName, "kube_config.0.password"), + resource.TestCheckResourceAttr(resourceName, "kube_admin_config.#", "0"), + resource.TestCheckResourceAttr(resourceName, "kube_admin_config_raw", ""), + resource.TestCheckResourceAttrSet(resourceName, "agent_pool_profile.0.max_pods"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.type", "VirtualMachineScaleSets"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMKubernetesCluster_autoScalingNoAvailabilityZones(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_autoscaleNoAvailabilityZones(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.type", "VirtualMachineScaleSets"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.min_count", "1"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.max_count", "2"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.enable_auto_scaling", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMKubernetesCluster_autoScalingWithAvailabilityZones(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_autoscaleWithAvailabilityZones(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.type", "VirtualMachineScaleSets"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.min_count", "1"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.max_count", "2"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.enable_auto_scaling", "true"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.availability_zones.#", "2"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.availability_zones.0", "1"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.availability_zones.1", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMKubernetesCluster_multipleAgents(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_multipleAgents(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.0.name", "pool1"), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.1.name", "pool2"), + ), + }, + }, + }) +} + +func TestAccAzureRMKubernetesCluster_nodeTaints(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_nodeTaints(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "agent_pool_profile.1.node_taints.0", "key=value:NoSchedule"), + ), + }, + }, + }) +} + +func TestAccAzureRMKubernetesCluster_nodeResourceGroup(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_nodeResourceGroup(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMKubernetesCluster_enablePodSecurityPolicy(t *testing.T) { + resourceName := "azurerm_kubernetes_cluster.test" + ri := tf.AccRandTimeInt() + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + config := testAccAzureRMKubernetesCluster_enablePodSecurityPolicy(ri, clientId, clientSecret, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKubernetesClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKubernetesClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "enable_pod_security_policy", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMKubernetesClusterExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Managed Kubernetes Cluster: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).containers.KubernetesClustersClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + aks, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Bad: Get on kubernetesClustersClient: %+v", err) + } + + if aks.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Managed Kubernetes Cluster %q (Resource Group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMKubernetesClusterDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).containers.KubernetesClustersClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_kubernetes_cluster" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Managed Kubernetes Cluster still exists:\n%#v", resp) + } + } + + return nil +} + +func testAccAzureRMKubernetesCluster_basic(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } +} +`, rInt, location, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_requiresImport(rInt int, clientId, clientSecret, location string) string { + template := testAccAzureRMKubernetesCluster_basic(rInt, clientId, clientSecret, location) + return fmt.Sprintf(` +%s + +resource "azurerm_kubernetes_cluster" "import" { + name = "${azurerm_kubernetes_cluster.test.name}" + location = "${azurerm_kubernetes_cluster.test.location}" + resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" + dns_prefix = "${azurerm_kubernetes_cluster.test.dns_prefix}" + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } +} +`, template, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_linuxProfile(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } +} +`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_windowsProfile(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + windows_profile { + admin_username = "azureuser" + admin_password = "pass_123-worD" + } + + agent_pool_profile { + name = "linux" + type = "VirtualMachineScaleSets" + count = "1" + vm_size = "Standard_DS2_v2" + max_pods = 30 + os_type = "Linux" + os_disk_size_gb = "30" + } + + agent_pool_profile { + name = "win" + type = "VirtualMachineScaleSets" + count = "1" + vm_size = "Standard_DS3_v2" + max_pods = 30 + os_type = "Windows" + os_disk_size_gb = "30" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } + + network_profile { + network_plugin = "azure" + network_policy = "azure" + dns_service_ip = "10.10.0.10" + docker_bridge_cidr = "172.18.0.1/16" + service_cidr = "10.10.0.0/16" + } +} +`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_addAgent(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + agent_pool_profile { + name = "default" + count = "2" + vm_size = "Standard_DS2_v2" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } +} +`, rInt, location, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_roleBasedAccessControl(rInt int, location, clientId, clientSecret string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } + + role_based_access_control { + enabled = true + } +} +`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_roleBasedAccessControlAAD(rInt int, location, clientId, clientSecret, tenantId string) string { + return fmt.Sprintf(` +variable "tenant_id" { + default = "%s" +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } + + role_based_access_control { + enabled = true + + azure_active_directory { + server_app_id = "%s" + server_app_secret = "%s" + client_app_id = "%s" + tenant_id = "${var.tenant_id}" + } + } +} +`, tenantId, rInt, location, rInt, rInt, rInt, clientId, clientSecret, clientId, clientSecret, clientId) +} + +func testAccAzureRMKubernetesCluster_internalNetwork(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["172.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Testing" + } +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "172.0.2.0/24" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + agent_pool_profile { + name = "default" + count = "2" + vm_size = "Standard_DS2_v2" + vnet_subnet_id = "${azurerm_subnet.test.id}" + max_pods = 60 + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_addonProfileAciConnectorLinux(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["172.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Testing" + } +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "172.0.2.0/24" +} + +resource "azurerm_subnet" "test-aci" { + name = "acctestsubnet-aci%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "172.0.3.0/24" + + delegation { + name = "aciDelegation" + + service_delegation { + name = "Microsoft.ContainerInstance/containerGroups" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" + vnet_subnet_id = "${azurerm_subnet.test.id}" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } + + addon_profile { + aci_connector_linux { + enabled = true + subnet_name = "${azurerm_subnet.test-aci.name}" + } + } + + network_profile { + network_plugin = "azure" + } +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_addonProfileOMS(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_log_analytics_workspace" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "PerGB2018" +} + +resource "azurerm_log_analytics_solution" "test" { + solution_name = "ContainerInsights" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + + plan { + publisher = "Microsoft" + product = "OMSGallery/ContainerInsights" + } +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } + + addon_profile { + oms_agent { + enabled = true + log_analytics_workspace_id = "${azurerm_log_analytics_workspace.test.id}" + } + } +} +`, rInt, location, rInt, rInt, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_addonProfileRouting(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" } service_principal { client_id = "%s" client_secret = "%s" } + + addon_profile { + http_application_routing { + enabled = true + } + } } -`, rInt, location, rInt, rInt, clientId, clientSecret) +`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_requiresImport(rInt int, clientId, clientSecret, location string) string { - template := testAccAzureRMKubernetesCluster_basic(rInt, clientId, clientSecret, location) +func testAccAzureRMKubernetesCluster_addonProfileKubeDashboard(rInt int, clientId string, clientSecret string, location string) string { return fmt.Sprintf(` -%s +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} -resource "azurerm_kubernetes_cluster" "import" { - name = "${azurerm_kubernetes_cluster.test.name}" - location = "${azurerm_kubernetes_cluster.test.location}" - resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}" - dns_prefix = "${azurerm_kubernetes_cluster.test.dns_prefix}" +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } agent_pool_profile { name = "default" @@ -556,11 +1496,17 @@ resource "azurerm_kubernetes_cluster" "import" { client_id = "%s" client_secret = "%s" } + + addon_profile { + kube_dashboard { + enabled = false + } + } } -`, template, clientId, clientSecret) +`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_linuxProfile(rInt int, clientId string, clientSecret string, location string) string { +func testAccAzureRMKubernetesCluster_upgrade(rInt int, location, clientId, clientSecret, version string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -572,6 +1518,7 @@ resource "azurerm_kubernetes_cluster" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" + kubernetes_version = "%s" linux_profile { admin_username = "acctestuser%d" @@ -592,43 +1539,111 @@ resource "azurerm_kubernetes_cluster" "test" { client_secret = "%s" } } -`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) +`, rInt, location, rInt, rInt, version, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_addAgent(rInt int, clientId string, clientSecret string, location string) string { +func testAccAzureRMKubernetesCluster_advancedNetworking(rInt int, clientId string, clientSecret string, location string, networkPlugin string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.1.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Testing" + } +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.1.0.0/24" +} + resource "azurerm_kubernetes_cluster" "test" { name = "acctestaks%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + agent_pool_profile { - name = "default" - count = "2" - vm_size = "Standard_DS2_v2" + name = "default" + count = "2" + vm_size = "Standard_DS2_v2" + vnet_subnet_id = "${azurerm_subnet.test.id}" } service_principal { client_id = "%s" client_secret = "%s" } + + network_profile { + network_plugin = "%s" + } } -`, rInt, location, rInt, rInt, clientId, clientSecret) +`, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret, networkPlugin) } -func testAccAzureRMKubernetesCluster_roleBasedAccessControl(rInt int, location, clientId, clientSecret string) string { +func testAccAzureRMKubernetesCluster_advancedNetworkingComplete(rInt int, clientId string, clientSecret string, location string, networkPlugin string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } +resource "azurerm_route_table" "test" { + name = "akc-routetable-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + route { + name = "akc-route-%d" + address_prefix = "10.100.0.0/14" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = "10.10.1.1" + } +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.1.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Testing" + } +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.1.0.0/24" + route_table_id = "${azurerm_route_table.test.id}" +} + +resource "azurerm_subnet_route_table_association" "test" { + subnet_id = "${azurerm_subnet.test.id}" + route_table_id = "${azurerm_route_table.test.id}" +} + resource "azurerm_kubernetes_cluster" "test" { name = "acctestaks%d" location = "${azurerm_resource_group.test.location}" @@ -644,9 +1659,10 @@ resource "azurerm_kubernetes_cluster" "test" { } agent_pool_profile { - name = "default" - count = "1" - vm_size = "Standard_DS2_v2" + name = "default" + count = "2" + vm_size = "Standard_DS2_v2" + vnet_subnet_id = "${azurerm_subnet.test.id}" } service_principal { @@ -654,24 +1670,41 @@ resource "azurerm_kubernetes_cluster" "test" { client_secret = "%s" } - role_based_access_control { - enabled = true + network_profile { + network_plugin = "%s" + dns_service_ip = "10.10.0.10" + docker_bridge_cidr = "172.18.0.1/16" + service_cidr = "10.10.0.0/16" } } -`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret, networkPlugin) } -func testAccAzureRMKubernetesCluster_roleBasedAccessControlAAD(rInt int, location, clientId, clientSecret, tenantId string) string { +func testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicy(rInt int, clientId string, clientSecret string, location string, networkPlugin string, networkPolicy string) string { return fmt.Sprintf(` -variable "tenant_id" { - default = "%s" -} - resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.1.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Testing" + } +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.1.0.0/24" +} + resource "azurerm_kubernetes_cluster" "test" { name = "acctestaks%d" location = "${azurerm_resource_group.test.location}" @@ -687,9 +1720,10 @@ resource "azurerm_kubernetes_cluster" "test" { } agent_pool_profile { - name = "default" - count = "1" - vm_size = "Standard_DS2_v2" + name = "default" + count = "2" + vm_size = "Standard_DS2_v2" + vnet_subnet_id = "${azurerm_subnet.test.id}" } service_principal { @@ -697,21 +1731,96 @@ resource "azurerm_kubernetes_cluster" "test" { client_secret = "%s" } - role_based_access_control { - enabled = true + network_profile { + network_plugin = "%s" + network_policy = "%s" + } +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret, networkPlugin, networkPolicy) +} - azure_active_directory { - server_app_id = "%s" - server_app_secret = "%s" - client_app_id = "%s" - tenant_id = "${var.tenant_id}" +func testAccAzureRMKubernetesCluster_advancedNetworkingWithPolicyComplete(rInt int, clientId string, clientSecret string, location string, networkPlugin string, networkPolicy string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_route_table" "test" { + name = "akc-routetable-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + route { + name = "akc-route-%d" + address_prefix = "10.100.0.0/14" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = "10.10.1.1" + } +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.1.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Testing" + } +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.1.0.0/24" + route_table_id = "${azurerm_route_table.test.id}" +} + +resource "azurerm_subnet_route_table_association" "test" { + subnet_id = "${azurerm_subnet.test.id}" + route_table_id = "${azurerm_route_table.test.id}" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" } } + + agent_pool_profile { + name = "default" + count = "2" + vm_size = "Standard_DS2_v2" + vnet_subnet_id = "${azurerm_subnet.test.id}" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } + + network_profile { + network_plugin = "%s" + network_policy = "%s" + dns_service_ip = "10.10.0.10" + docker_bridge_cidr = "172.18.0.1/16" + service_cidr = "10.10.0.0/16" + } } -`, tenantId, rInt, location, rInt, rInt, rInt, clientId, clientSecret, clientId, clientSecret, clientId) +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret, networkPlugin, networkPolicy) } -func testAccAzureRMKubernetesCluster_internalNetwork(rInt int, clientId string, clientSecret string, location string) string { +func testAccAzureRMKubernetesCluster_standardLoadBalancer(rInt int, clientId string, clientSecret string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -720,7 +1829,7 @@ resource "azurerm_resource_group" "test" { resource "azurerm_virtual_network" "test" { name = "acctestvirtnet%d" - address_space = ["172.0.0.0/16"] + address_space = ["10.1.0.0/16"] location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" @@ -733,7 +1842,7 @@ resource "azurerm_subnet" "test" { name = "acctestsubnet%d" resource_group_name = "${azurerm_resource_group.test.name}" virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "172.0.2.0/24" + address_prefix = "10.1.0.0/24" } resource "azurerm_kubernetes_cluster" "test" { @@ -741,6 +1850,8 @@ resource "azurerm_kubernetes_cluster" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" + kubernetes_version = "1.13.5" + linux_profile { admin_username = "acctestuser%d" @@ -755,27 +1866,44 @@ resource "azurerm_kubernetes_cluster" "test" { count = "2" vm_size = "Standard_DS2_v2" vnet_subnet_id = "${azurerm_subnet.test.id}" - max_pods = 60 } service_principal { client_id = "%s" client_secret = "%s" } + + network_profile { + network_plugin = "azure" + load_balancer_sku = "standard" + } } `, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_addonProfileAciConnectorLinux(rInt int, clientId string, clientSecret string, location string) string { +func testAccAzureRMKubernetesCluster_standardLoadBalancerComplete(rInt int, clientId string, clientSecret string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } +resource "azurerm_route_table" "test" { + name = "akc-routetable-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + route { + name = "akc-route-%d" + address_prefix = "10.100.0.0/14" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = "10.10.1.1" + } +} + resource "azurerm_virtual_network" "test" { name = "acctestvirtnet%d" - address_space = ["172.0.0.0/16"] + address_space = ["10.1.0.0/16"] location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" @@ -788,22 +1916,13 @@ resource "azurerm_subnet" "test" { name = "acctestsubnet%d" resource_group_name = "${azurerm_resource_group.test.name}" virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "172.0.2.0/24" + address_prefix = "10.1.0.0/24" + route_table_id = "${azurerm_route_table.test.id}" } -resource "azurerm_subnet" "test-aci" { - name = "acctestsubnet-aci%d" - resource_group_name = "${azurerm_resource_group.test.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "172.0.3.0/24" - - delegation { - name = "aciDelegation" - service_delegation { - name = "Microsoft.ContainerInstance/containerGroups" - actions = [ "Microsoft.Network/virtualNetworks/subnets/action" ] - } - } +resource "azurerm_subnet_route_table_association" "test" { + subnet_id = "${azurerm_subnet.test.id}" + route_table_id = "${azurerm_route_table.test.id}" } resource "azurerm_kubernetes_cluster" "test" { @@ -811,6 +1930,7 @@ resource "azurerm_kubernetes_cluster" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" + kubernetes_version = "1.13.5" linux_profile { admin_username = "acctestuser%d" @@ -822,7 +1942,7 @@ resource "azurerm_kubernetes_cluster" "test" { agent_pool_profile { name = "default" - count = "1" + count = "2" vm_size = "Standard_DS2_v2" vnet_subnet_id = "${azurerm_subnet.test.id}" } @@ -832,61 +1952,30 @@ resource "azurerm_kubernetes_cluster" "test" { client_secret = "%s" } - addon_profile { - aci_connector_linux { - enabled = true - subnet_name = "${azurerm_subnet.test-aci.name}" - } - } - network_profile { - network_plugin = "azure" + network_plugin = "azure" + dns_service_ip = "10.10.0.10" + docker_bridge_cidr = "172.18.0.1/16" + service_cidr = "10.10.0.0/16" + load_balancer_sku = "standard" } } -`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret) +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_addonProfileOMS(rInt int, clientId string, clientSecret string, location string) string { +func testAccAzureRMKubernetesCluster_apiServerAuthorizedIPRanges(rInt int, clientId string, clientSecret string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } -resource "azurerm_log_analytics_workspace" "test" { - name = "acctest-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - sku = "PerGB2018" -} - -resource "azurerm_log_analytics_solution" "test" { - solution_name = "ContainerInsights" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" - workspace_name = "${azurerm_log_analytics_workspace.test.name}" - - plan { - publisher = "Microsoft" - product = "OMSGallery/ContainerInsights" - } -} - resource "azurerm_kubernetes_cluster" "test" { name = "acctestaks%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" - linux_profile { - admin_username = "acctestuser%d" - - ssh_key { - key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" - } - } - agent_pool_profile { name = "default" count = "1" @@ -898,17 +1987,16 @@ resource "azurerm_kubernetes_cluster" "test" { client_secret = "%s" } - addon_profile { - oms_agent { - enabled = true - log_analytics_workspace_id = "${azurerm_log_analytics_workspace.test.id}" - } - } + api_server_authorized_ip_ranges = [ + "8.8.8.8/32", + "8.8.4.4/32", + "8.8.2.0/24", + ] } -`, rInt, location, rInt, rInt, rInt, rInt, clientId, clientSecret) +`, rInt, location, rInt, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_addonProfileRouting(rInt int, clientId string, clientSecret string, location string) string { +func testAccAzureRMKubernetesCluster_virtualMachineScaleSets(rInt int, clientId string, clientSecret string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -921,16 +2009,9 @@ resource "azurerm_kubernetes_cluster" "test" { resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" - linux_profile { - admin_username = "acctestuser%d" - - ssh_key { - key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" - } - } - agent_pool_profile { name = "default" + type = "VirtualMachineScaleSets" count = "1" vm_size = "Standard_DS2_v2" } @@ -939,17 +2020,11 @@ resource "azurerm_kubernetes_cluster" "test" { client_id = "%s" client_secret = "%s" } - - addon_profile { - http_application_routing { - enabled = true - } - } } -`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) +`, rInt, location, rInt, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_upgrade(rInt int, location, clientId, clientSecret, version string) string { +func testAccAzureRMKubernetesCluster_multipleAgents(rInt int, clientId string, clientSecret string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -961,18 +2036,15 @@ resource "azurerm_kubernetes_cluster" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" - kubernetes_version = "%s" - - linux_profile { - admin_username = "acctestuser%d" - ssh_key { - key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" - } + agent_pool_profile { + name = "pool1" + count = "1" + vm_size = "Standard_DS2_v2" } agent_pool_profile { - name = "default" + name = "pool2" count = "1" vm_size = "Standard_DS2_v2" } @@ -982,32 +2054,44 @@ resource "azurerm_kubernetes_cluster" "test" { client_secret = "%s" } } -`, rInt, location, rInt, rInt, version, rInt, clientId, clientSecret) +`, rInt, location, rInt, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_advancedNetworking(rInt int, clientId string, clientSecret string, location string, networkPlugin string) string { +func testAccAzureRMKubernetesCluster_autoscaleNoAvailabilityZones(rInt int, clientId string, clientSecret string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } -resource "azurerm_virtual_network" "test" { - name = "acctestvirtnet%d" - address_space = ["10.1.0.0/16"] +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" - tags = { - environment = "Testing" + agent_pool_profile { + name = "pool1" + min_count = "1" + max_count = "2" + enable_auto_scaling = "true" + type = "VirtualMachineScaleSets" + vm_size = "Standard_DS2_v2" } + + service_principal { + client_id = "%s" + client_secret = "%s" + } +} +`, rInt, location, rInt, rInt, clientId, clientSecret) } -resource "azurerm_subnet" "test" { - name = "acctestsubnet%d" - resource_group_name = "${azurerm_resource_group.test.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.1.0.0/24" +func testAccAzureRMKubernetesCluster_autoscaleWithAvailabilityZones(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" } resource "azurerm_kubernetes_cluster" "test" { @@ -1015,20 +2099,16 @@ resource "azurerm_kubernetes_cluster" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" - - linux_profile { - admin_username = "acctestuser%d" - - ssh_key { - key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" - } - } + kubernetes_version = "1.13.5" agent_pool_profile { - name = "default" - count = "2" - vm_size = "Standard_DS2_v2" - vnet_subnet_id = "${azurerm_subnet.test.id}" + name = "pool1" + min_count = "1" + max_count = "2" + enable_auto_scaling = "true" + type = "VirtualMachineScaleSets" + vm_size = "Standard_DS2_v2" + availability_zones = ["1", "2"] } service_principal { @@ -1037,54 +2117,56 @@ resource "azurerm_kubernetes_cluster" "test" { } network_profile { - network_plugin = "%s" + network_plugin = "kubenet" + load_balancer_sku = "standard" } } -`, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret, networkPlugin) +`, rInt, location, rInt, rInt, clientId, clientSecret) } -func testAccAzureRMKubernetesCluster_advancedNetworkingComplete(rInt int, clientId string, clientSecret string, location string, networkPlugin string) string { +func testAccAzureRMKubernetesCluster_nodeTaints(rInt int, clientId string, clientSecret string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } -resource "azurerm_route_table" "test" { - name = "akc-routetable-%d" +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" - route { - name = "akc-route-%d" - address_prefix = "10.100.0.0/14" - next_hop_type = "VirtualAppliance" - next_hop_in_ip_address = "10.10.1.1" + agent_pool_profile { + name = "default" + count = "1" + type = "VirtualMachineScaleSets" + vm_size = "Standard_DS2_v2" } -} -resource "azurerm_virtual_network" "test" { - name = "acctestvirtnet%d" - address_space = ["10.1.0.0/16"] - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" + agent_pool_profile { + name = "pool1" + count = "1" + type = "VirtualMachineScaleSets" + vm_size = "Standard_DS2_v2" + node_taints = [ + "key=value:NoSchedule" + ] + } - tags = { - environment = "Testing" + service_principal { + client_id = "%s" + client_secret = "%s" } } - -resource "azurerm_subnet" "test" { - name = "acctestsubnet%d" - resource_group_name = "${azurerm_resource_group.test.name}" - virtual_network_name = "${azurerm_virtual_network.test.name}" - address_prefix = "10.1.0.0/24" - route_table_id = "${azurerm_route_table.test.id}" +`, rInt, location, rInt, rInt, clientId, clientSecret) } -resource "azurerm_subnet_route_table_association" "test" { - subnet_id = "${azurerm_subnet.test.id}" - route_table_id = "${azurerm_route_table.test.id}" +func testAccAzureRMKubernetesCluster_nodeResourceGroup(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" } resource "azurerm_kubernetes_cluster" "test" { @@ -1092,33 +2174,51 @@ resource "azurerm_kubernetes_cluster" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" dns_prefix = "acctestaks%d" + node_resource_group = "acctestRGAKS-%d" - linux_profile { - admin_username = "acctestuser%d" + agent_pool_profile { + name = "default" + count = "1" + type = "VirtualMachineScaleSets" + vm_size = "Standard_DS2_v2" + } - ssh_key { - key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" - } + service_principal { + client_id = "%s" + client_secret = "%s" + } +} +`, rInt, location, rInt, rInt, rInt, clientId, clientSecret) +} + +func testAccAzureRMKubernetesCluster_enablePodSecurityPolicy(rInt int, clientId string, clientSecret string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks%d" + enable_pod_security_policy = true + + role_based_access_control { + enabled = true } agent_pool_profile { - name = "default" - count = "2" - vm_size = "Standard_DS2_v2" - vnet_subnet_id = "${azurerm_subnet.test.id}" + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" } service_principal { client_id = "%s" client_secret = "%s" } - - network_profile { - network_plugin = "%s" - dns_service_ip = "10.10.0.10" - docker_bridge_cidr = "172.18.0.1/16" - service_cidr = "10.10.0.0/16" - } } -`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret, networkPlugin) +`, rInt, location, rInt, rInt, clientId, clientSecret) } diff --git a/azurerm/resource_arm_kusto_cluster.go b/azurerm/resource_arm_kusto_cluster.go new file mode 100644 index 000000000000..327ad539140b --- /dev/null +++ b/azurerm/resource_arm_kusto_cluster.go @@ -0,0 +1,282 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/kusto/mgmt/2019-01-21/kusto" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmKustoCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceArmKustoClusterCreateUpdate, + Read: resourceArmKustoClusterRead, + Update: resourceArmKustoClusterCreateUpdate, + Delete: resourceArmKustoClusterDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateAzureRMKustoClusterName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "location": azure.SchemaLocation(), + + "sku": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateAzureRMKustoClusterSkuName(), + }, + + "capacity": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 1000), + }, + }, + }, + }, + + "uri": { + Type: schema.TypeString, + Computed: true, + }, + + "data_ingestion_uri": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmKustoClusterCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).kusto.ClustersClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Azure Kusto Cluster creation.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if requireResourcesToBeImported && d.IsNewResource() { + server, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(server.Response) { + return fmt.Errorf("Error checking for presence of existing Kusto Cluster %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if server.ID != nil && *server.ID != "" { + return tf.ImportAsExistsError("azurerm_kusto_cluster", *server.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + + sku, err := expandKustoClusterSku(d) + if err != nil { + return err + } + + clusterProperties := kusto.ClusterProperties{} + + t := d.Get("tags").(map[string]interface{}) + + kustoCluster := kusto.Cluster{ + Name: &name, + Location: &location, + Sku: sku, + ClusterProperties: &clusterProperties, + Tags: tags.Expand(t), + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, name, kustoCluster) + if err != nil { + return fmt.Errorf("Error creating or updating Kusto Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Kusto Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + resp, getDetailsErr := client.Get(ctx, resourceGroup, name) + if getDetailsErr != nil { + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read ID for Kusto Cluster %q (Resource Group %q)", name, resourceGroup) + } + + d.SetId(*resp.ID) + + return resourceArmKustoClusterRead(d, meta) +} + +func resourceArmKustoClusterRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).kusto.ClustersClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + name := id.Path["Clusters"] + + clusterResponse, err := client.Get(ctx, resourceGroup, name) + + if err != nil { + if utils.ResponseWasNotFound(clusterResponse.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error retrieving Kusto Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + + if location := clusterResponse.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if err := d.Set("sku", flattenKustoClusterSku(clusterResponse.Sku)); err != nil { + return fmt.Errorf("Error setting `sku`: %+v", err) + } + + if clusterProperties := clusterResponse.ClusterProperties; clusterProperties != nil { + d.Set("uri", clusterProperties.URI) + d.Set("data_ingestion_uri", clusterProperties.DataIngestionURI) + } + + return tags.FlattenAndSet(d, clusterResponse.Tags) +} + +func resourceArmKustoClusterDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).kusto.ClustersClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["Clusters"] + + future, err := client.Delete(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error deleting Kusto Cluster %q (Resource Group %q): %+v", name, resGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of Kusto Cluster %q (Resource Group %q): %+v", name, resGroup, err) + } + + return nil +} + +func validateAzureRMKustoClusterName(v interface{}, k string) (warnings []string, errors []error) { + name := v.(string) + + if !regexp.MustCompile(`^[a-z][a-z0-9]+$`).MatchString(name) { + errors = append(errors, fmt.Errorf("%q must begin with a letter and may only contain alphanumeric characters: %q", k, name)) + } + + if len(name) < 4 || len(name) > 22 { + errors = append(errors, fmt.Errorf("%q must be (inclusive) between 4 and 22 characters long but is %d", k, len(name))) + } + + return warnings, errors +} + +func validateAzureRMKustoClusterSkuName() schema.SchemaValidateFunc { + // using hard coded values because they're not like this in the sdk as constants + // found them here: https://docs.microsoft.com/en-us/rest/api/azurerekusto/clusters/createorupdate#azureskuname + possibleSkuNames := []string{ + "Dev(No SLA)_Standard_D11_v2", + "Standard_D11_v2", + "Standard_D12_v2", + "Standard_D13_v2", + "Standard_D14_v2", + "Standard_DS13_v2+1TB_PS", + "Standard_DS13_v2+2TB_PS", + "Standard_DS14_v2+3TB_PS", + "Standard_DS14_v2+4TB_PS", + "Standard_L16s", + "Standard_L4s", + "Standard_L8s", + } + + return validation.StringInSlice(possibleSkuNames, false) +} + +func expandKustoClusterSku(d *schema.ResourceData) (*kusto.AzureSku, error) { + skuList := d.Get("sku").([]interface{}) + + sku := skuList[0].(map[string]interface{}) + name := sku["name"].(string) + + skuNamePrefixToTier := map[string]string{ + "Dev(No SLA)": "Basic", + "Standard": "Standard", + } + + skuNamePrefix := strings.Split(sku["name"].(string), "_")[0] + tier, ok := skuNamePrefixToTier[skuNamePrefix] + if !ok { + return nil, fmt.Errorf("sku name begins with invalid tier, possible are Dev(No SLA) and Standard but is: %q", skuNamePrefix) + } + capacity := sku["capacity"].(int) + + azureSku := &kusto.AzureSku{ + Name: kusto.AzureSkuName(name), + Tier: &tier, + Capacity: utils.Int32(int32(capacity)), + } + + return azureSku, nil +} + +func flattenKustoClusterSku(sku *kusto.AzureSku) []interface{} { + if sku == nil { + return []interface{}{} + } + + s := map[string]interface{}{ + "name": string(sku.Name), + } + + if sku.Capacity != nil { + s["capacity"] = int(*sku.Capacity) + } + + return []interface{}{s} +} diff --git a/azurerm/resource_arm_kusto_cluster_test.go b/azurerm/resource_arm_kusto_cluster_test.go new file mode 100644 index 000000000000..b9e213627de9 --- /dev/null +++ b/azurerm/resource_arm_kusto_cluster_test.go @@ -0,0 +1,247 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMKustoCluster_basic(t *testing.T) { + resourceName := "azurerm_kusto_cluster.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(6) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKustoClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMKustoCluster_basic(ri, rs, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMKustoCluster_withTags(t *testing.T) { + resourceName := "azurerm_kusto_cluster.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(6) + preConfig := testAccAzureRMKustoCluster_withTags(ri, rs, testLocation()) + postConfig := testAccAzureRMKustoCluster_withTagsUpdate(ri, rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKustoClusterDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.label", "test"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.label", "test1"), + resource.TestCheckResourceAttr(resourceName, "tags.ENV", "prod"), + ), + }, + }, + }) +} + +func TestAccAzureRMKustoCluster_sku(t *testing.T) { + resourceName := "azurerm_kusto_cluster.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(6) + preConfig := testAccAzureRMKustoCluster_basic(ri, rs, testLocation()) + postConfig := testAccAzureRMKustoCluster_skuUpdate(ri, rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKustoClusterDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Dev(No SLA)_Standard_D11_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "1"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKustoClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Standard_D11_v2"), + resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "2"), + ), + }, + }, + }) +} + +func testAccAzureRMKustoCluster_basic(rInt int, rs string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kusto_cluster" "test" { + name = "acctestkc%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Dev(No SLA)_Standard_D11_v2" + capacity = 1 + } +} +`, rInt, location, rs) +} + +func testAccAzureRMKustoCluster_withTags(rInt int, rs string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kusto_cluster" "test" { + name = "acctestkc%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Dev(No SLA)_Standard_D11_v2" + capacity = 1 + } + + tags = { + label = "test" + } +} +`, rInt, location, rs) +} + +func testAccAzureRMKustoCluster_withTagsUpdate(rInt int, rs string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kusto_cluster" "test" { + name = "acctestkc%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Dev(No SLA)_Standard_D11_v2" + capacity = 1 + } + + tags = { + label = "test1" + ENV = "prod" + } +} +`, rInt, location, rs) +} + +func testAccAzureRMKustoCluster_skuUpdate(rInt int, rs string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kusto_cluster" "test" { + name = "acctestkc%s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "Standard_D11_v2" + capacity = 2 + } +} +`, rInt, location, rs) +} + +func testCheckAzureRMKustoClusterDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).kusto.ClustersClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_kusto_cluster" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return err + } + + return nil + } + + return nil +} + +func testCheckAzureRMKustoClusterExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + kustoCluster := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Kusto Cluster: %s", kustoCluster) + } + + client := testAccProvider.Meta().(*ArmClient).kusto.ClustersClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, kustoCluster) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Kusto Cluster %q (resource group: %q) does not exist", kustoCluster, resourceGroup) + } + + return fmt.Errorf("Bad: Get on ClustersClient: %+v", err) + } + + return nil + } +} diff --git a/azurerm/resource_arm_loadbalancer.go b/azurerm/resource_arm_loadbalancer.go index 62b0c25a4098..2fa81cadb109 100644 --- a/azurerm/resource_arm_loadbalancer.go +++ b/azurerm/resource_arm_loadbalancer.go @@ -4,13 +4,15 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,9 +34,9 @@ func resourceArmLoadBalancer() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeString, @@ -81,6 +83,13 @@ func resourceArmLoadBalancer() *schema.Resource { ValidateFunc: azure.ValidateResourceIDOrEmpty, }, + "public_ip_prefix_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: azure.ValidateResourceIDOrEmpty, + }, + "private_ip_address_allocation": { Type: schema.TypeString, Optional: true, @@ -123,7 +132,7 @@ func resourceArmLoadBalancer() *schema.Resource { Set: schema.HashString, }, - "zones": singleZonesSchema(), + "zones": azure.SchemaSingleZone(), }, }, }, @@ -140,13 +149,13 @@ func resourceArmLoadBalancer() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmLoadBalancerCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ARM Load Balancer creation.") @@ -154,7 +163,7 @@ func resourceArmLoadBalancerCreateUpdate(d *schema.ResourceData, meta interface{ name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -167,12 +176,12 @@ func resourceArmLoadBalancerCreateUpdate(d *schema.ResourceData, meta interface{ } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) sku := network.LoadBalancerSku{ Name: network.LoadBalancerSkuName(d.Get("sku").(string)), } - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) properties := network.LoadBalancerPropertiesFormat{} @@ -211,7 +220,7 @@ func resourceArmLoadBalancerCreateUpdate(d *schema.ResourceData, meta interface{ } func resourceArmLoadBalancerRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -229,7 +238,7 @@ func resourceArmLoadBalancerRead(d *schema.ResourceData, meta interface{}) error d.Set("name", loadBalancer.Name) d.Set("resource_group_name", id.ResourceGroup) if location := loadBalancer.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := loadBalancer.Sku; sku != nil { @@ -261,16 +270,14 @@ func resourceArmLoadBalancerRead(d *schema.ResourceData, meta interface{}) error } } - flattenAndSetTags(d, loadBalancer.Tags) - - return nil + return tags.FlattenAndSet(d, loadBalancer.Tags) } func resourceArmLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return fmt.Errorf("Error Parsing Azure Resource ID: %+v", err) } @@ -311,6 +318,12 @@ func expandAzureRmLoadBalancerFrontendIpConfigurations(d *schema.ResourceData) * } } + if v := data["public_ip_prefix_id"].(string); v != "" { + properties.PublicIPPrefix = &network.SubResource{ + ID: &v, + } + } + if v := data["subnet_id"].(string); v != "" { properties.Subnet = &network.Subnet{ ID: &v, @@ -318,7 +331,7 @@ func expandAzureRmLoadBalancerFrontendIpConfigurations(d *schema.ResourceData) * } name := data["name"].(string) - zones := expandZones(data["zones"].([]interface{})) + zones := azure.ExpandZones(data["zones"].([]interface{})) frontEndConfig := network.FrontendIPConfiguration{ Name: &name, FrontendIPConfigurationPropertiesFormat: &properties, @@ -365,6 +378,10 @@ func flattenLoadBalancerFrontendIpConfiguration(ipConfigs *[]network.FrontendIPC ipConfig["public_ip_address_id"] = *pip.ID } + if pip := props.PublicIPPrefix; pip != nil { + ipConfig["public_ip_prefix_id"] = *pip.ID + } + loadBalancingRules := make([]interface{}, 0) if rules := props.LoadBalancingRules; rules != nil { for _, rule := range *rules { diff --git a/azurerm/resource_arm_loadbalancer_backend_address_pool.go b/azurerm/resource_arm_loadbalancer_backend_address_pool.go index 684e33b391b3..1be4e44e3035 100644 --- a/azurerm/resource_arm_loadbalancer_backend_address_pool.go +++ b/azurerm/resource_arm_loadbalancer_backend_address_pool.go @@ -4,11 +4,13 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -29,9 +31,9 @@ func resourceArmLoadBalancerBackendAddressPool() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "loadbalancer_id": { Type: schema.TypeString, @@ -64,13 +66,13 @@ func resourceArmLoadBalancerBackendAddressPool() *schema.Resource { } func resourceArmLoadBalancerBackendAddressPoolCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext loadBalancerID := d.Get("loadbalancer_id").(string) name := d.Get("name").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { @@ -86,7 +88,7 @@ func resourceArmLoadBalancerBackendAddressPoolCreate(d *schema.ResourceData, met existingPool, existingPoolIndex, exists := findLoadBalancerBackEndAddressPoolByName(loadBalancer, name) if exists { if name == *existingPool.Name { - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { return tf.ImportAsExistsError("azurerm_lb_backend_address_pool", *existingPool.ID) } @@ -135,7 +137,7 @@ func resourceArmLoadBalancerBackendAddressPoolCreate(d *schema.ResourceData, met } func resourceArmLoadBalancerBackendAddressPoolRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -185,12 +187,12 @@ func resourceArmLoadBalancerBackendAddressPoolRead(d *schema.ResourceData, meta } func resourceArmLoadBalancerBackendAddressPoolDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { diff --git a/azurerm/resource_arm_loadbalancer_backend_address_pool_test.go b/azurerm/resource_arm_loadbalancer_backend_address_pool_test.go index eb8627911458..b2e12af1963f 100644 --- a/azurerm/resource_arm_loadbalancer_backend_address_pool_test.go +++ b/azurerm/resource_arm_loadbalancer_backend_address_pool_test.go @@ -5,10 +5,12 @@ import ( "os" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLoadBalancerBackEndAddressPool_basic(t *testing.T) { @@ -46,7 +48,7 @@ func TestAccAzureRMLoadBalancerBackEndAddressPool_basic(t *testing.T) { }) } func TestAccAzureRMLoadBalancerBackEndAddressPool_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -103,40 +105,6 @@ func TestAccAzureRMLoadBalancerBackEndAddressPool_removal(t *testing.T) { }) } -func TestAccAzureRMLoadBalancerBackEndAddressPool_reapply(t *testing.T) { - var lb network.LoadBalancer - ri := tf.AccRandTimeInt() - addressPoolName := fmt.Sprintf("%d-address-pool", ri) - - deleteAddressPoolState := func(s *terraform.State) error { - return s.Remove("azurerm_lb_backend_address_pool.test") - } - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMLoadBalancerDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMLoadBalancerBackEndAddressPool_basic(ri, addressPoolName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerBackEndAddressPoolExists(addressPoolName, &lb), - deleteAddressPoolState, - ), - ExpectNonEmptyPlan: true, - }, - { - Config: testAccAzureRMLoadBalancerBackEndAddressPool_basic(ri, addressPoolName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerBackEndAddressPoolExists(addressPoolName, &lb), - ), - }, - }, - }) -} - func TestAccAzureRMLoadBalancerBackEndAddressPool_disappears(t *testing.T) { var lb network.LoadBalancer ri := tf.AccRandTimeInt() @@ -184,7 +152,7 @@ func testCheckAzureRMLoadBalancerBackEndAddressPoolNotExists(addressPoolName str func testCheckAzureRMLoadBalancerBackEndAddressPoolDisappears(addressPoolName string, lb *network.LoadBalancer) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).loadBalancerClient + client := testAccProvider.Meta().(*ArmClient).network.LoadBalancersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext _, i, exists := findLoadBalancerBackEndAddressPoolByName(lb, addressPoolName) @@ -196,7 +164,7 @@ func testCheckAzureRMLoadBalancerBackEndAddressPoolDisappears(addressPoolName st pools := append(currentPools[:i], currentPools[i+1:]...) lb.LoadBalancerPropertiesFormat.BackendAddressPools = &pools - id, err := parseAzureResourceID(*lb.ID) + id, err := azure.ParseAzureResourceID(*lb.ID) if err != nil { return err } diff --git a/azurerm/resource_arm_loadbalancer_nat_pool.go b/azurerm/resource_arm_loadbalancer_nat_pool.go index c0628ab673cb..b5c8b06188ff 100644 --- a/azurerm/resource_arm_loadbalancer_nat_pool.go +++ b/azurerm/resource_arm_loadbalancer_nat_pool.go @@ -4,13 +4,15 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,9 +34,9 @@ func resourceArmLoadBalancerNatPool() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "loadbalancer_id": { Type: schema.TypeString, @@ -88,13 +90,13 @@ func resourceArmLoadBalancerNatPool() *schema.Resource { } func resourceArmLoadBalancerNatPoolCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext loadBalancerID := d.Get("loadbalancer_id").(string) name := d.Get("name").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { @@ -116,7 +118,7 @@ func resourceArmLoadBalancerNatPoolCreateUpdate(d *schema.ResourceData, meta int existingNatPool, existingNatPoolIndex, exists := findLoadBalancerNatPoolByName(loadBalancer, name) if exists { if name == *existingNatPool.Name { - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { return tf.ImportAsExistsError("azurerm_lb_nat_pool", *existingNatPool.ID) } @@ -165,7 +167,7 @@ func resourceArmLoadBalancerNatPoolCreateUpdate(d *schema.ResourceData, meta int } func resourceArmLoadBalancerNatPoolRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -198,7 +200,7 @@ func resourceArmLoadBalancerNatPoolRead(d *schema.ResourceData, meta interface{} d.Set("backend_port", props.BackendPort) if feipConfig := props.FrontendIPConfiguration; feipConfig != nil { - fipID, err := parseAzureResourceID(*feipConfig.ID) + fipID, err := azure.ParseAzureResourceID(*feipConfig.ID) if err != nil { return err } @@ -212,12 +214,12 @@ func resourceArmLoadBalancerNatPoolRead(d *schema.ResourceData, meta interface{} } func resourceArmLoadBalancerNatPoolDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { diff --git a/azurerm/resource_arm_loadbalancer_nat_pool_test.go b/azurerm/resource_arm_loadbalancer_nat_pool_test.go index d4e6326ee67c..a0d25c19c987 100644 --- a/azurerm/resource_arm_loadbalancer_nat_pool_test.go +++ b/azurerm/resource_arm_loadbalancer_nat_pool_test.go @@ -5,10 +5,12 @@ import ( "os" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLoadBalancerNatPool_basic(t *testing.T) { @@ -47,7 +49,7 @@ func TestAccAzureRMLoadBalancerNatPool_basic(t *testing.T) { } func TestAccAzureRMLoadBalancerNatPool_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -145,40 +147,6 @@ func TestAccAzureRMLoadBalancerNatPool_update(t *testing.T) { }) } -func TestAccAzureRMLoadBalancerNatPool_reapply(t *testing.T) { - var lb network.LoadBalancer - ri := tf.AccRandTimeInt() - natPoolName := fmt.Sprintf("NatPool-%d", ri) - - deleteNatPoolState := func(s *terraform.State) error { - return s.Remove("azurerm_lb_nat_pool.test") - } - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMLoadBalancerDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMLoadBalancerNatPool_basic(ri, natPoolName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerNatPoolExists(natPoolName, &lb), - deleteNatPoolState, - ), - ExpectNonEmptyPlan: true, - }, - { - Config: testAccAzureRMLoadBalancerNatPool_basic(ri, natPoolName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerNatPoolExists(natPoolName, &lb), - ), - }, - }, - }) -} - func TestAccAzureRMLoadBalancerNatPool_disappears(t *testing.T) { var lb network.LoadBalancer ri := tf.AccRandTimeInt() @@ -226,7 +194,7 @@ func testCheckAzureRMLoadBalancerNatPoolNotExists(natPoolName string, lb *networ func testCheckAzureRMLoadBalancerNatPoolDisappears(natPoolName string, lb *network.LoadBalancer) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).loadBalancerClient + client := testAccProvider.Meta().(*ArmClient).network.LoadBalancersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext _, i, exists := findLoadBalancerNatPoolByName(lb, natPoolName) @@ -238,7 +206,7 @@ func testCheckAzureRMLoadBalancerNatPoolDisappears(natPoolName string, lb *netwo pools := append(currentPools[:i], currentPools[i+1:]...) lb.LoadBalancerPropertiesFormat.InboundNatPools = &pools - id, err := parseAzureResourceID(*lb.ID) + id, err := azure.ParseAzureResourceID(*lb.ID) if err != nil { return err } diff --git a/azurerm/resource_arm_loadbalancer_nat_rule.go b/azurerm/resource_arm_loadbalancer_nat_rule.go index 0e25621a2019..8a2db22a3590 100644 --- a/azurerm/resource_arm_loadbalancer_nat_rule.go +++ b/azurerm/resource_arm_loadbalancer_nat_rule.go @@ -4,13 +4,15 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -33,9 +35,9 @@ func resourceArmLoadBalancerNatRule() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "loadbalancer_id": { Type: schema.TypeString, @@ -94,13 +96,13 @@ func resourceArmLoadBalancerNatRule() *schema.Resource { } func resourceArmLoadBalancerNatRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { @@ -122,7 +124,7 @@ func resourceArmLoadBalancerNatRuleCreateUpdate(d *schema.ResourceData, meta int existingNatRule, existingNatRuleIndex, exists := findLoadBalancerNatRuleByName(loadBalancer, name) if exists { if name == *existingNatRule.Name { - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { return tf.ImportAsExistsError("azurerm_lb_nat_rule", *existingNatRule.ID) } @@ -172,7 +174,7 @@ func resourceArmLoadBalancerNatRuleCreateUpdate(d *schema.ResourceData, meta int } func resourceArmLoadBalancerNatRuleRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -205,7 +207,7 @@ func resourceArmLoadBalancerNatRuleRead(d *schema.ResourceData, meta interface{} d.Set("enable_floating_ip", props.EnableFloatingIP) if ipconfiguration := props.FrontendIPConfiguration; ipconfiguration != nil { - fipID, err := parseAzureResourceID(*ipconfiguration.ID) + fipID, err := azure.ParseAzureResourceID(*ipconfiguration.ID) if err != nil { return err } @@ -223,12 +225,12 @@ func resourceArmLoadBalancerNatRuleRead(d *schema.ResourceData, meta interface{} } func resourceArmLoadBalancerNatRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { diff --git a/azurerm/resource_arm_loadbalancer_nat_rule_test.go b/azurerm/resource_arm_loadbalancer_nat_rule_test.go index 9596da8b665c..4a3ef95b35a3 100644 --- a/azurerm/resource_arm_loadbalancer_nat_rule_test.go +++ b/azurerm/resource_arm_loadbalancer_nat_rule_test.go @@ -5,10 +5,12 @@ import ( "os" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLoadBalancerNatRule_basic(t *testing.T) { @@ -47,7 +49,7 @@ func TestAccAzureRMLoadBalancerNatRule_basic(t *testing.T) { } func TestAccAzureRMLoadBalancerNatRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -147,40 +149,6 @@ func TestAccAzureRMLoadBalancerNatRule_update(t *testing.T) { }) } -func TestAccAzureRMLoadBalancerNatRule_reapply(t *testing.T) { - var lb network.LoadBalancer - ri := tf.AccRandTimeInt() - natRuleName := fmt.Sprintf("NatRule-%d", ri) - - deleteNatRuleState := func(s *terraform.State) error { - return s.Remove("azurerm_lb_nat_rule.test") - } - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMLoadBalancerDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMLoadBalancerNatRule_basic(ri, natRuleName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerNatRuleExists(natRuleName, &lb), - deleteNatRuleState, - ), - ExpectNonEmptyPlan: true, - }, - { - Config: testAccAzureRMLoadBalancerNatRule_basic(ri, natRuleName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerNatRuleExists(natRuleName, &lb), - ), - }, - }, - }) -} - func TestAccAzureRMLoadBalancerNatRule_disappears(t *testing.T) { var lb network.LoadBalancer ri := tf.AccRandTimeInt() @@ -286,7 +254,7 @@ func testCheckAzureRMLoadBalancerNatRuleNotExists(natRuleName string, lb *networ func testCheckAzureRMLoadBalancerNatRuleDisappears(natRuleName string, lb *network.LoadBalancer) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).loadBalancerClient + client := testAccProvider.Meta().(*ArmClient).network.LoadBalancersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext _, i, exists := findLoadBalancerNatRuleByName(lb, natRuleName) @@ -298,7 +266,7 @@ func testCheckAzureRMLoadBalancerNatRuleDisappears(natRuleName string, lb *netwo rules := append(currentRules[:i], currentRules[i+1:]...) lb.LoadBalancerPropertiesFormat.InboundNatRules = &rules - id, err := parseAzureResourceID(*lb.ID) + id, err := azure.ParseAzureResourceID(*lb.ID) if err != nil { return err } diff --git a/azurerm/resource_arm_loadbalancer_outbound_rule.go b/azurerm/resource_arm_loadbalancer_outbound_rule.go index f94fe4724ca2..40f5ff774e88 100644 --- a/azurerm/resource_arm_loadbalancer_outbound_rule.go +++ b/azurerm/resource_arm_loadbalancer_outbound_rule.go @@ -4,12 +4,14 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,7 +34,7 @@ func resourceArmLoadBalancerOutboundRule() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "loadbalancer_id": { Type: schema.TypeString, @@ -98,13 +100,13 @@ func resourceArmLoadBalancerOutboundRule() *schema.Resource { } func resourceArmLoadBalancerOutboundRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { @@ -130,7 +132,7 @@ func resourceArmLoadBalancerOutboundRuleCreateUpdate(d *schema.ResourceData, met existingOutboundRule, existingOutboundRuleIndex, exists := findLoadBalancerOutboundRuleByName(loadBalancer, name) if exists { if name == *existingOutboundRule.Name { - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { return tf.ImportAsExistsError("azurerm_lb_outbound_rule", *existingOutboundRule.ID) } @@ -182,7 +184,7 @@ func resourceArmLoadBalancerOutboundRuleCreateUpdate(d *schema.ResourceData, met } func resourceArmLoadBalancerOutboundRuleRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -218,7 +220,7 @@ func resourceArmLoadBalancerOutboundRuleRead(d *schema.ResourceData, meta interf continue } - feConfigId, err := parseAzureResourceID(*feConfig.ID) + feConfigId, err := azure.ParseAzureResourceID(*feConfig.ID) if err != nil { return nil } @@ -250,12 +252,12 @@ func resourceArmLoadBalancerOutboundRuleRead(d *schema.ResourceData, meta interf } func resourceArmLoadBalancerOutboundRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { diff --git a/azurerm/resource_arm_loadbalancer_outbound_rule_test.go b/azurerm/resource_arm_loadbalancer_outbound_rule_test.go index 99140873ecfd..3eda0ba226bd 100644 --- a/azurerm/resource_arm_loadbalancer_outbound_rule_test.go +++ b/azurerm/resource_arm_loadbalancer_outbound_rule_test.go @@ -5,10 +5,12 @@ import ( "os" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLoadBalancerOutboundRule_basic(t *testing.T) { @@ -47,7 +49,7 @@ func TestAccAzureRMLoadBalancerOutboundRule_basic(t *testing.T) { } func TestAccAzureRMLoadBalancerOutboundRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -145,14 +147,15 @@ func TestAccAzureRMLoadBalancerOutboundRule_update(t *testing.T) { }) } -func TestAccAzureRMLoadBalancerOutboundRule_reapply(t *testing.T) { +func TestAccAzureRMLoadBalancerOutboundRule_withPublicIPPrefix(t *testing.T) { var lb network.LoadBalancer ri := tf.AccRandTimeInt() outboundRuleName := fmt.Sprintf("OutboundRule-%d", ri) - deleteOutboundRuleState := func(s *terraform.State) error { - return s.Remove("azurerm_lb_outbound_rule.test") - } + subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") + outboundRuleId := fmt.Sprintf( + "/subscriptions/%s/resourceGroups/acctestRG-%d/providers/Microsoft.Network/loadBalancers/arm-test-loadbalancer-%d/outboundRules/%s", + subscriptionID, ri, ri, outboundRuleName) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -160,20 +163,20 @@ func TestAccAzureRMLoadBalancerOutboundRule_reapply(t *testing.T) { CheckDestroy: testCheckAzureRMLoadBalancerDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMLoadBalancerOutboundRule_basic(ri, outboundRuleName, testLocation()), + Config: testAccAzureRMLoadBalancerOutboundRule_withPublicIPPrefix(ri, outboundRuleName, testLocation()), Check: resource.ComposeTestCheckFunc( testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), testCheckAzureRMLoadBalancerOutboundRuleExists(outboundRuleName, &lb), - deleteOutboundRuleState, + resource.TestCheckResourceAttr( + "azurerm_lb_outbound_rule.test", "id", outboundRuleId), ), - ExpectNonEmptyPlan: true, }, { - Config: testAccAzureRMLoadBalancerOutboundRule_basic(ri, outboundRuleName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerOutboundRuleExists(outboundRuleName, &lb), - ), + ResourceName: "azurerm_lb.test", + ImportState: true, + ImportStateVerify: true, + // location is deprecated and was never actually used + ImportStateVerifyIgnore: []string{"location"}, }, }, }) @@ -224,7 +227,7 @@ func testCheckAzureRMLoadBalancerOutboundRuleNotExists(outboundRuleName string, func testCheckAzureRMLoadBalancerOutboundRuleDisappears(ruleName string, lb *network.LoadBalancer) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).loadBalancerClient + client := testAccProvider.Meta().(*ArmClient).network.LoadBalancersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext _, i, exists := findLoadBalancerOutboundRuleByName(lb, ruleName) @@ -236,7 +239,7 @@ func testCheckAzureRMLoadBalancerOutboundRuleDisappears(ruleName string, lb *net rules := append(currentRules[:i], currentRules[i+1:]...) lb.LoadBalancerPropertiesFormat.OutboundRules = &rules - id, err := parseAzureResourceID(*lb.ID) + id, err := azure.ParseAzureResourceID(*lb.ID) if err != nil { return err } @@ -276,7 +279,6 @@ resource "azurerm_lb" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku = "Standard" - frontend_ip_configuration { name = "one-%d" public_ip_address_id = "${azurerm_public_ip.test.id}" @@ -290,12 +292,11 @@ resource "azurerm_lb_backend_address_pool" "test" { } resource "azurerm_lb_outbound_rule" "test" { - resource_group_name = "${azurerm_resource_group.test.name}" - loadbalancer_id = "${azurerm_lb.test.id}" - name = "%s" - backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" - protocol = "All" - + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "%s" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" + protocol = "All" frontend_ip_configuration { name = "one-%d" @@ -310,11 +311,11 @@ func testAccAzureRMLoadBalancerOutboundRule_requiresImport(rInt int, name string %s resource "azurerm_lb_outbound_rule" "import" { - name = "${azurerm_lb_outbound_rule.test.name}" - resource_group_name = "${azurerm_lb_outbound_rule.test.resource_group_name}" - loadbalancer_id = "${azurerm_lb_outbound_rule.test.loadbalancer_id}" - backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" - protocol = "All" + name = "${azurerm_lb_outbound_rule.test.name}" + resource_group_name = "${azurerm_lb_outbound_rule.test.resource_group_name}" + loadbalancer_id = "${azurerm_lb_outbound_rule.test.loadbalancer_id}" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" + protocol = "All" frontend_ip_configuration { name = "${azurerm_lb_outbound_rule.test.frontend_ip_configuration.0.name}" @@ -405,11 +406,11 @@ resource "azurerm_lb_backend_address_pool" "test" { } resource "azurerm_lb_outbound_rule" "test" { - resource_group_name = "${azurerm_resource_group.test.name}" - loadbalancer_id = "${azurerm_lb.test.id}" - name = "%s" - protocol = "Tcp" - backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "%s" + protocol = "Tcp" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" frontend_ip_configuration { name = "fe1-%d" @@ -417,11 +418,11 @@ resource "azurerm_lb_outbound_rule" "test" { } resource "azurerm_lb_outbound_rule" "test2" { - resource_group_name = "${azurerm_resource_group.test.name}" - loadbalancer_id = "${azurerm_lb.test.id}" - name = "%s" - protocol = "Udp" - backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "%s" + protocol = "Udp" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" frontend_ip_configuration { name = "fe2-%d" @@ -477,11 +478,11 @@ resource "azurerm_lb_backend_address_pool" "test" { } resource "azurerm_lb_outbound_rule" "test" { - resource_group_name = "${azurerm_resource_group.test.name}" - loadbalancer_id = "${azurerm_lb.test.id}" - name = "%s" - protocol = "All" - backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "%s" + protocol = "All" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" frontend_ip_configuration { name = "fe1-%d" @@ -489,11 +490,11 @@ resource "azurerm_lb_outbound_rule" "test" { } resource "azurerm_lb_outbound_rule" "test2" { - resource_group_name = "${azurerm_resource_group.test.name}" - loadbalancer_id = "${azurerm_lb.test.id}" - name = "%s" - protocol = "All" - backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "%s" + protocol = "All" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" frontend_ip_configuration { name = "fe2-%d" @@ -501,3 +502,49 @@ resource "azurerm_lb_outbound_rule" "test2" { } `, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, outboundRuleName, rInt, outboundRule2Name, rInt) } + +func testAccAzureRMLoadBalancerOutboundRule_withPublicIPPrefix(rInt int, outboundRuleName string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "test-ip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + prefix_length = 31 +} + +resource "azurerm_lb" "test" { + name = "arm-test-loadbalancer-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + + frontend_ip_configuration { + name = "one-%d" + public_ip_prefix_id = "${azurerm_public_ip_prefix.test.id}" + } +} + +resource "azurerm_lb_backend_address_pool" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "be-%d" +} + +resource "azurerm_lb_outbound_rule" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "%s" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" + protocol = "All" + + frontend_ip_configuration { + name = "one-%d" + } +} +`, rInt, location, rInt, rInt, rInt, rInt, outboundRuleName, rInt) +} diff --git a/azurerm/resource_arm_loadbalancer_probe.go b/azurerm/resource_arm_loadbalancer_probe.go index 6b287b557d43..ae4c9213db04 100644 --- a/azurerm/resource_arm_loadbalancer_probe.go +++ b/azurerm/resource_arm_loadbalancer_probe.go @@ -4,13 +4,15 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,9 +34,9 @@ func resourceArmLoadBalancerProbe() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "loadbalancer_id": { Type: schema.TypeString, @@ -94,13 +96,13 @@ func resourceArmLoadBalancerProbe() *schema.Resource { } func resourceArmLoadBalancerProbeCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { @@ -118,7 +120,7 @@ func resourceArmLoadBalancerProbeCreateUpdate(d *schema.ResourceData, meta inter existingProbe, existingProbeIndex, exists := findLoadBalancerProbeByName(loadBalancer, name) if exists { if name == *existingProbe.Name { - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { return tf.ImportAsExistsError("azurerm_lb_probe", *existingProbe.ID) } @@ -167,7 +169,7 @@ func resourceArmLoadBalancerProbeCreateUpdate(d *schema.ResourceData, meta inter } func resourceArmLoadBalancerProbeRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -217,12 +219,12 @@ func resourceArmLoadBalancerProbeRead(d *schema.ResourceData, meta interface{}) } func resourceArmLoadBalancerProbeDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { diff --git a/azurerm/resource_arm_loadbalancer_probe_test.go b/azurerm/resource_arm_loadbalancer_probe_test.go index 9d6582fa5b6a..2f3b0014ec07 100644 --- a/azurerm/resource_arm_loadbalancer_probe_test.go +++ b/azurerm/resource_arm_loadbalancer_probe_test.go @@ -5,10 +5,12 @@ import ( "os" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLoadBalancerProbe_basic(t *testing.T) { @@ -47,7 +49,7 @@ func TestAccAzureRMLoadBalancerProbe_basic(t *testing.T) { } func TestAccAzureRMLoadBalancerProbe_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -176,40 +178,6 @@ func TestAccAzureRMLoadBalancerProbe_updateProtocol(t *testing.T) { }) } -func TestAccAzureRMLoadBalancerProbe_reapply(t *testing.T) { - var lb network.LoadBalancer - ri := tf.AccRandTimeInt() - probeName := fmt.Sprintf("probe-%d", ri) - - deleteProbeState := func(s *terraform.State) error { - return s.Remove("azurerm_lb_probe.test") - } - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMLoadBalancerDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMLoadBalancerProbe_basic(ri, probeName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerProbeExists(probeName, &lb), - deleteProbeState, - ), - ExpectNonEmptyPlan: true, - }, - { - Config: testAccAzureRMLoadBalancerProbe_basic(ri, probeName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerProbeExists(probeName, &lb), - ), - }, - }, - }) -} - func TestAccAzureRMLoadBalancerProbe_disappears(t *testing.T) { var lb network.LoadBalancer ri := tf.AccRandTimeInt() @@ -257,7 +225,7 @@ func testCheckAzureRMLoadBalancerProbeNotExists(natRuleName string, lb *network. func testCheckAzureRMLoadBalancerProbeDisappears(addressPoolName string, lb *network.LoadBalancer) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).loadBalancerClient + client := testAccProvider.Meta().(*ArmClient).network.LoadBalancersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext _, i, exists := findLoadBalancerProbeByName(lb, addressPoolName) @@ -269,7 +237,7 @@ func testCheckAzureRMLoadBalancerProbeDisappears(addressPoolName string, lb *net probes := append(currentProbes[:i], currentProbes[i+1:]...) lb.LoadBalancerPropertiesFormat.Probes = &probes - id, err := parseAzureResourceID(*lb.ID) + id, err := azure.ParseAzureResourceID(*lb.ID) if err != nil { return err } diff --git a/azurerm/resource_arm_loadbalancer_rule.go b/azurerm/resource_arm_loadbalancer_rule.go index 65e2002f0255..b8bf782f35d1 100644 --- a/azurerm/resource_arm_loadbalancer_rule.go +++ b/azurerm/resource_arm_loadbalancer_rule.go @@ -5,13 +5,15 @@ import ( "log" "regexp" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -34,9 +36,9 @@ func resourceArmLoadBalancerRule() *schema.Resource { ValidateFunc: validateArmLoadBalancerRuleName, }, - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "loadbalancer_id": { Type: schema.TypeString, @@ -98,6 +100,12 @@ func resourceArmLoadBalancerRule() *schema.Resource { Default: false, }, + "disable_outbound_snat": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "idle_timeout_in_minutes": { Type: schema.TypeInt, Optional: true, @@ -115,13 +123,13 @@ func resourceArmLoadBalancerRule() *schema.Resource { } func resourceArmLoadBalancerRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { @@ -135,7 +143,7 @@ func resourceArmLoadBalancerRuleCreateUpdate(d *schema.ResourceData, meta interf newLbRule, err := expandAzureRmLoadBalancerRule(d, loadBalancer) if err != nil { - return fmt.Errorf("Error Exanding Load Balancer Rule: %+v", err) + return fmt.Errorf("Error Expanding Load Balancer Rule: %+v", err) } lbRules := append(*loadBalancer.LoadBalancerPropertiesFormat.LoadBalancingRules, *newLbRule) @@ -143,7 +151,7 @@ func resourceArmLoadBalancerRuleCreateUpdate(d *schema.ResourceData, meta interf existingRule, existingRuleIndex, exists := findLoadBalancerRuleByName(loadBalancer, name) if exists { if name == *existingRule.Name { - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { return tf.ImportAsExistsError("azurerm_lb_rule", *existingRule.ID) } @@ -192,7 +200,7 @@ func resourceArmLoadBalancerRuleCreateUpdate(d *schema.ResourceData, meta interf } func resourceArmLoadBalancerRuleRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -222,6 +230,7 @@ func resourceArmLoadBalancerRuleRead(d *schema.ResourceData, meta interface{}) e d.Set("protocol", properties.Protocol) d.Set("frontend_port", properties.FrontendPort) d.Set("backend_port", properties.BackendPort) + d.Set("disable_outbound_snat", properties.DisableOutboundSnat) if properties.EnableFloatingIP != nil { d.Set("enable_floating_ip", properties.EnableFloatingIP) @@ -232,7 +241,7 @@ func resourceArmLoadBalancerRuleRead(d *schema.ResourceData, meta interface{}) e } if properties.FrontendIPConfiguration != nil { - fipID, err := parseAzureResourceID(*properties.FrontendIPConfiguration.ID) + fipID, err := azure.ParseAzureResourceID(*properties.FrontendIPConfiguration.ID) if err != nil { return err } @@ -258,12 +267,12 @@ func resourceArmLoadBalancerRuleRead(d *schema.ResourceData, meta interface{}) e } func resourceArmLoadBalancerRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).loadBalancerClient + client := meta.(*ArmClient).network.LoadBalancersClient ctx := meta.(*ArmClient).StopContext loadBalancerID := d.Get("loadbalancer_id").(string) - armMutexKV.Lock(loadBalancerID) - defer armMutexKV.Unlock(loadBalancerID) + locks.ByID(loadBalancerID) + defer locks.UnlockByID(loadBalancerID) loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) if err != nil { @@ -311,10 +320,11 @@ func resourceArmLoadBalancerRuleDelete(d *schema.ResourceData, meta interface{}) func expandAzureRmLoadBalancerRule(d *schema.ResourceData, lb *network.LoadBalancer) (*network.LoadBalancingRule, error) { properties := network.LoadBalancingRulePropertiesFormat{ - Protocol: network.TransportProtocol(d.Get("protocol").(string)), - FrontendPort: utils.Int32(int32(d.Get("frontend_port").(int))), - BackendPort: utils.Int32(int32(d.Get("backend_port").(int))), - EnableFloatingIP: utils.Bool(d.Get("enable_floating_ip").(bool)), + Protocol: network.TransportProtocol(d.Get("protocol").(string)), + FrontendPort: utils.Int32(int32(d.Get("frontend_port").(int))), + BackendPort: utils.Int32(int32(d.Get("backend_port").(int))), + EnableFloatingIP: utils.Bool(d.Get("enable_floating_ip").(bool)), + DisableOutboundSnat: utils.Bool(d.Get("disable_outbound_snat").(bool)), } if v, ok := d.GetOk("idle_timeout_in_minutes"); ok { diff --git a/azurerm/resource_arm_loadbalancer_rule_test.go b/azurerm/resource_arm_loadbalancer_rule_test.go index 94df30d9bad9..800c6aa01690 100644 --- a/azurerm/resource_arm_loadbalancer_rule_test.go +++ b/azurerm/resource_arm_loadbalancer_rule_test.go @@ -5,11 +5,13 @@ import ( "os" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestResourceAzureRMLoadBalancerRuleNameLabel_validation(t *testing.T) { @@ -103,8 +105,43 @@ func TestAccAzureRMLoadBalancerRule_basic(t *testing.T) { }) } +func TestAccAzureRMLoadBalancerRule_disableoutboundsnat(t *testing.T) { + var lb network.LoadBalancer + ri := tf.AccRandTimeInt() + lbRuleName := fmt.Sprintf("LbRule-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)) + + subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID") + lbRule_id := fmt.Sprintf( + "/subscriptions/%s/resourceGroups/acctestRG-%d/providers/Microsoft.Network/loadBalancers/arm-test-loadbalancer-%d/loadBalancingRules/%s", + subscriptionID, ri, ri, lbRuleName) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLoadBalancerRule_disableoutboundsnat(ri, lbRuleName, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), + testCheckAzureRMLoadBalancerRuleExists(lbRuleName, &lb), + resource.TestCheckResourceAttr("azurerm_lb_rule.test", "id", lbRule_id), + resource.TestCheckResourceAttr("azurerm_lb_rule.test", "disable_outbound_snat", "true"), + ), + }, + { + ResourceName: "azurerm_lb.test", + ImportState: true, + ImportStateVerify: true, + // location is deprecated and was never actually used + ImportStateVerifyIgnore: []string{"location"}, + }, + }, + }) +} + func TestAccAzureRMLoadBalancerRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -243,40 +280,6 @@ func TestAccAzureRMLoadBalancerRule_update(t *testing.T) { }) } -func TestAccAzureRMLoadBalancerRule_reapply(t *testing.T) { - var lb network.LoadBalancer - ri := tf.AccRandTimeInt() - lbRuleName := fmt.Sprintf("LbRule-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)) - - deleteRuleState := func(s *terraform.State) error { - return s.Remove("azurerm_lb_rule.test") - } - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMLoadBalancerDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAzureRMLoadBalancerRule_basic(ri, lbRuleName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerRuleExists(lbRuleName, &lb), - deleteRuleState, - ), - ExpectNonEmptyPlan: true, - }, - { - Config: testAccAzureRMLoadBalancerRule_basic(ri, lbRuleName, testLocation()), - Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLoadBalancerExists("azurerm_lb.test", &lb), - testCheckAzureRMLoadBalancerRuleExists(lbRuleName, &lb), - ), - }, - }, - }) -} - func TestAccAzureRMLoadBalancerRule_disappears(t *testing.T) { var lb network.LoadBalancer ri := tf.AccRandTimeInt() @@ -324,7 +327,7 @@ func testCheckAzureRMLoadBalancerRuleNotExists(lbRuleName string, lb *network.Lo func testCheckAzureRMLoadBalancerRuleDisappears(ruleName string, lb *network.LoadBalancer) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).loadBalancerClient + client := testAccProvider.Meta().(*ArmClient).network.LoadBalancersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext _, i, exists := findLoadBalancerRuleByName(lb, ruleName) @@ -336,7 +339,7 @@ func testCheckAzureRMLoadBalancerRuleDisappears(ruleName string, lb *network.Loa rules := append(currentRules[:i], currentRules[i+1:]...) lb.LoadBalancerPropertiesFormat.LoadBalancingRules = &rules - id, err := parseAzureResourceID(*lb.ID) + id, err := azure.ParseAzureResourceID(*lb.ID) if err != nil { return err } @@ -393,6 +396,47 @@ resource "azurerm_lb_rule" "test" { `, rInt, location, rInt, rInt, rInt, lbRuleName, rInt) } +func testAccAzureRMLoadBalancerRule_disableoutboundsnat(rInt int, lbRuleName string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip" "test" { + name = "test-ip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_lb" "test" { + name = "arm-test-loadbalancer-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + + frontend_ip_configuration { + name = "one-%d" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } +} + +resource "azurerm_lb_rule" "test" { + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "%s" + protocol = "Tcp" + frontend_port = 3389 + backend_port = 3389 + frontend_ip_configuration_name = "one-%d" + disable_outbound_snat = true +} +`, rInt, location, rInt, rInt, rInt, lbRuleName, rInt) +} + func testAccAzureRMLoadBalancerRule_requiresImport(rInt int, name string, location string) string { template := testAccAzureRMLoadBalancerRule_basic(rInt, name, location) return fmt.Sprintf(` diff --git a/azurerm/resource_arm_loadbalancer_test.go b/azurerm/resource_arm_loadbalancer_test.go index 08b108423601..6a76ae3e06f1 100644 --- a/azurerm/resource_arm_loadbalancer_test.go +++ b/azurerm/resource_arm_loadbalancer_test.go @@ -5,10 +5,11 @@ import ( "net/http" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestResourceAzureRMLoadBalancerPrivateIpAddressAllocation_validation(t *testing.T) { @@ -72,7 +73,7 @@ func TestAccAzureRMLoadBalancer_basic(t *testing.T) { } func TestAccAzureRMLoadBalancer_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -123,7 +124,32 @@ func TestAccAzureRMLoadBalancer_standard(t *testing.T) { }, }) } +func TestAccAzureRMLoadBalancer_frontEndConfigPublicIPPrefix(t *testing.T) { + var lb network.LoadBalancer + ri := tf.AccRandTimeInt() + location := testLocation() + resourceName := "azurerm_lb.test" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLoadBalancer_frontEndConfigPublicIPPrefix(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLoadBalancerExists(resourceName, &lb), + resource.TestCheckResourceAttr(resourceName, "frontend_ip_configuration.#", "1"), + ), + }, + { + ResourceName: "azurerm_lb.test", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} func TestAccAzureRMLoadBalancer_frontEndConfig(t *testing.T) { var lb network.LoadBalancer resourceName := "azurerm_lb.test" @@ -231,7 +257,7 @@ func testCheckAzureRMLoadBalancerExists(resourceName string, lb *network.LoadBal return fmt.Errorf("Bad: no resource group found in state for loadbalancer: %s", loadBalancerName) } - client := testAccProvider.Meta().(*ArmClient).loadBalancerClient + client := testAccProvider.Meta().(*ArmClient).network.LoadBalancersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, loadBalancerName, "") @@ -250,7 +276,7 @@ func testCheckAzureRMLoadBalancerExists(resourceName string, lb *network.LoadBal } func testCheckAzureRMLoadBalancerDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).loadBalancerClient + client := testAccProvider.Meta().(*ArmClient).network.LoadBalancersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -426,6 +452,34 @@ resource "azurerm_lb" "test" { `, rInt, location, rInt, rInt, rInt, rInt) } +func testAccAzureRMLoadBalancer_frontEndConfigPublicIPPrefix(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "test-ip-prefix-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + prefix_length = 31 +} + +resource "azurerm_lb" "test" { + name = "acctest-loadbalancer-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + + frontend_ip_configuration { + name = "prefix-%d" + public_ip_prefix_id = "${azurerm_public_ip_prefix.test.id}" + } +} +`, rInt, location, rInt, rInt, rInt) +} + func testAccAzureRMLoadBalancer_frontEndConfigRemoval(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/azurerm/resource_arm_local_network_gateway.go b/azurerm/resource_arm_local_network_gateway.go index 821c39a902b4..6b0ce73dbce7 100644 --- a/azurerm/resource_arm_local_network_gateway.go +++ b/azurerm/resource_arm_local_network_gateway.go @@ -3,10 +3,13 @@ package azurerm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,9 +30,9 @@ func resourceArmLocalNetworkGateway() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "gateway_address": { Type: schema.TypeString, @@ -69,19 +72,19 @@ func resourceArmLocalNetworkGateway() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmLocalNetworkGatewayCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).localNetConnClient + client := meta.(*ArmClient).network.LocalNetworkGatewaysClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -94,7 +97,7 @@ func resourceArmLocalNetworkGatewayCreateUpdate(d *schema.ResourceData, meta int } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) ipAddress := d.Get("gateway_address").(string) addressSpaces := expandLocalNetworkGatewayAddressSpaces(d) @@ -104,7 +107,7 @@ func resourceArmLocalNetworkGatewayCreateUpdate(d *schema.ResourceData, meta int return err } - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) gateway := network.LocalNetworkGateway{ Name: &name, @@ -116,7 +119,7 @@ func resourceArmLocalNetworkGatewayCreateUpdate(d *schema.ResourceData, meta int GatewayIPAddress: &ipAddress, BgpSettings: bgpSettings, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resGroup, name, gateway) @@ -142,7 +145,7 @@ func resourceArmLocalNetworkGatewayCreateUpdate(d *schema.ResourceData, meta int } func resourceArmLocalNetworkGatewayRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).localNetConnClient + client := meta.(*ArmClient).network.LocalNetworkGatewaysClient ctx := meta.(*ArmClient).StopContext resGroup, name, err := resourceGroupAndLocalNetworkGatewayFromId(d.Id()) @@ -163,7 +166,7 @@ func resourceArmLocalNetworkGatewayRead(d *schema.ResourceData, meta interface{} d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.LocalNetworkGatewayPropertiesFormat; props != nil { @@ -180,13 +183,11 @@ func resourceArmLocalNetworkGatewayRead(d *schema.ResourceData, meta interface{} } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmLocalNetworkGatewayDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).localNetConnClient + client := meta.(*ArmClient).network.LocalNetworkGatewaysClient ctx := meta.(*ArmClient).StopContext resGroup, name, err := resourceGroupAndLocalNetworkGatewayFromId(d.Id()) @@ -215,7 +216,7 @@ func resourceArmLocalNetworkGatewayDelete(d *schema.ResourceData, meta interface } func resourceGroupAndLocalNetworkGatewayFromId(localNetworkGatewayId string) (string, string, error) { - id, err := parseAzureResourceID(localNetworkGatewayId) + id, err := azure.ParseAzureResourceID(localNetworkGatewayId) if err != nil { return "", "", err } diff --git a/azurerm/resource_arm_local_network_gateway_test.go b/azurerm/resource_arm_local_network_gateway_test.go index 152f35d1c70b..b09783a5277f 100644 --- a/azurerm/resource_arm_local_network_gateway_test.go +++ b/azurerm/resource_arm_local_network_gateway_test.go @@ -6,8 +6,10 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +40,7 @@ func TestAccAzureRMLocalNetworkGateway_basic(t *testing.T) { } func TestAccAzureRMLocalNetworkGateway_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -254,7 +256,7 @@ func testCheckAzureRMLocalNetworkGatewayExists(resourceName string) resource.Tes } // then, extract the name and the resource group: - id, err := parseAzureResourceID(res.Primary.ID) + id, err := azure.ParseAzureResourceID(res.Primary.ID) if err != nil { return err } @@ -262,7 +264,7 @@ func testCheckAzureRMLocalNetworkGatewayExists(resourceName string) resource.Tes resGrp := id.ResourceGroup // and finally, check that it exists on Azure: - client := testAccProvider.Meta().(*ArmClient).localNetConnClient + client := testAccProvider.Meta().(*ArmClient).network.LocalNetworkGatewaysClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resGrp, localNetName) @@ -287,7 +289,7 @@ func testCheckAzureRMLocalNetworkGatewayDisappears(resourceName string) resource } // then, extract the name and the resource group: - id, err := parseAzureResourceID(res.Primary.ID) + id, err := azure.ParseAzureResourceID(res.Primary.ID) if err != nil { return err } @@ -295,7 +297,7 @@ func testCheckAzureRMLocalNetworkGatewayDisappears(resourceName string) resource resourceGroup := id.ResourceGroup // and finally, check that it exists on Azure: - client := testAccProvider.Meta().(*ArmClient).localNetConnClient + client := testAccProvider.Meta().(*ArmClient).network.LocalNetworkGatewaysClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, localNetName) @@ -320,14 +322,14 @@ func testCheckAzureRMLocalNetworkGatewayDestroy(s *terraform.State) error { continue } - id, err := parseAzureResourceID(res.Primary.ID) + id, err := azure.ParseAzureResourceID(res.Primary.ID) if err != nil { return err } localNetName := id.Path["localNetworkGateways"] resourceGroup := id.ResourceGroup - client := testAccProvider.Meta().(*ArmClient).localNetConnClient + client := testAccProvider.Meta().(*ArmClient).network.LocalNetworkGatewaysClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, localNetName) diff --git a/azurerm/resource_arm_log_analytics_linked_service.go b/azurerm/resource_arm_log_analytics_linked_service.go index 1fd03071f3e0..85ffb26e7e81 100644 --- a/azurerm/resource_arm_log_analytics_linked_service.go +++ b/azurerm/resource_arm_log_analytics_linked_service.go @@ -10,6 +10,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -25,7 +27,7 @@ func resourceArmLogAnalyticsLinkedService() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), "workspace_name": { Type: schema.TypeString, @@ -55,10 +57,13 @@ func resourceArmLogAnalyticsLinkedService() *schema.Resource { }, "linked_service_properties": { - Type: schema.TypeList, - Optional: true, - Computed: true, - ForceNew: true, + Type: schema.TypeList, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"resource_id"}, + MaxItems: 1, + Deprecated: "This property has been deprecated in favour of the 'resource_id' property and will be removed in version 2.0 of the provider", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "resource_id": { @@ -77,13 +82,13 @@ func resourceArmLogAnalyticsLinkedService() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmLogAnalyticsLinkedServiceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).linkedServicesClient + client := meta.(*ArmClient).logAnalytics.LinkedServicesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Log Analytics Linked Services creation.") @@ -92,7 +97,7 @@ func resourceArmLogAnalyticsLinkedServiceCreateUpdate(d *schema.ResourceData, me workspaceName := d.Get("workspace_name").(string) lsName := d.Get("linked_service_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, workspaceName, lsName) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -107,19 +112,19 @@ func resourceArmLogAnalyticsLinkedServiceCreateUpdate(d *schema.ResourceData, me resourceId := d.Get("resource_id").(string) if resourceId == "" { - props := d.Get("linked_service_properties").(map[string]interface{}) - resourceId = props["resource_id"].(string) + props := d.Get("linked_service_properties").([]interface{}) + resourceId = expandLogAnalyticsLinkedServiceProperties(props) if resourceId == "" { return fmt.Errorf("A `resource_id` must be specified either using the `resource_id` field at the top level or within the `linked_service_properties` block") } } - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := operationalinsights.LinkedService{ LinkedServiceProperties: &operationalinsights.LinkedServiceProperties{ ResourceID: utils.String(resourceId), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.CreateOrUpdate(ctx, resGroup, workspaceName, lsName, parameters); err != nil { @@ -140,10 +145,10 @@ func resourceArmLogAnalyticsLinkedServiceCreateUpdate(d *schema.ResourceData, me } func resourceArmLogAnalyticsLinkedServiceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).linkedServicesClient + client := meta.(*ArmClient).logAnalytics.LinkedServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -175,15 +180,14 @@ func resourceArmLogAnalyticsLinkedServiceRead(d *schema.ResourceData, meta inter return fmt.Errorf("Error setting `linked_service_properties`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmLogAnalyticsLinkedServiceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).linkedServicesClient + client := meta.(*ArmClient).logAnalytics.LinkedServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -204,6 +208,15 @@ func resourceArmLogAnalyticsLinkedServiceDelete(d *schema.ResourceData, meta int return nil } +func expandLogAnalyticsLinkedServiceProperties(input []interface{}) string { + if len(input) == 0 { + return "" + } + + props := input[0].(map[string]interface{}) + return props["resource_id"].(string) +} + func flattenLogAnalyticsLinkedServiceProperties(input *operationalinsights.LinkedServiceProperties) []interface{} { if input == nil { return []interface{}{} diff --git a/azurerm/resource_arm_log_analytics_linked_service_test.go b/azurerm/resource_arm_log_analytics_linked_service_test.go index fa2a4db021e4..36ba2435048b 100644 --- a/azurerm/resource_arm_log_analytics_linked_service_test.go +++ b/azurerm/resource_arm_log_analytics_linked_service_test.go @@ -3,11 +3,13 @@ package azurerm import ( "fmt" "net/http" + "regexp" "testing" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogAnalyticsLinkedService_basic(t *testing.T) { @@ -38,7 +40,7 @@ func TestAccAzureRMLogAnalyticsLinkedService_basic(t *testing.T) { } func TestAccAzureRMLogAnalyticsLinkedService_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -94,8 +96,50 @@ func TestAccAzureRMLogAnalyticsLinkedService_complete(t *testing.T) { }) } +// Deprecated - remove in 2.0 +func TestAccAzureRMLogAnalyticsLinkedService_noResourceID(t *testing.T) { + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMLogAnalyticsLinkedServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLogAnalyticsLinkedService_noResourceID(ri, testLocation()), + ExpectError: regexp.MustCompile("A `resource_id` must be specified either using the `resource_id` field at the top level or within the `linked_service_properties` block"), + }, + }, + }) +} + +// Deprecated - remove in 2.0 +func TestAccAzureRMLogAnalyticsLinkedService_linkedServiceProperties(t *testing.T) { + resourceName := "azurerm_log_analytics_linked_service.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMLogAnalyticsLinkedServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLogAnalyticsLinkedService_linkedServiceProperties(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLogAnalyticsLinkedServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMLogAnalyticsLinkedServiceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).linkedServicesClient + conn := testAccProvider.Meta().(*ArmClient).logAnalytics.LinkedServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -140,7 +184,7 @@ func testCheckAzureRMLogAnalyticsLinkedServiceExists(resourceName string) resour return fmt.Errorf("Bad: no resource group found in state for Log Analytics Linked Service: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).linkedServicesClient + conn := testAccProvider.Meta().(*ArmClient).logAnalytics.LinkedServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, workspaceName, lsName) @@ -196,6 +240,33 @@ resource "azurerm_log_analytics_linked_service" "test" { `, template) } +func testAccAzureRMLogAnalyticsLinkedService_noResourceID(rInt int, location string) string { + template := testAccAzureRMLogAnalyticsLinkedService_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_log_analytics_linked_service" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" +} +`, template) +} + +func testAccAzureRMLogAnalyticsLinkedService_linkedServiceProperties(rInt int, location string) string { + template := testAccAzureRMLogAnalyticsLinkedService_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_log_analytics_linked_service" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + linked_service_properties { + resource_id = "${azurerm_automation_account.test.id}" + } +} +`, template) +} + func testAccAzureRMLogAnalyticsLinkedService_template(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/azurerm/resource_arm_log_analytics_solution.go b/azurerm/resource_arm_log_analytics_solution.go index 0c88447f5024..a6f3471ed4ba 100644 --- a/azurerm/resource_arm_log_analytics_solution.go +++ b/azurerm/resource_arm_log_analytics_solution.go @@ -6,9 +6,11 @@ import ( "strings" "github.com/Azure/azure-sdk-for-go/services/preview/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" @@ -47,9 +49,9 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { DiffSuppressFunc: suppress.CaseDifference, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), "plan": { Type: schema.TypeList, @@ -84,7 +86,7 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { } func resourceArmLogAnalyticsSolutionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).solutionsClient + client := meta.(*ArmClient).logAnalytics.SolutionsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Log Analytics Solution creation.") @@ -93,7 +95,7 @@ func resourceArmLogAnalyticsSolutionCreateUpdate(d *schema.ResourceData, meta in name := fmt.Sprintf("%s(%s)", d.Get("solution_name").(string), d.Get("workspace_name").(string)) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -109,7 +111,7 @@ func resourceArmLogAnalyticsSolutionCreateUpdate(d *schema.ResourceData, meta in solutionPlan := expandAzureRmLogAnalyticsSolutionPlan(d) solutionPlan.Name = &name - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) workspaceID := d.Get("workspace_resource_id").(string) parameters := operationsmanagement.Solution{ @@ -146,9 +148,9 @@ func resourceArmLogAnalyticsSolutionCreateUpdate(d *schema.ResourceData, meta in } func resourceArmLogAnalyticsSolutionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).solutionsClient + client := meta.(*ArmClient).logAnalytics.SolutionsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -170,7 +172,7 @@ func resourceArmLogAnalyticsSolutionRead(d *schema.ResourceData, meta interface{ d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } // Reversing the mapping used to get .solution_name @@ -200,9 +202,9 @@ func resourceArmLogAnalyticsSolutionRead(d *schema.ResourceData, meta interface{ } func resourceArmLogAnalyticsSolutionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).solutionsClient + client := meta.(*ArmClient).logAnalytics.SolutionsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_log_analytics_solution_test.go b/azurerm/resource_arm_log_analytics_solution_test.go index db224dc08715..116103f0933c 100644 --- a/azurerm/resource_arm_log_analytics_solution_test.go +++ b/azurerm/resource_arm_log_analytics_solution_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogAnalyticsSolution_basicContainerMonitoring(t *testing.T) { @@ -35,7 +36,7 @@ func TestAccAzureRMLogAnalyticsSolution_basicContainerMonitoring(t *testing.T) { } func TestAccAzureRMLogAnalyticsSolution_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -87,7 +88,7 @@ func TestAccAzureRMLogAnalyticsSolution_basicSecurity(t *testing.T) { } func testCheckAzureRMLogAnalyticsSolutionDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).solutionsClient + conn := testAccProvider.Meta().(*ArmClient).logAnalytics.SolutionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -126,7 +127,7 @@ func testCheckAzureRMLogAnalyticsSolutionExists(resourceName string) resource.Te return fmt.Errorf("Bad: no resource group found in state for Log Analytics Workspace: %q", name) } - conn := testAccProvider.Meta().(*ArmClient).solutionsClient + conn := testAccProvider.Meta().(*ArmClient).logAnalytics.SolutionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_log_analytics_workspace.go b/azurerm/resource_arm_log_analytics_workspace.go index 4e9839bfe3e6..415d0995e22c 100644 --- a/azurerm/resource_arm_log_analytics_workspace.go +++ b/azurerm/resource_arm_log_analytics_workspace.go @@ -8,7 +8,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/operationalinsights/mgmt/2015-11-01-preview/operationalinsights" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,9 +34,9 @@ func resourceArmLogAnalyticsWorkspace() *schema.Resource { ValidateFunc: validateAzureRmLogAnalyticsWorkspaceName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), "sku": { Type: schema.TypeString, @@ -40,14 +44,14 @@ func resourceArmLogAnalyticsWorkspace() *schema.Resource { ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ string(operationalinsights.Free), + string(operationalinsights.PerGB2018), string(operationalinsights.PerNode), string(operationalinsights.Premium), string(operationalinsights.Standalone), string(operationalinsights.Standard), - string(operationalinsights.Unlimited), - string(operationalinsights.PerGB2018), + string("Unlimited"), // TODO check if this is actually no longer valid, removed in v28.0.0 of the SDK }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "retention_in_days": { @@ -79,20 +83,20 @@ func resourceArmLogAnalyticsWorkspace() *schema.Resource { Sensitive: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmLogAnalyticsWorkspaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).workspacesClient + client := meta.(*ArmClient).logAnalytics.WorkspacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Log Analytics Workspace creation.") name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -105,7 +109,7 @@ func resourceArmLogAnalyticsWorkspaceCreateUpdate(d *schema.ResourceData, meta i } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) skuName := d.Get("sku").(string) sku := &operationalinsights.Sku{ Name: operationalinsights.SkuNameEnum(skuName), @@ -113,12 +117,12 @@ func resourceArmLogAnalyticsWorkspaceCreateUpdate(d *schema.ResourceData, meta i retentionInDays := int32(d.Get("retention_in_days").(int)) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := operationalinsights.Workspace{ Name: &name, Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), WorkspaceProperties: &operationalinsights.WorkspaceProperties{ Sku: sku, RetentionInDays: &retentionInDays, @@ -150,9 +154,9 @@ func resourceArmLogAnalyticsWorkspaceCreateUpdate(d *schema.ResourceData, meta i } func resourceArmLogAnalyticsWorkspaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).workspacesClient + client := meta.(*ArmClient).logAnalytics.WorkspacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -171,7 +175,7 @@ func resourceArmLogAnalyticsWorkspaceRead(d *schema.ResourceData, meta interface d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("workspace_id", resp.CustomerID) @@ -189,14 +193,13 @@ func resourceArmLogAnalyticsWorkspaceRead(d *schema.ResourceData, meta interface d.Set("secondary_shared_key", sharedKeys.SecondarySharedKey) } - flattenAndSetTags(d, resp.Tags) - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmLogAnalyticsWorkspaceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).workspacesClient + client := meta.(*ArmClient).logAnalytics.WorkspacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_log_analytics_workspace_linked_service.go b/azurerm/resource_arm_log_analytics_workspace_linked_service.go index a418fdff9e45..2b0ee7e48ca0 100644 --- a/azurerm/resource_arm_log_analytics_workspace_linked_service.go +++ b/azurerm/resource_arm_log_analytics_workspace_linked_service.go @@ -10,6 +10,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,7 +34,7 @@ As such the existing 'azurerm_log_analytics_workspace_linked_service' resource i }, Schema: map[string]*schema.Schema{ - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), "workspace_name": { Type: schema.TypeString, @@ -62,10 +64,13 @@ As such the existing 'azurerm_log_analytics_workspace_linked_service' resource i }, "linked_service_properties": { - Type: schema.TypeList, - Optional: true, - Computed: true, - ForceNew: true, + Type: schema.TypeList, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"resource_id"}, + MaxItems: 1, + Deprecated: "This property has been deprecated in favour of the 'resource_id' property and will be removed in version 2.0 of the provider", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "resource_id": { @@ -84,13 +89,13 @@ As such the existing 'azurerm_log_analytics_workspace_linked_service' resource i Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmLogAnalyticsWorkspaceLinkedServiceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).linkedServicesClient + client := meta.(*ArmClient).logAnalytics.LinkedServicesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Log Analytics Linked Services creation.") @@ -99,7 +104,7 @@ func resourceArmLogAnalyticsWorkspaceLinkedServiceCreateUpdate(d *schema.Resourc workspaceName := d.Get("workspace_name").(string) lsName := d.Get("linked_service_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, workspaceName, lsName) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -114,19 +119,19 @@ func resourceArmLogAnalyticsWorkspaceLinkedServiceCreateUpdate(d *schema.Resourc resourceId := d.Get("resource_id").(string) if resourceId == "" { - props := d.Get("linked_service_properties").(map[string]interface{}) - resourceId = props["resource_id"].(string) + props := d.Get("linked_service_properties").([]interface{}) + resourceId = expandLogAnalyticsWorkspaceLinkedServiceProperties(props) if resourceId == "" { return fmt.Errorf("A `resource_id` must be specified either using the `resource_id` field at the top level or within the `linked_service_properties` block") } } - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) parameters := operationalinsights.LinkedService{ LinkedServiceProperties: &operationalinsights.LinkedServiceProperties{ ResourceID: utils.String(resourceId), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.CreateOrUpdate(ctx, resGroup, workspaceName, lsName, parameters); err != nil { @@ -147,10 +152,10 @@ func resourceArmLogAnalyticsWorkspaceLinkedServiceCreateUpdate(d *schema.Resourc } func resourceArmLogAnalyticsWorkspaceLinkedServiceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).linkedServicesClient + client := meta.(*ArmClient).logAnalytics.LinkedServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -182,15 +187,14 @@ func resourceArmLogAnalyticsWorkspaceLinkedServiceRead(d *schema.ResourceData, m return fmt.Errorf("Error setting `linked_service_properties`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmLogAnalyticsWorkspaceLinkedServiceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).linkedServicesClient + client := meta.(*ArmClient).logAnalytics.LinkedServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -211,6 +215,15 @@ func resourceArmLogAnalyticsWorkspaceLinkedServiceDelete(d *schema.ResourceData, return nil } +func expandLogAnalyticsWorkspaceLinkedServiceProperties(input []interface{}) string { + if len(input) == 0 { + return "" + } + + props := input[0].(map[string]interface{}) + return props["resource_id"].(string) +} + func flattenLogAnalyticsWorkspaceLinkedServiceProperties(input *operationalinsights.LinkedServiceProperties) []interface{} { if input == nil { return []interface{}{} diff --git a/azurerm/resource_arm_log_analytics_workspace_linked_service_test.go b/azurerm/resource_arm_log_analytics_workspace_linked_service_test.go index b814ce424698..91c27c131842 100644 --- a/azurerm/resource_arm_log_analytics_workspace_linked_service_test.go +++ b/azurerm/resource_arm_log_analytics_workspace_linked_service_test.go @@ -3,11 +3,13 @@ package azurerm import ( "fmt" "net/http" + "regexp" "testing" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogAnalyticsWorkspaceLinkedService_basic(t *testing.T) { @@ -38,7 +40,7 @@ func TestAccAzureRMLogAnalyticsWorkspaceLinkedService_basic(t *testing.T) { } func TestAccAzureRMLogAnalyticsWorkspaceLinkedService_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -94,8 +96,50 @@ func TestAccAzureRMLogAnalyticsWorkspaceLinkedService_complete(t *testing.T) { }) } +// Deprecated - remove in 2.0 +func TestAccAzureRMLogAnalyticsWorkspaceLinkedService_noResourceID(t *testing.T) { + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMLogAnalyticsWorkspaceLinkedServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLogAnalyticsWorkspaceLinkedService_noResourceID(ri, testLocation()), + ExpectError: regexp.MustCompile("A `resource_id` must be specified either using the `resource_id` field at the top level or within the `linked_service_properties` block"), + }, + }, + }) +} + +// Deprecated - remove in 2.0 +func TestAccAzureRMLogAnalyticsWorkspaceLinkedService_linkedServiceProperties(t *testing.T) { + resourceName := "azurerm_log_analytics_workspace_linked_service.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMLogAnalyticsLinkedServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLogAnalyticsWorkspaceLinkedService_linkedServiceProperties(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLogAnalyticsWorkspaceLinkedServiceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMLogAnalyticsWorkspaceLinkedServiceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).linkedServicesClient + conn := testAccProvider.Meta().(*ArmClient).logAnalytics.LinkedServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -140,7 +184,7 @@ func testCheckAzureRMLogAnalyticsWorkspaceLinkedServiceExists(resourceName strin return fmt.Errorf("Bad: no resource group found in state for Log Analytics Linked Service: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).linkedServicesClient + conn := testAccProvider.Meta().(*ArmClient).logAnalytics.LinkedServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, workspaceName, lsName) @@ -196,6 +240,31 @@ resource "azurerm_log_analytics_workspace_linked_service" "test" { `, template) } +func testAccAzureRMLogAnalyticsWorkspaceLinkedService_noResourceID(rInt int, location string) string { + template := testAccAzureRMLogAnalyticsWorkspaceLinkedService_template(rInt, location) + return fmt.Sprintf(` +%s +resource "azurerm_log_analytics_workspace_linked_service" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" +} +`, template) +} + +func testAccAzureRMLogAnalyticsWorkspaceLinkedService_linkedServiceProperties(rInt int, location string) string { + template := testAccAzureRMLogAnalyticsWorkspaceLinkedService_template(rInt, location) + return fmt.Sprintf(` +%s +resource "azurerm_log_analytics_workspace_linked_service" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + linked_service_properties { + resource_id = "${azurerm_automation_account.test.id}" + } +} +`, template) +} + func testAccAzureRMLogAnalyticsWorkspaceLinkedService_template(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/azurerm/resource_arm_log_analytics_workspace_test.go b/azurerm/resource_arm_log_analytics_workspace_test.go index a10458b59b33..7019cd7dd8b1 100644 --- a/azurerm/resource_arm_log_analytics_workspace_test.go +++ b/azurerm/resource_arm_log_analytics_workspace_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRmLogAnalyticsWorkspaceName_validation(t *testing.T) { @@ -77,7 +78,7 @@ func TestAccAzureRMLogAnalyticsWorkspace_basic(t *testing.T) { } func TestAccAzureRMLogAnalyticsWorkspace_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -130,7 +131,7 @@ func TestAccAzureRMLogAnalyticsWorkspace_complete(t *testing.T) { } func testCheckAzureRMLogAnalyticsWorkspaceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).workspacesClient + conn := testAccProvider.Meta().(*ArmClient).logAnalytics.WorkspacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -169,7 +170,7 @@ func testCheckAzureRMLogAnalyticsWorkspaceExists(resourceName string) resource.T return fmt.Errorf("Bad: no resource group found in state for Log Analytics Workspace: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).workspacesClient + conn := testAccProvider.Meta().(*ArmClient).logAnalytics.WorkspacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) @@ -228,7 +229,7 @@ resource "azurerm_log_analytics_workspace" "test" { sku = "PerGB2018" retention_in_days = 30 - tags = { + tags = { Environment = "Test" } } diff --git a/azurerm/resource_arm_logic_app_action_custom.go b/azurerm/resource_arm_logic_app_action_custom.go index 2ab4a09fa20d..1c995990d4ca 100644 --- a/azurerm/resource_arm_logic_app_action_custom.go +++ b/azurerm/resource_arm_logic_app_action_custom.go @@ -64,7 +64,7 @@ func resourceArmLogicAppActionCustomCreateUpdate(d *schema.ResourceData, meta in } func resourceArmLogicAppActionCustomRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -102,7 +102,7 @@ func resourceArmLogicAppActionCustomRead(d *schema.ResourceData, meta interface{ } func resourceArmLogicAppActionCustomDelete(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_logic_app_action_custom_test.go b/azurerm/resource_arm_logic_app_action_custom_test.go index 69b763d16007..82df31ed11d5 100644 --- a/azurerm/resource_arm_logic_app_action_custom_test.go +++ b/azurerm/resource_arm_logic_app_action_custom_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogicAppActionCustom_basic(t *testing.T) { @@ -34,7 +35,7 @@ func TestAccAzureRMLogicAppActionCustom_basic(t *testing.T) { } func TestAccAzureRMLogicAppActionCustom_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } diff --git a/azurerm/resource_arm_logic_app_action_http.go b/azurerm/resource_arm_logic_app_action_http.go index f98fdc9bbd92..5f0a78ff2348 100644 --- a/azurerm/resource_arm_logic_app_action_http.go +++ b/azurerm/resource_arm_logic_app_action_http.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" ) func resourceArmLogicAppActionHTTP() *schema.Resource { @@ -40,11 +41,11 @@ func resourceArmLogicAppActionHTTP() *schema.Resource { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{ - string(http.MethodDelete), - string(http.MethodGet), - string(http.MethodPatch), - string(http.MethodPost), - string(http.MethodPut), + http.MethodDelete, + http.MethodGet, + http.MethodPatch, + http.MethodPost, + http.MethodPut, }, false), }, @@ -99,7 +100,7 @@ func resourceArmLogicAppActionHTTPCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmLogicAppActionHTTPRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -162,7 +163,7 @@ func resourceArmLogicAppActionHTTPRead(d *schema.ResourceData, meta interface{}) } func resourceArmLogicAppActionHTTPDelete(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -183,7 +184,7 @@ func expandLogicAppActionHttpHeaders(headersRaw map[string]interface{}) (*map[st headers := make(map[string]string) for i, v := range headersRaw { - value, err := tagValueToString(v) + value, err := tags.TagValueToString(v) if err != nil { return nil, err } diff --git a/azurerm/resource_arm_logic_app_action_http_test.go b/azurerm/resource_arm_logic_app_action_http_test.go index 1fc19711daab..efc226a2a83c 100644 --- a/azurerm/resource_arm_logic_app_action_http_test.go +++ b/azurerm/resource_arm_logic_app_action_http_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogicAppActionHttp_basic(t *testing.T) { @@ -33,7 +34,7 @@ func TestAccAzureRMLogicAppActionHttp_basic(t *testing.T) { } func TestAccAzureRMLogicAppActionHttp_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } diff --git a/azurerm/resource_arm_logic_app_trigger_custom.go b/azurerm/resource_arm_logic_app_trigger_custom.go index d4da1885d616..13002c017722 100644 --- a/azurerm/resource_arm_logic_app_trigger_custom.go +++ b/azurerm/resource_arm_logic_app_trigger_custom.go @@ -64,7 +64,7 @@ func resourceArmLogicAppTriggerCustomCreateUpdate(d *schema.ResourceData, meta i } func resourceArmLogicAppTriggerCustomRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -102,7 +102,7 @@ func resourceArmLogicAppTriggerCustomRead(d *schema.ResourceData, meta interface } func resourceArmLogicAppTriggerCustomDelete(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_logic_app_trigger_custom_test.go b/azurerm/resource_arm_logic_app_trigger_custom_test.go index b415f772935e..513d9e2bea68 100644 --- a/azurerm/resource_arm_logic_app_trigger_custom_test.go +++ b/azurerm/resource_arm_logic_app_trigger_custom_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogicAppTriggerCustom_basic(t *testing.T) { @@ -33,7 +34,7 @@ func TestAccAzureRMLogicAppTriggerCustom_basic(t *testing.T) { } func TestAccAzureRMLogicAppTriggerCustom_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } diff --git a/azurerm/resource_arm_logic_app_trigger_http_request.go b/azurerm/resource_arm_logic_app_trigger_http_request.go index 97b43d492eb8..5390b97990c4 100644 --- a/azurerm/resource_arm_logic_app_trigger_http_request.go +++ b/azurerm/resource_arm_logic_app_trigger_http_request.go @@ -61,11 +61,11 @@ func resourceArmLogicAppTriggerHttpRequest() *schema.Resource { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{ - string(http.MethodDelete), - string(http.MethodGet), - string(http.MethodPatch), - string(http.MethodPost), - string(http.MethodPut), + http.MethodDelete, + http.MethodGet, + http.MethodPatch, + http.MethodPost, + http.MethodPut, }, false), }, @@ -113,7 +113,7 @@ func resourceArmLogicAppTriggerHttpRequestCreateUpdate(d *schema.ResourceData, m } func resourceArmLogicAppTriggerHttpRequestRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -169,7 +169,7 @@ func resourceArmLogicAppTriggerHttpRequestRead(d *schema.ResourceData, meta inte } func resourceArmLogicAppTriggerHttpRequestDelete(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_logic_app_trigger_http_request_test.go b/azurerm/resource_arm_logic_app_trigger_http_request_test.go index 88113049622b..e3a5990734d5 100644 --- a/azurerm/resource_arm_logic_app_trigger_http_request_test.go +++ b/azurerm/resource_arm_logic_app_trigger_http_request_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogicAppTriggerHttpRequest_basic(t *testing.T) { @@ -34,7 +35,7 @@ func TestAccAzureRMLogicAppTriggerHttpRequest_basic(t *testing.T) { } func TestAccAzureRMLogicAppTriggerHttpRequest_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } diff --git a/azurerm/resource_arm_logic_app_trigger_recurrence.go b/azurerm/resource_arm_logic_app_trigger_recurrence.go index d8528ea64da3..69be9bbac218 100644 --- a/azurerm/resource_arm_logic_app_trigger_recurrence.go +++ b/azurerm/resource_arm_logic_app_trigger_recurrence.go @@ -74,7 +74,7 @@ func resourceArmLogicAppTriggerRecurrenceCreateUpdate(d *schema.ResourceData, me } func resourceArmLogicAppTriggerRecurrenceRead(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -121,7 +121,7 @@ func resourceArmLogicAppTriggerRecurrenceRead(d *schema.ResourceData, meta inter } func resourceArmLogicAppTriggerRecurrenceDelete(d *schema.ResourceData, meta interface{}) error { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_logic_app_trigger_recurrence_test.go b/azurerm/resource_arm_logic_app_trigger_recurrence_test.go index 40da797f0445..0f39613e770b 100644 --- a/azurerm/resource_arm_logic_app_trigger_recurrence_test.go +++ b/azurerm/resource_arm_logic_app_trigger_recurrence_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogicAppTriggerRecurrence_month(t *testing.T) { @@ -35,7 +36,7 @@ func TestAccAzureRMLogicAppTriggerRecurrence_month(t *testing.T) { } func TestAccAzureRMLogicAppTriggerRecurrence_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } diff --git a/azurerm/resource_arm_logic_app_workflow.go b/azurerm/resource_arm_logic_app_workflow.go index 80ca142017fb..8617a78ec652 100644 --- a/azurerm/resource_arm_logic_app_workflow.go +++ b/azurerm/resource_arm_logic_app_workflow.go @@ -6,7 +6,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/logic/mgmt/2016-06-01/logic" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -29,9 +33,9 @@ func resourceArmLogicAppWorkflow() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), // TODO: should Parameters be split out into their own object to allow validation on the different sub-types? "parameters": { @@ -53,7 +57,7 @@ func resourceArmLogicAppWorkflow() *schema.Resource { Default: "1.0.0.0", }, - "tags": tagsSchema(), + "tags": tags.Schema(), "access_endpoint": { Type: schema.TypeString, @@ -64,7 +68,7 @@ func resourceArmLogicAppWorkflow() *schema.Resource { } func resourceArmLogicAppWorkflowCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).logicWorkflowsClient + client := meta.(*ArmClient).logic.WorkflowsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Logic App Workflow creation.") @@ -72,7 +76,7 @@ func resourceArmLogicAppWorkflowCreate(d *schema.ResourceData, meta interface{}) name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -85,12 +89,12 @@ func resourceArmLogicAppWorkflowCreate(d *schema.ResourceData, meta interface{}) } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) parameters := expandLogicAppWorkflowParameters(d.Get("parameters").(map[string]interface{})) workflowSchema := d.Get("workflow_schema").(string) workflowVersion := d.Get("workflow_version").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) properties := logic.Workflow{ Location: utils.String(location), @@ -103,7 +107,7 @@ func resourceArmLogicAppWorkflowCreate(d *schema.ResourceData, meta interface{}) }, Parameters: parameters, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.CreateOrUpdate(ctx, resourceGroup, name, properties); err != nil { @@ -124,10 +128,10 @@ func resourceArmLogicAppWorkflowCreate(d *schema.ResourceData, meta interface{}) } func resourceArmLogicAppWorkflowUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).logicWorkflowsClient + client := meta.(*ArmClient).logic.WorkflowsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -136,8 +140,8 @@ func resourceArmLogicAppWorkflowUpdate(d *schema.ResourceData, meta interface{}) name := id.Path["workflows"] // lock to prevent against Actions, Parameters or Triggers conflicting - azureRMLockByName(name, logicAppResourceName) - defer azureRMUnlockByName(name, logicAppResourceName) + locks.ByName(name, logicAppResourceName) + defer locks.UnlockByName(name, logicAppResourceName) read, err := client.Get(ctx, resourceGroup, name) if err != nil { @@ -153,9 +157,9 @@ func resourceArmLogicAppWorkflowUpdate(d *schema.ResourceData, meta interface{}) return fmt.Errorf("[ERROR] Error parsing Logic App Workflow - `WorkflowProperties` is nil") } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) parameters := expandLogicAppWorkflowParameters(d.Get("parameters").(map[string]interface{})) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) properties := logic.Workflow{ Location: utils.String(location), @@ -163,7 +167,7 @@ func resourceArmLogicAppWorkflowUpdate(d *schema.ResourceData, meta interface{}) Definition: read.WorkflowProperties.Definition, Parameters: parameters, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err = client.CreateOrUpdate(ctx, resourceGroup, name, properties); err != nil { @@ -174,10 +178,10 @@ func resourceArmLogicAppWorkflowUpdate(d *schema.ResourceData, meta interface{}) } func resourceArmLogicAppWorkflowRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).logicWorkflowsClient + client := meta.(*ArmClient).logic.WorkflowsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -198,7 +202,7 @@ func resourceArmLogicAppWorkflowRead(d *schema.ResourceData, meta interface{}) e d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.WorkflowProperties; props != nil { @@ -217,16 +221,14 @@ func resourceArmLogicAppWorkflowRead(d *schema.ResourceData, meta interface{}) e } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmLogicAppWorkflowDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).logicWorkflowsClient + client := meta.(*ArmClient).logic.WorkflowsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -234,8 +236,8 @@ func resourceArmLogicAppWorkflowDelete(d *schema.ResourceData, meta interface{}) name := id.Path["workflows"] // lock to prevent against Actions, Parameters or Triggers conflicting - azureRMLockByName(name, logicAppResourceName) - defer azureRMUnlockByName(name, logicAppResourceName) + locks.ByName(name, logicAppResourceName) + defer locks.UnlockByName(name, logicAppResourceName) resp, err := client.Delete(ctx, resourceGroup, name) if err != nil { diff --git a/azurerm/resource_arm_logic_app_workflow_test.go b/azurerm/resource_arm_logic_app_workflow_test.go index 4241bb9f5c89..b2c9930a7058 100644 --- a/azurerm/resource_arm_logic_app_workflow_test.go +++ b/azurerm/resource_arm_logic_app_workflow_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMLogicAppWorkflow_empty(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMLogicAppWorkflow_empty(t *testing.T) { } func TestAccAzureRMLogicAppWorkflow_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -117,7 +118,7 @@ func testCheckAzureRMLogicAppWorkflowExists(resourceName string) resource.TestCh return fmt.Errorf("Bad: no resource group found in state for Logic App Workflow: %s", workflowName) } - client := testAccProvider.Meta().(*ArmClient).logicWorkflowsClient + client := testAccProvider.Meta().(*ArmClient).logic.WorkflowsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, workflowName) @@ -134,7 +135,7 @@ func testCheckAzureRMLogicAppWorkflowExists(resourceName string) resource.TestCh } func testCheckAzureRMLogicAppWorkflowDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).logicWorkflowsClient + client := testAccProvider.Meta().(*ArmClient).logic.WorkflowsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_managed_disk.go b/azurerm/resource_arm_managed_disk.go index ae150a5cc8e5..612654300d02 100644 --- a/azurerm/resource_arm_managed_disk.go +++ b/azurerm/resource_arm_managed_disk.go @@ -8,9 +8,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,11 +35,11 @@ func resourceArmManagedDisk() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "zones": singleZonesSchema(), + "zones": azure.SchemaSingleZone(), "storage_account_type": { Type: schema.TypeString, @@ -59,6 +62,7 @@ func resourceArmManagedDisk() *schema.Resource { string(compute.Empty), string(compute.FromImage), string(compute.Import), + string(compute.Restore), }, true), }, @@ -99,7 +103,7 @@ func resourceArmManagedDisk() *schema.Resource { "encryption_settings": encryptionSettingsSchema(), - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } @@ -114,7 +118,7 @@ func validateDiskSizeGB(v interface{}, _ string) (warnings []string, errors []er } func resourceArmManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).diskClient + client := meta.(*ArmClient).compute.DisksClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ARM Managed Disk creation.") @@ -122,7 +126,7 @@ func resourceArmManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{} name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -135,12 +139,12 @@ func resourceArmManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{} } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) storageAccountType := d.Get("storage_account_type").(string) osType := d.Get("os_type").(string) - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) - zones := expandZones(d.Get("zones").([]interface{})) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) + zones := azure.ExpandZones(d.Get("zones").([]interface{})) var skuName compute.DiskStorageAccountTypes if strings.EqualFold(storageAccountType, string(compute.PremiumLRS)) { @@ -149,6 +153,8 @@ func resourceArmManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{} skuName = compute.StandardLRS } else if strings.EqualFold(storageAccountType, string(compute.StandardSSDLRS)) { skuName = compute.StandardSSDLRS + } else if strings.EqualFold(storageAccountType, string(compute.UltraSSDLRS)) { + skuName = compute.UltraSSDLRS } createDisk := compute.Disk{ @@ -180,7 +186,7 @@ func resourceArmManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{} } else { return fmt.Errorf("[ERROR] source_uri must be specified when create_option is `%s`", compute.Import) } - } else if strings.EqualFold(createOption, string(compute.Copy)) { + } else if strings.EqualFold(createOption, string(compute.Copy)) || strings.EqualFold(createOption, string(compute.Restore)) { if sourceResourceId := d.Get("source_resource_id").(string); sourceResourceId != "" { createDisk.CreationData.SourceResourceID = &sourceResourceId } else { @@ -225,10 +231,10 @@ func resourceArmManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{} } func resourceArmManagedDiskRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).diskClient + client := meta.(*ArmClient).compute.DisksClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -249,7 +255,7 @@ func resourceArmManagedDiskRead(d *schema.ResourceData, meta interface{}) error d.Set("zones", resp.Zones) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { @@ -276,16 +282,14 @@ func resourceArmManagedDiskRead(d *schema.ResourceData, meta interface{}) error } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmManagedDiskDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).diskClient + client := meta.(*ArmClient).compute.DisksClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_managed_disk_test.go b/azurerm/resource_arm_managed_disk_test.go index 439ae7f65e09..b95c1d4c6252 100644 --- a/azurerm/resource_arm_managed_disk_test.go +++ b/azurerm/resource_arm_managed_disk_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMManagedDisk_empty(t *testing.T) { @@ -39,7 +40,7 @@ func TestAccAzureRMManagedDisk_empty(t *testing.T) { } func TestAccAzureRMManagedDisk_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -288,7 +289,7 @@ func testCheckAzureRMManagedDiskExists(resourceName string, d *compute.Disk, sho return fmt.Errorf("Bad: no resource group found in state for disk: %s", dName) } - client := testAccProvider.Meta().(*ArmClient).diskClient + client := testAccProvider.Meta().(*ArmClient).compute.DisksClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, dName) @@ -310,7 +311,7 @@ func testCheckAzureRMManagedDiskExists(resourceName string, d *compute.Disk, sho } func testCheckAzureRMManagedDiskDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).diskClient + client := testAccProvider.Meta().(*ArmClient).compute.DisksClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -348,7 +349,7 @@ func testDeleteAzureRMVirtualMachine(resourceName string) resource.TestCheckFunc return fmt.Errorf("Bad: no resource group found in state for virtual machine: %s", vmName) } - client := testAccProvider.Meta().(*ArmClient).vmClient + client := testAccProvider.Meta().(*ArmClient).compute.VMClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, vmName) diff --git a/azurerm/resource_arm_management_group.go b/azurerm/resource_arm_management_group.go index 3cda20326707..2f41e5c174b4 100644 --- a/azurerm/resource_arm_management_group.go +++ b/azurerm/resource_arm_management_group.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -56,8 +57,8 @@ func resourceArmManagementGroup() *schema.Resource { } func resourceArmManagementGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).managementGroupsClient - subscriptionsClient := meta.(*ArmClient).managementGroupsSubscriptionClient + client := meta.(*ArmClient).managementGroups.GroupsClient + subscriptionsClient := meta.(*ArmClient).managementGroups.SubscriptionClient ctx := meta.(*ArmClient).StopContext armTenantID := meta.(*ArmClient).tenantId @@ -72,7 +73,7 @@ func resourceArmManagementGroupCreateUpdate(d *schema.ResourceData, meta interfa } recurse := false - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, groupId, "children", &recurse, "", managementGroupCacheControl) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -156,7 +157,7 @@ func resourceArmManagementGroupCreateUpdate(d *schema.ResourceData, meta interfa } func resourceArmManagementGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).managementGroupsClient + client := meta.(*ArmClient).managementGroups.GroupsClient ctx := meta.(*ArmClient).StopContext id, err := parseManagementGroupId(d.Id()) @@ -203,8 +204,8 @@ func resourceArmManagementGroupRead(d *schema.ResourceData, meta interface{}) er } func resourceArmManagementGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).managementGroupsClient - subscriptionsClient := meta.(*ArmClient).managementGroupsSubscriptionClient + client := meta.(*ArmClient).managementGroups.GroupsClient + subscriptionsClient := meta.(*ArmClient).managementGroups.SubscriptionClient ctx := meta.(*ArmClient).StopContext id, err := parseManagementGroupId(d.Id()) diff --git a/azurerm/resource_arm_management_group_test.go b/azurerm/resource_arm_management_group_test.go index 0f73fef6ee3e..8fd07043e99a 100644 --- a/azurerm/resource_arm_management_group_test.go +++ b/azurerm/resource_arm_management_group_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMManagementGroup_basic(t *testing.T) { @@ -35,7 +36,7 @@ func TestAccAzureRMManagementGroup_basic(t *testing.T) { } func TestAccAzureRMManagementGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -219,7 +220,7 @@ func testCheckAzureRMManagementGroupExists(resourceName string) resource.TestChe groupName := rs.Primary.Attributes["group_id"] - client := testAccProvider.Meta().(*ArmClient).managementGroupsClient + client := testAccProvider.Meta().(*ArmClient).managementGroups.GroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext recurse := false @@ -237,7 +238,7 @@ func testCheckAzureRMManagementGroupExists(resourceName string) resource.TestChe } func testCheckAzureRMManagementGroupDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).managementGroupsClient + client := testAccProvider.Meta().(*ArmClient).managementGroups.GroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_management_lock.go b/azurerm/resource_arm_management_lock.go index f8222082384a..80e8f04e6330 100644 --- a/azurerm/resource_arm_management_lock.go +++ b/azurerm/resource_arm_management_lock.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -57,14 +58,14 @@ func resourceArmManagementLock() *schema.Resource { } func resourceArmManagementLockCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).managementLocksClient + client := meta.(*ArmClient).resource.LocksClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Management Lock creation.") name := d.Get("name").(string) scope := d.Get("scope").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.GetByScope(ctx, scope, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -105,7 +106,7 @@ func resourceArmManagementLockCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmManagementLockRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).managementLocksClient + client := meta.(*ArmClient).resource.LocksClient ctx := meta.(*ArmClient).StopContext id, err := parseAzureRMLockId(d.Id()) @@ -134,7 +135,7 @@ func resourceArmManagementLockRead(d *schema.ResourceData, meta interface{}) err } func resourceArmManagementLockDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).managementLocksClient + client := meta.(*ArmClient).resource.LocksClient ctx := meta.(*ArmClient).StopContext id, err := parseAzureRMLockId(d.Id()) diff --git a/azurerm/resource_arm_management_lock_test.go b/azurerm/resource_arm_management_lock_test.go index e3e406dbd044..86222d63a9b6 100644 --- a/azurerm/resource_arm_management_lock_test.go +++ b/azurerm/resource_arm_management_lock_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -67,7 +68,7 @@ func TestAccAzureRMManagementLock_resourceGroupReadOnlyBasic(t *testing.T) { } func TestAccAzureRMManagementLock_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -296,7 +297,7 @@ func testCheckAzureRMManagementLockExists(resourceName string) resource.TestChec name := rs.Primary.Attributes["name"] scope := rs.Primary.Attributes["scope"] - client := testAccProvider.Meta().(*ArmClient).managementLocksClient + client := testAccProvider.Meta().(*ArmClient).resource.LocksClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.GetByScope(ctx, scope, name) @@ -313,7 +314,7 @@ func testCheckAzureRMManagementLockExists(resourceName string) resource.TestChec } func testCheckAzureRMManagementLockDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).managementLocksClient + client := testAccProvider.Meta().(*ArmClient).resource.LocksClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_maps_account.go b/azurerm/resource_arm_maps_account.go new file mode 100644 index 000000000000..3ae74ca2aba0 --- /dev/null +++ b/azurerm/resource_arm_maps_account.go @@ -0,0 +1,176 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/maps/mgmt/2018-05-01/maps" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + mapsint "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/maps" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmMapsAccount() *schema.Resource { + return &schema.Resource{ + Create: resourceArmMapsAccountCreateUpdate, + Read: resourceArmMapsAccountRead, + Update: resourceArmMapsAccountCreateUpdate, + Delete: resourceArmMapsAccountDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: mapsint.ValidateName(), + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "sku_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + "s0", + "s1", + }, false), + }, + + "tags": tags.Schema(), + + "x_ms_client_id": { + Type: schema.TypeString, + Computed: true, + }, + + "primary_access_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + + "secondary_access_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, + } +} + +func resourceArmMapsAccountCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).maps.AccountsClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for AzureRM Maps Account creation.") + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + t := d.Get("tags").(map[string]interface{}) + sku := d.Get("sku_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Maps Account %q (Resource Group %q): %+v", name, resGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_maps_account", *existing.ID) + } + } + + parameters := maps.AccountCreateParameters{ + Location: utils.String("global"), + Sku: &maps.Sku{ + Name: &sku, + }, + Tags: tags.Expand(t), + } + + if _, err := client.CreateOrUpdate(ctx, resGroup, name, parameters); err != nil { + return fmt.Errorf("Error creating/updating Maps Account %q (Resource Group %q) %+v", name, resGroup, err) + } + + read, err := client.Get(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving Maps Account %q (Resource Group %q) %+v", name, resGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read Maps Account %q (Resource Group %q) ID", name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmMapsAccountRead(d, meta) +} + +func resourceArmMapsAccountRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).maps.AccountsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["accounts"] + + resp, err := client.Get(ctx, resGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Maps Account %q (Resource Group %q): %+v", name, resGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + if sku := resp.Sku; sku != nil { + d.Set("sku_name", sku.Name) + } + if props := resp.Properties; props != nil { + d.Set("x_ms_client_id", props.XMsClientID) + } + + keysResp, err := client.ListKeys(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error making Read Access Keys request on Maps Account %q (Resource Group %q): %+v", name, resGroup, err) + } + d.Set("primary_access_key", keysResp.PrimaryKey) + d.Set("secondary_access_key", keysResp.SecondaryKey) + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmMapsAccountDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).maps.AccountsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["accounts"] + + if _, err := client.Delete(ctx, resGroup, name); err != nil { + return fmt.Errorf("Error deleting Maps Account %q (Resource Group %q): %+v", name, resGroup, err) + } + + return nil +} diff --git a/azurerm/resource_arm_maps_account_test.go b/azurerm/resource_arm_maps_account_test.go new file mode 100644 index 000000000000..faabadb013e0 --- /dev/null +++ b/azurerm/resource_arm_maps_account_test.go @@ -0,0 +1,209 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMMapsAccount_basic(t *testing.T) { + resourceName := "azurerm_maps_account.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMapsAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMapsAccount_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(resourceName, "name"), + resource.TestCheckResourceAttrSet(resourceName, "x_ms_client_id"), + resource.TestCheckResourceAttrSet(resourceName, "primary_access_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_access_key"), + resource.TestCheckResourceAttr(resourceName, "sku_name", "s0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMMapsAccount_sku(t *testing.T) { + resourceName := "azurerm_maps_account.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMapsAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMapsAccount_sku(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(resourceName, "name"), + resource.TestCheckResourceAttrSet(resourceName, "x_ms_client_id"), + resource.TestCheckResourceAttrSet(resourceName, "primary_access_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_access_key"), + resource.TestCheckResourceAttr(resourceName, "sku_name", "s1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMMapsAccount_tags(t *testing.T) { + resourceName := "azurerm_maps_account.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMapsAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMapsAccount_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMapsAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMMapsAccount_tags(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMapsAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "testing"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMMapsAccountExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + mapsAccountName := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + client := testAccProvider.Meta().(*ArmClient).maps.AccountsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, mapsAccountName) + if err != nil { + return fmt.Errorf("Bad: Get on MapsAccountClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Maps Account %q (resource group: %q) does not exist", mapsAccountName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMMapsAccountDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).maps.AccountsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_maps_account" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return fmt.Errorf("Error retrieving Maps Account %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + return nil + +} + +func testAccAzureRMMapsAccount_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_maps_account" "test" { + name = "accMapsAccount-%d" + resource_group_name = azurerm_resource_group.test.name + sku_name = "s0" +} +`, rInt, location, rInt) +} + +func testAccAzureRMMapsAccount_sku(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_maps_account" "test" { + name = "accMapsAccount-%d" + resource_group_name = azurerm_resource_group.test.name + sku_name = "s1" +} +`, rInt, location, rInt) +} + +func testAccAzureRMMapsAccount_tags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_maps_account" "test" { + name = "accMapsAccount-%d" + resource_group_name = azurerm_resource_group.test.name + sku_name = "s0" + + tags = { + environment = "testing" + } +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_mariadb_configuration.go b/azurerm/resource_arm_mariadb_configuration.go new file mode 100644 index 000000000000..21d5f4b2e982 --- /dev/null +++ b/azurerm/resource_arm_mariadb_configuration.go @@ -0,0 +1,155 @@ +package azurerm + +import ( + "fmt" + "log" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmMariaDbConfiguration() *schema.Resource { + return &schema.Resource{ + Create: resourceArmMariaDbConfigurationCreateUpdate, + Read: resourceArmMariaDbConfigurationRead, + Delete: resourceArmMariaDbConfigurationDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.NoZeroValues, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "server_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile("^[-a-zA-Z0-9]{3,50}$"), + "server_name must be 3 - 50 characters long, and contain only letters, numbers and hyphens", + ), + }, + + "value": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceArmMariaDbConfigurationCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for AzureRM MariaDb Configuration creation.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + serverName := d.Get("server_name").(string) + value := d.Get("value").(string) + + properties := mariadb.Configuration{ + ConfigurationProperties: &mariadb.ConfigurationProperties{ + Value: utils.String(value), + }, + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, serverName, name, properties) + if err != nil { + return fmt.Errorf("Error issuing create/update request for MariaDb Configuration %s (resource group %s, server name %s): %v", name, resourceGroup, serverName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for create/update of MariaDb Configuration %s (resource group %s, server name %s): %v", name, resourceGroup, serverName, err) + } + + read, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + return fmt.Errorf("Error issuing get request for MariaDb Configuration %s (resource group %s, server name %s): %v", name, resourceGroup, serverName, err) + } + if read.ID == nil { + return fmt.Errorf("Cannot read MariaDb Configuration %s (resource group %s, server name %s) ID", name, resourceGroup, serverName) + } + + d.SetId(*read.ID) + + return resourceArmMariaDbConfigurationRead(d, meta) +} + +func resourceArmMariaDbConfigurationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["configurations"] + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[WARN] MariaDb Configuration %q was not found (resource group %q)", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Azure MariaDb Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("server_name", serverName) + d.Set("resource_group_name", resourceGroup) + d.Set("value", resp.ConfigurationProperties.Value) + + return nil +} + +func resourceArmMariaDbConfigurationDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.ConfigurationsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["configurations"] + + // "delete" = resetting this to the default value + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + return fmt.Errorf("Error retrieving MariaDb Configuration %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + properties := mariadb.Configuration{ + ConfigurationProperties: &mariadb.ConfigurationProperties{ + // we can alternatively set `source: "system-default"` + Value: resp.DefaultValue, + }, + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, serverName, name, properties) + if err != nil { + return err + } + + return future.WaitForCompletionRef(ctx, client.Client) +} diff --git a/azurerm/resource_arm_mariadb_configuration_test.go b/azurerm/resource_arm_mariadb_configuration_test.go new file mode 100644 index 000000000000..1e6e131ef145 --- /dev/null +++ b/azurerm/resource_arm_mariadb_configuration_test.go @@ -0,0 +1,252 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMMariaDbConfiguration_characterSetServer(t *testing.T) { + resourceName := "azurerm_mariadb_configuration.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDbConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDbConfiguration_characterSetServer(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDbConfigurationValue(resourceName, "hebrew"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMMariaDbConfiguration_empty(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + // "delete" resets back to the default value + testCheckAzureRMMariaDbConfigurationValueReset(ri, "character_set_server"), + ), + }, + }, + }) +} + +func TestAccAzureRMMariaDbConfiguration_interactiveTimeout(t *testing.T) { + resourceName := "azurerm_mariadb_configuration.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDbConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDbConfiguration_interactiveTimeout(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDbConfigurationValue(resourceName, "30"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMMariaDbConfiguration_empty(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + // "delete" resets back to the default value + testCheckAzureRMMariaDbConfigurationValueReset(ri, "interactive_timeout"), + ), + }, + }, + }) +} + +func TestAccAzureRMMariaDbConfiguration_logSlowAdminStatements(t *testing.T) { + resourceName := "azurerm_mariadb_configuration.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDbConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDbConfiguration_logSlowAdminStatements(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDbConfigurationValue(resourceName, "on"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMMariaDbConfiguration_empty(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + // "delete" resets back to the default value + testCheckAzureRMMariaDbConfigurationValueReset(ri, "log_slow_admin_statements"), + ), + }, + }, + }) +} + +func testCheckAzureRMMariaDbConfigurationValue(resourceName string, value string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + serverName := rs.Primary.Attributes["server_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for MariaDb Configuration: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).mariadb.ConfigurationsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: MariaDb Configuration %q (server %q resource group: %q) does not exist", name, serverName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on mariadbConfigurationsClient: %+v", err) + } + + if *resp.Value != value { + return fmt.Errorf("MariaDb Configuration wasn't set. Expected '%s' - got '%s': \n%+v", value, *resp.Value, resp) + } + + return nil + } +} + +func testCheckAzureRMMariaDbConfigurationValueReset(rInt int, configurationName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + + resourceGroup := fmt.Sprintf("acctestRG-%d", rInt) + serverName := fmt.Sprintf("acctestmariadbsvr-%d", rInt) + + client := testAccProvider.Meta().(*ArmClient).mariadb.ConfigurationsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, configurationName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: MariaDb Configuration %q (server %q resource group: %q) does not exist", configurationName, serverName, resourceGroup) + } + return fmt.Errorf("Bad: Get on mariadbConfigurationsClient: %+v", err) + } + + actualValue := *resp.Value + defaultValue := *resp.DefaultValue + + if defaultValue != actualValue { + return fmt.Errorf("MariaDb Configuration wasn't set to the default value. Expected '%s' - got '%s': \n%+v", defaultValue, actualValue, resp) + } + + return nil + } +} + +func testCheckAzureRMMariaDbConfigurationDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).mariadb.ConfigurationsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_mariadb_configuration" { + continue + } + + name := rs.Primary.Attributes["name"] + serverName := rs.Primary.Attributes["server_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + } + + return nil +} + +func testAccAzureRMMariaDbConfiguration_characterSetServer(rInt int, location string) string { + return testAccAzureRMMariaDbConfiguration_template(rInt, location, "character_set_server", "hebrew") +} + +func testAccAzureRMMariaDbConfiguration_interactiveTimeout(rInt int, location string) string { + return testAccAzureRMMariaDbConfiguration_template(rInt, location, "interactive_timeout", "30") +} + +func testAccAzureRMMariaDbConfiguration_logSlowAdminStatements(rInt int, location string) string { + return testAccAzureRMMariaDbConfiguration_template(rInt, location, "log_slow_admin_statements", "on") +} + +func testAccAzureRMMariaDbConfiguration_template(rInt int, location string, name string, value string) string { + server := testAccAzureRMMariaDbConfiguration_empty(rInt, location) + config := fmt.Sprintf(` +resource "azurerm_mariadb_configuration" "test" { + name = "%s" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + value = "%s" +} +`, name, value) + return server + config +} + +func testAccAzureRMMariaDbConfiguration_empty(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } + + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "10.2" + ssl_enforcement = "Enabled" +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_mariadb_database.go b/azurerm/resource_arm_mariadb_database.go index 75297e3bb696..563b81abc068 100644 --- a/azurerm/resource_arm_mariadb_database.go +++ b/azurerm/resource_arm_mariadb_database.go @@ -5,11 +5,14 @@ import ( "log" "regexp" - "github.com/Azure/azure-sdk-for-go/services/preview/mariadb/mgmt/2018-06-01-preview/mariadb" + "github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -33,7 +36,7 @@ func resourceArmMariaDbDatabase() *schema.Resource { ), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -59,14 +62,14 @@ func resourceArmMariaDbDatabase() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validateCollation(), + ValidateFunc: validate.DatabaseCollation, }, }, } } func resourceArmMariaDbDatabaseCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mariadbDatabasesClient + client := meta.(*ArmClient).mariadb.DatabasesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM MariaDB database creation") @@ -75,7 +78,7 @@ func resourceArmMariaDbDatabaseCreateUpdate(d *schema.ResourceData, meta interfa resourceGroup := d.Get("resource_group_name").(string) serverName := d.Get("server_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -121,10 +124,10 @@ func resourceArmMariaDbDatabaseCreateUpdate(d *schema.ResourceData, meta interfa } func resourceArmMariaDbDatabaseRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mariadbDatabasesClient + client := meta.(*ArmClient).mariadb.DatabasesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return fmt.Errorf("cannot parse MariaDB database %q ID:\n%+v", d.Id(), err) } @@ -156,10 +159,10 @@ func resourceArmMariaDbDatabaseRead(d *schema.ResourceData, meta interface{}) er } func resourceArmMariaDbDatabaseDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mariadbDatabasesClient + client := meta.(*ArmClient).mariadb.DatabasesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return fmt.Errorf("cannot parse MariaDB database %q ID:\n%+v", d.Id(), err) } diff --git a/azurerm/resource_arm_mariadb_database_test.go b/azurerm/resource_arm_mariadb_database_test.go index 77fad770c357..4789c83ff335 100644 --- a/azurerm/resource_arm_mariadb_database_test.go +++ b/azurerm/resource_arm_mariadb_database_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +39,7 @@ func TestAccAzureRMMariaDbDatabase_basic(t *testing.T) { } func TestAccAzureRMMariaDbDatabase_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -81,7 +82,7 @@ func testCheckAzureRMMariaDbDatabaseExists(resourceName string) resource.TestChe return fmt.Errorf("bad: no resource group found in state for MariaDB database: %q", name) } - client := testAccProvider.Meta().(*ArmClient).mariadbDatabasesClient + client := testAccProvider.Meta().(*ArmClient).mariadb.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, name) @@ -97,7 +98,7 @@ func testCheckAzureRMMariaDbDatabaseExists(resourceName string) resource.TestChe } func testCheckAzureRMMariaDbDatabaseDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).mariadbDatabasesClient + client := testAccProvider.Meta().(*ArmClient).mariadb.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_mariadb_firewall_rule.go b/azurerm/resource_arm_mariadb_firewall_rule.go new file mode 100644 index 000000000000..d020188b74b4 --- /dev/null +++ b/azurerm/resource_arm_mariadb_firewall_rule.go @@ -0,0 +1,160 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmMariaDBFirewallRule() *schema.Resource { + return &schema.Resource{ + Create: resourceArmMariaDBFirewallRuleCreateUpdate, + Read: resourceArmMariaDBFirewallRuleRead, + Update: resourceArmMariaDBFirewallRuleCreateUpdate, + Delete: resourceArmMariaDBFirewallRuleDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.MariaDBFirewallRuleName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "server_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.MariaDBServerName, + }, + + "start_ip_address": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.IPv4Address, + }, + + "end_ip_address": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.IPv4Address, + }, + }, + } +} + +func resourceArmMariaDBFirewallRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.FirewallRulesClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for AzureRM MariaDB Firewall Rule creation.") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + serverName := d.Get("server_name").(string) + startIPAddress := d.Get("start_ip_address").(string) + endIPAddress := d.Get("end_ip_address").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing MariaDB Firewall Rule %q (resource group %q, server name %q): %v", name, resourceGroup, serverName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_mariadb_firewall_rule", *existing.ID) + } + } + + properties := mariadb.FirewallRule{ + FirewallRuleProperties: &mariadb.FirewallRuleProperties{ + StartIPAddress: utils.String(startIPAddress), + EndIPAddress: utils.String(endIPAddress), + }, + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, serverName, name, properties) + if err != nil { + return fmt.Errorf("Error issuing create/update request for MariaDB Firewall Rule %q (resource group %q, server name %q): %v", name, resourceGroup, serverName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting onf create/update future for MariaDB Firewall Rule %q (resource group %q, server name %q): %v", name, resourceGroup, serverName, err) + } + + read, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + return fmt.Errorf("Error issuing get request for MariaDB Firewall Rule %q (resource group %q, server name %q): %v", name, resourceGroup, serverName, err) + } + if read.ID == nil { + return fmt.Errorf("Cannot read MariaDB Firewall Rule %q (Gesource Group %q) ID", name, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmMariaDBFirewallRuleRead(d, meta) +} + +func resourceArmMariaDBFirewallRuleRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.FirewallRulesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["firewallRules"] + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on Azure MariaDB Firewall Rule %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("server_name", serverName) + d.Set("start_ip_address", resp.StartIPAddress) + d.Set("end_ip_address", resp.EndIPAddress) + + return nil +} + +func resourceArmMariaDBFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.FirewallRulesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["firewallRules"] + + future, err := client.Delete(ctx, resourceGroup, serverName, name) + if err != nil { + return err + } + + return future.WaitForCompletionRef(ctx, client.Client) +} diff --git a/azurerm/resource_arm_mariadb_firewall_rule_test.go b/azurerm/resource_arm_mariadb_firewall_rule_test.go new file mode 100644 index 000000000000..aa87486040d5 --- /dev/null +++ b/azurerm/resource_arm_mariadb_firewall_rule_test.go @@ -0,0 +1,176 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMMariaDBFirewallRule_basic(t *testing.T) { + resourceName := "azurerm_mariadb_firewall_rule.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBFirewallRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDBFirewallRule_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBFirewallRuleExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMMariaDBFirewallRule_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_mariadb_firewall_rule.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBFirewallRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDBFirewallRule_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBFirewallRuleExists(resourceName), + ), + }, + { + Config: testAccAzureRMMariaDBFirewallRule_requiresImport(ri, testLocation()), + ExpectError: testRequiresImportError("azurerm_mariadb_firewall_rule"), + }, + }, + }) +} + +func testCheckAzureRMMariaDBFirewallRuleExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + serverName := rs.Primary.Attributes["server_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for MariaDB Firewall Rule: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).mariadb.FirewallRulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: MariaDB Firewall Rule %q (server %q resource group: %q) does not exist", name, serverName, resourceGroup) + } + return fmt.Errorf("Bad: Get on mariadbFirewallRulesClient: %s", err) + } + + return nil + } +} + +func testCheckAzureRMMariaDBFirewallRuleDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).mariadb.DatabasesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_mariadb_firewall_rule" { + continue + } + + name := rs.Primary.Attributes["name"] + serverName := rs.Primary.Attributes["server_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return fmt.Errorf("MariaDB Firewall Rule still exists:\n%#v", resp) + } + } + + return nil +} + +func testAccAzureRMMariaDBFirewallRule_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } + + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "10.2" + ssl_enforcement = "Enabled" +} + +resource "azurerm_mariadb_firewall_rule" "test" { + name = "acctestfwrule-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + start_ip_address = "0.0.0.0" + end_ip_address = "255.255.255.255" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMMariaDBFirewallRule_requiresImport(rInt int, location string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_mariadb_firewall_rule" "import" { + name = "${azurerm_mariadb_firewall_rule.test.name}" + resource_group_name = "${azurerm_mariadb_firewall_rule.test.resource_group_name}" + server_name = "${azurerm_mariadb_firewall_rule.test.server_name}" + start_ip_address = "${azurerm_mariadb_firewall_rule.test.start_ip_address}" + end_ip_address = "${azurerm_mariadb_firewall_rule.test.end_ip_address}" +} +`, testAccAzureRMMariaDBFirewallRule_basic(rInt, location)) +} diff --git a/azurerm/resource_arm_mariadb_server.go b/azurerm/resource_arm_mariadb_server.go index c730a76a84b4..91e0bb8738d4 100644 --- a/azurerm/resource_arm_mariadb_server.go +++ b/azurerm/resource_arm_mariadb_server.go @@ -7,10 +7,13 @@ import ( "strconv" "strings" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" - "github.com/Azure/azure-sdk-for-go/services/preview/mariadb/mgmt/2018-06-01-preview/mariadb" + "github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" @@ -38,9 +41,9 @@ func resourceArmMariaDbServer() *schema.Resource { ), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeList, @@ -120,6 +123,7 @@ func resourceArmMariaDbServer() *schema.Resource { ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ "10.2", + "10.3", }, false), }, @@ -167,13 +171,13 @@ func resourceArmMariaDbServer() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmMariaDbServerCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mariadbServersClient + client := meta.(*ArmClient).mariadb.ServersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM MariaDB Server creation.") @@ -181,7 +185,7 @@ func resourceArmMariaDbServerCreateUpdate(d *schema.ResourceData, meta interface name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -194,12 +198,12 @@ func resourceArmMariaDbServerCreateUpdate(d *schema.ResourceData, meta interface } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) adminLogin := d.Get("administrator_login").(string) adminLoginPassword := d.Get("administrator_login_password").(string) sslEnforcement := d.Get("ssl_enforcement").(string) version := d.Get("version").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) sku := expandAzureRmMariaDbServerSku(d) storageProfile := expandAzureRmMariaDbStorageProfile(d) @@ -267,7 +271,7 @@ func resourceArmMariaDbServerCreateUpdate(d *schema.ResourceData, meta interface CreateMode: mariadb.CreateModeDefault, }, Sku: sku, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.Create(ctx, resourceGroup, name, properties) @@ -294,10 +298,10 @@ func resourceArmMariaDbServerCreateUpdate(d *schema.ResourceData, meta interface } func resourceArmMariaDbServerRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mariadbServersClient + client := meta.(*ArmClient).mariadb.ServersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -319,7 +323,7 @@ func resourceArmMariaDbServerRead(d *schema.ResourceData, meta interface{}) erro d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if properties := resp.ServerProperties; properties != nil { @@ -338,16 +342,14 @@ func resourceArmMariaDbServerRead(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("Error setting `sku`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmMariaDbServerDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mariadbServersClient + client := meta.(*ArmClient).mariadb.ServersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_mariadb_server_test.go b/azurerm/resource_arm_mariadb_server_test.go index f1112aac062c..9cace7b2a28f 100644 --- a/azurerm/resource_arm_mariadb_server_test.go +++ b/azurerm/resource_arm_mariadb_server_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -42,7 +43,7 @@ func TestAccAzureRMMariaDbServer_basic(t *testing.T) { } func TestAccAzureRMMariaDbServer_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -277,7 +278,7 @@ func testCheckAzureRMMariaDbServerExists(resourceName string) resource.TestCheck return fmt.Errorf("Bad: no resource group found in state for MariaDB Server: %s", name) } - client := testAccProvider.Meta().(*ArmClient).mariadbServersClient + client := testAccProvider.Meta().(*ArmClient).mariadb.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -294,7 +295,7 @@ func testCheckAzureRMMariaDbServerExists(resourceName string) resource.TestCheck } func testCheckAzureRMMariaDbServerDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).mariadbServersClient + client := testAccProvider.Meta().(*ArmClient).mariadb.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_mariadb_virtual_network_rule.go b/azurerm/resource_arm_mariadb_virtual_network_rule.go new file mode 100644 index 000000000000..653cb0c1a3aa --- /dev/null +++ b/azurerm/resource_arm_mariadb_virtual_network_rule.go @@ -0,0 +1,243 @@ +package azurerm + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmMariaDbVirtualNetworkRule() *schema.Resource { + return &schema.Resource{ + Create: resourceArmMariaDbVirtualNetworkRuleCreateUpdate, + Read: resourceArmMariaDbVirtualNetworkRuleRead, + Update: resourceArmMariaDbVirtualNetworkRuleCreateUpdate, + Delete: resourceArmMariaDbVirtualNetworkRuleDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.VirtualNetworkRuleName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "server_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "subnet_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + }, + } +} + +func resourceArmMariaDbVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + serverName := d.Get("server_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + subnetId := d.Get("subnet_id").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_mariadb_virtual_network_rule", *existing.ID) + } + } + + // due to a bug in the API we have to ensure the Subnet's configured correctly or the API call will timeout + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3719 + subnetsClient := meta.(*ArmClient).network.SubnetsClient + subnetParsedId, err := azure.ParseAzureResourceID(subnetId) + if err != nil { + return err + } + + subnetResourceGroup := subnetParsedId.ResourceGroup + virtualNetwork := subnetParsedId.Path["virtualNetworks"] + subnetName := subnetParsedId.Path["subnets"] + subnet, err := subnetsClient.Get(ctx, subnetResourceGroup, virtualNetwork, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(subnet.Response) { + return fmt.Errorf("Subnet with ID %q was not found: %+v", subnetId, err) + } + + return fmt.Errorf("Error obtaining Subnet %q (Virtual Network %q / Resource Group %q: %+v", subnetName, virtualNetwork, subnetResourceGroup, err) + } + + containsEndpoint := false + if props := subnet.SubnetPropertiesFormat; props != nil { + if endpoints := props.ServiceEndpoints; endpoints != nil { + for _, e := range *endpoints { + if e.Service == nil { + continue + } + + if strings.EqualFold(*e.Service, "Microsoft.Sql") { + containsEndpoint = true + break + } + } + } + } + + if !containsEndpoint { + return fmt.Errorf("Error creating MariaDb Virtual Network Rule: Subnet %q (Virtual Network %q / Resource Group %q) must contain a Service Endpoint for `Microsoft.Sql`", subnetName, virtualNetwork, subnetResourceGroup) + } + + parameters := mariadb.VirtualNetworkRule{ + VirtualNetworkRuleProperties: &mariadb.VirtualNetworkRuleProperties{ + VirtualNetworkSubnetID: utils.String(subnetId), + IgnoreMissingVnetServiceEndpoint: utils.Bool(false), + }, + } + + if _, err = client.CreateOrUpdate(ctx, resourceGroup, serverName, name, parameters); err != nil { + return fmt.Errorf("Error creating MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + //Wait for the provisioning state to become ready + log.Printf("[DEBUG] Waiting for MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) to become ready: %+v", name, serverName, resourceGroup, err) + stateConf := &resource.StateChangeConf{ + Pending: []string{"Initializing", "InProgress", "Unknown", "ResponseNotFound"}, + Target: []string{"Ready"}, + Refresh: MariaDbVirtualNetworkStateStatusCodeRefreshFunc(ctx, client, resourceGroup, serverName, name), + Timeout: 30 * time.Minute, + MinTimeout: 1 * time.Minute, + ContinuousTargetOccurence: 5, + } + + if _, err = stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) to be created or updated: %+v", name, serverName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + return fmt.Errorf("Error retrieving MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmMariaDbVirtualNetworkRuleRead(d, meta) +} + +func resourceArmMariaDbVirtualNetworkRuleRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["virtualNetworkRules"] + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading MariaDb Virtual Network Rule %q - removing from state", d.Id()) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading MariaDb Virtual Network Rule: %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("server_name", serverName) + + if props := resp.VirtualNetworkRuleProperties; props != nil { + d.Set("subnet_id", props.VirtualNetworkSubnetID) + } + + return nil +} + +func resourceArmMariaDbVirtualNetworkRuleDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["virtualNetworkRules"] + + future, err := client.Delete(ctx, resourceGroup, serverName, name) + if err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + + return fmt.Errorf("Error deleting MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error waiting for deletion of MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + } + + return nil +} + +func MariaDbVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client *mariadb.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + resp, err := client.Get(ctx, resourceGroup, serverName, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Retrieving MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) returned 404.", resourceGroup, serverName, name) + return nil, "ResponseNotFound", nil + } + + return nil, "", fmt.Errorf("Error polling for the state of the MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + if props := resp.VirtualNetworkRuleProperties; props != nil { + log.Printf("[DEBUG] Retrieving MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) returned Status %s", resourceGroup, serverName, name, props.State) + return resp, string(props.State), nil + } + + //Valid response was returned but VirtualNetworkRuleProperties was nil. Basically the rule exists, but with no properties for some reason. Assume Unknown instead of returning error. + log.Printf("[DEBUG] Retrieving MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) returned empty VirtualNetworkRuleProperties", resourceGroup, serverName, name) + return resp, "Unknown", nil + } +} diff --git a/azurerm/resource_arm_mariadb_virtual_network_rule_test.go b/azurerm/resource_arm_mariadb_virtual_network_rule_test.go new file mode 100644 index 000000000000..6159d23accb9 --- /dev/null +++ b/azurerm/resource_arm_mariadb_virtual_network_rule_test.go @@ -0,0 +1,517 @@ +package azurerm + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMMariaDBVirtualNetworkRule_basic(t *testing.T) { + resourceName := "azurerm_mariadb_virtual_network_rule.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDBVirtualNetworkRule_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + ), + }, + }, + }) +} + +func TestAccAzureRMMariaDBVirtualNetworkRule_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_mariadb_virtual_network_rule.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDBVirtualNetworkRule_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + ), + }, + { + Config: testAccAzureRMMariaDBVirtualNetworkRule_requiresImport(ri, testLocation()), + ExpectError: testRequiresImportError("azurerm_mariadb_virtual_network_rule"), + }, + }, + }) +} + +func TestAccAzureRMMariaDBVirtualNetworkRule_switchSubnets(t *testing.T) { + resourceName := "azurerm_mariadb_virtual_network_rule.test" + ri := tf.AccRandTimeInt() + + preConfig := testAccAzureRMMariaDBVirtualNetworkRule_subnetSwitchPre(ri, testLocation()) + postConfig := testAccAzureRMMariaDBVirtualNetworkRule_subnetSwitchPost(ri, testLocation()) + + // Create regex strings that will ensure that one subnet name exists, but not the other + preConfigRegex := regexp.MustCompile(fmt.Sprintf("(subnet1%d)$|(subnet[^2]%d)$", ri, ri)) //subnet 1 but not 2 + postConfigRegex := regexp.MustCompile(fmt.Sprintf("(subnet2%d)$|(subnet[^1]%d)$", ri, ri)) //subnet 2 but not 1 + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + resource.TestMatchResourceAttr(resourceName, "subnet_id", preConfigRegex), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + resource.TestMatchResourceAttr(resourceName, "subnet_id", postConfigRegex), + ), + }, + }, + }) +} + +func TestAccAzureRMMariaDBVirtualNetworkRule_disappears(t *testing.T) { + resourceName := "azurerm_mariadb_virtual_network_rule.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMMariaDBVirtualNetworkRule_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + testCheckAzureRMMariaDBVirtualNetworkRuleDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAzureRMMariaDBVirtualNetworkRule_multipleSubnets(t *testing.T) { + resourceName1 := "azurerm_mariadb_virtual_network_rule.rule1" + resourceName2 := "azurerm_mariadb_virtual_network_rule.rule2" + resourceName3 := "azurerm_mariadb_virtual_network_rule.rule3" + ri := tf.AccRandTimeInt() + config := testAccAzureRMMariaDBVirtualNetworkRule_multipleSubnets(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName1), + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName2), + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName3), + ), + }, + }, + }) +} + +func testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + ruleName := rs.Primary.Attributes["name"] + + client := testAccProvider.Meta().(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: MariaDB Virtual Network Rule %q (Server %q / Resource Group %q) was not found", ruleName, serverName, resourceGroup) + } + + return err + } + + return nil + } +} + +func testCheckAzureRMMariaDBVirtualNetworkRuleDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_mariadb_virtual_network_rule" { + continue + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + ruleName := rs.Primary.Attributes["name"] + + client := testAccProvider.Meta().(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return fmt.Errorf("Bad: MariaDB Firewall Rule %q (Server %q / Resource Group %q) still exists: %+v", ruleName, serverName, resourceGroup, resp) + } + + return nil +} + +func testCheckAzureRMMariaDBVirtualNetworkRuleDisappears(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + ruleName := rs.Primary.Attributes["name"] + + client := testAccProvider.Meta().(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + future, err := client.Delete(ctx, resourceGroup, serverName, ruleName) + if err != nil { + //If the error is that the resource we want to delete does not exist in the first + //place (404), then just return with no error. + if response.WasNotFound(future.Response()) { + return nil + } + + return fmt.Errorf("Error deleting MariaDB Virtual Network Rule: %+v", err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + //Same deal as before. Just in case. + if response.WasNotFound(future.Response()) { + return nil + } + + return fmt.Errorf("Error deleting MariaDB Virtual Network Rule: %+v", err) + } + + return nil + } +} + +func testAccAzureRMMariaDBVirtualNetworkRule_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvnet%d" + address_space = ["10.7.29.0/29"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.0/29" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "10.2" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "test" { + name = "acctestmariadbvnetrule%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.test.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMMariaDBVirtualNetworkRule_requiresImport(rInt int, location string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_mariadb_virtual_network_rule" "import" { + name = "${azurerm_mariadb_virtual_network_rule.test.name}" + resource_group_name = "${azurerm_mariadb_virtual_network_rule.test.resource_group_name}" + server_name = "${azurerm_mariadb_virtual_network_rule.test.server_name}" + subnet_id = "${azurerm_mariadb_virtual_network_rule.test.subnet_id}" +} +`, testAccAzureRMMariaDBVirtualNetworkRule_basic(rInt, location)) +} + +func testAccAzureRMMariaDBVirtualNetworkRule_subnetSwitchPre(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvnet%d" + address_space = ["10.7.29.0/24"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test1" { + name = "subnet1%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.0/25" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_subnet" "test2" { + name = "subnet2%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.128/25" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "10.2" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "test" { + name = "acctestmariadbvnetrule%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.test1.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMMariaDBVirtualNetworkRule_subnetSwitchPost(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvnet%d" + address_space = ["10.7.29.0/24"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test1" { + name = "subnet1%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.0/25" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_subnet" "test2" { + name = "subnet2%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.128/25" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "10.2" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "test" { + name = "acctestmariadbvnetrule%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.test2.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMMariaDBVirtualNetworkRule_multipleSubnets(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "vnet1" { + name = "acctestvnet1%d" + address_space = ["10.7.29.0/24"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_virtual_network" "vnet2" { + name = "acctestvnet2%d" + address_space = ["10.1.29.0/29"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "vnet1_subnet1" { + name = "acctestsubnet1%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.vnet1.name}" + address_prefix = "10.7.29.0/29" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_subnet" "vnet1_subnet2" { + name = "acctestsubnet2%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.vnet1.name}" + address_prefix = "10.7.29.128/29" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_subnet" "vnet2_subnet1" { + name = "acctestsubnet3%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.vnet2.name}" + address_prefix = "10.1.29.0/29" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "10.2" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "rule1" { + name = "acctestmariadbvnetrule1%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.vnet1_subnet1.id}" +} + +resource "azurerm_mariadb_virtual_network_rule" "rule2" { + name = "acctestmariadbvnetrule2%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.vnet1_subnet2.id}" +} + +resource "azurerm_mariadb_virtual_network_rule" "rule3" { + name = "acctestmariadbvnetrule3%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.vnet2_subnet1.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_media_services_account.go b/azurerm/resource_arm_media_services_account.go index a529a0f60f79..ed8c03d0163a 100644 --- a/azurerm/resource_arm_media_services_account.go +++ b/azurerm/resource_arm_media_services_account.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -34,9 +35,9 @@ func resourceArmMediaServicesAccount() *schema.Resource { ), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "storage_account": { Type: schema.TypeSet, @@ -60,17 +61,17 @@ func resourceArmMediaServicesAccount() *schema.Resource { // TODO: support Tags when this bug is fixed: // https://github.com/Azure/azure-rest-api-specs/issues/5249 - //"tags": tagsSchema(), + //"tags": tags.Schema(), }, } } func resourceArmMediaServicesAccountCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mediaServicesClient + client := meta.(*ArmClient).media.ServicesClient ctx := meta.(*ArmClient).StopContext accountName := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resourceGroup := d.Get("resource_group_name").(string) storageAccountsRaw := d.Get("storage_account").(*schema.Set).List() @@ -100,10 +101,10 @@ func resourceArmMediaServicesAccountCreateUpdate(d *schema.ResourceData, meta in } func resourceArmMediaServicesAccountRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mediaServicesClient + client := meta.(*ArmClient).media.ServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -125,7 +126,7 @@ func resourceArmMediaServicesAccountRead(d *schema.ResourceData, meta interface{ d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.ServiceProperties; props != nil { @@ -135,16 +136,14 @@ func resourceArmMediaServicesAccountRead(d *schema.ResourceData, meta interface{ } } - //flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmMediaServicesAccountDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mediaServicesClient + client := meta.(*ArmClient).media.ServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_media_services_account_test.go b/azurerm/resource_arm_media_services_account_test.go index 7939946246df..8791a6e56fb6 100644 --- a/azurerm/resource_arm_media_services_account_test.go +++ b/azurerm/resource_arm_media_services_account_test.go @@ -99,7 +99,7 @@ func testCheckAzureRMMediaServicesAccountExists(resourceName string) resource.Te return fmt.Errorf("Bad: no resource group found in state for Media Services Account: '%s'", name) } - conn := testAccProvider.Meta().(*ArmClient).mediaServicesClient + conn := testAccProvider.Meta().(*ArmClient).media.ServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) @@ -116,7 +116,7 @@ func testCheckAzureRMMediaServicesAccountExists(resourceName string) resource.Te } func testCheckAzureRMMediaServicesAccountDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).mediaServicesClient + conn := testAccProvider.Meta().(*ArmClient).media.ServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_metric_alertrule.go b/azurerm/resource_arm_metric_alertrule.go index 884022d624b4..57fa08457575 100644 --- a/azurerm/resource_arm_metric_alertrule.go +++ b/azurerm/resource_arm_metric_alertrule.go @@ -8,7 +8,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/monitor/mgmt/2018-03-01/insights" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,9 +41,9 @@ As such the existing 'azurerm_metric_alertrule' resource is deprecated and will ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "description": { Type: schema.TypeString, @@ -65,7 +70,7 @@ As such the existing 'azurerm_metric_alertrule' resource is deprecated and will "operator": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(insights.ConditionOperatorGreaterThan), string(insights.ConditionOperatorGreaterThanOrEqual), @@ -82,13 +87,13 @@ As such the existing 'azurerm_metric_alertrule' resource is deprecated and will "period": { Type: schema.TypeString, Required: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "aggregation": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(insights.TimeAggregationOperatorAverage), string(insights.TimeAggregationOperatorLast), @@ -158,7 +163,7 @@ As such the existing 'azurerm_metric_alertrule' resource is deprecated and will } func resourceArmMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorAlertRulesClient + client := meta.(*ArmClient).monitor.AlertRulesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Alert Rule creation.") @@ -166,7 +171,7 @@ func resourceArmMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta interfa name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -179,8 +184,8 @@ func resourceArmMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta interfa } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) alertRule, err := expandAzureRmMetricThresholdAlertRule(d) if err != nil { @@ -190,7 +195,7 @@ func resourceArmMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta interfa alertRuleResource := insights.AlertRuleResource{ Name: &name, Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), AlertRule: alertRule, } @@ -212,7 +217,7 @@ func resourceArmMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta interfa } func resourceArmMetricAlertRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorAlertRulesClient + client := meta.(*ArmClient).monitor.AlertRulesClient ctx := meta.(*ArmClient).StopContext resourceGroup, name, err := resourceGroupAndAlertRuleNameFromId(d.Id()) @@ -234,7 +239,7 @@ func resourceArmMetricAlertRuleRead(d *schema.ResourceData, meta interface{}) er d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if alertRule := resp.AlertRule; alertRule != nil { @@ -303,15 +308,13 @@ func resourceArmMetricAlertRuleRead(d *schema.ResourceData, meta interface{}) er } // Return a new tag map filtered by the specified tag names. - tagMap := filterTags(resp.Tags, "$type") + tagMap := tags.Filter(resp.Tags, "$type") - flattenAndSetTags(d, tagMap) - - return nil + return tags.FlattenAndSet(d, tagMap) } func resourceArmMetricAlertRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorAlertRulesClient + client := meta.(*ArmClient).monitor.AlertRulesClient ctx := meta.(*ArmClient).StopContext resourceGroup, name, err := resourceGroupAndAlertRuleNameFromId(d.Id()) @@ -432,7 +435,7 @@ func expandAzureRmMetricThresholdAlertRule(d *schema.ResourceData) (*insights.Al func validateMetricAlertRuleTags(v interface{}, f string) (warnings []string, errors []error) { // Normal validation required by any AzureRM resource. - warnings, errors = validateAzureRMTags(v, f) + warnings, errors = tags.Validate(v, f) tagsMap := v.(map[string]interface{}) @@ -446,7 +449,7 @@ func validateMetricAlertRuleTags(v interface{}, f string) (warnings []string, er } func resourceGroupAndAlertRuleNameFromId(alertRuleId string) (string, string, error) { - id, err := parseAzureResourceID(alertRuleId) + id, err := azure.ParseAzureResourceID(alertRuleId) if err != nil { return "", "", err } diff --git a/azurerm/resource_arm_metric_alertrule_test.go b/azurerm/resource_arm_metric_alertrule_test.go index 1fece9470fc9..c37b57aa0077 100644 --- a/azurerm/resource_arm_metric_alertrule_test.go +++ b/azurerm/resource_arm_metric_alertrule_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -105,7 +106,7 @@ func TestAccAzureRMMetricAlertRule_virtualMachineCpu(t *testing.T) { } func TestAccAzureRMMetricAlertRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -113,7 +114,6 @@ func TestAccAzureRMMetricAlertRule_requiresImport(t *testing.T) { resourceName := "azurerm_metric_alertrule.test" ri := tf.AccRandTimeInt() location := testLocation() - enabled := true resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -121,13 +121,13 @@ func TestAccAzureRMMetricAlertRule_requiresImport(t *testing.T) { CheckDestroy: testCheckAzureRMMetricAlertRuleDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMMetricAlertRule_virtualMachineCpu(ri, location, enabled), + Config: testAccAzureRMMetricAlertRule_virtualMachineCpu(ri, location, true), Check: resource.ComposeTestCheckFunc( testCheckAzureRMMetricAlertRuleExists(resourceName), ), }, { - Config: testAccAzureRMMetricAlertRule_requiresImport(ri, location, enabled), + Config: testAccAzureRMMetricAlertRule_requiresImport(ri, location, true), ExpectError: testRequiresImportError("azurerm_metric_alertrule"), }, }, @@ -169,7 +169,7 @@ func testCheckAzureRMMetricAlertRuleExists(resourceName string) resource.TestChe return fmt.Errorf("Bad: no resource group found in state for Alert Rule: %s", name) } - client := testAccProvider.Meta().(*ArmClient).monitorAlertRulesClient + client := testAccProvider.Meta().(*ArmClient).monitor.AlertRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -186,7 +186,7 @@ func testCheckAzureRMMetricAlertRuleExists(resourceName string) resource.TestChe } func testCheckAzureRMMetricAlertRuleDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).monitorAlertRulesClient + client := testAccProvider.Meta().(*ArmClient).monitor.AlertRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_monitor_action_group.go b/azurerm/resource_arm_monitor_action_group.go index 041650ca6709..6b9fae589fc5 100644 --- a/azurerm/resource_arm_monitor_action_group.go +++ b/azurerm/resource_arm_monitor_action_group.go @@ -6,9 +6,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/monitor/mgmt/2018-03-01/insights" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,7 +33,7 @@ func resourceArmMonitorActionGroup() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "short_name": { Type: schema.TypeString, @@ -106,19 +109,19 @@ func resourceArmMonitorActionGroup() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmMonitorActionGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorActionGroupsClient + client := meta.(*ArmClient).monitor.ActionGroupsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -138,11 +141,11 @@ func resourceArmMonitorActionGroupCreateUpdate(d *schema.ResourceData, meta inte smsReceiversRaw := d.Get("sms_receiver").([]interface{}) webhookReceiversRaw := d.Get("webhook_receiver").([]interface{}) - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) parameters := insights.ActionGroupResource{ - Location: utils.String(azureRMNormalizeLocation("Global")), + Location: utils.String(azure.NormalizeLocation("Global")), ActionGroup: &insights.ActionGroup{ GroupShortName: utils.String(shortName), Enabled: utils.Bool(enabled), @@ -171,10 +174,10 @@ func resourceArmMonitorActionGroupCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmMonitorActionGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorActionGroupsClient + client := meta.(*ArmClient).monitor.ActionGroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -210,16 +213,14 @@ func resourceArmMonitorActionGroupRead(d *schema.ResourceData, meta interface{}) } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmMonitorActionGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorActionGroupsClient + client := meta.(*ArmClient).monitor.ActionGroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_monitor_action_group_test.go b/azurerm/resource_arm_monitor_action_group_test.go index 7308b8f43452..0fca63fd8d9e 100644 --- a/azurerm/resource_arm_monitor_action_group_test.go +++ b/azurerm/resource_arm_monitor_action_group_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMMonitorActionGroup_basic(t *testing.T) { @@ -40,7 +41,7 @@ func TestAccAzureRMMonitorActionGroup_basic(t *testing.T) { } func TestAccAzureRMMonitorActionGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -491,7 +492,7 @@ resource "azurerm_monitor_action_group" "test" { } func testCheckAzureRMMonitorActionGroupDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).monitorActionGroupsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.ActionGroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -530,7 +531,7 @@ func testCheckAzureRMMonitorActionGroupExists(resourceName string) resource.Test return fmt.Errorf("Bad: no resource group found in state for Action Group Instance: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).monitorActionGroupsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.ActionGroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_monitor_activity_log_alert.go b/azurerm/resource_arm_monitor_activity_log_alert.go index fb6bb1e0b77c..36bce65dfcfa 100644 --- a/azurerm/resource_arm_monitor_activity_log_alert.go +++ b/azurerm/resource_arm_monitor_activity_log_alert.go @@ -14,6 +14,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +38,7 @@ func resourceArmMonitorActivityLogAlert() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "scopes": { Type: schema.TypeSet, @@ -148,19 +150,19 @@ func resourceArmMonitorActivityLogAlert() *schema.Resource { Default: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmMonitorActivityLogAlertCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorActivityLogAlertsClient + client := meta.(*ArmClient).monitor.ActivityLogAlertsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -179,15 +181,15 @@ func resourceArmMonitorActivityLogAlertCreateUpdate(d *schema.ResourceData, meta criteriaRaw := d.Get("criteria").([]interface{}) actionRaw := d.Get("action").(*schema.Set).List() - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) parameters := insights.ActivityLogAlertResource{ - Location: utils.String(azureRMNormalizeLocation("Global")), + Location: utils.String(azure.NormalizeLocation("Global")), ActivityLogAlert: &insights.ActivityLogAlert{ Enabled: utils.Bool(enabled), Description: utils.String(description), - Scopes: utils.ExpandStringArray(scopesRaw), + Scopes: utils.ExpandStringSlice(scopesRaw), Condition: expandMonitorActivityLogAlertCriteria(criteriaRaw), Actions: expandMonitorActivityLogAlertAction(actionRaw), }, @@ -211,10 +213,10 @@ func resourceArmMonitorActivityLogAlertCreateUpdate(d *schema.ResourceData, meta } func resourceArmMonitorActivityLogAlertRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorActivityLogAlertsClient + client := meta.(*ArmClient).monitor.ActivityLogAlertsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -236,7 +238,7 @@ func resourceArmMonitorActivityLogAlertRead(d *schema.ResourceData, meta interfa if alert := resp.ActivityLogAlert; alert != nil { d.Set("enabled", alert.Enabled) d.Set("description", alert.Description) - if err := d.Set("scopes", utils.FlattenStringArray(alert.Scopes)); err != nil { + if err := d.Set("scopes", utils.FlattenStringSlice(alert.Scopes)); err != nil { return fmt.Errorf("Error setting `scopes`: %+v", err) } if err := d.Set("criteria", flattenMonitorActivityLogAlertCriteria(alert.Condition)); err != nil { @@ -246,16 +248,14 @@ func resourceArmMonitorActivityLogAlertRead(d *schema.ResourceData, meta interfa return fmt.Errorf("Error setting `action`: %+v", err) } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmMonitorActivityLogAlertDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorActivityLogAlertsClient + client := meta.(*ArmClient).monitor.ActivityLogAlertsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_monitor_activity_log_alert_test.go b/azurerm/resource_arm_monitor_activity_log_alert_test.go index df378c8b1a92..3063c4eda561 100644 --- a/azurerm/resource_arm_monitor_activity_log_alert_test.go +++ b/azurerm/resource_arm_monitor_activity_log_alert_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMMonitorActivityLogAlert_basic(t *testing.T) { @@ -43,7 +44,7 @@ func TestAccAzureRMMonitorActivityLogAlert_basic(t *testing.T) { } func TestAccAzureRMMonitorActivityLogAlert_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -355,7 +356,7 @@ resource "azurerm_monitor_activity_log_alert" "test" { } func testCheckAzureRMMonitorActivityLogAlertDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).monitorActivityLogAlertsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.ActivityLogAlertsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -394,7 +395,7 @@ func testCheckAzureRMMonitorActivityLogAlertExists(resourceName string) resource return fmt.Errorf("Bad: no resource group found in state for Activity Log Alert Instance: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).monitorActivityLogAlertsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.ActivityLogAlertsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_monitor_autoscale_setting.go b/azurerm/resource_arm_monitor_autoscale_setting.go index 7f760b4e6a56..866eb7c5360d 100644 --- a/azurerm/resource_arm_monitor_autoscale_setting.go +++ b/azurerm/resource_arm_monitor_autoscale_setting.go @@ -12,8 +12,11 @@ import ( "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,9 +38,9 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "target_resource_id": { Type: schema.TypeString, @@ -112,7 +115,7 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { "time_grain": { Type: schema.TypeString, Required: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "statistic": { Type: schema.TypeString, @@ -123,12 +126,12 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { string(insights.MetricStatisticTypeMin), string(insights.MetricStatisticTypeSum), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "time_window": { Type: schema.TypeString, Required: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "time_aggregation": { Type: schema.TypeString, @@ -140,7 +143,7 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { string(insights.TimeAggregationTypeMinimum), string(insights.TimeAggregationTypeTotal), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "operator": { Type: schema.TypeString, @@ -153,7 +156,7 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { string(insights.LessThanOrEqual), string(insights.NotEquals), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "threshold": { Type: schema.TypeFloat, @@ -175,7 +178,7 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { string(insights.ScaleDirectionDecrease), string(insights.ScaleDirectionIncrease), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "type": { Type: schema.TypeString, @@ -185,7 +188,7 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { string(insights.ExactCount), string(insights.PercentChangeCount), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "value": { Type: schema.TypeInt, @@ -195,7 +198,7 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { "cooldown": { Type: schema.TypeString, Required: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, }, }, @@ -218,12 +221,12 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { "start": { Type: schema.TypeString, Required: true, - ValidateFunc: validateRFC3339Date, + ValidateFunc: validate.RFC3339Time, }, "end": { Type: schema.TypeString, Required: true, - ValidateFunc: validateRFC3339Date, + ValidateFunc: validate.RFC3339Time, }, }, }, @@ -254,7 +257,7 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { "Saturday", "Sunday", }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, "hours": { @@ -335,19 +338,19 @@ func resourceArmMonitorAutoScaleSetting() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmMonitorAutoScaleSettingCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).autoscaleSettingsClient + client := meta.(*ArmClient).monitor.AutoscaleSettingsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -360,7 +363,7 @@ func resourceArmMonitorAutoScaleSettingCreateUpdate(d *schema.ResourceData, meta } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) enabled := d.Get("enabled").(bool) targetResourceId := d.Get("target_resource_id").(string) @@ -373,8 +376,8 @@ func resourceArmMonitorAutoScaleSettingCreateUpdate(d *schema.ResourceData, meta return fmt.Errorf("Error expanding `profile`: %+v", err) } - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) parameters := insights.AutoscaleSettingResource{ Location: utils.String(location), @@ -405,10 +408,10 @@ func resourceArmMonitorAutoScaleSettingCreateUpdate(d *schema.ResourceData, meta } func resourceArmMonitorAutoScaleSettingRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).autoscaleSettingsClient + client := meta.(*ArmClient).monitor.AutoscaleSettingsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -429,7 +432,7 @@ func resourceArmMonitorAutoScaleSettingRead(d *schema.ResourceData, meta interfa d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("enabled", resp.Enabled) @@ -449,17 +452,15 @@ func resourceArmMonitorAutoScaleSettingRead(d *schema.ResourceData, meta interfa } // Return a new tag map filtered by the specified tag names. - tagMap := filterTags(resp.Tags, "$type") - flattenAndSetTags(d, tagMap) - - return nil + tagMap := tags.Filter(resp.Tags, "$type") + return tags.FlattenAndSet(d, tagMap) } func resourceArmMonitorAutoScaleSettingDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).autoscaleSettingsClient + client := meta.(*ArmClient).monitor.AutoscaleSettingsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_monitor_autoscale_setting_test.go b/azurerm/resource_arm_monitor_autoscale_setting_test.go index a827e088e604..8c3e0c64de78 100644 --- a/azurerm/resource_arm_monitor_autoscale_setting_test.go +++ b/azurerm/resource_arm_monitor_autoscale_setting_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMMonitorAutoScaleSetting_basic(t *testing.T) { @@ -43,7 +44,7 @@ func TestAccAzureRMMonitorAutoScaleSetting_basic(t *testing.T) { } func TestAccAzureRMMonitorAutoScaleSetting_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -332,7 +333,7 @@ func testCheckAzureRMMonitorAutoScaleSettingExists(resourceName string) resource return fmt.Errorf("Bad: no resource group found in state for Monitor AutoScale Setting: %s", autoscaleSettingName) } - conn := testAccProvider.Meta().(*ArmClient).autoscaleSettingsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.AutoscaleSettingsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, autoscaleSettingName) @@ -349,7 +350,7 @@ func testCheckAzureRMMonitorAutoScaleSettingExists(resourceName string) resource } func testCheckAzureRMMonitorAutoScaleSettingDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).autoscaleSettingsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.AutoscaleSettingsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_monitor_diagnostic_setting.go b/azurerm/resource_arm_monitor_diagnostic_setting.go index ba1a98812452..143d182bfb3b 100644 --- a/azurerm/resource_arm_monitor_diagnostic_setting.go +++ b/azurerm/resource_arm_monitor_diagnostic_setting.go @@ -15,6 +15,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -73,6 +74,13 @@ func resourceArmMonitorDiagnosticSetting() *schema.Resource { ValidateFunc: azure.ValidateResourceID, }, + "log_analytics_destination_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: false, + ValidateFunc: validation.StringInSlice([]string{"Dedicated"}, false), + }, + "log": { Type: schema.TypeSet, Optional: true, @@ -155,14 +163,14 @@ func resourceArmMonitorDiagnosticSetting() *schema.Resource { } func resourceArmMonitorDiagnosticSettingCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorDiagnosticSettingsClient + client := meta.(*ArmClient).monitor.DiagnosticSettingsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ARM Diagnostic Settings.") name := d.Get("name").(string) actualResourceId := d.Get("target_resource_id").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, actualResourceId, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -234,6 +242,14 @@ func resourceArmMonitorDiagnosticSettingCreateUpdate(d *schema.ResourceData, met valid = true } + if v := d.Get("log_analytics_destination_type").(string); v != "" { + if workspaceId != "" { + properties.DiagnosticSettings.LogAnalyticsDestinationType = &v + } else { + return fmt.Errorf("`log_analytics_workspace_id` must be set for `log_analytics_destination_type` to be used") + } + } + if !valid { return fmt.Errorf("Either a `eventhub_authorization_rule_id`, `log_analytics_workspace_id` or `storage_account_id` must be set") } @@ -258,7 +274,7 @@ func resourceArmMonitorDiagnosticSettingCreateUpdate(d *schema.ResourceData, met } func resourceArmMonitorDiagnosticSettingRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorDiagnosticSettingsClient + client := meta.(*ArmClient).monitor.DiagnosticSettingsClient ctx := meta.(*ArmClient).StopContext id, err := parseMonitorDiagnosticId(d.Id()) @@ -287,6 +303,8 @@ func resourceArmMonitorDiagnosticSettingRead(d *schema.ResourceData, meta interf d.Set("log_analytics_workspace_id", resp.WorkspaceID) d.Set("storage_account_id", resp.StorageAccountID) + d.Set("log_analytics_destination_type", resp.LogAnalyticsDestinationType) + if err := d.Set("log", flattenMonitorDiagnosticLogs(resp.Logs)); err != nil { return fmt.Errorf("Error setting `log`: %+v", err) } @@ -299,7 +317,7 @@ func resourceArmMonitorDiagnosticSettingRead(d *schema.ResourceData, meta interf } func resourceArmMonitorDiagnosticSettingDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorDiagnosticSettingsClient + client := meta.(*ArmClient).monitor.DiagnosticSettingsClient ctx := meta.(*ArmClient).StopContext id, err := parseMonitorDiagnosticId(d.Id()) @@ -332,7 +350,7 @@ func resourceArmMonitorDiagnosticSettingDelete(d *schema.ResourceData, meta inte return nil } -func monitorDiagnosticSettingDeletedRefreshFunc(ctx context.Context, client insights.DiagnosticSettingsClient, targetResourceId string, name string) resource.StateRefreshFunc { +func monitorDiagnosticSettingDeletedRefreshFunc(ctx context.Context, client *insights.DiagnosticSettingsClient, targetResourceId string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, targetResourceId, name) if err != nil { diff --git a/azurerm/resource_arm_monitor_diagnostic_setting_test.go b/azurerm/resource_arm_monitor_diagnostic_setting_test.go index 33a694fc8d46..92092d29153b 100644 --- a/azurerm/resource_arm_monitor_diagnostic_setting_test.go +++ b/azurerm/resource_arm_monitor_diagnostic_setting_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -43,7 +44,7 @@ func TestAccAzureRMMonitorDiagnosticSetting_eventhub(t *testing.T) { } func TestAccAzureRMMonitorDiagnosticSetting_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -101,6 +102,39 @@ func TestAccAzureRMMonitorDiagnosticSetting_logAnalyticsWorkspace(t *testing.T) }) } +func TestAccAzureRMMonitorDiagnosticSetting_logAnalyticsWorkspaceDedicated(t *testing.T) { + resourceName := "azurerm_monitor_diagnostic_setting.test" + ri := acctest.RandIntRange(10000, 99999) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMonitorDiagnosticSettingDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMonitorDiagnosticSetting_logAnalyticsWorkspaceDedicated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMonitorDiagnosticSettingExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "log_analytics_workspace_id"), + resource.TestCheckResourceAttr(resourceName, "log_analytics_destination_type", "Dedicated"), + resource.TestCheckResourceAttr(resourceName, "log.#", "3"), + resource.TestCheckResourceAttr(resourceName, "log.3188484811.category", "ActivityRuns"), + resource.TestCheckResourceAttr(resourceName, "log.595859111.category", "PipelineRuns"), + resource.TestCheckResourceAttr(resourceName, "log.2542277390.category", "TriggerRuns"), + resource.TestCheckResourceAttr(resourceName, "metric.#", "1"), + resource.TestCheckResourceAttr(resourceName, "metric.4109484471.category", "AllMetrics"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMMonitorDiagnosticSetting_storageAccount(t *testing.T) { resourceName := "azurerm_monitor_diagnostic_setting.test" ri := acctest.RandIntRange(10000, 99999) @@ -139,7 +173,7 @@ func testCheckAzureRMMonitorDiagnosticSettingExists(resourceName string) resourc return fmt.Errorf("Not found: %q", resourceName) } - client := testAccProvider.Meta().(*ArmClient).monitorDiagnosticSettingsClient + client := testAccProvider.Meta().(*ArmClient).monitor.DiagnosticSettingsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext name := rs.Primary.Attributes["name"] actualResourceId := rs.Primary.Attributes["target_resource_id"] @@ -159,7 +193,7 @@ func testCheckAzureRMMonitorDiagnosticSettingExists(resourceName string) resourc } func testCheckAzureRMMonitorDiagnosticSettingDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).monitorDiagnosticSettingsClient + client := testAccProvider.Meta().(*ArmClient).monitor.DiagnosticSettingsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -338,6 +372,74 @@ resource "azurerm_monitor_diagnostic_setting" "test" { `, rInt, location, rInt, rInt, rInt) } +func testAccAzureRMMonitorDiagnosticSetting_logAnalyticsWorkspaceDedicated(rInt int, location string) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctest%d" + location = "%s" +} + +resource "azurerm_log_analytics_workspace" "test" { + name = "acctestlaw%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "PerGB2018" + retention_in_days = 30 +} + +resource "azurerm_data_factory" "test" { + name = "acctestdf%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_monitor_diagnostic_setting" "test" { + name = "acctestds%d" + target_resource_id = "${azurerm_data_factory.test.id}" + log_analytics_workspace_id = "${azurerm_log_analytics_workspace.test.id}" + + log_analytics_destination_type = "Dedicated" + + log { + category = "ActivityRuns" + + retention_policy { + enabled = false + } + } + + log { + category = "PipelineRuns" + enabled = false + + retention_policy { + enabled = false + } + } + + log { + category = "TriggerRuns" + enabled = false + + retention_policy { + enabled = false + } + } + + metric { + category = "AllMetrics" + enabled = false + + retention_policy { + enabled = false + } + } +} +`, rInt, location, rInt, rInt, rInt) +} + func testAccAzureRMMonitorDiagnosticSetting_storageAccount(rInt int, location string) string { return fmt.Sprintf(` data "azurerm_client_config" "current" {} diff --git a/azurerm/resource_arm_monitor_log_profile.go b/azurerm/resource_arm_monitor_log_profile.go index d0f127bf5ce7..46bbaa62f576 100644 --- a/azurerm/resource_arm_monitor_log_profile.go +++ b/azurerm/resource_arm_monitor_log_profile.go @@ -10,8 +10,10 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -48,8 +50,8 @@ func resourceArmMonitorLogProfile() *schema.Resource { Required: true, Elem: &schema.Schema{ Type: schema.TypeString, - StateFunc: azureRMNormalizeLocation, - DiffSuppressFunc: azureRMSuppressLocationDiff, + StateFunc: azure.NormalizeLocation, + DiffSuppressFunc: azure.SuppressLocationDiff, }, Set: schema.HashString, }, @@ -59,7 +61,7 @@ func resourceArmMonitorLogProfile() *schema.Resource { MinItems: 1, Elem: &schema.Schema{ Type: schema.TypeString, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, Set: schema.HashString, }, @@ -86,11 +88,11 @@ func resourceArmMonitorLogProfile() *schema.Resource { } func resourceArmLogProfileCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorLogProfilesClient + client := meta.(*ArmClient).monitor.LogProfilesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -148,7 +150,7 @@ func resourceArmLogProfileCreateUpdate(d *schema.ResourceData, meta interface{}) } func resourceArmLogProfileRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorLogProfilesClient + client := meta.(*ArmClient).monitor.LogProfilesClient ctx := meta.(*ArmClient).StopContext name, err := parseLogProfileNameFromID(d.Id()) @@ -185,7 +187,7 @@ func resourceArmLogProfileRead(d *schema.ResourceData, meta interface{}) error { } func resourceArmLogProfileDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorLogProfilesClient + client := meta.(*ArmClient).monitor.LogProfilesClient ctx := meta.(*ArmClient).StopContext name, err := parseLogProfileNameFromID(d.Id()) @@ -217,7 +219,7 @@ func expandLogProfileLocations(d *schema.ResourceData) []string { locations := make([]string, 0) for _, location := range logProfileLocations { - locations = append(locations, azureRMNormalizeLocation(location.(string))) + locations = append(locations, azure.NormalizeLocation(location.(string))) } return locations @@ -241,7 +243,7 @@ func flattenAzureRmLogProfileLocations(input *[]string) []string { result := make([]string, 0) if input != nil { for _, location := range *input { - result = append(result, azureRMNormalizeLocation(location)) + result = append(result, azure.NormalizeLocation(location)) } } @@ -267,7 +269,7 @@ func flattenAzureRmLogProfileRetentionPolicy(input *insights.RetentionPolicy) [] func retryLogProfilesClientGet(name string, meta interface{}) func() *resource.RetryError { return func() *resource.RetryError { - client := meta.(*ArmClient).monitorLogProfilesClient + client := meta.(*ArmClient).monitor.LogProfilesClient ctx := meta.(*ArmClient).StopContext if _, err := client.Get(ctx, name); err != nil { diff --git a/azurerm/resource_arm_monitor_log_profile_test.go b/azurerm/resource_arm_monitor_log_profile_test.go index 5cd8e84f736a..64a3bef915d9 100644 --- a/azurerm/resource_arm_monitor_log_profile_test.go +++ b/azurerm/resource_arm_monitor_log_profile_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -72,7 +73,7 @@ func testAccAzureRMMonitorLogProfile_basic(t *testing.T) { } func testAccAzureRMMonitorLogProfile_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -165,7 +166,7 @@ func testAccAzureRMMonitorLogProfile_disappears(t *testing.T) { } func testCheckAzureRMLogProfileDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).monitorLogProfilesClient + client := testAccProvider.Meta().(*ArmClient).monitor.LogProfilesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -193,7 +194,7 @@ func testCheckAzureRMLogProfileExists(resourceName string) resource.TestCheckFun return fmt.Errorf("Not found: %s", resourceName) } - client := testAccProvider.Meta().(*ArmClient).monitorLogProfilesClient + client := testAccProvider.Meta().(*ArmClient).monitor.LogProfilesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext name := rs.Primary.Attributes["name"] @@ -220,7 +221,7 @@ func testCheckAzureRMLogProfileDisappears(resourceName string) resource.TestChec name := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).monitorLogProfilesClient + client := testAccProvider.Meta().(*ArmClient).monitor.LogProfilesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext if _, err := client.Delete(ctx, name); err != nil { @@ -234,7 +235,7 @@ func testCheckAzureRMLogProfileDisappears(resourceName string) resource.TestChec func testAccAzureRMMonitorLogProfile_basicConfig(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%d" + name = "acctestRG-%d" location = "%s" } @@ -289,7 +290,7 @@ resource "azurerm_monitor_log_profile" "import" { func testAccAzureRMMonitorLogProfile_servicebusConfig(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%d" + name = "acctestRG-%d" location = "%s" } @@ -333,7 +334,7 @@ resource "azurerm_monitor_log_profile" "test" { func testAccAzureRMMonitorLogProfile_completeConfig(rInt int, rString string, location string, altLocation string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { - name = "acctestrg-%d" + name = "acctestRG-%d" location = "%s" } diff --git a/azurerm/resource_arm_monitor_metric_alert.go b/azurerm/resource_arm_monitor_metric_alert.go index a5b81bbc5377..e739bab38d7e 100644 --- a/azurerm/resource_arm_monitor_metric_alert.go +++ b/azurerm/resource_arm_monitor_metric_alert.go @@ -13,6 +13,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +37,7 @@ func resourceArmMonitorMetricAlert() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), // TODO: Multiple resource IDs (Remove MaxItems) support is missing in SDK // Issue to track: https://github.com/Azure/azure-sdk-for-go/issues/2920 @@ -203,19 +205,19 @@ func resourceArmMonitorMetricAlert() *schema.Resource { }, false), }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmMonitorMetricAlertCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorMetricAlertsClient + client := meta.(*ArmClient).monitor.MetricAlertsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -238,11 +240,11 @@ func resourceArmMonitorMetricAlertCreateUpdate(d *schema.ResourceData, meta inte criteriaRaw := d.Get("criteria").([]interface{}) actionRaw := d.Get("action").(*schema.Set).List() - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) parameters := insights.MetricAlertResource{ - Location: utils.String(azureRMNormalizeLocation("Global")), + Location: utils.String(azure.NormalizeLocation("Global")), MetricAlertProperties: &insights.MetricAlertProperties{ Enabled: utils.Bool(enabled), AutoMitigate: utils.Bool(autoMitigate), @@ -250,7 +252,7 @@ func resourceArmMonitorMetricAlertCreateUpdate(d *schema.ResourceData, meta inte Severity: utils.Int32(int32(severity)), EvaluationFrequency: utils.String(frequency), WindowSize: utils.String(windowSize), - Scopes: utils.ExpandStringArray(scopesRaw), + Scopes: utils.ExpandStringSlice(scopesRaw), Criteria: expandMonitorMetricAlertCriteria(criteriaRaw), Actions: expandMonitorMetricAlertAction(actionRaw), }, @@ -274,10 +276,10 @@ func resourceArmMonitorMetricAlertCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmMonitorMetricAlertRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorMetricAlertsClient + client := meta.(*ArmClient).monitor.MetricAlertsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -303,7 +305,7 @@ func resourceArmMonitorMetricAlertRead(d *schema.ResourceData, meta interface{}) d.Set("severity", alert.Severity) d.Set("frequency", alert.EvaluationFrequency) d.Set("window_size", alert.WindowSize) - if err := d.Set("scopes", utils.FlattenStringArray(alert.Scopes)); err != nil { + if err := d.Set("scopes", utils.FlattenStringSlice(alert.Scopes)); err != nil { return fmt.Errorf("Error setting `scopes`: %+v", err) } if err := d.Set("criteria", flattenMonitorMetricAlertCriteria(alert.Criteria)); err != nil { @@ -313,16 +315,14 @@ func resourceArmMonitorMetricAlertRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error setting `action`: %+v", err) } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmMonitorMetricAlertDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorMetricAlertsClient + client := meta.(*ArmClient).monitor.MetricAlertsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -349,7 +349,7 @@ func expandMonitorMetricAlertCriteria(input []interface{}) *insights.MetricAlert dimensions = append(dimensions, insights.MetricDimension{ Name: utils.String(dVal["name"].(string)), Operator: utils.String(dVal["operator"].(string)), - Values: utils.ExpandStringArray(dVal["values"].([]interface{})), + Values: utils.ExpandStringSlice(dVal["values"].([]interface{})), }) } @@ -427,7 +427,7 @@ func flattenMonitorMetricAlertCriteria(input insights.BasicMetricAlertCriteria) if dimension.Operator != nil { dVal["operator"] = *dimension.Operator } - dVal["values"] = utils.FlattenStringArray(dimension.Values) + dVal["values"] = utils.FlattenStringSlice(dimension.Values) dimResult = append(dimResult, dVal) } v["dimension"] = dimResult diff --git a/azurerm/resource_arm_monitor_metric_alert_test.go b/azurerm/resource_arm_monitor_metric_alert_test.go index 30d89e47aa63..42b387dbef8f 100644 --- a/azurerm/resource_arm_monitor_metric_alert_test.go +++ b/azurerm/resource_arm_monitor_metric_alert_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMMonitorMetricAlert_basic(t *testing.T) { @@ -48,7 +49,7 @@ func TestAccAzureRMMonitorMetricAlert_basic(t *testing.T) { } func TestAccAzureRMMonitorMetricAlert_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -356,7 +357,7 @@ resource "azurerm_monitor_metric_alert" "test" { } func testCheckAzureRMMonitorMetricAlertDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).monitorMetricAlertsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.MetricAlertsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_monitor_metric_alert" { @@ -391,7 +392,7 @@ func testCheckAzureRMMonitorMetricAlertExists(resourceName string) resource.Test return fmt.Errorf("Bad: no resource group found in state for Metric Alert Instance: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).monitorMetricAlertsClient + conn := testAccProvider.Meta().(*ArmClient).monitor.MetricAlertsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_monitor_metric_alertrule.go b/azurerm/resource_arm_monitor_metric_alertrule.go index f0d4ce9b7ded..3f5ed7eb2a5c 100644 --- a/azurerm/resource_arm_monitor_metric_alertrule.go +++ b/azurerm/resource_arm_monitor_metric_alertrule.go @@ -8,7 +8,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/monitor/mgmt/2018-03-01/insights" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -29,9 +34,9 @@ func resourceArmMonitorMetricAlertRule() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "description": { Type: schema.TypeString, @@ -58,7 +63,7 @@ func resourceArmMonitorMetricAlertRule() *schema.Resource { "operator": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(insights.ConditionOperatorGreaterThan), string(insights.ConditionOperatorGreaterThanOrEqual), @@ -75,13 +80,13 @@ func resourceArmMonitorMetricAlertRule() *schema.Resource { "period": { Type: schema.TypeString, Required: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "aggregation": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(insights.TimeAggregationOperatorAverage), string(insights.TimeAggregationOperatorLast), @@ -151,7 +156,7 @@ func resourceArmMonitorMetricAlertRule() *schema.Resource { } func resourceArmMonitorMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorAlertRulesClient + client := meta.(*ArmClient).monitor.AlertRulesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Alert Rule creation.") @@ -159,7 +164,7 @@ func resourceArmMonitorMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -172,8 +177,8 @@ func resourceArmMonitorMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) alertRule, err := expandAzureRmMonitorMetricThresholdAlertRule(d) if err != nil { @@ -183,7 +188,7 @@ func resourceArmMonitorMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta alertRuleResource := insights.AlertRuleResource{ Name: &name, Location: &location, - Tags: expandTags(tags), + Tags: tags.Expand(t), AlertRule: alertRule, } @@ -205,10 +210,10 @@ func resourceArmMonitorMetricAlertRuleCreateUpdate(d *schema.ResourceData, meta } func resourceArmMonitorMetricAlertRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorAlertRulesClient + client := meta.(*ArmClient).monitor.AlertRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -229,7 +234,7 @@ func resourceArmMonitorMetricAlertRuleRead(d *schema.ResourceData, meta interfac d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if alertRule := resp.AlertRule; alertRule != nil { @@ -298,18 +303,16 @@ func resourceArmMonitorMetricAlertRuleRead(d *schema.ResourceData, meta interfac } // Return a new tag map filtered by the specified tag names. - tagMap := filterTags(resp.Tags, "$type") + tagMap := tags.Filter(resp.Tags, "$type") - flattenAndSetTags(d, tagMap) - - return nil + return tags.FlattenAndSet(d, tagMap) } func resourceArmMonitorMetricAlertRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).monitorAlertRulesClient + client := meta.(*ArmClient).monitor.AlertRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -429,7 +432,7 @@ func expandAzureRmMonitorMetricThresholdAlertRule(d *schema.ResourceData) (*insi func validateMonitorMetricAlertRuleTags(v interface{}, f string) (warnings []string, errors []error) { // Normal validation required by any AzureRM resource. - warnings, errors = validateAzureRMTags(v, f) + warnings, errors = tags.Validate(v, f) tagsMap := v.(map[string]interface{}) diff --git a/azurerm/resource_arm_monitor_metric_alertrule_test.go b/azurerm/resource_arm_monitor_metric_alertrule_test.go index b0feadac65f6..8b0151c6251d 100644 --- a/azurerm/resource_arm_monitor_metric_alertrule_test.go +++ b/azurerm/resource_arm_monitor_metric_alertrule_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -105,7 +106,7 @@ func TestAccAzureRMMonitorMetricAlertRule_virtualMachineCpu(t *testing.T) { } func TestAccAzureRMMonitorMetricAlertRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -113,7 +114,6 @@ func TestAccAzureRMMonitorMetricAlertRule_requiresImport(t *testing.T) { resourceName := "azurerm_monitor_metric_alertrule.test" ri := tf.AccRandTimeInt() location := testLocation() - enabled := true resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -121,13 +121,13 @@ func TestAccAzureRMMonitorMetricAlertRule_requiresImport(t *testing.T) { CheckDestroy: testCheckAzureRMMonitorMetricAlertRuleDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMMonitorMetricAlertRule_virtualMachineCpu(ri, location, enabled), + Config: testAccAzureRMMonitorMetricAlertRule_virtualMachineCpu(ri, location, true), Check: resource.ComposeTestCheckFunc( testCheckAzureRMMonitorMetricAlertRuleExists(resourceName), ), }, { - Config: testAccAzureRMMonitorMetricAlertRule_requiresImport(ri, location, enabled), + Config: testAccAzureRMMonitorMetricAlertRule_requiresImport(ri, location, true), ExpectError: testRequiresImportError("azurerm_monitor_metric_alertrule"), }, }, @@ -169,7 +169,7 @@ func testCheckAzureRMMonitorMetricAlertRuleExists(resourceName string) resource. return fmt.Errorf("Bad: no resource group found in state for Alert Rule: %s", name) } - client := testAccProvider.Meta().(*ArmClient).monitorAlertRulesClient + client := testAccProvider.Meta().(*ArmClient).monitor.AlertRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -186,7 +186,7 @@ func testCheckAzureRMMonitorMetricAlertRuleExists(resourceName string) resource. } func testCheckAzureRMMonitorMetricAlertRuleDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).monitorAlertRulesClient + client := testAccProvider.Meta().(*ArmClient).monitor.AlertRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go index f64bd09395df..377924f5e883 100644 --- a/azurerm/resource_arm_mssql_elasticpool.go +++ b/azurerm/resource_arm_mssql_elasticpool.go @@ -12,6 +12,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -33,9 +35,9 @@ func resourceArmMsSqlElasticPool() *schema.Resource { ValidateFunc: azure.ValidateMsSqlElasticPoolName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -176,10 +178,10 @@ func resourceArmMsSqlElasticPool() *schema.Resource { "zone_redundant": { Type: schema.TypeBool, - Computed: true, + Optional: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error { @@ -194,7 +196,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource { } func resourceArmMsSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).msSqlElasticPoolsClient + client := meta.(*ArmClient).mssql.ElasticPoolsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for MSSQL ElasticPool creation.") @@ -203,7 +205,7 @@ func resourceArmMsSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interf serverName := d.Get("server_name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, serverName, elasticPoolName) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -216,20 +218,24 @@ func resourceArmMsSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interf } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) sku := expandAzureRmMsSqlElasticPoolSku(d) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) elasticPool := sql.ElasticPool{ Name: &elasticPoolName, Location: &location, Sku: sku, - Tags: expandTags(tags), + Tags: tags.Expand(t), ElasticPoolProperties: &sql.ElasticPoolProperties{ PerDatabaseSettings: expandAzureRmMsSqlElasticPoolPerDatabaseSettings(d), }, } + if v, ok := d.GetOkExists("zone_redundant"); ok { + elasticPool.ElasticPoolProperties.ZoneRedundant = utils.Bool(v.(bool)) + } + if d.HasChange("max_size_gb") { if v, ok := d.GetOk("max_size_gb"); ok { maxSizeBytes := v.(float64) * 1073741824 @@ -264,7 +270,7 @@ func resourceArmMsSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interf } func resourceArmMsSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).msSqlElasticPoolsClient + client := meta.(*ArmClient).mssql.ElasticPoolsClient ctx := meta.(*ArmClient).StopContext resGroup, serverName, name, err := parseArmMsSqlElasticPoolId(d.Id()) @@ -285,7 +291,7 @@ func resourceArmMsSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) e d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("server_name", serverName) @@ -315,13 +321,11 @@ func resourceArmMsSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) e } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmMsSqlElasticPoolDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).msSqlElasticPoolsClient + client := meta.(*ArmClient).mssql.ElasticPoolsClient ctx := meta.(*ArmClient).StopContext resGroup, serverName, name, err := parseArmSqlElasticPoolId(d.Id()) @@ -334,7 +338,7 @@ func resourceArmMsSqlElasticPoolDelete(d *schema.ResourceData, meta interface{}) } func parseArmMsSqlElasticPoolId(sqlElasticPoolId string) (string, string, string, error) { - id, err := parseAzureResourceID(sqlElasticPoolId) + id, err := azure.ParseAzureResourceID(sqlElasticPoolId) if err != nil { return "", "", "", fmt.Errorf("[ERROR] Unable to parse MsSQL ElasticPool ID %q: %+v", sqlElasticPoolId, err) } diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go index 9030054a8700..5b34e79b40eb 100644 --- a/azurerm/resource_arm_mssql_elasticpool_test.go +++ b/azurerm/resource_arm_mssql_elasticpool_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) // TODO: add import tests @@ -38,7 +39,7 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU(t *testing.T) { } func TestAccAzureRMMsSqlElasticPool_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -98,6 +99,34 @@ func TestAccAzureRMMsSqlElasticPool_standard_DTU(t *testing.T) { }) } +func TestAccAzureRMMsSqlElasticPool_premium_DTU_zone_redundant(t *testing.T) { + resourceName := "azurerm_mssql_elasticpool.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMMsSqlElasticPool_premium_DTU_zone_redundant(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMsSqlElasticPoolExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "PremiumPool"), + resource.TestCheckResourceAttr(resourceName, "zone_redundant", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"max_size_gb"}, + }, + }, + }) +} + func TestAccAzureRMMsSqlElasticPool_basic_vCore(t *testing.T) { resourceName := "azurerm_mssql_elasticpool.test" ri := tf.AccRandTimeInt() @@ -271,7 +300,7 @@ func testCheckAzureRMMsSqlElasticPoolExists(resourceName string) resource.TestCh serverName := rs.Primary.Attributes["server_name"] poolName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).msSqlElasticPoolsClient + client := testAccProvider.Meta().(*ArmClient).mssql.ElasticPoolsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, poolName) @@ -288,7 +317,7 @@ func testCheckAzureRMMsSqlElasticPoolExists(resourceName string) resource.TestCh } func testCheckAzureRMMsSqlElasticPoolDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).msSqlElasticPoolsClient + client := testAccProvider.Meta().(*ArmClient).mssql.ElasticPoolsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -325,7 +354,7 @@ func testCheckAzureRMMsSqlElasticPoolDisappears(resourceName string) resource.Te serverName := rs.Primary.Attributes["server_name"] poolName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).msSqlElasticPoolsClient + client := testAccProvider.Meta().(*ArmClient).mssql.ElasticPoolsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext if _, err := client.Delete(ctx, resourceGroup, serverName, poolName); err != nil { @@ -337,11 +366,11 @@ func testCheckAzureRMMsSqlElasticPoolDisappears(resourceName string) resource.Te } func testAccAzureRMMsSqlElasticPool_basic_DTU(rInt int, location string) string { - return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 4.8828125, 0, 5) + return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 4.8828125, 0, 5, false) } func testAccAzureRMMsSqlElasticPool_requiresImport(rInt int, location string) string { - template := testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 5242880000, 0, 5) + template := testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 5242880000, 0, 5, false) return fmt.Sprintf(` %s @@ -357,12 +386,16 @@ resource "azurerm_mssql_elasticpool" "import" { `, template) } +func testAccAzureRMMsSqlElasticPool_premium_DTU_zone_redundant(rInt int, location string) string { + return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "PremiumPool", "Premium", 125, 50, 0, 50, true) +} + func testAccAzureRMMsSqlElasticPool_standard_DTU(rInt int, location string) string { - return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 50, 50, 0, 50) + return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 50, 50, 0, 50, false) } func testAccAzureRMMsSqlElasticPool_resize_DTU(rInt int, location string) string { - return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 100, 100, 50, 100) + return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 100, 100, 50, 100, false) } func testAccAzureRMMsSqlElasticPool_basic_vCore(rInt int, location string) string { @@ -453,7 +486,7 @@ resource "azurerm_mssql_elasticpool" "test" { `, rInt, location, skuName, skuTier, skuCapacity, skuFamily, databaseSettingsMin, databaseSettingsMax) } -func testAccAzureRMMsSqlElasticPool_DTU_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string { +func testAccAzureRMMsSqlElasticPool_DTU_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int, zoneRedundant bool) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%[1]d" @@ -475,6 +508,7 @@ resource "azurerm_mssql_elasticpool" "test" { location = "${azurerm_resource_group.test.location}" server_name = "${azurerm_sql_server.test.name}" max_size_gb = %.7[6]f + zone_redundant = %[9]t sku { name = "%[3]s" @@ -487,5 +521,5 @@ resource "azurerm_mssql_elasticpool" "test" { max_capacity = %[8]d } } -`, rInt, location, skuName, skuTier, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax) +`, rInt, location, skuName, skuTier, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax, zoneRedundant) } diff --git a/azurerm/resource_arm_mysql_configuration.go b/azurerm/resource_arm_mysql_configuration.go index 8f69fcd6ab4b..7a9f6b2d1567 100644 --- a/azurerm/resource_arm_mysql_configuration.go +++ b/azurerm/resource_arm_mysql_configuration.go @@ -6,6 +6,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -14,6 +15,7 @@ func resourceArmMySQLConfiguration() *schema.Resource { Create: resourceArmMySQLConfigurationCreate, Read: resourceArmMySQLConfigurationRead, Delete: resourceArmMySQLConfigurationDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -25,12 +27,13 @@ func resourceArmMySQLConfiguration() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateMySqlServerName, }, "value": { @@ -43,7 +46,7 @@ func resourceArmMySQLConfiguration() *schema.Resource { } func resourceArmMySQLConfigurationCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlConfigurationsClient + client := meta.(*ArmClient).mysql.ConfigurationsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM MySQL Configuration creation.") @@ -82,10 +85,10 @@ func resourceArmMySQLConfigurationCreate(d *schema.ResourceData, meta interface{ } func resourceArmMySQLConfigurationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlConfigurationsClient + client := meta.(*ArmClient).mysql.ConfigurationsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -113,10 +116,10 @@ func resourceArmMySQLConfigurationRead(d *schema.ResourceData, meta interface{}) } func resourceArmMySQLConfigurationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlConfigurationsClient + client := meta.(*ArmClient).mysql.ConfigurationsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_mysql_configuration_test.go b/azurerm/resource_arm_mysql_configuration_test.go index 5f3b96e15921..3a2f2c11afe1 100644 --- a/azurerm/resource_arm_mysql_configuration_test.go +++ b/azurerm/resource_arm_mysql_configuration_test.go @@ -118,7 +118,7 @@ func testCheckAzureRMMySQLConfigurationValue(resourceName string, value string) return fmt.Errorf("Bad: no resource group found in state for MySQL Configuration: %s", name) } - client := testAccProvider.Meta().(*ArmClient).mysqlConfigurationsClient + client := testAccProvider.Meta().(*ArmClient).mysql.ConfigurationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, name) @@ -144,7 +144,7 @@ func testCheckAzureRMMySQLConfigurationValueReset(rInt int, configurationName st resourceGroup := fmt.Sprintf("acctestRG-%d", rInt) serverName := fmt.Sprintf("acctestmysqlsvr-%d", rInt) - client := testAccProvider.Meta().(*ArmClient).mysqlConfigurationsClient + client := testAccProvider.Meta().(*ArmClient).mysql.ConfigurationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, configurationName) @@ -167,7 +167,7 @@ func testCheckAzureRMMySQLConfigurationValueReset(rInt int, configurationName st } func testCheckAzureRMMySQLConfigurationDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).mysqlConfigurationsClient + client := testAccProvider.Meta().(*ArmClient).mysql.ConfigurationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_mysql_database.go b/azurerm/resource_arm_mysql_database.go index af039a623a1c..c117d4aac7ef 100644 --- a/azurerm/resource_arm_mysql_database.go +++ b/azurerm/resource_arm_mysql_database.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -15,6 +18,7 @@ func resourceArmMySqlDatabase() *schema.Resource { Create: resourceArmMySqlDatabaseCreate, Read: resourceArmMySqlDatabaseRead, Delete: resourceArmMySqlDatabaseDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -26,18 +30,19 @@ func resourceArmMySqlDatabase() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateMySqlServerName, }, "charset": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ForceNew: true, }, @@ -51,7 +56,7 @@ func resourceArmMySqlDatabase() *schema.Resource { } func resourceArmMySqlDatabaseCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlDatabasesClient + client := meta.(*ArmClient).mysql.DatabasesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM MySQL Database creation.") @@ -63,7 +68,7 @@ func resourceArmMySqlDatabaseCreate(d *schema.ResourceData, meta interface{}) er charset := d.Get("charset").(string) collation := d.Get("collation").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -106,10 +111,10 @@ func resourceArmMySqlDatabaseCreate(d *schema.ResourceData, meta interface{}) er } func resourceArmMySqlDatabaseRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlDatabasesClient + client := meta.(*ArmClient).mysql.DatabasesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -137,10 +142,10 @@ func resourceArmMySqlDatabaseRead(d *schema.ResourceData, meta interface{}) erro } func resourceArmMySqlDatabaseDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlDatabasesClient + client := meta.(*ArmClient).mysql.DatabasesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_mysql_database_test.go b/azurerm/resource_arm_mysql_database_test.go index 920e89c8d599..9aabbb60e56e 100644 --- a/azurerm/resource_arm_mysql_database_test.go +++ b/azurerm/resource_arm_mysql_database_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +36,7 @@ func TestAccAzureRMMySQLDatabase_basic(t *testing.T) { } func TestAccAzureRMMySQLDatabase_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -129,7 +130,7 @@ func testCheckAzureRMMySQLDatabaseExists(resourceName string) resource.TestCheck return fmt.Errorf("Bad: no resource group found in state for MySQL Database: %s", name) } - client := testAccProvider.Meta().(*ArmClient).mysqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).mysql.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, name) @@ -145,7 +146,7 @@ func testCheckAzureRMMySQLDatabaseExists(resourceName string) resource.TestCheck } func testCheckAzureRMMySQLDatabaseDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).mysqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).mysql.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_mysql_firewall_rule.go b/azurerm/resource_arm_mysql_firewall_rule.go index c7820e64ba3b..eb0a2ee5d174 100644 --- a/azurerm/resource_arm_mysql_firewall_rule.go +++ b/azurerm/resource_arm_mysql_firewall_rule.go @@ -6,7 +6,9 @@ import ( "github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -16,6 +18,7 @@ func resourceArmMySqlFirewallRule() *schema.Resource { Read: resourceArmMySqlFirewallRuleRead, Update: resourceArmMySqlFirewallRuleCreateUpdate, Delete: resourceArmMySqlFirewallRuleDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -27,12 +30,13 @@ func resourceArmMySqlFirewallRule() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateMySqlServerName, }, "start_ip_address": { @@ -49,7 +53,7 @@ func resourceArmMySqlFirewallRule() *schema.Resource { } func resourceArmMySqlFirewallRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlFirewallRulesClient + client := meta.(*ArmClient).mysql.FirewallRulesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM MySQL Firewall Rule creation.") @@ -60,7 +64,7 @@ func resourceArmMySqlFirewallRuleCreateUpdate(d *schema.ResourceData, meta inter startIPAddress := d.Get("start_ip_address").(string) endIPAddress := d.Get("end_ip_address").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -103,10 +107,10 @@ func resourceArmMySqlFirewallRuleCreateUpdate(d *schema.ResourceData, meta inter } func resourceArmMySqlFirewallRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlFirewallRulesClient + client := meta.(*ArmClient).mysql.FirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -133,10 +137,10 @@ func resourceArmMySqlFirewallRuleRead(d *schema.ResourceData, meta interface{}) } func resourceArmMySqlFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlFirewallRulesClient + client := meta.(*ArmClient).mysql.FirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_mysql_firewall_rule_test.go b/azurerm/resource_arm_mysql_firewall_rule_test.go index 795cf0f82a8a..9113bae23279 100644 --- a/azurerm/resource_arm_mysql_firewall_rule_test.go +++ b/azurerm/resource_arm_mysql_firewall_rule_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +36,7 @@ func TestAccAzureRMMySQLFirewallRule_basic(t *testing.T) { } func TestAccAzureRMMySQLFirewallRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -77,7 +78,7 @@ func testCheckAzureRMMySQLFirewallRuleExists(resourceName string) resource.TestC return fmt.Errorf("Bad: no resource group found in state for MySQL Firewall Rule: %s", name) } - client := testAccProvider.Meta().(*ArmClient).mysqlFirewallRulesClient + client := testAccProvider.Meta().(*ArmClient).mysql.FirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, name) @@ -93,7 +94,7 @@ func testCheckAzureRMMySQLFirewallRuleExists(resourceName string) resource.TestC } func testCheckAzureRMMySQLFirewallRuleDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).mysqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).mysql.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_mysql_server.go b/azurerm/resource_arm_mysql_server.go index a3ab1281ba58..32e41f7e8b83 100644 --- a/azurerm/resource_arm_mysql_server.go +++ b/azurerm/resource_arm_mysql_server.go @@ -8,9 +8,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -20,20 +23,22 @@ func resourceArmMySqlServer() *schema.Resource { Read: resourceArmMySqlServerRead, Update: resourceArmMySqlServerUpdate, Delete: resourceArmMySqlServerDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateMySqlServerName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeList, @@ -174,7 +179,7 @@ func resourceArmMySqlServer() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error { @@ -192,13 +197,13 @@ func resourceArmMySqlServer() *schema.Resource { } func resourceArmMySqlServerCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlServersClient + client := meta.(*ArmClient).mysql.ServersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM MySQL Server creation.") name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resourceGroup := d.Get("resource_group_name").(string) adminLogin := d.Get("administrator_login").(string) @@ -206,9 +211,9 @@ func resourceArmMySqlServerCreate(d *schema.ResourceData, meta interface{}) erro sslEnforcement := d.Get("ssl_enforcement").(string) version := d.Get("version").(string) createMode := "Default" - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -235,7 +240,7 @@ func resourceArmMySqlServerCreate(d *schema.ResourceData, meta interface{}) erro CreateMode: mysql.CreateMode(createMode), }, Sku: sku, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.Create(ctx, resourceGroup, name, properties) @@ -262,7 +267,7 @@ func resourceArmMySqlServerCreate(d *schema.ResourceData, meta interface{}) erro } func resourceArmMySqlServerUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlServersClient + client := meta.(*ArmClient).mysql.ServersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM MySQL Server update.") @@ -275,7 +280,7 @@ func resourceArmMySqlServerUpdate(d *schema.ResourceData, meta interface{}) erro version := d.Get("version").(string) sku := expandMySQLServerSku(d) storageProfile := expandMySQLStorageProfile(d) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) properties := mysql.ServerUpdateParameters{ ServerUpdateParametersProperties: &mysql.ServerUpdateParametersProperties{ @@ -285,7 +290,7 @@ func resourceArmMySqlServerUpdate(d *schema.ResourceData, meta interface{}) erro SslEnforcement: mysql.SslEnforcementEnum(sslEnforcement), }, Sku: sku, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.Update(ctx, resourceGroup, name, properties) @@ -312,10 +317,10 @@ func resourceArmMySqlServerUpdate(d *schema.ResourceData, meta interface{}) erro } func resourceArmMySqlServerRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlServersClient + client := meta.(*ArmClient).mysql.ServersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -336,7 +341,7 @@ func resourceArmMySqlServerRead(d *schema.ResourceData, meta interface{}) error d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("administrator_login", resp.AdministratorLogin) @@ -351,19 +356,17 @@ func resourceArmMySqlServerRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error setting `storage_profile`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - // Computed d.Set("fqdn", resp.FullyQualifiedDomainName) - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmMySqlServerDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlServersClient + client := meta.(*ArmClient).mysql.ServersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_mysql_server_test.go b/azurerm/resource_arm_mysql_server_test.go index e82401bff04a..021cd8cb0f3b 100644 --- a/azurerm/resource_arm_mysql_server_test.go +++ b/azurerm/resource_arm_mysql_server_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +39,7 @@ func TestAccAzureRMMySQLServer_basicFiveSix(t *testing.T) { } func TestAccAzureRMMySQLServer_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -66,7 +67,7 @@ func TestAccAzureRMMySQLServer_requiresImport(t *testing.T) { } func TestAccAzureRMMySQLServer_basicFiveSeven(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -253,7 +254,7 @@ func testCheckAzureRMMySQLServerExists(resourceName string) resource.TestCheckFu return fmt.Errorf("Bad: no resource group found in state for MySQL Server: %s", name) } - client := testAccProvider.Meta().(*ArmClient).mysqlServersClient + client := testAccProvider.Meta().(*ArmClient).mysql.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -270,7 +271,7 @@ func testCheckAzureRMMySQLServerExists(resourceName string) resource.TestCheckFu } func testCheckAzureRMMySQLServerDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).mysqlServersClient + client := testAccProvider.Meta().(*ArmClient).mysql.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_mysql_virtual_network_rule.go b/azurerm/resource_arm_mysql_virtual_network_rule.go index a2ff3caafb47..4a5a62bf7433 100644 --- a/azurerm/resource_arm_mysql_virtual_network_rule.go +++ b/azurerm/resource_arm_mysql_virtual_network_rule.go @@ -14,6 +14,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +36,7 @@ func resourceArmMySqlVirtualNetworkRule() *schema.Resource { ValidateFunc: validate.VirtualNetworkRuleName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -54,7 +55,7 @@ func resourceArmMySqlVirtualNetworkRule() *schema.Resource { } func resourceArmMySqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlVirtualNetworkRulesClient + client := meta.(*ArmClient).mysql.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -62,7 +63,7 @@ func resourceArmMySqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta resourceGroup := d.Get("resource_group_name").(string) subnetId := d.Get("subnet_id").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -77,8 +78,8 @@ func resourceArmMySqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta // due to a bug in the API we have to ensure the Subnet's configured correctly or the API call will timeout // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3719 - subnetsClient := meta.(*ArmClient).subnetClient - subnetParsedId, err := parseAzureResourceID(subnetId) + subnetsClient := meta.(*ArmClient).network.SubnetsClient + subnetParsedId, err := azure.ParseAzureResourceID(subnetId) if err != nil { return err } @@ -152,10 +153,10 @@ func resourceArmMySqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta } func resourceArmMySqlVirtualNetworkRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlVirtualNetworkRulesClient + client := meta.(*ArmClient).mysql.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -187,10 +188,10 @@ func resourceArmMySqlVirtualNetworkRuleRead(d *schema.ResourceData, meta interfa } func resourceArmMySqlVirtualNetworkRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).mysqlVirtualNetworkRulesClient + client := meta.(*ArmClient).mysql.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -217,7 +218,7 @@ func resourceArmMySqlVirtualNetworkRuleDelete(d *schema.ResourceData, meta inter return nil } -func mySQLVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client mysql.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc { +func mySQLVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client *mysql.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { resp, err := client.Get(ctx, resourceGroup, serverName, name) diff --git a/azurerm/resource_arm_mysql_virtual_network_rule_test.go b/azurerm/resource_arm_mysql_virtual_network_rule_test.go index 3cafbbc1caa6..6bb1aba338e0 100644 --- a/azurerm/resource_arm_mysql_virtual_network_rule_test.go +++ b/azurerm/resource_arm_mysql_virtual_network_rule_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,7 +33,7 @@ func TestAccAzureRMMySqlVirtualNetworkRule_basic(t *testing.T) { } func TestAccAzureRMMySqlVirtualNetworkRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -150,7 +151,7 @@ func testCheckAzureRMMySqlVirtualNetworkRuleExists(resourceName string) resource serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).mysqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).mysql.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) @@ -176,7 +177,7 @@ func testCheckAzureRMMySqlVirtualNetworkRuleDestroy(s *terraform.State) error { serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).mysqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).mysql.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) @@ -206,7 +207,7 @@ func testCheckAzureRMMySqlVirtualNetworkRuleDisappears(resourceName string) reso serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).mysqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).mysql.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, serverName, ruleName) diff --git a/azurerm/resource_arm_network_connection_monitor.go b/azurerm/resource_arm_network_connection_monitor.go new file mode 100644 index 000000000000..c73970961eda --- /dev/null +++ b/azurerm/resource_arm_network_connection_monitor.go @@ -0,0 +1,333 @@ +package azurerm + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" +) + +func resourceArmNetworkConnectionMonitor() *schema.Resource { + return &schema.Resource{ + Create: resourceArmNetworkConnectionMonitorCreateUpdate, + Read: resourceArmNetworkConnectionMonitorRead, + Update: resourceArmNetworkConnectionMonitorCreateUpdate, + Delete: resourceArmNetworkConnectionMonitorDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "network_watcher_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "location": azure.SchemaLocation(), + + "auto_start": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Default: true, + }, + + "interval_in_seconds": { + Type: schema.TypeInt, + Optional: true, + Default: 60, + ValidateFunc: validation.IntAtLeast(30), + }, + + "source": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "virtual_machine_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + "port": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + ValidateFunc: validate.PortNumberOrZero, + }, + }, + }, + }, + + "destination": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "virtual_machine_id": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: azure.ValidateResourceID, + ConflictsWith: []string{"destination.0.address"}, + }, + "address": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"destination.0.virtual_machine_id"}, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validate.PortNumber, + }, + }, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmNetworkConnectionMonitorCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.ConnectionMonitorsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + watcherName := d.Get("network_watcher_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + autoStart := d.Get("auto_start").(bool) + intervalInSeconds := int32(d.Get("interval_in_seconds").(int)) + + source, err := expandArmNetworkConnectionMonitorSource(d) + if err != nil { + return err + } + + dest, err := expandArmNetworkConnectionMonitorDestination(d) + if err != nil { + return err + } + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, watcherName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Connection Monitor %q (Watcher %q / Resource Group %q): %s", name, watcherName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_network_connection_monitor", *existing.ID) + } + } + + t := d.Get("tags").(map[string]interface{}) + + properties := network.ConnectionMonitor{ + Location: utils.String(location), + Tags: tags.Expand(t), + ConnectionMonitorParameters: &network.ConnectionMonitorParameters{ + Source: source, + Destination: dest, + AutoStart: utils.Bool(autoStart), + MonitoringIntervalInSeconds: utils.Int32(intervalInSeconds), + }, + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, watcherName, name, properties) + if err != nil { + return fmt.Errorf("Error creating Connection Monitor %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Connection Monitor %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, watcherName, name) + if err != nil { + return fmt.Errorf("Error retrieving Connection Monitor %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + if resp.ID == nil { + return fmt.Errorf("Cannot read Connection Monitor %q (Watcher %q / Resource Group %q) ID", name, watcherName, resourceGroup) + } + + d.SetId(*resp.ID) + + return resourceArmNetworkConnectionMonitorRead(d, meta) +} + +func resourceArmNetworkConnectionMonitorRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.ConnectionMonitorsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + watcherName := id.Path["networkWatchers"] + name := id.Path["NetworkConnectionMonitors"] + + resp, err := client.Get(ctx, resourceGroup, watcherName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error reading Connection Monitor %q (Watcher %q / Resource Group %q) %+v", name, watcherName, resourceGroup, err) + } + + d.Set("name", name) + d.Set("network_watcher_name", watcherName) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.ConnectionMonitorResultProperties; props != nil { + d.Set("auto_start", props.AutoStart) + d.Set("interval_in_seconds", props.MonitoringIntervalInSeconds) + + source := flattenArmNetworkConnectionMonitorSource(props.Source) + if err := d.Set("source", source); err != nil { + return fmt.Errorf("Error setting `source`: %+v", err) + } + + dest := flattenArmNetworkConnectionMonitorDestination(props.Destination) + if err := d.Set("destination", dest); err != nil { + return fmt.Errorf("Error setting `destination`: %+v", err) + } + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmNetworkConnectionMonitorDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.ConnectionMonitorsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + watcherName := id.Path["networkWatchers"] + name := id.Path["NetworkConnectionMonitors"] + + future, err := client.Delete(ctx, resourceGroup, watcherName, name) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting Connection Monitor %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for the deletion of Connection Monitor %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + + return nil +} + +func flattenArmNetworkConnectionMonitorSource(input *network.ConnectionMonitorSource) []interface{} { + if input == nil { + return []interface{}{} + } + + output := make(map[string]interface{}) + + if resourceID := input.ResourceID; resourceID != nil { + output["virtual_machine_id"] = *resourceID + } + if port := input.Port; port != nil { + output["port"] = *port + } + + return []interface{}{output} +} + +func expandArmNetworkConnectionMonitorSource(d *schema.ResourceData) (*network.ConnectionMonitorSource, error) { + sources := d.Get("source").([]interface{}) + source := sources[0].(map[string]interface{}) + + monitorSource := network.ConnectionMonitorSource{} + if v := source["virtual_machine_id"]; v != "" { + monitorSource.ResourceID = utils.String(v.(string)) + } + if v := source["port"]; v != "" { + monitorSource.Port = utils.Int32(int32(v.(int))) + } + + return &monitorSource, nil +} + +func flattenArmNetworkConnectionMonitorDestination(input *network.ConnectionMonitorDestination) []interface{} { + if input == nil { + return []interface{}{} + } + + output := make(map[string]interface{}) + + // When monitoring a VM, the address field will contain the current address + // of the VM. We only want to copy over the address field if the virtual + // machine field is not set to avoid unwanted diffs. + if resourceID := input.ResourceID; resourceID != nil { + output["virtual_machine_id"] = *resourceID + } else if address := input.Address; address != nil { + output["address"] = *address + } + + if port := input.Port; port != nil { + output["port"] = *port + } + + return []interface{}{output} +} + +func expandArmNetworkConnectionMonitorDestination(d *schema.ResourceData) (*network.ConnectionMonitorDestination, error) { + dests := d.Get("destination").([]interface{}) + dest := dests[0].(map[string]interface{}) + + monitorDest := network.ConnectionMonitorDestination{} + + if v := dest["virtual_machine_id"]; v != "" { + monitorDest.ResourceID = utils.String(v.(string)) + } + if v := dest["address"]; v != "" { + monitorDest.Address = utils.String(v.(string)) + } + if v := dest["port"]; v != "" { + monitorDest.Port = utils.Int32(int32(v.(int))) + } + + if monitorDest.ResourceID == nil && monitorDest.Address == nil { + return nil, fmt.Errorf("Error: either `destination.virtual_machine_id` or `destination.address` must be specified") + } + + return &monitorDest, nil +} diff --git a/azurerm/resource_arm_network_connection_monitor_test.go b/azurerm/resource_arm_network_connection_monitor_test.go new file mode 100644 index 000000000000..b2781ac5887d --- /dev/null +++ b/azurerm/resource_arm_network_connection_monitor_test.go @@ -0,0 +1,699 @@ +package azurerm + +import ( + "fmt" + "net/http" + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func testAccAzureRMNetworkConnectionMonitor_addressBasic(t *testing.T) { + resourceName := "azurerm_network_connection_monitor.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_basicAddressConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "resource_group_name"), + resource.TestCheckResourceAttr(resourceName, "location", azure.NormalizeLocation(location)), + resource.TestCheckResourceAttr(resourceName, "auto_start", "true"), + resource.TestCheckResourceAttr(resourceName, "interval_in_seconds", "60"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkConnectionMonitor_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_network_connection_monitor.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_basicAddressConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + ), + }, + { + Config: testAccAzureRMNetworkConnectionMonitor_requiresImportConfig(ri, location), + ExpectError: testRequiresImportError("azurerm_network_connection_monitor"), + }, + }, + }) + +} + +func testAccAzureRMNetworkConnectionMonitor_addressComplete(t *testing.T) { + resourceName := "azurerm_network_connection_monitor.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + autoStart := "false" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_completeAddressConfig(ri, location, autoStart), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_start", "false"), + resource.TestCheckResourceAttr(resourceName, "interval_in_seconds", "30"), + resource.TestCheckResourceAttr(resourceName, "source.0.port", "20020"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.env", "test"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkConnectionMonitor_addressUpdate(t *testing.T) { + resourceName := "azurerm_network_connection_monitor.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + autoStart := "true" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_basicAddressConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + ), + }, + { + Config: testAccAzureRMNetworkConnectionMonitor_completeAddressConfig(ri, location, autoStart), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_start", "true"), + resource.TestCheckResourceAttr(resourceName, "interval_in_seconds", "30"), + resource.TestCheckResourceAttr(resourceName, "source.0.port", "20020"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.env", "test"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkConnectionMonitor_vmBasic(t *testing.T) { + resourceName := "azurerm_network_connection_monitor.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_basicVmConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "resource_group_name"), + resource.TestCheckResourceAttr(resourceName, "location", azure.NormalizeLocation(location)), + resource.TestCheckResourceAttr(resourceName, "auto_start", "true"), + resource.TestCheckResourceAttr(resourceName, "interval_in_seconds", "60"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkConnectionMonitor_vmComplete(t *testing.T) { + resourceName := "azurerm_network_connection_monitor.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + autoStart := "false" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_completeVmConfig(ri, location, autoStart), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_start", "false"), + resource.TestCheckResourceAttr(resourceName, "interval_in_seconds", "30"), + resource.TestCheckResourceAttr(resourceName, "source.0.port", "20020"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.env", "test"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkConnectionMonitor_vmUpdate(t *testing.T) { + resourceName := "azurerm_network_connection_monitor.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_basicVmConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + ), + }, + { + Config: testAccAzureRMNetworkConnectionMonitor_completeVmConfig(ri, location, "true"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_start", "true"), + resource.TestCheckResourceAttr(resourceName, "interval_in_seconds", "30"), + resource.TestCheckResourceAttr(resourceName, "source.0.port", "20020"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.env", "test"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkConnectionMonitor_destinationUpdate(t *testing.T) { + resourceName := "azurerm_network_connection_monitor.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_basicAddressConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "destination.0.address"), + ), + }, + { + Config: testAccAzureRMNetworkConnectionMonitor_basicVmConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "destination.0.virtual_machine_id"), + ), + }, + { + Config: testAccAzureRMNetworkConnectionMonitor_basicAddressConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkConnectionMonitorExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "destination.0.address"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkConnectionMonitor_missingDestination(t *testing.T) { + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_missingDestinationConfig(ri, location), + ExpectError: regexp.MustCompile("Error: either `destination.virtual_machine_id` or `destination.address` must be specified"), + }, + }, + }) +} + +func testAccAzureRMNetworkConnectionMonitor_conflictingDestinations(t *testing.T) { + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkConnectionMonitorDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkConnectionMonitor_conflictingDestinationsConfig(ri, location), + ExpectError: regexp.MustCompile("conflicts with destination.0.address"), + }, + }, + }) +} + +func testCheckAzureRMNetworkConnectionMonitorExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).network.ConnectionMonitorsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + watcherName := rs.Primary.Attributes["network_watcher_name"] + NetworkConnectionMonitorName := rs.Primary.Attributes["name"] + + resp, err := client.Get(ctx, resourceGroup, watcherName, NetworkConnectionMonitorName) + if err != nil { + return fmt.Errorf("Bad: Get on NetworkConnectionMonitorsClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Connection Monitor does not exist: %s", NetworkConnectionMonitorName) + } + + return nil + } +} + +func testCheckAzureRMNetworkConnectionMonitorDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).network.ConnectionMonitorsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_network_connection_monitor" { + continue + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + watcherName := rs.Primary.Attributes["network_watcher_name"] + NetworkConnectionMonitorName := rs.Primary.Attributes["name"] + + resp, err := client.Get(ctx, resourceGroup, watcherName, NetworkConnectionMonitorName) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Connection Monitor still exists:%s", *resp.Name) + } + } + + return nil +} + +func testAccAzureRMNetworkConnectionMonitor_baseConfig(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_network_watcher" "test" { + name = "acctnw-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "internal" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "src" { + name = "acctni-src%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_virtual_machine" "src" { + name = "acctvm-src%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.src.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "osdisk-src%d" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "hostname%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } +} + +resource "azurerm_virtual_machine_extension" "src" { + name = "network-watcher" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_machine_name = "${azurerm_virtual_machine.src.name}" + publisher = "Microsoft.Azure.NetworkWatcher" + type = "NetworkWatcherAgentLinux" + type_handler_version = "1.4" + auto_upgrade_minor_version = true +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMNetworkConnectionMonitor_baseWithDestConfig(rInt int, location string) string { + config := testAccAzureRMNetworkConnectionMonitor_baseConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_interface" "dest" { + name = "acctni-dest%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_virtual_machine" "dest" { + name = "acctvm-dest%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.dest.id}"] + vm_size = "Standard_D1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "osdisk-dest%d" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "hostname%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } +} +`, config, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMNetworkConnectionMonitor_basicAddressConfig(rInt int, location string) string { + config := testAccAzureRMNetworkConnectionMonitor_baseConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_connection_monitor" "test" { + name = "acctestcm-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_network_watcher.test.location}" + + source { + virtual_machine_id = "${azurerm_virtual_machine.src.id}" + } + + destination { + address = "terraform.io" + port = 80 + } + + depends_on = ["azurerm_virtual_machine_extension.src"] +} +`, config, rInt) +} + +func testAccAzureRMNetworkConnectionMonitor_completeAddressConfig(rInt int, location, autoStart string) string { + config := testAccAzureRMNetworkConnectionMonitor_baseConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_connection_monitor" "test" { + name = "acctestcm-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_network_watcher.test.location}" + + auto_start = %s + interval_in_seconds = 30 + + source { + virtual_machine_id = "${azurerm_virtual_machine.src.id}" + port = 20020 + } + + destination { + address = "terraform.io" + port = 443 + } + + tags = { + env = "test" + } + + depends_on = ["azurerm_virtual_machine_extension.src"] +} +`, config, rInt, autoStart) +} + +func testAccAzureRMNetworkConnectionMonitor_basicVmConfig(rInt int, location string) string { + config := testAccAzureRMNetworkConnectionMonitor_baseWithDestConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_connection_monitor" "test" { + name = "acctestcm-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_network_watcher.test.location}" + + source { + virtual_machine_id = "${azurerm_virtual_machine.src.id}" + } + + destination { + virtual_machine_id = "${azurerm_virtual_machine.dest.id}" + port = 80 + } + + depends_on = ["azurerm_virtual_machine_extension.src"] +} +`, config, rInt) +} + +func testAccAzureRMNetworkConnectionMonitor_completeVmConfig(rInt int, location, autoStart string) string { + config := testAccAzureRMNetworkConnectionMonitor_baseWithDestConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_connection_monitor" "test" { + name = "acctestcm-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_network_watcher.test.location}" + + auto_start = %s + interval_in_seconds = 30 + + source { + virtual_machine_id = "${azurerm_virtual_machine.src.id}" + port = 20020 + } + + destination { + virtual_machine_id = "${azurerm_virtual_machine.dest.id}" + port = 443 + } + + tags = { + env = "test" + } + + depends_on = ["azurerm_virtual_machine_extension.src"] +} +`, config, rInt, autoStart) +} + +func testAccAzureRMNetworkConnectionMonitor_missingDestinationConfig(rInt int, location string) string { + config := testAccAzureRMNetworkConnectionMonitor_baseConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_connection_monitor" "test" { + name = "acctestcm-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_network_watcher.test.location}" + + source { + virtual_machine_id = "${azurerm_virtual_machine.src.id}" + } + + destination { + port = 80 + } + + depends_on = ["azurerm_virtual_machine_extension.src"] +} +`, config, rInt) +} + +func testAccAzureRMNetworkConnectionMonitor_conflictingDestinationsConfig(rInt int, location string) string { + config := testAccAzureRMNetworkConnectionMonitor_baseConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_connection_monitor" "test" { + name = "acctestcm-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_network_watcher.test.location}" + + source { + virtual_machine_id = "${azurerm_virtual_machine.src.id}" + } + + destination { + address = "terraform.io" + virtual_machine_id = "${azurerm_virtual_machine.src.id}" + port = 80 + } + + depends_on = ["azurerm_virtual_machine_extension.src"] +} +`, config, rInt) +} + +func testAccAzureRMNetworkConnectionMonitor_requiresImportConfig(rInt int, location string) string { + config := testAccAzureRMNetworkConnectionMonitor_basicAddressConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_connection_monitor" "import" { + name = "${azurerm_network_connection_monitor.test.name}" + network_watcher_name = "${azurerm_network_connection_monitor.test.network_watcher_name}" + resource_group_name = "${azurerm_network_connection_monitor.test.resource_group_name}" + location = "${azurerm_network_connection_monitor.test.location}" + + source { + virtual_machine_id = "${azurerm_virtual_machine.src.id}" + } + + destination { + address = "terraform.io" + port = 80 + } + + depends_on = ["azurerm_virtual_machine_extension.src"] +} +`, config) +} diff --git a/azurerm/resource_arm_network_ddos_protection_plan.go b/azurerm/resource_arm_network_ddos_protection_plan.go new file mode 100644 index 000000000000..d7583910e927 --- /dev/null +++ b/azurerm/resource_arm_network_ddos_protection_plan.go @@ -0,0 +1,235 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +const azureNetworkDDoSProtectionPlanResourceName = "azurerm_network_ddos_protection_plan" + +func resourceArmNetworkDDoSProtectionPlan() *schema.Resource { + return &schema.Resource{ + Create: resourceArmNetworkDDoSProtectionPlanCreateUpdate, + Read: resourceArmNetworkDDoSProtectionPlanRead, + Update: resourceArmNetworkDDoSProtectionPlanCreateUpdate, + Delete: resourceArmNetworkDDoSProtectionPlanDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": azure.SchemaLocation(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "virtual_network_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmNetworkDDoSProtectionPlanCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.DDOSProtectionPlansClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for DDoS protection plan creation") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing DDoS Protection Plan %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_network_ddos_protection_plan", *existing.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) + + vnetsToLock, err := expandArmNetworkDDoSProtectionPlanVnetNames(d) + if err != nil { + return fmt.Errorf("Error extracting names of Virtual Network: %+v", err) + } + + locks.ByName(name, azureNetworkDDoSProtectionPlanResourceName) + defer locks.UnlockByName(name, azureNetworkDDoSProtectionPlanResourceName) + + locks.MultipleByName(vnetsToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(vnetsToLock, virtualNetworkResourceName) + + parameters := network.DdosProtectionPlan{ + Location: &location, + Tags: tags.Expand(t), + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, name, parameters) + if err != nil { + return fmt.Errorf("Error creating/updating DDoS Protection Plan %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation/update of DDoS Protection Plan %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + plan, err := client.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error retrieving DDoS Protection Plan %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if plan.ID == nil { + return fmt.Errorf("Cannot read DDoS Protection Plan %q (Resource Group %q) ID", name, resourceGroup) + } + + d.SetId(*plan.ID) + + return resourceArmNetworkDDoSProtectionPlanRead(d, meta) +} + +func resourceArmNetworkDDoSProtectionPlanRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.DDOSProtectionPlansClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["ddosProtectionPlans"] + + plan, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(plan.Response) { + log.Printf("[DEBUG] DDoS Protection Plan %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on DDoS Protection Plan %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", plan.Name) + d.Set("resource_group_name", resourceGroup) + if location := plan.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := plan.DdosProtectionPlanPropertiesFormat; props != nil { + vNetIDs := flattenArmNetworkDDoSProtectionPlanVirtualNetworkIDs(props.VirtualNetworks) + if err := d.Set("virtual_network_ids", vNetIDs); err != nil { + return fmt.Errorf("Error setting `virtual_network_ids`: %+v", err) + } + } + + return tags.FlattenAndSet(d, plan.Tags) +} + +func resourceArmNetworkDDoSProtectionPlanDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.DDOSProtectionPlansClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["ddosProtectionPlans"] + + read, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + // deleted outside of TF + log.Printf("[DEBUG] DDoS Protection Plan %q was not found in Resource Group %q - assuming removed!", name, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving DDoS Protection Plan %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + vnetsToLock, err := extractVnetNames(d) + if err != nil { + return fmt.Errorf("Error extracting names of Virtual Network: %+v", err) + } + + locks.ByName(name, azureNetworkDDoSProtectionPlanResourceName) + defer locks.UnlockByName(name, azureNetworkDDoSProtectionPlanResourceName) + + locks.MultipleByName(vnetsToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(vnetsToLock, virtualNetworkResourceName) + + future, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Error deleting DDoS Protection Plan %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for the deletion of DDoS Protection Plan %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + return err +} + +func expandArmNetworkDDoSProtectionPlanVnetNames(d *schema.ResourceData) (*[]string, error) { + vnetIDs := d.Get("virtual_network_ids").([]interface{}) + vnetNames := make([]string, 0) + + for _, vnetID := range vnetIDs { + vnetResourceID, err := azure.ParseAzureResourceID(vnetID.(string)) + if err != nil { + return nil, err + } + + vnetName := vnetResourceID.Path["virtualNetworks"] + + if !sliceContainsValue(vnetNames, vnetName) { + vnetNames = append(vnetNames, vnetName) + } + } + + return &vnetNames, nil +} + +func flattenArmNetworkDDoSProtectionPlanVirtualNetworkIDs(input *[]network.SubResource) []string { + vnetIDs := make([]string, 0) + if input == nil { + return vnetIDs + } + + // if-continue is used to simplify the deeply nested if-else statement. + for _, subRes := range *input { + if subRes.ID != nil { + vnetIDs = append(vnetIDs, *subRes.ID) + } + } + + return vnetIDs +} diff --git a/azurerm/resource_arm_network_ddos_protection_plan_test.go b/azurerm/resource_arm_network_ddos_protection_plan_test.go new file mode 100644 index 000000000000..e1408178713e --- /dev/null +++ b/azurerm/resource_arm_network_ddos_protection_plan_test.go @@ -0,0 +1,307 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +// NOTE: this is a test group to avoid each test case to run in parallel, since Azure only allows one DDoS Protection +// Plan per region. +func TestAccAzureRMNetworkDDoSProtectionPlan(t *testing.T) { + testCases := map[string]map[string]func(t *testing.T){ + "normal": { + "basic": testAccAzureRMNetworkDDoSProtectionPlan_basic, + "requiresImport": testAccAzureRMNetworkDDoSProtectionPlan_requiresImport, + "withTags": testAccAzureRMNetworkDDoSProtectionPlan_withTags, + "disappears": testAccAzureRMNetworkDDoSProtectionPlan_disappears, + }, + "deprecated": { + "basic": testAccAzureRMDDoSProtectionPlan_basic, + "requiresImport": testAccAzureRMDDoSProtectionPlan_requiresImport, + "withTags": testAccAzureRMDDoSProtectionPlan_withTags, + "disappears": testAccAzureRMDDoSProtectionPlan_disappears, + }, + } + + for group, steps := range testCases { + t.Run(group, func(t *testing.T) { + for name, tc := range steps { + t.Run(name, func(t *testing.T) { + tc(t) + }) + } + }) + } +} + +func testAccAzureRMNetworkDDoSProtectionPlan_basic(t *testing.T) { + resourceName := "azurerm_network_ddos_protection_plan.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkDDoSProtectionPlanDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkDDoSProtectionPlan_basicConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkDDoSProtectionPlanExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "virtual_network_ids.#"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkDDoSProtectionPlan_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_network_ddos_protection_plan.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkDDoSProtectionPlanDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkDDoSProtectionPlan_basicConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkDDoSProtectionPlanExists(resourceName), + ), + }, + { + Config: testAccAzureRMNetworkDDoSProtectionPlan_requiresImportConfig(ri, location), + ExpectError: testRequiresImportError("azurerm_network_ddos_protection_plan"), + }, + }, + }) +} + +func testAccAzureRMNetworkDDoSProtectionPlan_withTags(t *testing.T) { + resourceName := "azurerm_network_ddos_protection_plan.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkDDoSProtectionPlanDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkDDoSProtectionPlan_withTagsConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkDDoSProtectionPlanExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "Production"), + resource.TestCheckResourceAttr(resourceName, "tags.cost_center", "MSFT"), + ), + }, + { + Config: testAccAzureRMNetworkDDoSProtectionPlan_withUpdatedTagsConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkDDoSProtectionPlanExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "Staging"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkDDoSProtectionPlan_disappears(t *testing.T) { + resourceName := "azurerm_network_ddos_protection_plan.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkDDoSProtectionPlanDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkDDoSProtectionPlan_basicConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkDDoSProtectionPlanExists(resourceName), + testCheckAzureRMNetworkDDoSProtectionPlanDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testCheckAzureRMNetworkDDoSProtectionPlanExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).network.DDOSProtectionPlansClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for DDoS Protection Plan: %q", name) + } + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: DDoS Protection Plan %q (Resource Group: %q) does not exist", name, resourceGroup) + } + + return fmt.Errorf("Bad: Get on NetworkDDoSProtectionPlanClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMNetworkDDoSProtectionPlanDisappears(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for DDoS Protection Plan: %q", name) + } + + client := testAccProvider.Meta().(*ArmClient).network.DDOSProtectionPlansClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + future, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Bad: Delete on NetworkDDoSProtectionPlanClient: %+v", err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Bad: waiting for Deletion on NetworkDDoSProtectionPlanClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMNetworkDDoSProtectionPlanDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).network.DDOSProtectionPlansClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_network_ddos_protection_plan" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return fmt.Errorf("DDoS Protection Plan still exists:\n%#v", resp.DdosProtectionPlanPropertiesFormat) + } + + return nil +} + +func testAccAzureRMNetworkDDoSProtectionPlan_basicConfig(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_network_ddos_protection_plan" "test" { + name = "acctestddospplan-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rInt) +} + +func testAccAzureRMNetworkDDoSProtectionPlan_requiresImportConfig(rInt int, location string) string { + basicConfig := testAccAzureRMNetworkDDoSProtectionPlan_basicConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_ddos_protection_plan" "import" { + name = "${azurerm_network_ddos_protection_plan.test.name}" + location = "${azurerm_network_ddos_protection_plan.test.location}" + resource_group_name = "${azurerm_network_ddos_protection_plan.test.resource_group_name}" +} +`, basicConfig) +} + +func testAccAzureRMNetworkDDoSProtectionPlan_withTagsConfig(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_network_ddos_protection_plan" "test" { + name = "acctestddospplan-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Production" + cost_center = "MSFT" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMNetworkDDoSProtectionPlan_withUpdatedTagsConfig(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_network_ddos_protection_plan" "test" { + name = "acctestddospplan-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Staging" + } +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_network_interface.go b/azurerm/resource_arm_network_interface.go index ef5d69bf7a97..f7b820227f87 100644 --- a/azurerm/resource_arm_network_interface.go +++ b/azurerm/resource_arm_network_interface.go @@ -5,13 +5,16 @@ import ( "log" "strings" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,9 +38,9 @@ func resourceArmNetworkInterface() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "network_security_group_id": { Type: schema.TypeString, @@ -238,13 +241,13 @@ func resourceArmNetworkInterface() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmNetworkInterfaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Network Interface creation.") @@ -252,7 +255,7 @@ func resourceArmNetworkInterfaceCreateUpdate(d *schema.ResourceData, meta interf name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -265,18 +268,18 @@ func resourceArmNetworkInterfaceCreateUpdate(d *schema.ResourceData, meta interf } } - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) enableIpForwarding := d.Get("enable_ip_forwarding").(bool) enableAcceleratedNetworking := d.Get("enable_accelerated_networking").(bool) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) properties := network.InterfacePropertiesFormat{ EnableIPForwarding: &enableIpForwarding, EnableAcceleratedNetworking: &enableAcceleratedNetworking, } - azureRMLockByName(name, networkInterfaceResourceName) - defer azureRMUnlockByName(name, networkInterfaceResourceName) + locks.ByName(name, networkInterfaceResourceName) + defer locks.UnlockByName(name, networkInterfaceResourceName) if v, ok := d.GetOk("network_security_group_id"); ok { nsgId := v.(string) @@ -284,13 +287,15 @@ func resourceArmNetworkInterfaceCreateUpdate(d *schema.ResourceData, meta interf ID: &nsgId, } - networkSecurityGroupName, err := parseNetworkSecurityGroupName(nsgId) + parsedNsgID, err := azure.ParseAzureResourceID(nsgId) if err != nil { - return err + return fmt.Errorf("Error parsing Network Security Group ID %q: %+v", nsgId, err) } - azureRMLockByName(networkSecurityGroupName, networkSecurityGroupResourceName) - defer azureRMUnlockByName(networkSecurityGroupName, networkSecurityGroupResourceName) + networkSecurityGroupName := parsedNsgID.Path["networkSecurityGroups"] + + locks.ByName(networkSecurityGroupName, networkSecurityGroupResourceName) + defer locks.UnlockByName(networkSecurityGroupName, networkSecurityGroupResourceName) } dns, hasDns := d.GetOk("dns_servers") @@ -321,11 +326,11 @@ func resourceArmNetworkInterfaceCreateUpdate(d *schema.ResourceData, meta interf return fmt.Errorf("Error Building list of Network Interface IP Configurations: %+v", sgErr) } - azureRMLockMultipleByName(subnetnToLock, subnetResourceName) - defer azureRMUnlockMultipleByName(subnetnToLock, subnetResourceName) + locks.MultipleByName(subnetnToLock, subnetResourceName) + defer locks.UnlockMultipleByName(subnetnToLock, subnetResourceName) - azureRMLockMultipleByName(vnnToLock, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(vnnToLock, virtualNetworkResourceName) + locks.MultipleByName(vnnToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(vnnToLock, virtualNetworkResourceName) if len(ipConfigs) > 0 { properties.IPConfigurations = &ipConfigs @@ -335,7 +340,7 @@ func resourceArmNetworkInterfaceCreateUpdate(d *schema.ResourceData, meta interf Name: &name, Location: &location, InterfacePropertiesFormat: &properties, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resGroup, name, iface) @@ -361,10 +366,10 @@ func resourceArmNetworkInterfaceCreateUpdate(d *schema.ResourceData, meta interf } func resourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -383,7 +388,7 @@ func resourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) e d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.InterfacePropertiesFormat; props != nil { @@ -445,34 +450,34 @@ func resourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) e d.Set("enable_accelerated_networking", resp.EnableAcceleratedNetworking) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } resGroup := id.ResourceGroup name := id.Path["networkInterfaces"] - azureRMLockByName(name, networkInterfaceResourceName) - defer azureRMUnlockByName(name, networkInterfaceResourceName) + locks.ByName(name, networkInterfaceResourceName) + defer locks.UnlockByName(name, networkInterfaceResourceName) if v, ok := d.GetOk("network_security_group_id"); ok { networkSecurityGroupId := v.(string) - networkSecurityGroupName, err2 := parseNetworkSecurityGroupName(networkSecurityGroupId) - if err2 != nil { - return err2 + parsedNsgID, err := azure.ParseAzureResourceID(networkSecurityGroupId) + if err != nil { + return fmt.Errorf("Error parsing Network Security Group ID %q: %+v", networkSecurityGroupId, err) } - azureRMLockByName(networkSecurityGroupName, networkSecurityGroupResourceName) - defer azureRMUnlockByName(networkSecurityGroupName, networkSecurityGroupResourceName) + networkSecurityGroupName := parsedNsgID.Path["networkSecurityGroups"] + + locks.ByName(networkSecurityGroupName, networkSecurityGroupResourceName) + defer locks.UnlockByName(networkSecurityGroupName, networkSecurityGroupResourceName) } configs := d.Get("ip_configuration").([]interface{}) @@ -484,7 +489,7 @@ func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) subnet_id := data["subnet_id"].(string) if subnet_id != "" { - subnetId, err2 := parseAzureResourceID(subnet_id) + subnetId, err2 := azure.ParseAzureResourceID(subnet_id) if err2 != nil { return err2 } @@ -500,11 +505,11 @@ func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) } } - azureRMLockMultipleByName(&subnetNamesToLock, subnetResourceName) - defer azureRMUnlockMultipleByName(&subnetNamesToLock, subnetResourceName) + locks.MultipleByName(&subnetNamesToLock, subnetResourceName) + defer locks.UnlockMultipleByName(&subnetNamesToLock, subnetResourceName) - azureRMLockMultipleByName(&virtualNetworkNamesToLock, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(&virtualNetworkNamesToLock, virtualNetworkResourceName) + locks.MultipleByName(&virtualNetworkNamesToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(&virtualNetworkNamesToLock, virtualNetworkResourceName) future, err := client.Delete(ctx, resGroup, name) if err != nil { @@ -614,7 +619,7 @@ func expandAzureRmNetworkInterfaceIpConfigurations(d *schema.ResourceData) ([]ne ID: &subnet_id, } - subnetId, err := parseAzureResourceID(subnet_id) + subnetId, err := azure.ParseAzureResourceID(subnet_id) if err != nil { return []network.InterfaceIPConfiguration{}, nil, nil, err } diff --git a/azurerm/resource_arm_network_interface_application_gateway_association.go b/azurerm/resource_arm_network_interface_application_gateway_association.go index f249338dcd7c..4c1aa3bcb396 100644 --- a/azurerm/resource_arm_network_interface_application_gateway_association.go +++ b/azurerm/resource_arm_network_interface_application_gateway_association.go @@ -5,11 +5,13 @@ import ( "log" "strings" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -48,7 +50,7 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociation( } func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Network Interface <-> Application Gateway Backend Address Pool Association creation.") @@ -57,7 +59,7 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationC ipConfigurationName := d.Get("ip_configuration_name").(string) backendAddressPoolId := d.Get("backend_address_pool_id").(string) - id, err := parseAzureResourceID(networkInterfaceId) + id, err := azure.ParseAzureResourceID(networkInterfaceId) if err != nil { return err } @@ -65,8 +67,8 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationC networkInterfaceName := id.Path["networkInterfaces"] resourceGroup := id.ResourceGroup - azureRMLockByName(networkInterfaceName, networkInterfaceResourceName) - defer azureRMUnlockByName(networkInterfaceName, networkInterfaceResourceName) + locks.ByName(networkInterfaceName, networkInterfaceResourceName) + defer locks.UnlockByName(networkInterfaceName, networkInterfaceResourceName) read, err := client.Get(ctx, resourceGroup, networkInterfaceName, "") if err != nil { @@ -106,7 +108,7 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationC for _, existingPool := range *p.ApplicationGatewayBackendAddressPools { if id := existingPool.ID; id != nil { if *id == backendAddressPoolId { - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { return tf.ImportAsExistsError("azurerm_network_interface_application_gateway_backend_address_pool_association", resourceId) } @@ -141,7 +143,7 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationC } func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext splitId := strings.Split(d.Id(), "|") @@ -149,7 +151,7 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationR return fmt.Errorf("Expected ID to be in the format {networkInterfaceId}/ipConfigurations/{ipConfigurationName}|{backendAddressPoolId} but got %q", d.Id()) } - nicID, err := parseAzureResourceID(splitId[0]) + nicID, err := azure.ParseAzureResourceID(splitId[0]) if err != nil { return err } @@ -218,7 +220,7 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationR } func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext splitId := strings.Split(d.Id(), "|") @@ -226,7 +228,7 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationD return fmt.Errorf("Expected ID to be in the format {networkInterfaceId}/ipConfigurations/{ipConfigurationName}|{backendAddressPoolId} but got %q", d.Id()) } - nicID, err := parseAzureResourceID(splitId[0]) + nicID, err := azure.ParseAzureResourceID(splitId[0]) if err != nil { return err } @@ -236,8 +238,8 @@ func resourceArmNetworkInterfaceApplicationGatewayBackendAddressPoolAssociationD resourceGroup := nicID.ResourceGroup backendAddressPoolId := splitId[1] - azureRMLockByName(networkInterfaceName, networkInterfaceResourceName) - defer azureRMUnlockByName(networkInterfaceName, networkInterfaceResourceName) + locks.ByName(networkInterfaceName, networkInterfaceResourceName) + defer locks.UnlockByName(networkInterfaceName, networkInterfaceResourceName) read, err := client.Get(ctx, resourceGroup, networkInterfaceName, "") if err != nil { diff --git a/azurerm/resource_arm_network_interface_application_gateway_association_test.go b/azurerm/resource_arm_network_interface_application_gateway_association_test.go index 528469793f5d..03c918ea0413 100644 --- a/azurerm/resource_arm_network_interface_application_gateway_association_test.go +++ b/azurerm/resource_arm_network_interface_application_gateway_association_test.go @@ -4,11 +4,12 @@ import ( "fmt" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMNetworkInterfaceApplicationGatewayBackendAddressPoolAssociation_basic(t *testing.T) { @@ -31,7 +32,7 @@ func TestAccAzureRMNetworkInterfaceApplicationGatewayBackendAddressPoolAssociati } func TestAccAzureRMNetworkInterfaceApplicationGatewayBackendAddressPoolAssociation_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -90,7 +91,7 @@ func testCheckAzureRMNetworkInterfaceApplicationGatewayBackendAddressPoolAssocia return fmt.Errorf("Not found: %s", resourceName) } - nicID, err := parseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) + nicID, err := azure.ParseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) if err != nil { return err } @@ -100,7 +101,7 @@ func testCheckAzureRMNetworkInterfaceApplicationGatewayBackendAddressPoolAssocia backendAddressPoolId := rs.Primary.Attributes["backend_address_pool_id"] ipConfigurationName := rs.Primary.Attributes["ip_configuration_name"] - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, nicName, "") @@ -140,7 +141,7 @@ func testCheckAzureRMNetworkInterfaceApplicationGatewayBackendAddressPoolAssocia return fmt.Errorf("Not found: %s", resourceName) } - nicID, err := parseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) + nicID, err := azure.ParseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) if err != nil { return err } @@ -150,7 +151,7 @@ func testCheckAzureRMNetworkInterfaceApplicationGatewayBackendAddressPoolAssocia backendAddressPoolId := rs.Primary.Attributes["backend_address_pool_id"] ipConfigurationName := rs.Primary.Attributes["ip_configuration_name"] - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, nicName, "") diff --git a/azurerm/resource_arm_network_interface_application_security_group_association.go b/azurerm/resource_arm_network_interface_application_security_group_association.go index f2c46a6ec5c6..8fbabbc220dd 100644 --- a/azurerm/resource_arm_network_interface_application_security_group_association.go +++ b/azurerm/resource_arm_network_interface_application_security_group_association.go @@ -5,11 +5,13 @@ import ( "log" "strings" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -48,7 +50,7 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociation() *schema.Re } func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Network Interface <-> Application Security Group Association creation.") @@ -57,7 +59,7 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationCreate(d *sch ipConfigurationName := d.Get("ip_configuration_name").(string) applicationSecurityGroupId := d.Get("application_security_group_id").(string) - id, err := parseAzureResourceID(networkInterfaceId) + id, err := azure.ParseAzureResourceID(networkInterfaceId) if err != nil { return err } @@ -65,8 +67,8 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationCreate(d *sch networkInterfaceName := id.Path["networkInterfaces"] resourceGroup := id.ResourceGroup - azureRMLockByName(networkInterfaceName, networkInterfaceResourceName) - defer azureRMUnlockByName(networkInterfaceName, networkInterfaceResourceName) + locks.ByName(networkInterfaceName, networkInterfaceResourceName) + defer locks.UnlockByName(networkInterfaceName, networkInterfaceResourceName) read, err := client.Get(ctx, resourceGroup, networkInterfaceName, "") if err != nil { @@ -105,7 +107,7 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationCreate(d *sch for _, existingGroup := range *p.ApplicationSecurityGroups { if id := existingGroup.ID; id != nil { if *id == applicationSecurityGroupId { - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { return tf.ImportAsExistsError("azurerm_network_interface_application_security_group_association", *id) } @@ -141,7 +143,7 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationCreate(d *sch } func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext splitId := strings.Split(d.Id(), "|") @@ -149,7 +151,7 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationRead(d *schem return fmt.Errorf("Expected ID to be in the format {networkInterfaceId}/ipConfigurations/{ipConfigurationName}|{applicationSecurityGroupId} but got %q", d.Id()) } - nicID, err := parseAzureResourceID(splitId[0]) + nicID, err := azure.ParseAzureResourceID(splitId[0]) if err != nil { return err } @@ -218,7 +220,7 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationRead(d *schem } func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext splitId := strings.Split(d.Id(), "|") @@ -226,7 +228,7 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationDelete(d *sch return fmt.Errorf("Expected ID to be in the format {networkInterfaceId}/ipConfigurations/{ipConfigurationName}|{applicationSecurityGroupId} but got %q", d.Id()) } - nicID, err := parseAzureResourceID(splitId[0]) + nicID, err := azure.ParseAzureResourceID(splitId[0]) if err != nil { return err } @@ -236,8 +238,8 @@ func resourceArmNetworkInterfaceApplicationSecurityGroupAssociationDelete(d *sch resourceGroup := nicID.ResourceGroup applicationSecurityGroupId := splitId[1] - azureRMLockByName(networkInterfaceName, networkInterfaceResourceName) - defer azureRMUnlockByName(networkInterfaceName, networkInterfaceResourceName) + locks.ByName(networkInterfaceName, networkInterfaceResourceName) + defer locks.UnlockByName(networkInterfaceName, networkInterfaceResourceName) read, err := client.Get(ctx, resourceGroup, networkInterfaceName, "") if err != nil { diff --git a/azurerm/resource_arm_network_interface_application_security_group_association_test.go b/azurerm/resource_arm_network_interface_application_security_group_association_test.go index a71f26cd4baf..eb8ae0ecc4b7 100644 --- a/azurerm/resource_arm_network_interface_application_security_group_association_test.go +++ b/azurerm/resource_arm_network_interface_application_security_group_association_test.go @@ -4,11 +4,12 @@ import ( "fmt" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMNetworkInterfaceApplicationSecurityGroupAssociation_basic(t *testing.T) { @@ -31,7 +32,7 @@ func TestAccAzureRMNetworkInterfaceApplicationSecurityGroupAssociation_basic(t * } func TestAccAzureRMNetworkInterfaceApplicationSecurityGroupAssociation_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -90,7 +91,7 @@ func testCheckAzureRMNetworkInterfaceApplicationSecurityGroupAssociationExists(r return fmt.Errorf("Not found: %s", resourceName) } - nicID, err := parseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) + nicID, err := azure.ParseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) if err != nil { return err } @@ -100,7 +101,7 @@ func testCheckAzureRMNetworkInterfaceApplicationSecurityGroupAssociationExists(r applicationSecurityGroupId := rs.Primary.Attributes["application_security_group_id"] ipConfigurationName := rs.Primary.Attributes["ip_configuration_name"] - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, nicName, "") @@ -140,7 +141,7 @@ func testCheckAzureRMNetworkInterfaceApplicationSecurityGroupAssociationDisappea return fmt.Errorf("Not found: %s", resourceName) } - nicID, err := parseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) + nicID, err := azure.ParseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) if err != nil { return err } @@ -150,7 +151,7 @@ func testCheckAzureRMNetworkInterfaceApplicationSecurityGroupAssociationDisappea applicationSecurityGroupId := rs.Primary.Attributes["application_security_group_id"] ipConfigurationName := rs.Primary.Attributes["ip_configuration_name"] - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, nicName, "") @@ -223,7 +224,7 @@ resource "azurerm_network_interface" "test" { name = "testconfiguration1" subnet_id = "${azurerm_subnet.test.id}" private_ip_address_allocation = "Dynamic" - application_security_group_ids = [ "${azurerm_application_security_group.test.id}" ] + application_security_group_ids = ["${azurerm_application_security_group.test.id}"] } } diff --git a/azurerm/resource_arm_network_interface_backend_address_pool_association.go b/azurerm/resource_arm_network_interface_backend_address_pool_association.go index 520d202fd678..980073d83b95 100644 --- a/azurerm/resource_arm_network_interface_backend_address_pool_association.go +++ b/azurerm/resource_arm_network_interface_backend_address_pool_association.go @@ -5,11 +5,13 @@ import ( "log" "strings" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -48,7 +50,7 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociation() *schema.Resource } func resourceArmNetworkInterfaceBackendAddressPoolAssociationCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Network Interface <-> Load Balancer Backend Address Pool Association creation.") @@ -57,7 +59,7 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociationCreate(d *schema.Re ipConfigurationName := d.Get("ip_configuration_name").(string) backendAddressPoolId := d.Get("backend_address_pool_id").(string) - id, err := parseAzureResourceID(networkInterfaceId) + id, err := azure.ParseAzureResourceID(networkInterfaceId) if err != nil { return err } @@ -65,8 +67,8 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociationCreate(d *schema.Re networkInterfaceName := id.Path["networkInterfaces"] resourceGroup := id.ResourceGroup - azureRMLockByName(networkInterfaceName, networkInterfaceResourceName) - defer azureRMUnlockByName(networkInterfaceName, networkInterfaceResourceName) + locks.ByName(networkInterfaceName, networkInterfaceResourceName) + defer locks.UnlockByName(networkInterfaceName, networkInterfaceResourceName) read, err := client.Get(ctx, resourceGroup, networkInterfaceName, "") if err != nil { @@ -106,7 +108,7 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociationCreate(d *schema.Re for _, existingPool := range *p.LoadBalancerBackendAddressPools { if id := existingPool.ID; id != nil { if *id == backendAddressPoolId { - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { return tf.ImportAsExistsError("azurerm_network_interface_backend_address_pool_association", resourceId) } @@ -141,7 +143,7 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociationCreate(d *schema.Re } func resourceArmNetworkInterfaceBackendAddressPoolAssociationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext splitId := strings.Split(d.Id(), "|") @@ -149,7 +151,7 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociationRead(d *schema.Reso return fmt.Errorf("Expected ID to be in the format {networkInterfaceId}/ipConfigurations/{ipConfigurationName}|{backendAddressPoolId} but got %q", d.Id()) } - nicID, err := parseAzureResourceID(splitId[0]) + nicID, err := azure.ParseAzureResourceID(splitId[0]) if err != nil { return err } @@ -218,7 +220,7 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociationRead(d *schema.Reso } func resourceArmNetworkInterfaceBackendAddressPoolAssociationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext splitId := strings.Split(d.Id(), "|") @@ -226,7 +228,7 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociationDelete(d *schema.Re return fmt.Errorf("Expected ID to be in the format {networkInterfaceId}/ipConfigurations/{ipConfigurationName}|{backendAddressPoolId} but got %q", d.Id()) } - nicID, err := parseAzureResourceID(splitId[0]) + nicID, err := azure.ParseAzureResourceID(splitId[0]) if err != nil { return err } @@ -236,8 +238,8 @@ func resourceArmNetworkInterfaceBackendAddressPoolAssociationDelete(d *schema.Re resourceGroup := nicID.ResourceGroup backendAddressPoolId := splitId[1] - azureRMLockByName(networkInterfaceName, networkInterfaceResourceName) - defer azureRMUnlockByName(networkInterfaceName, networkInterfaceResourceName) + locks.ByName(networkInterfaceName, networkInterfaceResourceName) + defer locks.UnlockByName(networkInterfaceName, networkInterfaceResourceName) read, err := client.Get(ctx, resourceGroup, networkInterfaceName, "") if err != nil { diff --git a/azurerm/resource_arm_network_interface_backend_address_pool_association_test.go b/azurerm/resource_arm_network_interface_backend_address_pool_association_test.go index 8fe67d4c93c9..1de6b6286cb1 100644 --- a/azurerm/resource_arm_network_interface_backend_address_pool_association_test.go +++ b/azurerm/resource_arm_network_interface_backend_address_pool_association_test.go @@ -4,11 +4,12 @@ import ( "fmt" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMNetworkInterfaceBackendAddressPoolAssociation_basic(t *testing.T) { @@ -31,7 +32,7 @@ func TestAccAzureRMNetworkInterfaceBackendAddressPoolAssociation_basic(t *testin } func TestAccAzureRMNetworkInterfaceBackendAddressPoolAssociation_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -90,7 +91,7 @@ func testCheckAzureRMNetworkInterfaceBackendAddressPoolAssociationExists(resourc return fmt.Errorf("Not found: %s", resourceName) } - nicID, err := parseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) + nicID, err := azure.ParseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) if err != nil { return err } @@ -100,7 +101,7 @@ func testCheckAzureRMNetworkInterfaceBackendAddressPoolAssociationExists(resourc backendAddressPoolId := rs.Primary.Attributes["backend_address_pool_id"] ipConfigurationName := rs.Primary.Attributes["ip_configuration_name"] - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, nicName, "") @@ -140,7 +141,7 @@ func testCheckAzureRMNetworkInterfaceBackendAddressPoolAssociationDisappears(res return fmt.Errorf("Not found: %s", resourceName) } - nicID, err := parseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) + nicID, err := azure.ParseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) if err != nil { return err } @@ -150,7 +151,7 @@ func testCheckAzureRMNetworkInterfaceBackendAddressPoolAssociationDisappears(res backendAddressPoolId := rs.Primary.Attributes["backend_address_pool_id"] ipConfigurationName := rs.Primary.Attributes["ip_configuration_name"] - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, nicName, "") diff --git a/azurerm/resource_arm_network_interface_nat_rule_association.go b/azurerm/resource_arm_network_interface_nat_rule_association.go index 2027b9cd338b..22b8bc7934fd 100644 --- a/azurerm/resource_arm_network_interface_nat_rule_association.go +++ b/azurerm/resource_arm_network_interface_nat_rule_association.go @@ -5,11 +5,13 @@ import ( "log" "strings" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -48,7 +50,7 @@ func resourceArmNetworkInterfaceNatRuleAssociation() *schema.Resource { } func resourceArmNetworkInterfaceNatRuleAssociationCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Network Interface <-> Load Balancer NAT Rule Association creation.") @@ -57,7 +59,7 @@ func resourceArmNetworkInterfaceNatRuleAssociationCreate(d *schema.ResourceData, ipConfigurationName := d.Get("ip_configuration_name").(string) natRuleId := d.Get("nat_rule_id").(string) - id, err := parseAzureResourceID(networkInterfaceId) + id, err := azure.ParseAzureResourceID(networkInterfaceId) if err != nil { return err } @@ -65,8 +67,8 @@ func resourceArmNetworkInterfaceNatRuleAssociationCreate(d *schema.ResourceData, networkInterfaceName := id.Path["networkInterfaces"] resourceGroup := id.ResourceGroup - azureRMLockByName(networkInterfaceName, networkInterfaceResourceName) - defer azureRMUnlockByName(networkInterfaceName, networkInterfaceResourceName) + locks.ByName(networkInterfaceName, networkInterfaceResourceName) + defer locks.UnlockByName(networkInterfaceName, networkInterfaceResourceName) read, err := client.Get(ctx, resourceGroup, networkInterfaceName, "") if err != nil { @@ -106,7 +108,7 @@ func resourceArmNetworkInterfaceNatRuleAssociationCreate(d *schema.ResourceData, for _, existingRule := range *p.LoadBalancerInboundNatRules { if id := existingRule.ID; id != nil { if *id == natRuleId { - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { return tf.ImportAsExistsError("azurerm_network_interface_nat_rule_association", resourceId) } @@ -141,7 +143,7 @@ func resourceArmNetworkInterfaceNatRuleAssociationCreate(d *schema.ResourceData, } func resourceArmNetworkInterfaceNatRuleAssociationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext splitId := strings.Split(d.Id(), "|") @@ -149,7 +151,7 @@ func resourceArmNetworkInterfaceNatRuleAssociationRead(d *schema.ResourceData, m return fmt.Errorf("Expected ID to be in the format {networkInterfaceId}/ipConfigurations/{ipConfigurationName}|{natRuleId} but got %q", d.Id()) } - nicID, err := parseAzureResourceID(splitId[0]) + nicID, err := azure.ParseAzureResourceID(splitId[0]) if err != nil { return err } @@ -218,7 +220,7 @@ func resourceArmNetworkInterfaceNatRuleAssociationRead(d *schema.ResourceData, m } func resourceArmNetworkInterfaceNatRuleAssociationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).ifaceClient + client := meta.(*ArmClient).network.InterfacesClient ctx := meta.(*ArmClient).StopContext splitId := strings.Split(d.Id(), "|") @@ -226,7 +228,7 @@ func resourceArmNetworkInterfaceNatRuleAssociationDelete(d *schema.ResourceData, return fmt.Errorf("Expected ID to be in the format {networkInterfaceId}/ipConfigurations/{ipConfigurationName}|{natRuleId} but got %q", d.Id()) } - nicID, err := parseAzureResourceID(splitId[0]) + nicID, err := azure.ParseAzureResourceID(splitId[0]) if err != nil { return err } @@ -236,8 +238,8 @@ func resourceArmNetworkInterfaceNatRuleAssociationDelete(d *schema.ResourceData, resourceGroup := nicID.ResourceGroup natRuleId := splitId[1] - azureRMLockByName(networkInterfaceName, networkInterfaceResourceName) - defer azureRMUnlockByName(networkInterfaceName, networkInterfaceResourceName) + locks.ByName(networkInterfaceName, networkInterfaceResourceName) + defer locks.UnlockByName(networkInterfaceName, networkInterfaceResourceName) read, err := client.Get(ctx, resourceGroup, networkInterfaceName, "") if err != nil { diff --git a/azurerm/resource_arm_network_interface_nat_rule_association_test.go b/azurerm/resource_arm_network_interface_nat_rule_association_test.go index b4367f6d090a..74f3276ea8f3 100644 --- a/azurerm/resource_arm_network_interface_nat_rule_association_test.go +++ b/azurerm/resource_arm_network_interface_nat_rule_association_test.go @@ -4,11 +4,12 @@ import ( "fmt" "testing" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMNetworkInterfaceNATRuleAssociation_basic(t *testing.T) { @@ -31,7 +32,7 @@ func TestAccAzureRMNetworkInterfaceNATRuleAssociation_basic(t *testing.T) { } func TestAccAzureRMNetworkInterfaceNATRuleAssociation_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -90,7 +91,7 @@ func testCheckAzureRMNetworkInterfaceNATRuleAssociationExists(resourceName strin return fmt.Errorf("Not found: %s", resourceName) } - nicID, err := parseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) + nicID, err := azure.ParseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) if err != nil { return err } @@ -100,7 +101,7 @@ func testCheckAzureRMNetworkInterfaceNATRuleAssociationExists(resourceName strin natRuleId := rs.Primary.Attributes["nat_rule_id"] ipConfigurationName := rs.Primary.Attributes["ip_configuration_name"] - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, nicName, "") @@ -140,7 +141,7 @@ func testCheckAzureRMNetworkInterfaceNATRuleAssociationDisappears(resourceName s return fmt.Errorf("Not found: %s", resourceName) } - nicID, err := parseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) + nicID, err := azure.ParseAzureResourceID(rs.Primary.Attributes["network_interface_id"]) if err != nil { return err } @@ -150,7 +151,7 @@ func testCheckAzureRMNetworkInterfaceNATRuleAssociationDisappears(resourceName s ipConfigurationName := rs.Primary.Attributes["ip_configuration_name"] natRuleId := rs.Primary.Attributes["nat_rule_id"] - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext read, err := client.Get(ctx, resourceGroup, nicName, "") diff --git a/azurerm/resource_arm_network_interface_test.go b/azurerm/resource_arm_network_interface_test.go index 8a5d05bd4078..e820ef6404d4 100644 --- a/azurerm/resource_arm_network_interface_test.go +++ b/azurerm/resource_arm_network_interface_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -31,7 +32,7 @@ func TestAccAzureRMNetworkInterface_disappears(t *testing.T) { } func TestAccAzureRMNetworkInterface_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -423,7 +424,7 @@ func testCheckAzureRMNetworkInterfaceExists(resourceName string) resource.TestCh return fmt.Errorf("Bad: no resource group found in state for availability set: %q", name) } - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name, "") @@ -453,7 +454,7 @@ func testCheckAzureRMNetworkInterfaceDisappears(resourceName string) resource.Te return fmt.Errorf("Bad: no resource group found in state for availability set: %q", name) } - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, name) @@ -470,7 +471,7 @@ func testCheckAzureRMNetworkInterfaceDisappears(resourceName string) resource.Te } func testCheckAzureRMNetworkInterfaceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).ifaceClient + client := testAccProvider.Meta().(*ArmClient).network.InterfacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_network_packet_capture.go b/azurerm/resource_arm_network_packet_capture.go new file mode 100644 index 000000000000..ae191fda6664 --- /dev/null +++ b/azurerm/resource_arm_network_packet_capture.go @@ -0,0 +1,387 @@ +package azurerm + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + + "log" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmNetworkPacketCapture() *schema.Resource { + return &schema.Resource{ + Create: resourceArmNetworkPacketCaptureCreate, + Read: resourceArmNetworkPacketCaptureRead, + Delete: resourceArmNetworkPacketCaptureDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "network_watcher_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "target_resource_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "maximum_bytes_per_packet": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + Default: 0, + }, + + "maximum_bytes_per_session": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + Default: 1073741824, + }, + + "maximum_capture_duration": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + Default: 18000, + ValidateFunc: validation.IntBetween(1, 18000), + }, + + "storage_location": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "file_path": { + Type: schema.TypeString, + Optional: true, + }, + "storage_account_id": { + Type: schema.TypeString, + Optional: true, + }, + "storage_path": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "filter": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "local_ip_address": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "local_port": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "protocol": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.PcProtocolAny), + string(network.PcProtocolTCP), + string(network.PcProtocolUDP), + }, false), + }, + "remote_ip_address": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "remote_port": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + }, + }, + }, + } +} + +func resourceArmNetworkPacketCaptureCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.PacketCapturesClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + watcherName := d.Get("network_watcher_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + targetResourceId := d.Get("target_resource_id").(string) + bytesToCapturePerPacket := d.Get("maximum_bytes_per_packet").(int) + totalBytesPerSession := d.Get("maximum_bytes_per_session").(int) + timeLimitInSeconds := d.Get("maximum_capture_duration").(int) + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, resourceGroup, watcherName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Packet Capture %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_network_packet_capture", *existing.ID) + } + } + + storageLocation, err := expandArmNetworkPacketCaptureStorageLocation(d) + if err != nil { + return err + } + + filters, err := expandArmNetworkPacketCaptureFilters(d) + if err != nil { + return err + } + + properties := network.PacketCapture{ + PacketCaptureParameters: &network.PacketCaptureParameters{ + Target: utils.String(targetResourceId), + StorageLocation: storageLocation, + BytesToCapturePerPacket: utils.Int32(int32(bytesToCapturePerPacket)), + TimeLimitInSeconds: utils.Int32(int32(timeLimitInSeconds)), + TotalBytesPerSession: utils.Int32(int32(totalBytesPerSession)), + Filters: filters, + }, + } + + future, err := client.Create(ctx, resourceGroup, watcherName, name, properties) + if err != nil { + return fmt.Errorf("Error creating Packet Capture %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for creation of Packet Capture %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, watcherName, name) + if err != nil { + return fmt.Errorf("Error retrieving Packet Capture %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmNetworkPacketCaptureRead(d, meta) +} + +func resourceArmNetworkPacketCaptureRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.PacketCapturesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + watcherName := id.Path["networkWatchers"] + name := id.Path["NetworkPacketCaptures"] + + resp, err := client.Get(ctx, resourceGroup, watcherName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[WARN] Packet Capture %q (Watcher %q / Resource Group %q) %qw not found - removing from state", name, watcherName, resourceGroup, id) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Packet Capture %q (Watcher %q / Resource Group %q) %+v", name, watcherName, resourceGroup, err) + } + + d.Set("name", name) + d.Set("network_watcher_name", watcherName) + d.Set("resource_group_name", resourceGroup) + + if props := resp.PacketCaptureResultProperties; props != nil { + d.Set("target_resource_id", props.Target) + d.Set("maximum_bytes_per_packet", int(*props.BytesToCapturePerPacket)) + d.Set("maximum_bytes_per_session", int(*props.TotalBytesPerSession)) + d.Set("maximum_capture_duration", int(*props.TimeLimitInSeconds)) + + location := flattenArmNetworkPacketCaptureStorageLocation(props.StorageLocation) + if err := d.Set("storage_location", location); err != nil { + return fmt.Errorf("Error setting `storage_location`: %+v", err) + } + + filters := flattenArmNetworkPacketCaptureFilters(props.Filters) + if err := d.Set("filter", filters); err != nil { + return fmt.Errorf("Error setting `filter`: %+v", err) + } + } + + return nil +} + +func resourceArmNetworkPacketCaptureDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.PacketCapturesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + watcherName := id.Path["networkWatchers"] + name := id.Path["NetworkPacketCaptures"] + + future, err := client.Delete(ctx, resourceGroup, watcherName, name) + if err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + + return fmt.Errorf("Error deleting Packet Capture %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + + return fmt.Errorf("Error waiting for the deletion of Packet Capture %q (Watcher %q / Resource Group %q): %+v", name, watcherName, resourceGroup, err) + } + + return nil +} + +func expandArmNetworkPacketCaptureStorageLocation(d *schema.ResourceData) (*network.PacketCaptureStorageLocation, error) { + locations := d.Get("storage_location").([]interface{}) + if len(locations) == 0 { + return nil, fmt.Errorf("Error expandng `storage_location`: not found") + } + + location := locations[0].(map[string]interface{}) + + storageLocation := network.PacketCaptureStorageLocation{} + + if v := location["file_path"]; v != "" { + storageLocation.FilePath = utils.String(v.(string)) + } + if v := location["storage_account_id"]; v != "" { + storageLocation.StorageID = utils.String(v.(string)) + } + + return &storageLocation, nil +} + +func flattenArmNetworkPacketCaptureStorageLocation(input *network.PacketCaptureStorageLocation) []interface{} { + if input == nil { + return []interface{}{} + } + + output := make(map[string]interface{}) + + if path := input.FilePath; path != nil { + output["file_path"] = *path + } + + if account := input.StorageID; account != nil { + output["storage_account_id"] = *account + } + + if path := input.StoragePath; path != nil { + output["storage_path"] = *path + } + + return []interface{}{output} +} + +func expandArmNetworkPacketCaptureFilters(d *schema.ResourceData) (*[]network.PacketCaptureFilter, error) { + inputFilters := d.Get("filter").([]interface{}) + if len(inputFilters) == 0 { + return nil, nil + } + + filters := make([]network.PacketCaptureFilter, 0) + + for _, v := range inputFilters { + inputFilter := v.(map[string]interface{}) + + localIPAddress := inputFilter["local_ip_address"].(string) + localPort := inputFilter["local_port"].(string) // TODO: should this be an int? + protocol := inputFilter["protocol"].(string) + remoteIPAddress := inputFilter["remote_ip_address"].(string) + remotePort := inputFilter["remote_port"].(string) + + filter := network.PacketCaptureFilter{ + LocalIPAddress: utils.String(localIPAddress), + LocalPort: utils.String(localPort), + Protocol: network.PcProtocol(protocol), + RemoteIPAddress: utils.String(remoteIPAddress), + RemotePort: utils.String(remotePort), + } + filters = append(filters, filter) + } + + return &filters, nil +} + +func flattenArmNetworkPacketCaptureFilters(input *[]network.PacketCaptureFilter) []interface{} { + filters := make([]interface{}, 0) + + if inFilter := input; inFilter != nil { + for _, v := range *inFilter { + filter := make(map[string]interface{}) + + if address := v.LocalIPAddress; address != nil { + filter["local_ip_address"] = *address + } + + if port := v.LocalPort; port != nil { + filter["local_port"] = *port + } + + filter["protocol"] = string(v.Protocol) + + if address := v.RemoteIPAddress; address != nil { + filter["remote_ip_address"] = *address + } + + if port := v.RemotePort; port != nil { + filter["remote_port"] = *port + } + + filters = append(filters, filter) + } + } + + return filters +} diff --git a/azurerm/resource_arm_network_packet_capture_test.go b/azurerm/resource_arm_network_packet_capture_test.go new file mode 100644 index 000000000000..d196b245a1e2 --- /dev/null +++ b/azurerm/resource_arm_network_packet_capture_test.go @@ -0,0 +1,415 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func testAccAzureRMNetworkPacketCapture_localDisk(t *testing.T) { + resourceName := "azurerm_network_packet_capture.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkPacketCaptureDestroy, + Steps: []resource.TestStep{ + { + Config: testAzureRMNetworkPacketCapture_localDiskConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkPacketCaptureExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkPacketCapture_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_network_packet_capture.test" + ri := tf.AccRandTimeInt() + + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkPacketCaptureDestroy, + Steps: []resource.TestStep{ + { + Config: testAzureRMNetworkPacketCapture_localDiskConfig(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkPacketCaptureExists(resourceName), + ), + }, + { + Config: testAzureRMNetworkPacketCapture_localDiskConfig_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_network_packet_capture"), + }, + }, + }) +} +func testAccAzureRMNetworkPacketCapture_storageAccount(t *testing.T) { + resourceName := "azurerm_network_packet_capture.test" + + ri := tf.AccRandTimeInt() + rs := acctest.RandString(5) + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkPacketCaptureDestroy, + Steps: []resource.TestStep{ + { + Config: testAzureRMNetworkPacketCapture_storageAccountConfig(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkPacketCaptureExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkPacketCapture_storageAccountAndLocalDisk(t *testing.T) { + resourceName := "azurerm_network_packet_capture.test" + + ri := tf.AccRandTimeInt() + rs := acctest.RandString(5) + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkPacketCaptureDestroy, + Steps: []resource.TestStep{ + { + Config: testAzureRMNetworkPacketCapture_storageAccountAndLocalDiskConfig(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkPacketCaptureExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMNetworkPacketCapture_withFilters(t *testing.T) { + resourceName := "azurerm_network_packet_capture.test" + + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkPacketCaptureDestroy, + Steps: []resource.TestStep{ + { + Config: testAzureRMNetworkPacketCapture_localDiskConfigWithFilters(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkPacketCaptureExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMNetworkPacketCaptureExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).network.PacketCapturesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("not found: %s", resourceName) + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + watcherName := rs.Primary.Attributes["network_watcher_name"] + NetworkPacketCaptureName := rs.Primary.Attributes["name"] + + resp, err := client.Get(ctx, resourceGroup, watcherName, NetworkPacketCaptureName) + if err != nil { + return fmt.Errorf("Bad: Get on NetworkPacketCapturesClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Packet Capture does not exist: %s", NetworkPacketCaptureName) + } + + return nil + } +} + +func testCheckAzureRMNetworkPacketCaptureDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).network.PacketCapturesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_network_packet_capture" { + continue + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + watcherName := rs.Primary.Attributes["network_watcher_name"] + NetworkPacketCaptureName := rs.Primary.Attributes["name"] + + resp, err := client.Get(ctx, resourceGroup, watcherName, NetworkPacketCaptureName) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Packet Capture still exists:%s", *resp.Name) + } + } + + return nil +} + +func testAzureRMNetworkPacketCapture_base(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_network_watcher" "test" { + name = "acctestnw-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_virtual_network" "test" { + name = "acctvn-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "internal" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctni-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "acctvm-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_F2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "osdisk" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "hostname%d" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } +} + +resource "azurerm_virtual_machine_extension" "test" { + name = "network-watcher" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_machine_name = "${azurerm_virtual_machine.test.name}" + publisher = "Microsoft.Azure.NetworkWatcher" + type = "NetworkWatcherAgentLinux" + type_handler_version = "1.4" + auto_upgrade_minor_version = true +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt) +} + +func testAzureRMNetworkPacketCapture_localDiskConfig(rInt int, location string) string { + config := testAzureRMNetworkPacketCapture_base(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_packet_capture" "test" { + name = "acctestpc-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + target_resource_id = "${azurerm_virtual_machine.test.id}" + + storage_location { + file_path = "/var/captures/packet.cap" + } + + depends_on = ["azurerm_virtual_machine_extension.test"] +} +`, config, rInt) +} + +func testAzureRMNetworkPacketCapture_localDiskConfig_requiresImport(rInt int, location string) string { + config := testAzureRMNetworkPacketCapture_localDiskConfig(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_packet_capture" "import" { + name = "${azurerm_network_packet_capture.test.name}" + network_watcher_name = "${azurerm_network_packet_capture.test.network_watcher_name}" + resource_group_name = "${azurerm_network_packet_capture.test.resource_group_name}" + target_resource_id = "${azurerm_network_packet_capture.test.target_resource_id}" + + storage_location { + file_path = "/var/captures/packet.cap" + } + + depends_on = ["azurerm_virtual_machine_extension.test"] +} +`, config) +} + +func testAzureRMNetworkPacketCapture_localDiskConfigWithFilters(rInt int, location string) string { + config := testAzureRMNetworkPacketCapture_base(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_packet_capture" "test" { + name = "acctestpc-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + target_resource_id = "${azurerm_virtual_machine.test.id}" + + storage_location { + file_path = "/var/captures/packet.cap" + } + + filter { + local_ip_address = "127.0.0.1" + local_port = "8080;9020;" + protocol = "TCP" + } + + filter { + local_ip_address = "127.0.0.1" + local_port = "80;443;" + protocol = "UDP" + } + + depends_on = ["azurerm_virtual_machine_extension.test"] +} +`, config, rInt) +} + +func testAzureRMNetworkPacketCapture_storageAccountConfig(rInt int, rString string, location string) string { + config := testAzureRMNetworkPacketCapture_base(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_network_packet_capture" "test" { + name = "acctestpc-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + target_resource_id = "${azurerm_virtual_machine.test.id}" + + storage_location { + storage_account_id = "${azurerm_storage_account.test.id}" + } + + depends_on = ["azurerm_virtual_machine_extension.test"] +} +`, config, rString, rInt) +} + +func testAzureRMNetworkPacketCapture_storageAccountAndLocalDiskConfig(rInt int, rString string, location string) string { + config := testAzureRMNetworkPacketCapture_base(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_network_packet_capture" "test" { + name = "acctestpc-%d" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + target_resource_id = "${azurerm_virtual_machine.test.id}" + + storage_location { + file_path = "/var/captures/packet.cap" + storage_account_id = "${azurerm_storage_account.test.id}" + } + + depends_on = ["azurerm_virtual_machine_extension.test"] +} +`, config, rString, rInt) +} diff --git a/azurerm/resource_arm_network_profile.go b/azurerm/resource_arm_network_profile.go new file mode 100644 index 000000000000..e2f6f06543fe --- /dev/null +++ b/azurerm/resource_arm_network_profile.go @@ -0,0 +1,369 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +const azureNetworkProfileResourceName = "azurerm_network_profile" + +func resourceArmNetworkProfile() *schema.Resource { + return &schema.Resource{ + Create: resourceArmNetworkProfileCreateUpdate, + Read: resourceArmNetworkProfileRead, + Update: resourceArmNetworkProfileCreateUpdate, + Delete: resourceArmNetworkProfileDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "location": azure.SchemaLocation(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "container_network_interface": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "ip_configuration": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "subnet_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + }, + }, + }, + }, + }, + }, + + "container_network_interface_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmNetworkProfileCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.ProfileClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Network Profile creation") + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Network Profile %q (Resource Group %q): %s", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_network_profile", *existing.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) + + cniConfigs, err := expandNetworkProfileContainerNetworkInterface(d) + if err != nil { + return fmt.Errorf("Error building list of Container Network Interface Configurations: %+v", err) + } + + subnetsToLock, vnetsToLock, err := expandNetworkProfileVirtualNetworkSubnetNames(d) + if err != nil { + return fmt.Errorf("Error extracting names of Subnet and Virtual Network: %+v", err) + } + + locks.ByName(name, azureNetworkProfileResourceName) + defer locks.UnlockByName(name, azureNetworkProfileResourceName) + + locks.MultipleByName(subnetsToLock, subnetResourceName) + defer locks.UnlockMultipleByName(subnetsToLock, subnetResourceName) + + locks.MultipleByName(vnetsToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(vnetsToLock, virtualNetworkResourceName) + + parameters := network.Profile{ + Location: &location, + Tags: tags.Expand(t), + ProfilePropertiesFormat: &network.ProfilePropertiesFormat{ + ContainerNetworkInterfaceConfigurations: cniConfigs, + }, + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, name, parameters); err != nil { + return fmt.Errorf("Error creating/updating Network Profile %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + profile, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + return fmt.Errorf("Error retrieving Network Profile %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if profile.ID == nil { + return fmt.Errorf("Cannot read Network Profile %q (Resource Group %q) ID", name, resourceGroup) + } + + d.SetId(*profile.ID) + + return resourceArmNetworkProfileRead(d, meta) +} + +func resourceArmNetworkProfileRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.ProfileClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["networkProfiles"] + + profile, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + if utils.ResponseWasNotFound(profile.Response) { + log.Printf("[DEBUG] Network Profile %q was not found in Resource Group %q - removing from state!", name, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Network Profile %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", profile.Name) + d.Set("resource_group_name", resourceGroup) + if location := profile.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := profile.ProfilePropertiesFormat; props != nil { + cniConfigs := flattenNetworkProfileContainerNetworkInterface(props.ContainerNetworkInterfaceConfigurations) + if err := d.Set("container_network_interface", cniConfigs); err != nil { + return fmt.Errorf("Error setting `container_network_interface`: %+v", err) + } + + cniIDs := flattenNetworkProfileContainerNetworkInterfaceIDs(props.ContainerNetworkInterfaces) + if err := d.Set("container_network_interface_ids", cniIDs); err != nil { + return fmt.Errorf("Error setting `container_network_interface_ids`: %+v", err) + } + } + + return tags.FlattenAndSet(d, profile.Tags) +} + +func resourceArmNetworkProfileDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.ProfileClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["networkProfiles"] + + read, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + // deleted outside of TF + log.Printf("[DEBUG] Network Profile %q was not found in Resource Group %q - assuming removed!", name, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving Network Profile %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + subnetsToLock, vnetsToLock, err := expandNetworkProfileVirtualNetworkSubnetNames(d) + if err != nil { + return fmt.Errorf("Error extracting names of Subnet and Virtual Network: %+v", err) + } + + locks.ByName(name, azureNetworkProfileResourceName) + defer locks.UnlockByName(name, azureNetworkProfileResourceName) + + locks.MultipleByName(subnetsToLock, subnetResourceName) + defer locks.UnlockMultipleByName(subnetsToLock, subnetResourceName) + + locks.MultipleByName(vnetsToLock, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(vnetsToLock, virtualNetworkResourceName) + + if _, err = client.Delete(ctx, resourceGroup, name); err != nil { + return fmt.Errorf("Error deleting Network Profile %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + return err +} + +func expandNetworkProfileContainerNetworkInterface(d *schema.ResourceData) (*[]network.ContainerNetworkInterfaceConfiguration, error) { + cniConfigs := d.Get("container_network_interface").([]interface{}) + retCNIConfigs := make([]network.ContainerNetworkInterfaceConfiguration, 0) + + for _, cniConfig := range cniConfigs { + nciData := cniConfig.(map[string]interface{}) + nciName := nciData["name"].(string) + ipConfigs := nciData["ip_configuration"].([]interface{}) + + retIPConfigs := make([]network.IPConfigurationProfile, 0) + for _, ipConfig := range ipConfigs { + ipData := ipConfig.(map[string]interface{}) + ipName := ipData["name"].(string) + subNetID := ipData["subnet_id"].(string) + + retIPConfig := network.IPConfigurationProfile{ + Name: &ipName, + IPConfigurationProfilePropertiesFormat: &network.IPConfigurationProfilePropertiesFormat{ + Subnet: &network.Subnet{ + ID: &subNetID, + }, + }, + } + + retIPConfigs = append(retIPConfigs, retIPConfig) + } + + retCNIConfig := network.ContainerNetworkInterfaceConfiguration{ + Name: &nciName, + ContainerNetworkInterfaceConfigurationPropertiesFormat: &network.ContainerNetworkInterfaceConfigurationPropertiesFormat{ + IPConfigurations: &retIPConfigs, + }, + } + + retCNIConfigs = append(retCNIConfigs, retCNIConfig) + } + + return &retCNIConfigs, nil +} + +func expandNetworkProfileVirtualNetworkSubnetNames(d *schema.ResourceData) (*[]string, *[]string, error) { + cniConfigs := d.Get("container_network_interface").([]interface{}) + subnetNames := make([]string, 0) + vnetNames := make([]string, 0) + + for _, cniConfig := range cniConfigs { + nciData := cniConfig.(map[string]interface{}) + ipConfigs := nciData["ip_configuration"].([]interface{}) + + for _, ipConfig := range ipConfigs { + ipData := ipConfig.(map[string]interface{}) + subnetID := ipData["subnet_id"].(string) + + subnetResourceID, err := azure.ParseAzureResourceID(subnetID) + if err != nil { + return nil, nil, err + } + + subnetName := subnetResourceID.Path["subnets"] + vnetName := subnetResourceID.Path["virtualNetworks"] + + if !sliceContainsValue(subnetNames, subnetName) { + subnetNames = append(subnetNames, subnetName) + } + + if !sliceContainsValue(vnetNames, vnetName) { + vnetNames = append(vnetNames, vnetName) + } + } + } + + return &subnetNames, &vnetNames, nil +} + +func flattenNetworkProfileContainerNetworkInterface(input *[]network.ContainerNetworkInterfaceConfiguration) []interface{} { + retCNIConfigs := make([]interface{}, 0) + if input == nil { + return retCNIConfigs + } + + // if-continue is used to simplify the deeply nested if-else statement. + for _, cniConfig := range *input { + retCNIConfig := make(map[string]interface{}) + + if cniConfig.Name != nil { + retCNIConfig["name"] = *cniConfig.Name + } + + retIPConfigs := make([]interface{}, 0) + if cniProps := cniConfig.ContainerNetworkInterfaceConfigurationPropertiesFormat; cniProps != nil && cniProps.IPConfigurations != nil { + for _, ipConfig := range *cniProps.IPConfigurations { + retIPConfig := make(map[string]interface{}) + + if ipConfig.Name != nil { + retIPConfig["name"] = *ipConfig.Name + } + + if ipProps := ipConfig.IPConfigurationProfilePropertiesFormat; ipProps != nil && ipProps.Subnet != nil && ipProps.Subnet.ID != nil { + retIPConfig["subnet_id"] = *ipProps.Subnet.ID + } + + retIPConfigs = append(retIPConfigs, retIPConfig) + } + } + retCNIConfig["ip_configuration"] = retIPConfigs + + retCNIConfigs = append(retCNIConfigs, retCNIConfig) + } + + return retCNIConfigs +} + +func flattenNetworkProfileContainerNetworkInterfaceIDs(input *[]network.ContainerNetworkInterface) []string { + retCNIs := make([]string, 0) + if input == nil { + return retCNIs + } + + for _, retCNI := range *input { + if retCNI.ID != nil { + retCNIs = append(retCNIs, *retCNI.ID) + } + } + + return retCNIs +} diff --git a/azurerm/resource_arm_network_profile_test.go b/azurerm/resource_arm_network_profile_test.go new file mode 100644 index 000000000000..a5d9e9985f26 --- /dev/null +++ b/azurerm/resource_arm_network_profile_test.go @@ -0,0 +1,377 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMNetworkProfile_basic(t *testing.T) { + resourceName := "azurerm_network_profile.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkProfileDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkProfile_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkProfileExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "container_network_interface_ids.#"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMNetworkProfile_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_network_profile.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkProfileDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkProfile_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkProfileExists(resourceName), + ), + }, + { + Config: testAccAzureRMNetworkProfile_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_network_profile"), + }, + }, + }) +} + +func TestAccAzureRMNetworkProfile_withTags(t *testing.T) { + resourceName := "azurerm_network_profile.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkProfileDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkProfile_withTags(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkProfileExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "Production"), + resource.TestCheckResourceAttr(resourceName, "tags.cost_center", "MSFT"), + ), + }, + { + Config: testAccAzureRMNetworkProfile_withUpdatedTags(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkProfileExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "Staging"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMNetworkProfile_disappears(t *testing.T) { + resourceName := "azurerm_network_profile.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNetworkProfileDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNetworkProfile_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkProfileExists(resourceName), + testCheckAzureRMNetworkProfileDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testCheckAzureRMNetworkProfileExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Network Profile: %q", name) + } + + client := testAccProvider.Meta().(*ArmClient).network.ProfileClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Network Profile %q (Resource Group: %q) does not exist", name, resourceGroup) + } + + return fmt.Errorf("Bad: Get on netProfileClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMNetworkProfileDisappears(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Network Profile: %q", name) + } + + client := testAccProvider.Meta().(*ArmClient).network.ProfileClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + if _, err := client.Delete(ctx, resourceGroup, name); err != nil { + return fmt.Errorf("Bad: Delete on netProfileClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMNetworkProfileDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).network.ProfileClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_network_profile" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return fmt.Errorf("Network Profile still exists:\n%#v", resp.ProfilePropertiesFormat) + } + + return nil +} + +func testAccAzureRMNetworkProfile_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = ["10.1.0.0/16"] +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.1.0.0/24" + + delegation { + name = "acctestdelegation-%d" + + service_delegation { + name = "Microsoft.ContainerInstance/containerGroups" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } +} + +resource "azurerm_network_profile" "test" { + name = "acctestnetprofile-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + container_network_interface { + name = "acctesteth-%d" + + ip_configuration { + name = "acctestipconfig-%d" + subnet_id = "${azurerm_subnet.test.id}" + } + } +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMNetworkProfile_requiresImport(rInt int, location string) string { + basicConfig := testAccAzureRMNetworkProfile_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_network_profile" "import" { + name = "${azurerm_network_profile.test.name}" + location = "${azurerm_network_profile.test.location}" + resource_group_name = "${azurerm_network_profile.test.resource_group_name}" + + container_network_interface { + name = "${azurerm_network_profile.test.container_network_interface.0.name}" + + ip_configuration { + name = "${azurerm_network_profile.test.container_network_interface.0.ip_configuration.0.name}" + subnet_id = "${azurerm_subnet.test.id}" + } + } +} +`, basicConfig) +} + +func testAccAzureRMNetworkProfile_withTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = ["10.1.0.0/16"] +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.1.0.0/24" + + delegation { + name = "acctestdelegation-%d" + + service_delegation { + name = "Microsoft.ContainerInstance/containerGroups" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } +} + +resource "azurerm_network_profile" "test" { + name = "acctestnetprofile-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + container_network_interface { + name = "acctesteth-%d" + + ip_configuration { + name = "acctestipconfig-%d" + subnet_id = "${azurerm_subnet.test.id}" + } + } + + tags = { + environment = "Production" + cost_center = "MSFT" + } +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMNetworkProfile_withUpdatedTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = ["10.1.0.0/16"] +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.1.0.0/24" + + delegation { + name = "acctestdelegation-%d" + + service_delegation { + name = "Microsoft.ContainerInstance/containerGroups" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } +} + +resource "azurerm_network_profile" "test" { + name = "acctestnetprofile-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + container_network_interface { + name = "acctesteth-%d" + + ip_configuration { + name = "acctestipconfig-%d" + subnet_id = "${azurerm_subnet.test.id}" + } + } + + tags = { + environment = "Staging" + } +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_network_security_group.go b/azurerm/resource_arm_network_security_group.go index 06b164d53971..286be8ae5481 100644 --- a/azurerm/resource_arm_network_security_group.go +++ b/azurerm/resource_arm_network_security_group.go @@ -3,12 +3,17 @@ package azurerm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -31,14 +36,15 @@ func resourceArmNetworkSecurityGroup() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "security_rule": { - Type: schema.TypeSet, - Optional: true, - Computed: true, + Type: schema.TypeSet, + ConfigMode: schema.SchemaConfigModeAttr, + Optional: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { @@ -60,7 +66,7 @@ func resourceArmNetworkSecurityGroup() *schema.Resource { string(network.SecurityRuleProtocolTCP), string(network.SecurityRuleProtocolUDP), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "source_port_range": { @@ -132,7 +138,7 @@ func resourceArmNetworkSecurityGroup() *schema.Resource { string(network.SecurityRuleAccessAllow), string(network.SecurityRuleAccessDeny), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "priority": { @@ -148,25 +154,25 @@ func resourceArmNetworkSecurityGroup() *schema.Resource { string(network.SecurityRuleDirectionInbound), string(network.SecurityRuleDirectionOutbound), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmNetworkSecurityGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).secGroupClient + client := meta.(*ArmClient).network.SecurityGroupClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -179,16 +185,16 @@ func resourceArmNetworkSecurityGroupCreateUpdate(d *schema.ResourceData, meta in } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) sgRules, sgErr := expandAzureRmSecurityRules(d) if sgErr != nil { return fmt.Errorf("Error Building list of Network Security Group Rules: %+v", sgErr) } - azureRMLockByName(name, networkSecurityGroupResourceName) - defer azureRMUnlockByName(name, networkSecurityGroupResourceName) + locks.ByName(name, networkSecurityGroupResourceName) + defer locks.UnlockByName(name, networkSecurityGroupResourceName) sg := network.SecurityGroup{ Name: &name, @@ -196,7 +202,7 @@ func resourceArmNetworkSecurityGroupCreateUpdate(d *schema.ResourceData, meta in SecurityGroupPropertiesFormat: &network.SecurityGroupPropertiesFormat{ SecurityRules: &sgRules, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resGroup, name, sg) @@ -222,10 +228,10 @@ func resourceArmNetworkSecurityGroupCreateUpdate(d *schema.ResourceData, meta in } func resourceArmNetworkSecurityGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).secGroupClient + client := meta.(*ArmClient).network.SecurityGroupClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -244,7 +250,7 @@ func resourceArmNetworkSecurityGroupRead(d *schema.ResourceData, meta interface{ d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.SecurityGroupPropertiesFormat; props != nil { @@ -254,16 +260,14 @@ func resourceArmNetworkSecurityGroupRead(d *schema.ResourceData, meta interface{ } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmNetworkSecurityGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).secGroupClient + client := meta.(*ArmClient).network.SecurityGroupClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_network_security_group_test.go b/azurerm/resource_arm_network_security_group_test.go index 3635e12908f4..df197946ca0e 100644 --- a/azurerm/resource_arm_network_security_group_test.go +++ b/azurerm/resource_arm_network_security_group_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +36,7 @@ func TestAccAzureRMNetworkSecurityGroup_basic(t *testing.T) { } func TestAccAzureRMNetworkSecurityGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -98,12 +99,32 @@ func TestAccAzureRMNetworkSecurityGroup_update(t *testing.T) { Config: testAccAzureRMNetworkSecurityGroup_singleRule(rInt, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMNetworkSecurityGroupExists(resourceName), + + // The configuration for this step contains one security_rule + // block, which should now be reflected in the state. + resource.TestCheckResourceAttr(resourceName, "security_rule.#", "1"), ), }, { Config: testAccAzureRMNetworkSecurityGroup_basic(rInt, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMNetworkSecurityGroupExists(resourceName), + + // The configuration for this step contains no security_rule + // blocks at all, which means "ignore any existing security groups" + // and thus the one from the previous step is preserved. + resource.TestCheckResourceAttr(resourceName, "security_rule.#", "1"), + ), + }, + { + Config: testAccAzureRMNetworkSecurityGroup_rulesExplicitZero(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNetworkSecurityGroupExists(resourceName), + + // The configuration for this step assigns security_rule = [] + // to state explicitly that no rules are desired, so the + // rule from the first step should now be removed. + resource.TestCheckResourceAttr(resourceName, "security_rule.#", "0"), ), }, }, @@ -258,7 +279,7 @@ func testCheckAzureRMNetworkSecurityGroupExists(resourceName string) resource.Te return fmt.Errorf("Bad: no resource group found in state for network security group: %q", sgName) } - client := testAccProvider.Meta().(*ArmClient).secGroupClient + client := testAccProvider.Meta().(*ArmClient).network.SecurityGroupClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, sgName, "") if err != nil { @@ -287,7 +308,7 @@ func testCheckAzureRMNetworkSecurityGroupDisappears(resourceName string) resourc return fmt.Errorf("Bad: no resource group found in state for network security group: %q", sgName) } - client := testAccProvider.Meta().(*ArmClient).secGroupClient + client := testAccProvider.Meta().(*ArmClient).network.SecurityGroupClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, sgName) if err != nil { @@ -301,7 +322,7 @@ func testCheckAzureRMNetworkSecurityGroupDisappears(resourceName string) resourc } func testCheckAzureRMNetworkSecurityGroupDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).secGroupClient + client := testAccProvider.Meta().(*ArmClient).network.SecurityGroupClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -355,6 +376,23 @@ resource "azurerm_network_security_group" "test" { `, template) } +func testAccAzureRMNetworkSecurityGroup_rulesExplicitZero(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_network_security_group" "test" { + name = "acceptanceTestSecurityGroup1" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + security_rule = [] +} +`, rInt, location) +} + func testAccAzureRMNetworkSecurityGroup_singleRule(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/azurerm/resource_arm_network_security_rule.go b/azurerm/resource_arm_network_security_rule.go index e26869bb8198..3e70738c105f 100644 --- a/azurerm/resource_arm_network_security_rule.go +++ b/azurerm/resource_arm_network_security_rule.go @@ -3,10 +3,14 @@ package azurerm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,7 +31,7 @@ func resourceArmNetworkSecurityRule() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "network_security_group_name": { Type: schema.TypeString, @@ -49,7 +53,7 @@ func resourceArmNetworkSecurityRule() *schema.Resource { string(network.SecurityRuleProtocolTCP), string(network.SecurityRuleProtocolUDP), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "source_port_range": { @@ -131,7 +135,7 @@ func resourceArmNetworkSecurityRule() *schema.Resource { string(network.SecurityRuleAccessAllow), string(network.SecurityRuleAccessDeny), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "priority": { @@ -147,21 +151,21 @@ func resourceArmNetworkSecurityRule() *schema.Resource { string(network.SecurityRuleDirectionInbound), string(network.SecurityRuleDirectionOutbound), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, }, } } func resourceArmNetworkSecurityRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).secRuleClient + client := meta.(*ArmClient).network.SecurityRuleClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) nsgName := d.Get("network_security_group_name").(string) resGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, nsgName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -183,8 +187,8 @@ func resourceArmNetworkSecurityRuleCreateUpdate(d *schema.ResourceData, meta int direction := d.Get("direction").(string) protocol := d.Get("protocol").(string) - azureRMLockByName(nsgName, networkSecurityGroupResourceName) - defer azureRMUnlockByName(nsgName, networkSecurityGroupResourceName) + locks.ByName(nsgName, networkSecurityGroupResourceName) + defer locks.UnlockByName(nsgName, networkSecurityGroupResourceName) rule := network.SecurityRule{ Name: &name, @@ -290,10 +294,10 @@ func resourceArmNetworkSecurityRuleCreateUpdate(d *schema.ResourceData, meta int } func resourceArmNetworkSecurityRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).secRuleClient + client := meta.(*ArmClient).network.SecurityRuleClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -342,10 +346,10 @@ func resourceArmNetworkSecurityRuleRead(d *schema.ResourceData, meta interface{} } func resourceArmNetworkSecurityRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).secRuleClient + client := meta.(*ArmClient).network.SecurityRuleClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -353,8 +357,8 @@ func resourceArmNetworkSecurityRuleDelete(d *schema.ResourceData, meta interface nsgName := id.Path["networkSecurityGroups"] sgRuleName := id.Path["securityRules"] - azureRMLockByName(nsgName, networkSecurityGroupResourceName) - defer azureRMUnlockByName(nsgName, networkSecurityGroupResourceName) + locks.ByName(nsgName, networkSecurityGroupResourceName) + defer locks.UnlockByName(nsgName, networkSecurityGroupResourceName) future, err := client.Delete(ctx, resGroup, nsgName, sgRuleName) if err != nil { diff --git a/azurerm/resource_arm_network_security_rule_test.go b/azurerm/resource_arm_network_security_rule_test.go index 9a6bfcf03f22..7eaae852f240 100644 --- a/azurerm/resource_arm_network_security_rule_test.go +++ b/azurerm/resource_arm_network_security_rule_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMNetworkSecurityRule_basic(t *testing.T) { } func TestAccAzureRMNetworkSecurityRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -171,7 +172,7 @@ func testCheckAzureRMNetworkSecurityRuleExists(resourceName string) resource.Tes return fmt.Errorf("Bad: no resource group found in state for network security rule: %q", sgName) } - client := testAccProvider.Meta().(*ArmClient).secRuleClient + client := testAccProvider.Meta().(*ArmClient).network.SecurityRuleClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, sgName, sgrName) @@ -201,7 +202,7 @@ func testCheckAzureRMNetworkSecurityRuleDisappears(resourceName string) resource return fmt.Errorf("Bad: no resource group found in state for network security rule: %s", sgName) } - client := testAccProvider.Meta().(*ArmClient).secRuleClient + client := testAccProvider.Meta().(*ArmClient).network.SecurityRuleClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, sgName, sgrName) if err != nil { @@ -215,7 +216,7 @@ func testCheckAzureRMNetworkSecurityRuleDisappears(resourceName string) resource } func testCheckAzureRMNetworkSecurityRuleDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).secRuleClient + client := testAccProvider.Meta().(*ArmClient).network.SecurityRuleClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_network_watcher.go b/azurerm/resource_arm_network_watcher.go index 72633418c5d9..3e18b54cada9 100644 --- a/azurerm/resource_arm_network_watcher.go +++ b/azurerm/resource_arm_network_watcher.go @@ -3,10 +3,13 @@ package azurerm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -27,23 +30,23 @@ func resourceArmNetworkWatcher() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmNetworkWatcherCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).watcherClient + client := meta.(*ArmClient).network.WatcherClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -56,12 +59,12 @@ func resourceArmNetworkWatcherCreateUpdate(d *schema.ResourceData, meta interfac } } - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) watcher := network.Watcher{ Location: utils.String(location), - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.CreateOrUpdate(ctx, resourceGroup, name, watcher); err != nil { @@ -82,10 +85,10 @@ func resourceArmNetworkWatcherCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmNetworkWatcherRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).watcherClient + client := meta.(*ArmClient).network.WatcherClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -104,19 +107,17 @@ func resourceArmNetworkWatcherRead(d *schema.ResourceData, meta interface{}) err d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmNetworkWatcherDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).watcherClient + client := meta.(*ArmClient).network.WatcherClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_network_watcher_test.go b/azurerm/resource_arm_network_watcher_test.go index 4d5309542795..5d9c1fbd0831 100644 --- a/azurerm/resource_arm_network_watcher_test.go +++ b/azurerm/resource_arm_network_watcher_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -26,7 +27,7 @@ func TestAccAzureRMNetworkWatcher(t *testing.T) { "DataSource": { "basic": testAccDataSourceAzureRMNetworkWatcher_basic, }, - "ConnectionMonitor": { + "ConnectionMonitorOld": { "addressBasic": testAccAzureRMConnectionMonitor_addressBasic, "addressComplete": testAccAzureRMConnectionMonitor_addressComplete, "addressUpdate": testAccAzureRMConnectionMonitor_addressUpdate, @@ -38,13 +39,32 @@ func TestAccAzureRMNetworkWatcher(t *testing.T) { "bothDestinationsInvalid": testAccAzureRMConnectionMonitor_conflictingDestinations, "requiresImport": testAccAzureRMConnectionMonitor_requiresImport, }, - "PacketCapture": { + "PacketCaptureOld": { "localDisk": testAccAzureRMPacketCapture_localDisk, "storageAccount": testAccAzureRMPacketCapture_storageAccount, "storageAccountAndLocalDisk": testAccAzureRMPacketCapture_storageAccountAndLocalDisk, "withFilters": testAccAzureRMPacketCapture_withFilters, "requiresImport": testAccAzureRMPacketCapture_requiresImport, }, + "ConnectionMonitor": { + "addressBasic": testAccAzureRMNetworkConnectionMonitor_addressBasic, + "addressComplete": testAccAzureRMNetworkConnectionMonitor_addressComplete, + "addressUpdate": testAccAzureRMNetworkConnectionMonitor_addressUpdate, + "vmBasic": testAccAzureRMNetworkConnectionMonitor_vmBasic, + "vmComplete": testAccAzureRMNetworkConnectionMonitor_vmComplete, + "vmUpdate": testAccAzureRMNetworkConnectionMonitor_vmUpdate, + "destinationUpdate": testAccAzureRMNetworkConnectionMonitor_destinationUpdate, + "missingDestinationInvalid": testAccAzureRMNetworkConnectionMonitor_missingDestination, + "bothDestinationsInvalid": testAccAzureRMNetworkConnectionMonitor_conflictingDestinations, + "requiresImport": testAccAzureRMNetworkConnectionMonitor_requiresImport, + }, + "PacketCapture": { + "localDisk": testAccAzureRMNetworkPacketCapture_localDisk, + "storageAccount": testAccAzureRMNetworkPacketCapture_storageAccount, + "storageAccountAndLocalDisk": testAccAzureRMNetworkPacketCapture_storageAccountAndLocalDisk, + "withFilters": testAccAzureRMNetworkPacketCapture_withFilters, + "requiresImport": testAccAzureRMNetworkPacketCapture_requiresImport, + }, } for group, m := range testCases { @@ -84,7 +104,7 @@ func testAccAzureRMNetworkWatcher_basic(t *testing.T) { } func testAccAzureRMNetworkWatcher_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -194,7 +214,7 @@ func testCheckAzureRMNetworkWatcherExists(resourceName string) resource.TestChec return fmt.Errorf("Bad: no resource group found in state for Network Watcher: %q", name) } - client := testAccProvider.Meta().(*ArmClient).watcherClient + client := testAccProvider.Meta().(*ArmClient).network.WatcherClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -223,7 +243,7 @@ func testCheckAzureRMNetworkWatcherDisappears(resourceName string) resource.Test return fmt.Errorf("Bad: no resource group found in state for Network Watcher: %q", name) } - client := testAccProvider.Meta().(*ArmClient).watcherClient + client := testAccProvider.Meta().(*ArmClient).network.WatcherClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, name) if err != nil { @@ -250,7 +270,7 @@ func testCheckAzureRMNetworkWatcherDestroy(s *terraform.State) error { name := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).watcherClient + client := testAccProvider.Meta().(*ArmClient).network.WatcherClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_notification_hub.go b/azurerm/resource_arm_notification_hub.go index 37aedc794f37..0828c008e5a3 100644 --- a/azurerm/resource_arm_notification_hub.go +++ b/azurerm/resource_arm_notification_hub.go @@ -11,10 +11,14 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +var notificationHubResourceName = "azurerm_notification_hub" + const apnsProductionName = "Production" const apnsProductionEndpoint = "https://api.push.apple.com:443/3/device" const apnsSandboxName = "Sandbox" @@ -63,9 +67,9 @@ func resourceArmNotificationHub() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "apns_credential": { Type: schema.TypeList, @@ -123,21 +127,21 @@ func resourceArmNotificationHub() *schema.Resource { // NOTE: skipping tags as there's a bug in the API where the Keys for Tags are returned in lower-case // Azure Rest API Specs issue: https://github.com/Azure/azure-sdk-for-go/issues/2239 - //"tags": tagsSchema(), + //"tags": tags.Schema(), }, } } func resourceArmNotificationHubCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationHubsClient + client := meta.(*ArmClient).notificationHubs.HubsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) namespaceName := d.Get("namespace_name").(string) resourceGroup := d.Get("resource_group_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, namespaceName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -202,7 +206,7 @@ func resourceArmNotificationHubCreateUpdate(d *schema.ResourceData, meta interfa return resourceArmNotificationHubRead(d, meta) } -func notificationHubStateRefreshFunc(ctx context.Context, client notificationhubs.Client, resourceGroup, namespaceName, name string) resource.StateRefreshFunc { +func notificationHubStateRefreshFunc(ctx context.Context, client *notificationhubs.Client, resourceGroup, namespaceName, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, resourceGroup, namespaceName, name) if err != nil { @@ -218,10 +222,10 @@ func notificationHubStateRefreshFunc(ctx context.Context, client notificationhub } func resourceArmNotificationHubRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationHubsClient + client := meta.(*ArmClient).notificationHubs.HubsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -249,7 +253,7 @@ func resourceArmNotificationHubRead(d *schema.ResourceData, meta interface{}) er d.Set("namespace_name", namespaceName) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := credentials.PnsCredentialsProperties; props != nil { @@ -268,10 +272,10 @@ func resourceArmNotificationHubRead(d *schema.ResourceData, meta interface{}) er } func resourceArmNotificationHubDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationHubsClient + client := meta.(*ArmClient).notificationHubs.HubsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_notification_hub_authorization_rule.go b/azurerm/resource_arm_notification_hub_authorization_rule.go index e5ae644dca38..a3dc2ba04449 100644 --- a/azurerm/resource_arm_notification_hub_authorization_rule.go +++ b/azurerm/resource_arm_notification_hub_authorization_rule.go @@ -6,7 +6,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/notificationhubs/mgmt/2017-04-01/notificationhubs" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,7 +43,7 @@ func resourceArmNotificationHubAuthorizationRule() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "manage": { Type: schema.TypeBool, @@ -74,7 +77,7 @@ func resourceArmNotificationHubAuthorizationRule() *schema.Resource { } func resourceArmNotificationHubAuthorizationRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationHubsClient + client := meta.(*ArmClient).notificationHubs.HubsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -86,7 +89,7 @@ func resourceArmNotificationHubAuthorizationRuleCreateUpdate(d *schema.ResourceD send := d.Get("send").(bool) listen := d.Get("listen").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.GetAuthorizationRule(ctx, resourceGroup, namespaceName, notificationHubName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -99,6 +102,12 @@ func resourceArmNotificationHubAuthorizationRuleCreateUpdate(d *schema.ResourceD } } + locks.ByName(notificationHubName, notificationHubResourceName) + defer locks.UnlockByName(notificationHubName, notificationHubResourceName) + + locks.ByName(namespaceName, notificationHubNamespaceResourceName) + defer locks.UnlockByName(namespaceName, notificationHubNamespaceResourceName) + parameters := notificationhubs.SharedAccessAuthorizationRuleCreateOrUpdateParameters{ Properties: ¬ificationhubs.SharedAccessAuthorizationRuleProperties{ Rights: expandNotificationHubAuthorizationRuleRights(manage, send, listen), @@ -120,13 +129,14 @@ func resourceArmNotificationHubAuthorizationRuleCreateUpdate(d *schema.ResourceD d.SetId(*read.ID) return resourceArmNotificationHubAuthorizationRuleRead(d, meta) + } func resourceArmNotificationHubAuthorizationRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationHubsClient + client := meta.(*ArmClient).notificationHubs.HubsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -170,10 +180,10 @@ func resourceArmNotificationHubAuthorizationRuleRead(d *schema.ResourceData, met } func resourceArmNotificationHubAuthorizationRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationHubsClient + client := meta.(*ArmClient).notificationHubs.HubsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -182,6 +192,12 @@ func resourceArmNotificationHubAuthorizationRuleDelete(d *schema.ResourceData, m notificationHubName := id.Path["notificationHubs"] name := id.Path["AuthorizationRules"] + locks.ByName(notificationHubName, notificationHubResourceName) + defer locks.UnlockByName(notificationHubName, notificationHubResourceName) + + locks.ByName(namespaceName, notificationHubNamespaceResourceName) + defer locks.UnlockByName(namespaceName, notificationHubNamespaceResourceName) + resp, err := client.DeleteAuthorizationRule(ctx, resourceGroup, namespaceName, notificationHubName, name) if err != nil { if !utils.ResponseWasNotFound(resp) { diff --git a/azurerm/resource_arm_notification_hub_authorization_rule_test.go b/azurerm/resource_arm_notification_hub_authorization_rule_test.go index f1c1d0d0cc9e..b78cda4a81b3 100644 --- a/azurerm/resource_arm_notification_hub_authorization_rule_test.go +++ b/azurerm/resource_arm_notification_hub_authorization_rule_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMNotificationHubAuthorizationRule_listen(t *testing.T) { @@ -40,7 +41,7 @@ func TestAccAzureRMNotificationHubAuthorizationRule_listen(t *testing.T) { } func TestAccAzureRMNotificationHubAuthorizationRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -134,6 +135,61 @@ func TestAccAzureRMNotificationHubAuthorizationRule_send(t *testing.T) { }) } +func TestAccAzureRMNotificationHubAuthorizationRule_multi(t *testing.T) { + resourceOneName := "azurerm_notification_hub_authorization_rule.test1" + resourceTwoName := "azurerm_notification_hub_authorization_rule.test2" + resourceThreeName := "azurerm_notification_hub_authorization_rule.test3" + + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNotificationHubAuthorizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAzureRMNotificationHubAuthorizationRule_multi(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNotificationHubAuthorizationRuleExists(resourceOneName), + resource.TestCheckResourceAttr(resourceOneName, "manage", "false"), + resource.TestCheckResourceAttr(resourceOneName, "send", "true"), + resource.TestCheckResourceAttr(resourceOneName, "listen", "true"), + resource.TestCheckResourceAttrSet(resourceOneName, "primary_access_key"), + resource.TestCheckResourceAttrSet(resourceOneName, "secondary_access_key"), + testCheckAzureRMNotificationHubAuthorizationRuleExists(resourceTwoName), + resource.TestCheckResourceAttr(resourceTwoName, "manage", "false"), + resource.TestCheckResourceAttr(resourceTwoName, "send", "true"), + resource.TestCheckResourceAttr(resourceTwoName, "listen", "true"), + resource.TestCheckResourceAttrSet(resourceTwoName, "primary_access_key"), + resource.TestCheckResourceAttrSet(resourceTwoName, "secondary_access_key"), + testCheckAzureRMNotificationHubAuthorizationRuleExists(resourceThreeName), + resource.TestCheckResourceAttr(resourceThreeName, "manage", "false"), + resource.TestCheckResourceAttr(resourceThreeName, "send", "true"), + resource.TestCheckResourceAttr(resourceThreeName, "listen", "true"), + resource.TestCheckResourceAttrSet(resourceThreeName, "primary_access_key"), + resource.TestCheckResourceAttrSet(resourceThreeName, "secondary_access_key"), + ), + }, + { + ResourceName: resourceOneName, + ImportState: true, + ImportStateVerify: true, + }, + { + ResourceName: resourceTwoName, + ImportState: true, + ImportStateVerify: true, + }, + { + ResourceName: resourceThreeName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMNotificationHubAuthorizationRule_updated(t *testing.T) { resourceName := "azurerm_notification_hub_authorization_rule.test" @@ -178,7 +234,7 @@ func testCheckAzureRMNotificationHubAuthorizationRuleExists(resourceName string) return fmt.Errorf("not found: %s", resourceName) } - client := testAccProvider.Meta().(*ArmClient).notificationHubsClient + client := testAccProvider.Meta().(*ArmClient).notificationHubs.HubsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resourceGroup := rs.Primary.Attributes["resource_group_name"] @@ -200,7 +256,7 @@ func testCheckAzureRMNotificationHubAuthorizationRuleExists(resourceName string) } func testCheckAzureRMNotificationHubAuthorizationRuleDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).notificationHubsClient + client := testAccProvider.Meta().(*ArmClient).notificationHubs.HubsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -271,6 +327,41 @@ resource "azurerm_notification_hub_authorization_rule" "test" { `, template, ri) } +func testAzureRMNotificationHubAuthorizationRule_multi(ri int, location string) string { + template := testAzureRMNotificationHubAuthorizationRule_template(ri, location) + return fmt.Sprintf(` +%s + +resource "azurerm_notification_hub_authorization_rule" "test1" { + name = "acctestruleone-%d" + notification_hub_name = "${azurerm_notification_hub.test.name}" + namespace_name = "${azurerm_notification_hub_namespace.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + send = true + listen = true +} + +resource "azurerm_notification_hub_authorization_rule" "test2" { + name = "acctestruletwo-%d" + notification_hub_name = "${azurerm_notification_hub.test.name}" + namespace_name = "${azurerm_notification_hub_namespace.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + send = true + listen = true +} + +resource "azurerm_notification_hub_authorization_rule" "test3" { + name = "acctestrulethree-%d" + notification_hub_name = "${azurerm_notification_hub.test.name}" + namespace_name = "${azurerm_notification_hub_namespace.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + send = true + listen = true +} + +`, template, ri, ri, ri) +} + func testAzureRMNotificationHubAuthorizationRule_manage(ri int, location string) string { template := testAzureRMNotificationHubAuthorizationRule_template(ri, location) return fmt.Sprintf(` diff --git a/azurerm/resource_arm_notification_hub_namespace.go b/azurerm/resource_arm_notification_hub_namespace.go index 7e5c44ebe3a8..3f81197b22d2 100644 --- a/azurerm/resource_arm_notification_hub_namespace.go +++ b/azurerm/resource_arm_notification_hub_namespace.go @@ -11,11 +11,16 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +var notificationHubNamespaceResourceName = "azurerm_notification_hub_namespace" + func resourceArmNotificationHubNamespace() *schema.Resource { return &schema.Resource{ Create: resourceArmNotificationHubNamespaceCreateUpdate, @@ -34,14 +39,17 @@ func resourceArmNotificationHubNamespace() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "sku": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, + Type: schema.TypeList, + Optional: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the 'sku_name' property and will be removed in version 2.0 of the provider", + ConflictsWith: []string{"sku_name"}, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { @@ -58,6 +66,19 @@ func resourceArmNotificationHubNamespace() *schema.Resource { }, }, + "sku_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"sku"}, + ValidateFunc: validation.StringInSlice([]string{ + string(notificationhubs.Basic), + string(notificationhubs.Free), + string(notificationhubs.Standard), + }, false), + }, + "enabled": { Type: schema.TypeBool, Optional: true, @@ -71,12 +92,12 @@ func resourceArmNotificationHubNamespace() *schema.Resource { string(notificationhubs.Messaging), string(notificationhubs.NotificationHub), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, // NOTE: skipping tags as there's a bug in the API where the Keys for Tags are returned in lower-case // Azure Rest API Specs issue: https://github.com/Azure/azure-sdk-for-go/issues/2239 - //"tags": tagsSchema(), + //"tags": tags.Schema(), "servicebus_endpoint": { Type: schema.TypeString, @@ -87,16 +108,37 @@ func resourceArmNotificationHubNamespace() *schema.Resource { } func resourceArmNotificationHubNamespaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationNamespacesClient + client := meta.(*ArmClient).notificationHubs.NamespacesClient ctx := meta.(*ArmClient).StopContext + // Remove in 2.0 + var sku notificationhubs.Sku + + if inputs := d.Get("sku").([]interface{}); len(inputs) != 0 { + input := inputs[0].(map[string]interface{}) + v := input["name"].(string) + + sku = notificationhubs.Sku{ + Name: notificationhubs.SkuName(v), + } + } else { + // Keep in 2.0 + sku = notificationhubs.Sku{ + Name: notificationhubs.SkuName(d.Get("sku_name").(string)), + } + } + + if sku.Name == "" { + return fmt.Errorf("either 'sku_name' or 'sku' must be defined in the configuration file") + } + name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) namespaceType := d.Get("namespace_type").(string) enabled := d.Get("enabled").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -111,7 +153,7 @@ func resourceArmNotificationHubNamespaceCreateUpdate(d *schema.ResourceData, met parameters := notificationhubs.NamespaceCreateOrUpdateParameters{ Location: utils.String(location), - Sku: expandNotificationHubNamespacesSku(d.Get("sku").([]interface{})), + Sku: &sku, NamespaceProperties: ¬ificationhubs.NamespaceProperties{ Region: utils.String(location), NamespaceType: notificationhubs.NamespaceType(namespaceType), @@ -149,10 +191,10 @@ func resourceArmNotificationHubNamespaceCreateUpdate(d *schema.ResourceData, met } func resourceArmNotificationHubNamespaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationNamespacesClient + client := meta.(*ArmClient).notificationHubs.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -173,12 +215,20 @@ func resourceArmNotificationHubNamespaceRead(d *schema.ResourceData, meta interf d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } - sku := flattenNotificationHubNamespacesSku(resp.Sku) - if err := d.Set("sku", sku); err != nil { - return fmt.Errorf("Error setting `sku`: %+v", err) + if sku := resp.Sku; sku != nil { + // Remove in 2.0 + if err := d.Set("sku", flattenNotificationHubNamespacesSku(sku)); err != nil { + return fmt.Errorf("Error setting 'sku': %+v", err) + } + + if err := d.Set("sku_name", string(sku.Name)); err != nil { + return fmt.Errorf("Error setting 'sku_name': %+v", err) + } + } else { + return fmt.Errorf("Error making Read request on Notification Hub Namespace %q (Resource Group %q): Unable to retrieve 'sku' value", name, resourceGroup) } if props := resp.NamespaceProperties; props != nil { @@ -191,10 +241,10 @@ func resourceArmNotificationHubNamespaceRead(d *schema.ResourceData, meta interf } func resourceArmNotificationHubNamespaceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).notificationNamespacesClient + client := meta.(*ArmClient).notificationHubs.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -224,16 +274,7 @@ func resourceArmNotificationHubNamespaceDelete(d *schema.ResourceData, meta inte return nil } -func expandNotificationHubNamespacesSku(input []interface{}) *notificationhubs.Sku { - v := input[0].(map[string]interface{}) - - skuName := v["name"].(string) - - return ¬ificationhubs.Sku{ - Name: notificationhubs.SkuName(skuName), - } -} - +// Remove in 2.0 func flattenNotificationHubNamespacesSku(input *notificationhubs.Sku) []interface{} { outputs := make([]interface{}, 0) if input == nil { @@ -247,7 +288,7 @@ func flattenNotificationHubNamespacesSku(input *notificationhubs.Sku) []interfac return outputs } -func notificationHubNamespaceStateRefreshFunc(ctx context.Context, client notificationhubs.NamespacesClient, resourceGroupName string, name string) resource.StateRefreshFunc { +func notificationHubNamespaceStateRefreshFunc(ctx context.Context, client *notificationhubs.NamespacesClient, resourceGroupName string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, resourceGroupName, name) if err != nil { @@ -262,7 +303,7 @@ func notificationHubNamespaceStateRefreshFunc(ctx context.Context, client notifi } } -func notificationHubNamespaceDeleteStateRefreshFunc(ctx context.Context, client notificationhubs.NamespacesClient, resourceGroupName string, name string) resource.StateRefreshFunc { +func notificationHubNamespaceDeleteStateRefreshFunc(ctx context.Context, client *notificationhubs.NamespacesClient, resourceGroupName string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, resourceGroupName, name) if err != nil { diff --git a/azurerm/resource_arm_notification_hub_namespace_test.go b/azurerm/resource_arm_notification_hub_namespace_test.go index 423a6bb93dfa..72d3c2d98eaa 100644 --- a/azurerm/resource_arm_notification_hub_namespace_test.go +++ b/azurerm/resource_arm_notification_hub_namespace_test.go @@ -3,11 +3,13 @@ package azurerm import ( "fmt" "net/http" + "regexp" "testing" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMNotificationHubNamespace_free(t *testing.T) { @@ -34,8 +36,50 @@ func TestAccAzureRMNotificationHubNamespace_free(t *testing.T) { }) } +// Remove in 2.0 +func TestAccAzureRMNotificationHubNamespace_freeClassic(t *testing.T) { + resourceName := "azurerm_notification_hub_namespace.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNotificationHubNamespaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNotificationHubNamespace_freeClassic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMNotificationHubNamespaceExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +// Remove in 2.0 +func TestAccAzureRMNotificationHubNamespace_freeNotDefined(t *testing.T) { + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMNotificationHubNamespaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMNotificationHubNamespace_freeNotDefined(ri, testLocation()), + ExpectError: regexp.MustCompile("either 'sku_name' or 'sku' must be defined in the configuration file"), + }, + }, + }) +} + func TestAccAzureRMNotificationHubNamespace_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -69,7 +113,7 @@ func testCheckAzureRMNotificationHubNamespaceExists(resourceName string) resourc return fmt.Errorf("not found: %s", resourceName) } - client := testAccProvider.Meta().(*ArmClient).notificationNamespacesClient + client := testAccProvider.Meta().(*ArmClient).notificationHubs.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resourceGroup := rs.Primary.Attributes["resource_group_name"] @@ -89,7 +133,7 @@ func testCheckAzureRMNotificationHubNamespaceExists(resourceName string) resourc } func testCheckAzureRMNotificationHubNamespaceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).notificationNamespacesClient + client := testAccProvider.Meta().(*ArmClient).notificationHubs.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -120,6 +164,24 @@ resource "azurerm_resource_group" "test" { location = "%s" } +resource "azurerm_notification_hub_namespace" "test" { + name = "acctestnhn-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + namespace_type = "NotificationHub" + + sku_name = "Free" +} +`, ri, location, ri) +} + +func testAccAzureRMNotificationHubNamespace_freeClassic(ri int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + resource "azurerm_notification_hub_namespace" "test" { name = "acctestnhn-%d" resource_group_name = "${azurerm_resource_group.test.name}" @@ -133,6 +195,22 @@ resource "azurerm_notification_hub_namespace" "test" { `, ri, location, ri) } +func testAccAzureRMNotificationHubNamespace_freeNotDefined(ri int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_notification_hub_namespace" "test" { + name = "acctestnhn-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + namespace_type = "NotificationHub" +} +`, ri, location, ri) +} + func testAccAzureRMNotificationHubNamespace_requiresImport(ri int, location string) string { return fmt.Sprintf(` %s @@ -143,9 +221,7 @@ resource "azurerm_notification_hub_namespace" "import" { location = "${azurerm_notification_hub_namespace.test.location}" namespace_type = "${azurerm_notification_hub_namespace.test.namespace_type}" - sku { - name = "Free" - } + sku_name = "Free" } `, testAccAzureRMNotificationHubNamespace_free(ri, location)) } diff --git a/azurerm/resource_arm_notification_hub_test.go b/azurerm/resource_arm_notification_hub_test.go index 6160d2befeb4..1055b8730e72 100644 --- a/azurerm/resource_arm_notification_hub_test.go +++ b/azurerm/resource_arm_notification_hub_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMNotificationHub_basic(t *testing.T) { @@ -37,7 +38,7 @@ func TestAccAzureRMNotificationHub_basic(t *testing.T) { } func TestAccAzureRMNotificationHub_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -73,7 +74,7 @@ func testCheckAzureRMNotificationHubExists(resourceName string) resource.TestChe return fmt.Errorf("not found: %s", resourceName) } - client := testAccProvider.Meta().(*ArmClient).notificationHubsClient + client := testAccProvider.Meta().(*ArmClient).notificationHubs.HubsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resourceGroup := rs.Primary.Attributes["resource_group_name"] @@ -94,7 +95,7 @@ func testCheckAzureRMNotificationHubExists(resourceName string) resource.TestChe } func testCheckAzureRMNotificationHubDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).notificationHubsClient + client := testAccProvider.Meta().(*ArmClient).notificationHubs.HubsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_packet_capture.go b/azurerm/resource_arm_packet_capture.go index af70e2abce14..52fe9689bda4 100644 --- a/azurerm/resource_arm_packet_capture.go +++ b/azurerm/resource_arm_packet_capture.go @@ -3,11 +3,13 @@ package azurerm import ( "fmt" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "log" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" @@ -30,7 +32,7 @@ func resourceArmPacketCapture() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "network_watcher_name": { Type: schema.TypeString, @@ -133,7 +135,7 @@ func resourceArmPacketCapture() *schema.Resource { } func resourceArmPacketCaptureCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).packetCapturesClient + client := meta.(*ArmClient).network.PacketCapturesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -145,7 +147,7 @@ func resourceArmPacketCaptureCreate(d *schema.ResourceData, meta interface{}) er totalBytesPerSession := d.Get("maximum_bytes_per_session").(int) timeLimitInSeconds := d.Get("maximum_capture_duration").(int) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.Get(ctx, resourceGroup, watcherName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -199,10 +201,10 @@ func resourceArmPacketCaptureCreate(d *schema.ResourceData, meta interface{}) er } func resourceArmPacketCaptureRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).packetCapturesClient + client := meta.(*ArmClient).network.PacketCapturesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -247,10 +249,10 @@ func resourceArmPacketCaptureRead(d *schema.ResourceData, meta interface{}) erro } func resourceArmPacketCaptureDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).packetCapturesClient + client := meta.(*ArmClient).network.PacketCapturesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_packet_capture_test.go b/azurerm/resource_arm_packet_capture_test.go index 85d232306a31..c586c17e748d 100644 --- a/azurerm/resource_arm_packet_capture_test.go +++ b/azurerm/resource_arm_packet_capture_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func testAccAzureRMPacketCapture_localDisk(t *testing.T) { @@ -38,7 +39,7 @@ func testAccAzureRMPacketCapture_localDisk(t *testing.T) { } func testAccAzureRMPacketCapture_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -157,7 +158,7 @@ func testCheckAzureRMPacketCaptureExists(resourceName string) resource.TestCheck watcherName := rs.Primary.Attributes["network_watcher_name"] packetCaptureName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).packetCapturesClient + client := testAccProvider.Meta().(*ArmClient).network.PacketCapturesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, watcherName, packetCaptureName) @@ -174,7 +175,7 @@ func testCheckAzureRMPacketCaptureExists(resourceName string) resource.TestCheck } func testCheckAzureRMPacketCaptureDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).packetCapturesClient + client := testAccProvider.Meta().(*ArmClient).network.PacketCapturesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_policy_assignment.go b/azurerm/resource_arm_policy_assignment.go index 04450f2432b1..e5cafe219906 100644 --- a/azurerm/resource_arm_policy_assignment.go +++ b/azurerm/resource_arm_policy_assignment.go @@ -4,7 +4,9 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "time" @@ -58,7 +60,7 @@ func resourceArmPolicyAssignment() *schema.Resource { Optional: true, }, - "location": locationSchemaOptional(), + "location": azure.SchemaLocationOptional(), "identity": { Type: schema.TypeList, @@ -106,7 +108,7 @@ func resourceArmPolicyAssignment() *schema.Resource { } func resourceArmPolicyAssignmentCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policyAssignmentsClient + client := meta.(*ArmClient).policy.AssignmentsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -115,7 +117,7 @@ func resourceArmPolicyAssignmentCreateOrUpdate(d *schema.ResourceData, meta inte policyDefinitionId := d.Get("policy_definition_id").(string) displayName := d.Get("display_name").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, scope, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -146,7 +148,7 @@ func resourceArmPolicyAssignmentCreateOrUpdate(d *schema.ResourceData, meta inte } if v := d.Get("location").(string); v != "" { - assignment.Location = utils.String(azureRMNormalizeLocation(v)) + assignment.Location = utils.String(azure.NormalizeLocation(v)) } if v := d.Get("parameters").(string); v != "" { @@ -193,7 +195,7 @@ func resourceArmPolicyAssignmentCreateOrUpdate(d *schema.ResourceData, meta inte } func resourceArmPolicyAssignmentRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policyAssignmentsClient + client := meta.(*ArmClient).policy.AssignmentsClient ctx := meta.(*ArmClient).StopContext id := d.Id() @@ -216,7 +218,7 @@ func resourceArmPolicyAssignmentRead(d *schema.ResourceData, meta interface{}) e } if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.AssignmentProperties; props != nil { @@ -242,7 +244,7 @@ func resourceArmPolicyAssignmentRead(d *schema.ResourceData, meta interface{}) e } func resourceArmPolicyAssignmentDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policyAssignmentsClient + client := meta.(*ArmClient).policy.AssignmentsClient ctx := meta.(*ArmClient).StopContext id := d.Id() @@ -259,7 +261,7 @@ func resourceArmPolicyAssignmentDelete(d *schema.ResourceData, meta interface{}) return nil } -func policyAssignmentRefreshFunc(ctx context.Context, client policy.AssignmentsClient, scope string, name string) resource.StateRefreshFunc { +func policyAssignmentRefreshFunc(ctx context.Context, client *policy.AssignmentsClient, scope string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, scope, name) if err != nil { diff --git a/azurerm/resource_arm_policy_assignment_test.go b/azurerm/resource_arm_policy_assignment_test.go index e20863937a25..241ad6f2ca58 100644 --- a/azurerm/resource_arm_policy_assignment_test.go +++ b/azurerm/resource_arm_policy_assignment_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMPolicyAssignment_basic(t *testing.T) { @@ -35,7 +36,7 @@ func TestAccAzureRMPolicyAssignment_basic(t *testing.T) { } func TestAccAzureRMPolicyAssignment_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -146,7 +147,7 @@ func testCheckAzureRMPolicyAssignmentExists(resourceName string) resource.TestCh return fmt.Errorf("not found: %s", resourceName) } - client := testAccProvider.Meta().(*ArmClient).policyAssignmentsClient + client := testAccProvider.Meta().(*ArmClient).policy.AssignmentsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext id := rs.Primary.ID @@ -164,7 +165,7 @@ func testCheckAzureRMPolicyAssignmentExists(resourceName string) resource.TestCh } func testCheckAzureRMPolicyAssignmentDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).policyAssignmentsClient + client := testAccProvider.Meta().(*ArmClient).policy.AssignmentsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -303,9 +304,11 @@ resource "azurerm_policy_assignment" "test" { name = "acctestpa-%d" scope = "${azurerm_resource_group.test.id}" policy_definition_id = "${azurerm_policy_definition.test.id}" + identity { type = "SystemAssigned" } + location = "%s" } `, ri, ri, ri, location, ri, location) diff --git a/azurerm/resource_arm_policy_definition.go b/azurerm/resource_arm_policy_definition.go index c5ac5c389982..68c5a6bd3e04 100644 --- a/azurerm/resource_arm_policy_definition.go +++ b/azurerm/resource_arm_policy_definition.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "time" @@ -102,7 +103,7 @@ func resourceArmPolicyDefinition() *schema.Resource { } func resourceArmPolicyDefinitionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policyDefinitionsClient + client := meta.(*ArmClient).policy.DefinitionsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -112,7 +113,7 @@ func resourceArmPolicyDefinitionCreateUpdate(d *schema.ResourceData, meta interf description := d.Get("description").(string) managementGroupID := d.Get("management_group_id").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := getPolicyDefinition(ctx, client, name, managementGroupID) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -198,7 +199,7 @@ func resourceArmPolicyDefinitionCreateUpdate(d *schema.ResourceData, meta interf } func resourceArmPolicyDefinitionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policyDefinitionsClient + client := meta.(*ArmClient).policy.DefinitionsClient ctx := meta.(*ArmClient).StopContext name, err := parsePolicyDefinitionNameFromId(d.Id()) @@ -246,7 +247,7 @@ func resourceArmPolicyDefinitionRead(d *schema.ResourceData, meta interface{}) e } func resourceArmPolicyDefinitionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policyDefinitionsClient + client := meta.(*ArmClient).policy.DefinitionsClient ctx := meta.(*ArmClient).StopContext name, err := parsePolicyDefinitionNameFromId(d.Id()) @@ -295,7 +296,7 @@ func parseManagementGroupIdFromPolicyId(id string) string { return "" } -func policyDefinitionRefreshFunc(ctx context.Context, client policy.DefinitionsClient, name string, managementGroupID string) resource.StateRefreshFunc { +func policyDefinitionRefreshFunc(ctx context.Context, client *policy.DefinitionsClient, name string, managementGroupID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := getPolicyDefinition(ctx, client, name, managementGroupID) @@ -322,7 +323,7 @@ func resourceArmPolicyDefinitionImport(d *schema.ResourceData, meta interface{}) return schema.ImportStatePassthrough(d, meta) } -func getPolicyDefinition(ctx context.Context, client policy.DefinitionsClient, name string, managementGroupID string) (res policy.Definition, err error) { +func getPolicyDefinition(ctx context.Context, client *policy.DefinitionsClient, name string, managementGroupID string) (res policy.Definition, err error) { if managementGroupID == "" { res, err = client.Get(ctx, name) } else { diff --git a/azurerm/resource_arm_policy_definition_test.go b/azurerm/resource_arm_policy_definition_test.go index f1abb5083ff1..12743c5cc9e8 100644 --- a/azurerm/resource_arm_policy_definition_test.go +++ b/azurerm/resource_arm_policy_definition_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMPolicyDefinition_basic(t *testing.T) { @@ -35,7 +36,7 @@ func TestAccAzureRMPolicyDefinition_basic(t *testing.T) { } func TestAccAzureRMPolicyDefinition_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -89,7 +90,6 @@ func TestAccAzureRMPolicyDefinition_computedMetadata(t *testing.T) { func TestAccAzureRMPolicyDefinitionAtMgmtGroup_basic(t *testing.T) { resourceName := "azurerm_policy_definition.test" - mgmtGroupName := "azurerm_management_group.test" ri := tf.AccRandTimeInt() @@ -101,7 +101,7 @@ func TestAccAzureRMPolicyDefinitionAtMgmtGroup_basic(t *testing.T) { { Config: testAzureRMPolicyDefinition_ManagementGroup(ri), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMPolicyDefinitionExistsInMgmtGroup(resourceName, mgmtGroupName), + testCheckAzureRMPolicyDefinitionExistsInMgmtGroup(resourceName), ), }, { @@ -113,7 +113,7 @@ func TestAccAzureRMPolicyDefinitionAtMgmtGroup_basic(t *testing.T) { }) } -func testCheckAzureRMPolicyDefinitionExistsInMgmtGroup(policyName string, managementGroupName string) resource.TestCheckFunc { +func testCheckAzureRMPolicyDefinitionExistsInMgmtGroup(policyName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[policyName] if !ok { @@ -123,7 +123,7 @@ func testCheckAzureRMPolicyDefinitionExistsInMgmtGroup(policyName string, manage policyName := rs.Primary.Attributes["name"] managementGroupID := rs.Primary.Attributes["management_group_id"] - client := testAccProvider.Meta().(*ArmClient).policyDefinitionsClient + client := testAccProvider.Meta().(*ArmClient).policy.DefinitionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.GetAtManagementGroup(ctx, policyName, managementGroupID) @@ -148,7 +148,7 @@ func testCheckAzureRMPolicyDefinitionExists(resourceName string) resource.TestCh policyName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).policyDefinitionsClient + client := testAccProvider.Meta().(*ArmClient).policy.DefinitionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, policyName) @@ -165,7 +165,7 @@ func testCheckAzureRMPolicyDefinitionExists(resourceName string) resource.TestCh } func testCheckAzureRMPolicyDefinitionDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).policyDefinitionsClient + client := testAccProvider.Meta().(*ArmClient).policy.DefinitionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_policy_set_definition.go b/azurerm/resource_arm_policy_set_definition.go index acc1aa6d6ffc..baf76d3fbc63 100644 --- a/azurerm/resource_arm_policy_set_definition.go +++ b/azurerm/resource_arm_policy_set_definition.go @@ -12,6 +12,7 @@ import ( "time" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/go-autorest/autorest" @@ -110,7 +111,7 @@ func policyDefinitionsDiffSuppressFunc(k, old, new string, d *schema.ResourceDat } func resourceArmPolicySetDefinitionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policySetDefinitionsClient + client := meta.(*ArmClient).policy.SetDefinitionsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -119,7 +120,7 @@ func resourceArmPolicySetDefinitionCreateUpdate(d *schema.ResourceData, meta int description := d.Get("description").(string) managementGroupID := d.Get("management_group_id").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := getPolicySetDefinition(ctx, client, name, managementGroupID) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -206,7 +207,7 @@ func resourceArmPolicySetDefinitionCreateUpdate(d *schema.ResourceData, meta int } func resourceArmPolicySetDefinitionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policySetDefinitionsClient + client := meta.(*ArmClient).policy.SetDefinitionsClient ctx := meta.(*ArmClient).StopContext name, err := parsePolicySetDefinitionNameFromId(d.Id()) @@ -271,7 +272,7 @@ func resourceArmPolicySetDefinitionRead(d *schema.ResourceData, meta interface{} } func resourceArmPolicySetDefinitionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).policySetDefinitionsClient + client := meta.(*ArmClient).policy.SetDefinitionsClient ctx := meta.(*ArmClient).StopContext name, err := parsePolicySetDefinitionNameFromId(d.Id()) @@ -320,7 +321,7 @@ func parseManagementGroupIdFromPolicySetId(id string) string { return "" } -func policySetDefinitionRefreshFunc(ctx context.Context, client policy.SetDefinitionsClient, name string, managementGroupId string) resource.StateRefreshFunc { +func policySetDefinitionRefreshFunc(ctx context.Context, client *policy.SetDefinitionsClient, name string, managementGroupId string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := getPolicySetDefinition(ctx, client, name, managementGroupId) if err != nil { @@ -331,7 +332,7 @@ func policySetDefinitionRefreshFunc(ctx context.Context, client policy.SetDefini } } -func getPolicySetDefinition(ctx context.Context, client policy.SetDefinitionsClient, name string, managementGroupID string) (res policy.SetDefinition, err error) { +func getPolicySetDefinition(ctx context.Context, client *policy.SetDefinitionsClient, name string, managementGroupID string) (res policy.SetDefinition, err error) { if managementGroupID == "" { res, err = client.Get(ctx, name) } else { diff --git a/azurerm/resource_arm_policy_set_definition_test.go b/azurerm/resource_arm_policy_set_definition_test.go index 80654593c283..ffca463e61ed 100644 --- a/azurerm/resource_arm_policy_set_definition_test.go +++ b/azurerm/resource_arm_policy_set_definition_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/policy" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" "github.com/hashicorp/terraform/terraform" @@ -39,7 +40,7 @@ func TestAccAzureRMPolicySetDefinition_builtIn(t *testing.T) { } func TestAccAzureRMPolicySetDefinition_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -239,7 +240,7 @@ POLICY_DEFINITIONS func testAzureRMPolicySetDefinition_ManagementGroup(ri int) string { return fmt.Sprintf(` resource "azurerm_management_group" "test" { - display_name = "acctestmg-%d" + display_name = "acctestmg-%d" } resource "azurerm_policy_set_definition" "test" { @@ -287,7 +288,7 @@ func testCheckAzureRMPolicySetDefinitionExists(resourceName string) resource.Tes policySetName := rs.Primary.Attributes["name"] managementGroupId := rs.Primary.Attributes["management_group_id"] - client := testAccProvider.Meta().(*ArmClient).policySetDefinitionsClient + client := testAccProvider.Meta().(*ArmClient).policy.SetDefinitionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext var err error @@ -311,7 +312,7 @@ func testCheckAzureRMPolicySetDefinitionExists(resourceName string) resource.Tes } func testCheckAzureRMPolicySetDefinitionDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).policySetDefinitionsClient + client := testAccProvider.Meta().(*ArmClient).policy.SetDefinitionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_postgresql_configuration.go b/azurerm/resource_arm_postgresql_configuration.go index 30a83f9a7713..6fc7d33d570a 100644 --- a/azurerm/resource_arm_postgresql_configuration.go +++ b/azurerm/resource_arm_postgresql_configuration.go @@ -6,6 +6,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -26,7 +27,7 @@ func resourceArmPostgreSQLConfiguration() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -44,7 +45,7 @@ func resourceArmPostgreSQLConfiguration() *schema.Resource { } func resourceArmPostgreSQLConfigurationCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlConfigurationsClient + client := meta.(*ArmClient).postgres.ConfigurationsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM PostgreSQL Configuration creation.") @@ -83,10 +84,10 @@ func resourceArmPostgreSQLConfigurationCreateUpdate(d *schema.ResourceData, meta } func resourceArmPostgreSQLConfigurationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlConfigurationsClient + client := meta.(*ArmClient).postgres.ConfigurationsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -114,10 +115,10 @@ func resourceArmPostgreSQLConfigurationRead(d *schema.ResourceData, meta interfa } func resourceArmPostgreSQLConfigurationDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlConfigurationsClient + client := meta.(*ArmClient).postgres.ConfigurationsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_postgresql_configuration_test.go b/azurerm/resource_arm_postgresql_configuration_test.go index babcef200e85..e261f0d97a4b 100644 --- a/azurerm/resource_arm_postgresql_configuration_test.go +++ b/azurerm/resource_arm_postgresql_configuration_test.go @@ -124,7 +124,7 @@ func testCheckAzureRMPostgreSQLConfigurationValue(resourceName string, value str return fmt.Errorf("Bad: no resource group found in state for PostgreSQL Configuration: %s", name) } - client := testAccProvider.Meta().(*ArmClient).postgresqlConfigurationsClient + client := testAccProvider.Meta().(*ArmClient).postgres.ConfigurationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, name) @@ -150,7 +150,7 @@ func testCheckAzureRMPostgreSQLConfigurationValueReset(rInt int, configurationNa resourceGroup := fmt.Sprintf("acctestRG-%d", rInt) serverName := fmt.Sprintf("acctestpsqlsvr-%d", rInt) - client := testAccProvider.Meta().(*ArmClient).postgresqlConfigurationsClient + client := testAccProvider.Meta().(*ArmClient).postgres.ConfigurationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, configurationName) @@ -173,7 +173,7 @@ func testCheckAzureRMPostgreSQLConfigurationValueReset(rInt int, configurationNa } func testCheckAzureRMPostgreSQLConfigurationDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).postgresqlConfigurationsClient + client := testAccProvider.Meta().(*ArmClient).postgres.ConfigurationsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -237,7 +237,7 @@ resource "azurerm_postgresql_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - name = "GP_Gen5_2" + name = "GP_Gen5_2" capacity = 2 tier = "GeneralPurpose" family = "Gen5" diff --git a/azurerm/resource_arm_postgresql_database.go b/azurerm/resource_arm_postgresql_database.go index 075887682086..c036fa35d16d 100644 --- a/azurerm/resource_arm_postgresql_database.go +++ b/azurerm/resource_arm_postgresql_database.go @@ -5,7 +5,11 @@ import ( "log" "strings" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql" "github.com/hashicorp/terraform/helper/schema" @@ -29,7 +33,7 @@ func resourceArmPostgreSQLDatabase() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -40,7 +44,7 @@ func resourceArmPostgreSQLDatabase() *schema.Resource { "charset": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ForceNew: true, }, @@ -48,14 +52,14 @@ func resourceArmPostgreSQLDatabase() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validateCollation(), + ValidateFunc: validate.DatabaseCollation, }, }, } } func resourceArmPostgreSQLDatabaseCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlDatabasesClient + client := meta.(*ArmClient).postgres.DatabasesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM PostgreSQL Database creation.") @@ -67,7 +71,7 @@ func resourceArmPostgreSQLDatabaseCreate(d *schema.ResourceData, meta interface{ charset := d.Get("charset").(string) collation := d.Get("collation").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.Get(ctx, resGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -110,10 +114,10 @@ func resourceArmPostgreSQLDatabaseCreate(d *schema.ResourceData, meta interface{ } func resourceArmPostgreSQLDatabaseRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlDatabasesClient + client := meta.(*ArmClient).postgres.DatabasesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -149,10 +153,10 @@ func resourceArmPostgreSQLDatabaseRead(d *schema.ResourceData, meta interface{}) } func resourceArmPostgreSQLDatabaseDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlDatabasesClient + client := meta.(*ArmClient).postgres.DatabasesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_postgresql_database_test.go b/azurerm/resource_arm_postgresql_database_test.go index 27fb0420703b..03c0f756fa67 100644 --- a/azurerm/resource_arm_postgresql_database_test.go +++ b/azurerm/resource_arm_postgresql_database_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,7 +33,7 @@ func TestAccAzureRMPostgreSQLDatabase_basic(t *testing.T) { } func TestAccAzureRMPostgreSQLDatabase_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -118,7 +119,7 @@ func testCheckAzureRMPostgreSQLDatabaseExists(resourceName string) resource.Test return fmt.Errorf("Bad: no resource group found in state for PostgreSQL Database: %s", name) } - client := testAccProvider.Meta().(*ArmClient).postgresqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).postgres.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, name) @@ -134,7 +135,7 @@ func testCheckAzureRMPostgreSQLDatabaseExists(resourceName string) resource.Test } func testCheckAzureRMPostgreSQLDatabaseDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).postgresqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).postgres.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_postgresql_firewall_rule.go b/azurerm/resource_arm_postgresql_firewall_rule.go index 04fa8e0774b9..6c18478345e8 100644 --- a/azurerm/resource_arm_postgresql_firewall_rule.go +++ b/azurerm/resource_arm_postgresql_firewall_rule.go @@ -4,7 +4,9 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql" "github.com/hashicorp/terraform/helper/schema" @@ -28,7 +30,7 @@ func resourceArmPostgreSQLFirewallRule() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -52,7 +54,7 @@ func resourceArmPostgreSQLFirewallRule() *schema.Resource { } func resourceArmPostgreSQLFirewallRuleCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlFirewallRulesClient + client := meta.(*ArmClient).postgres.FirewallRulesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM PostgreSQL Firewall Rule creation.") @@ -63,7 +65,7 @@ func resourceArmPostgreSQLFirewallRuleCreate(d *schema.ResourceData, meta interf startIPAddress := d.Get("start_ip_address").(string) endIPAddress := d.Get("end_ip_address").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.Get(ctx, resGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -106,10 +108,10 @@ func resourceArmPostgreSQLFirewallRuleCreate(d *schema.ResourceData, meta interf } func resourceArmPostgreSQLFirewallRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlFirewallRulesClient + client := meta.(*ArmClient).postgres.FirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -138,10 +140,10 @@ func resourceArmPostgreSQLFirewallRuleRead(d *schema.ResourceData, meta interfac } func resourceArmPostgreSQLFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlFirewallRulesClient + client := meta.(*ArmClient).postgres.FirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_postgresql_firewall_rule_test.go b/azurerm/resource_arm_postgresql_firewall_rule_test.go index f5753b93de33..41f99bc424da 100644 --- a/azurerm/resource_arm_postgresql_firewall_rule_test.go +++ b/azurerm/resource_arm_postgresql_firewall_rule_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMPostgreSQLFirewallRule_basic(t *testing.T) { } func TestAccAzureRMPostgreSQLFirewallRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -81,7 +82,7 @@ func testCheckAzureRMPostgreSQLFirewallRuleExists(resourceName string) resource. return fmt.Errorf("Bad: no resource group found in state for PostgreSQL Firewall Rule: %s", name) } - client := testAccProvider.Meta().(*ArmClient).postgresqlFirewallRulesClient + client := testAccProvider.Meta().(*ArmClient).postgres.FirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, name) @@ -98,7 +99,7 @@ func testCheckAzureRMPostgreSQLFirewallRuleExists(resourceName string) resource. } func testCheckAzureRMPostgreSQLFirewallRuleDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).postgresqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).postgres.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_postgresql_server.go b/azurerm/resource_arm_postgresql_server.go index 4a8ce6049b6a..f3ac12bed6a6 100644 --- a/azurerm/resource_arm_postgresql_server.go +++ b/azurerm/resource_arm_postgresql_server.go @@ -5,7 +5,10 @@ import ( "log" "strings" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" @@ -34,9 +37,9 @@ func resourceArmPostgreSQLServer() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeList, @@ -129,9 +132,9 @@ func resourceArmPostgreSQLServer() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{ string(postgresql.NineFullStopFive), string(postgresql.NineFullStopSix), + string(postgresql.OneOne), string(postgresql.OneZero), string(postgresql.OneZeroFullStopZero), - string(postgresql.OneZeroFullStopTwo), }, true), DiffSuppressFunc: suppress.CaseDifference, }, @@ -182,7 +185,7 @@ func resourceArmPostgreSQLServer() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error { @@ -200,13 +203,13 @@ func resourceArmPostgreSQLServer() *schema.Resource { } func resourceArmPostgreSQLServerCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlServersClient + client := meta.(*ArmClient).postgres.ServersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM PostgreSQL Server creation.") name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resourceGroup := d.Get("resource_group_name").(string) adminLogin := d.Get("administrator_login").(string) @@ -214,9 +217,9 @@ func resourceArmPostgreSQLServerCreate(d *schema.ResourceData, meta interface{}) sslEnforcement := d.Get("ssl_enforcement").(string) version := d.Get("version").(string) createMode := "Default" - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -243,7 +246,7 @@ func resourceArmPostgreSQLServerCreate(d *schema.ResourceData, meta interface{}) CreateMode: postgresql.CreateMode(createMode), }, Sku: sku, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.Create(ctx, resourceGroup, name, properties) @@ -270,7 +273,7 @@ func resourceArmPostgreSQLServerCreate(d *schema.ResourceData, meta interface{}) } func resourceArmPostgreSQLServerUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlServersClient + client := meta.(*ArmClient).postgres.ServersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM PostgreSQL Server update.") @@ -283,7 +286,7 @@ func resourceArmPostgreSQLServerUpdate(d *schema.ResourceData, meta interface{}) version := d.Get("version").(string) sku := expandAzureRmPostgreSQLServerSku(d) storageProfile := expandAzureRmPostgreSQLStorageProfile(d) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) properties := postgresql.ServerUpdateParameters{ ServerUpdateParametersProperties: &postgresql.ServerUpdateParametersProperties{ @@ -293,7 +296,7 @@ func resourceArmPostgreSQLServerUpdate(d *schema.ResourceData, meta interface{}) SslEnforcement: postgresql.SslEnforcementEnum(sslEnforcement), }, Sku: sku, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.Update(ctx, resourceGroup, name, properties) @@ -320,10 +323,10 @@ func resourceArmPostgreSQLServerUpdate(d *schema.ResourceData, meta interface{}) } func resourceArmPostgreSQLServerRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlServersClient + client := meta.(*ArmClient).postgres.ServersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -345,7 +348,7 @@ func resourceArmPostgreSQLServerRead(d *schema.ResourceData, meta interface{}) e d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("administrator_login", resp.AdministratorLogin) @@ -360,19 +363,17 @@ func resourceArmPostgreSQLServerRead(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("Error setting `storage_profile`: %+v", err) } - flattenAndSetTags(d, resp.Tags) - // Computed d.Set("fqdn", resp.FullyQualifiedDomainName) - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmPostgreSQLServerDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlServersClient + client := meta.(*ArmClient).postgres.ServersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_postgresql_server_test.go b/azurerm/resource_arm_postgresql_server_test.go index 45d9e12d2695..f6d3c385efc4 100644 --- a/azurerm/resource_arm_postgresql_server_test.go +++ b/azurerm/resource_arm_postgresql_server_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -102,8 +103,38 @@ func TestAccAzureRMPostgreSQLServer_basicTenPointZero(t *testing.T) { }) } +func TestAccAzureRMPostgreSQLServer_basicEleven(t *testing.T) { + resourceName := "azurerm_postgresql_server.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPostgreSQLServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMPostgreSQLServer_basicEleven(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPostgreSQLServerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "administrator_login", "acctestun"), + resource.TestCheckResourceAttr(resourceName, "version", "11"), + resource.TestCheckResourceAttr(resourceName, "ssl_enforcement", "Enabled"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "administrator_login_password", // not returned as sensitive + }, + }, + }, + }) +} + func TestAccAzureRMPostgreSQLServer_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -340,7 +371,7 @@ func testCheckAzureRMPostgreSQLServerExists(resourceName string) resource.TestCh return fmt.Errorf("Bad: no resource group found in state for PostgreSQL Server: %s", name) } - client := testAccProvider.Meta().(*ArmClient).postgresqlServersClient + client := testAccProvider.Meta().(*ArmClient).postgres.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -357,7 +388,7 @@ func testCheckAzureRMPostgreSQLServerExists(resourceName string) resource.TestCh } func testCheckAzureRMPostgreSQLServerDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).postgresqlServersClient + client := testAccProvider.Meta().(*ArmClient).postgres.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -384,7 +415,7 @@ func testCheckAzureRMPostgreSQLServerDestroy(s *terraform.State) error { return nil } -func testAccAzureRMPostgreSQLServer_basicNinePointFive(rInt int, location string) string { +func testAccAzureRMPostgreSQLServer_basic(rInt int, location string, version string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -411,76 +442,26 @@ resource "azurerm_postgresql_server" "test" { administrator_login = "acctestun" administrator_login_password = "H@Sh1CoR3!" - version = "9.5" + version = "%s" ssl_enforcement = "Enabled" } -`, rInt, location, rInt) +`, rInt, location, rInt, version) } -func testAccAzureRMPostgreSQLServer_basicNinePointSix(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" +func testAccAzureRMPostgreSQLServer_basicNinePointFive(rInt int, location string) string { + return testAccAzureRMPostgreSQLServer_basic(rInt, location, "9.5") } -resource "azurerm_postgresql_server" "test" { - name = "acctestpsqlsvr-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - - sku { - name = "GP_Gen5_2" - capacity = 2 - tier = "GeneralPurpose" - family = "Gen5" - } - - storage_profile { - storage_mb = 51200 - backup_retention_days = 7 - geo_redundant_backup = "Disabled" - } - - administrator_login = "acctestun" - administrator_login_password = "H@Sh1CoR3!" - version = "9.6" - ssl_enforcement = "Enabled" -} -`, rInt, location, rInt) +func testAccAzureRMPostgreSQLServer_basicNinePointSix(rInt int, location string) string { + return testAccAzureRMPostgreSQLServer_basic(rInt, location, "9.6") } func testAccAzureRMPostgreSQLServer_basicTenPointZero(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" + return testAccAzureRMPostgreSQLServer_basic(rInt, location, "10.0") } -resource "azurerm_postgresql_server" "test" { - name = "acctestpsqlsvr-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - - sku { - name = "GP_Gen5_2" - capacity = 2 - tier = "GeneralPurpose" - family = "Gen5" - } - - storage_profile { - storage_mb = 51200 - backup_retention_days = 7 - geo_redundant_backup = "Disabled" - } - - administrator_login = "acctestun" - administrator_login_password = "H@Sh1CoR3!" - version = "10.0" - ssl_enforcement = "Enabled" -} -`, rInt, location, rInt) +func testAccAzureRMPostgreSQLServer_basicEleven(rInt int, location string) string { + return testAccAzureRMPostgreSQLServer_basic(rInt, location, "11") } func testAccAzureRMPostgreSQLServer_requiresImport(rInt int, location string) string { diff --git a/azurerm/resource_arm_postgresql_virtual_network_rule.go b/azurerm/resource_arm_postgresql_virtual_network_rule.go index c4fc0a8aadd8..b83232d1ad6f 100644 --- a/azurerm/resource_arm_postgresql_virtual_network_rule.go +++ b/azurerm/resource_arm_postgresql_virtual_network_rule.go @@ -7,6 +7,7 @@ import ( "time" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql" "github.com/hashicorp/terraform/helper/resource" @@ -35,7 +36,7 @@ func resourceArmPostgreSQLVirtualNetworkRule() *schema.Resource { ValidateFunc: validate.VirtualNetworkRuleName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -59,7 +60,7 @@ func resourceArmPostgreSQLVirtualNetworkRule() *schema.Resource { } func resourceArmPostgreSQLVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlVirtualNetworkRulesClient + client := meta.(*ArmClient).postgres.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -68,7 +69,7 @@ func resourceArmPostgreSQLVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, subnetId := d.Get("subnet_id").(string) ignoreMissingVnetServiceEndpoint := d.Get("ignore_missing_vnet_service_endpoint").(bool) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -123,10 +124,10 @@ func resourceArmPostgreSQLVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, } func resourceArmPostgreSQLVirtualNetworkRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlVirtualNetworkRulesClient + client := meta.(*ArmClient).postgres.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -159,10 +160,10 @@ func resourceArmPostgreSQLVirtualNetworkRuleRead(d *schema.ResourceData, meta in } func resourceArmPostgreSQLVirtualNetworkRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).postgresqlVirtualNetworkRulesClient + client := meta.(*ArmClient).postgres.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -191,7 +192,7 @@ func resourceArmPostgreSQLVirtualNetworkRuleDelete(d *schema.ResourceData, meta return nil } -func postgreSQLVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client postgresql.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc { +func postgreSQLVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client *postgresql.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { resp, err := client.Get(ctx, resourceGroup, serverName, name) diff --git a/azurerm/resource_arm_postgresql_virtual_network_rule_test.go b/azurerm/resource_arm_postgresql_virtual_network_rule_test.go index f1f3c3b7275d..d6b948cab2d7 100644 --- a/azurerm/resource_arm_postgresql_virtual_network_rule_test.go +++ b/azurerm/resource_arm_postgresql_virtual_network_rule_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMPostgreSQLVirtualNetworkRule_basic(t *testing.T) { } func TestAccAzureRMPostgreSQLVirtualNetworkRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -176,7 +177,7 @@ func testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(resourceName string) res serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).postgresqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).postgres.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) @@ -202,7 +203,7 @@ func testCheckAzureRMPostgreSQLVirtualNetworkRuleDestroy(s *terraform.State) err serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).postgresqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).postgres.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) @@ -232,7 +233,7 @@ func testCheckAzureRMPostgreSQLVirtualNetworkRuleDisappears(resourceName string) serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).postgresqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).postgres.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, serverName, ruleName) diff --git a/azurerm/resource_arm_private_dns_a_record.go b/azurerm/resource_arm_private_dns_a_record.go new file mode 100644 index 000000000000..f965d6a03536 --- /dev/null +++ b/azurerm/resource_arm_private_dns_a_record.go @@ -0,0 +1,194 @@ +package azurerm + +import ( + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmPrivateDnsARecord() *schema.Resource { + return &schema.Resource{ + Create: resourceArmPrivateDnsARecordCreateUpdate, + Read: resourceArmPrivateDnsARecordRead, + Update: resourceArmPrivateDnsARecordCreateUpdate, + Delete: resourceArmPrivateDnsARecordDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + // TODO: make this case sensitive once the API's fixed https://github.com/Azure/azure-rest-api-specs/issues/6641 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "zone_name": { + Type: schema.TypeString, + Required: true, + }, + + "records": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + + "ttl": { + Type: schema.TypeInt, + Required: true, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmPrivateDnsARecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).privateDns.RecordSetsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + zoneName := d.Get("zone_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resGroup, zoneName, privatedns.A, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Private DNS A Record %q (Private Zone %q / Resource Group %q): %s", name, zoneName, resGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_private_dns_a_record", *existing.ID) + } + } + + ttl := int64(d.Get("ttl").(int)) + t := d.Get("tags").(map[string]interface{}) + + parameters := privatedns.RecordSet{ + Name: &name, + RecordSetProperties: &privatedns.RecordSetProperties{ + Metadata: tags.Expand(t), + TTL: &ttl, + ARecords: expandAzureRmPrivateDnsARecords(d), + }, + } + + eTag := "" + ifNoneMatch := "" // set to empty to allow updates to records after creation + if _, err := client.CreateOrUpdate(ctx, resGroup, zoneName, privatedns.A, name, parameters, eTag, ifNoneMatch); err != nil { + return fmt.Errorf("Error creating/updating Private DNS A Record %q (Zone %q / Resource Group %q): %s", name, zoneName, resGroup, err) + } + + resp, err := client.Get(ctx, resGroup, zoneName, privatedns.A, name) + if err != nil { + return fmt.Errorf("Error retrieving Private DNS A Record %q (Zone %q / Resource Group %q): %s", name, zoneName, resGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Private DNS A Record %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*resp.ID) + + return resourceArmPrivateDnsARecordRead(d, meta) +} + +func resourceArmPrivateDnsARecordRead(d *schema.ResourceData, meta interface{}) error { + dnsClient := meta.(*ArmClient).privateDns.RecordSetsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["A"] + zoneName := id.Path["privateDnsZones"] + + resp, err := dnsClient.Get(ctx, resGroup, zoneName, privatedns.A, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error reading Private DNS A record %s: %+v", name, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resGroup) + d.Set("zone_name", zoneName) + d.Set("ttl", resp.TTL) + + if err := d.Set("records", flattenAzureRmPrivateDnsARecords(resp.ARecords)); err != nil { + return err + } + return tags.FlattenAndSet(d, resp.Metadata) +} + +func resourceArmPrivateDnsARecordDelete(d *schema.ResourceData, meta interface{}) error { + dnsClient := meta.(*ArmClient).privateDns.RecordSetsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["A"] + zoneName := id.Path["privateDnsZones"] + + resp, err := dnsClient.Delete(ctx, resGroup, zoneName, privatedns.A, name, "") + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("Error deleting Private DNS A Record %s: %+v", name, err) + } + + return nil +} + +func flattenAzureRmPrivateDnsARecords(records *[]privatedns.ARecord) []string { + results := make([]string, 0) + if records == nil { + return results + } + + for _, record := range *records { + if record.Ipv4Address == nil { + continue + } + + results = append(results, *record.Ipv4Address) + } + + return results +} + +func expandAzureRmPrivateDnsARecords(d *schema.ResourceData) *[]privatedns.ARecord { + recordStrings := d.Get("records").(*schema.Set).List() + records := make([]privatedns.ARecord, len(recordStrings)) + + for i, v := range recordStrings { + ipv4 := v.(string) + records[i] = privatedns.ARecord{ + Ipv4Address: &ipv4, + } + } + + return &records +} diff --git a/azurerm/resource_arm_private_dns_a_record_test.go b/azurerm/resource_arm_private_dns_a_record_test.go new file mode 100644 index 000000000000..2559cc825485 --- /dev/null +++ b/azurerm/resource_arm_private_dns_a_record_test.go @@ -0,0 +1,303 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMPrivateDnsARecord_basic(t *testing.T) { + resourceName := "azurerm_private_dns_a_record.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMPrivateDnsARecord_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsARecordDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsARecordExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsARecord_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_private_dns_a_record.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsARecordDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMPrivateDnsARecord_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsARecordExists(resourceName), + ), + }, + { + Config: testAccAzureRMPrivateDnsARecord_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_private_dns_a_record"), + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsARecord_updateRecords(t *testing.T) { + resourceName := "azurerm_private_dns_a_record.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMPrivateDnsARecord_basic(ri, location) + postConfig := testAccAzureRMPrivateDnsARecord_updateRecords(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsARecordDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsARecordExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "records.#", "2"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsARecordExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "records.#", "3"), + ), + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsARecord_withTags(t *testing.T) { + resourceName := "azurerm_private_dns_a_record.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMPrivateDnsARecord_withTags(ri, location) + postConfig := testAccAzureRMPrivateDnsARecord_withTagsUpdate(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsARecordDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsARecordExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsARecordExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMPrivateDnsARecordExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + aName := rs.Primary.Attributes["name"] + zoneName := rs.Primary.Attributes["zone_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Private DNS A record: %s", aName) + } + + conn := testAccProvider.Meta().(*ArmClient).privateDns.RecordSetsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, zoneName, privatedns.A, aName) + if err != nil { + return fmt.Errorf("Bad: Get A RecordSet: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Private DNS A record %s (resource group: %s) does not exist", aName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMPrivateDnsARecordDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).privateDns.RecordSetsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_private_dns_a_record" { + continue + } + + aName := rs.Primary.Attributes["name"] + zoneName := rs.Primary.Attributes["zone_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, zoneName, privatedns.A, aName) + + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + + return err + } + + return fmt.Errorf("Private DNS A record still exists:\n%#v", resp.RecordSetProperties) + } + + return nil +} + +func testAccAzureRMPrivateDnsARecord_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_a_record" "test" { + name = "myarecord%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + records = ["1.2.3.4", "1.2.4.5"] +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPrivateDnsARecord_requiresImport(rInt int, location string) string { + template := testAccAzureRMPrivateDnsARecord_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_private_dns_a_record" "import" { + name = "${azurerm_private_dns_a_record.test.name}" + resource_group_name = "${azurerm_private_dns_a_record.test.resource_group_name}" + zone_name = "${azurerm_private_dns_a_record.test.zone_name}" + ttl = 300 + records = ["1.2.3.4", "1.2.4.5"] +} +`, template) +} + +func testAccAzureRMPrivateDnsARecord_updateRecords(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_a_record" "test" { + name = "myarecord%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + records = ["1.2.3.4", "1.2.4.5", "1.2.3.7"] +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPrivateDnsARecord_withTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_a_record" "test" { + name = "myarecord%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + records = ["1.2.3.4", "1.2.4.5"] + + tags = { + environment = "Production" + cost_center = "MSFT" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPrivateDnsARecord_withTagsUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_a_record" "test" { + name = "myarecord%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + records = ["1.2.3.4", "1.2.4.5"] + + tags = { + environment = "staging" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_private_dns_cname_record.go b/azurerm/resource_arm_private_dns_cname_record.go new file mode 100644 index 000000000000..e68cfdd41faa --- /dev/null +++ b/azurerm/resource_arm_private_dns_cname_record.go @@ -0,0 +1,174 @@ +package azurerm + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmPrivateDnsCNameRecord() *schema.Resource { + return &schema.Resource{ + Create: resourceArmPrivateDnsCNameRecordCreateUpdate, + Read: resourceArmPrivateDnsCNameRecordRead, + Update: resourceArmPrivateDnsCNameRecordCreateUpdate, + Delete: resourceArmPrivateDnsCNameRecordDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + // TODO: make this case sensitive once the API's fixed https://github.com/Azure/azure-rest-api-specs/issues/6641 + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "zone_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "record": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "ttl": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 2147483647), + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmPrivateDnsCNameRecordCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).privateDns.RecordSetsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + zoneName := d.Get("zone_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resGroup, zoneName, privatedns.CNAME, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Private DNS CNAME Record %q (Zone %q / Resource Group %q): %s", name, zoneName, resGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_private_dns_cname_record", *existing.ID) + } + } + + ttl := int64(d.Get("ttl").(int)) + record := d.Get("record").(string) + t := d.Get("tags").(map[string]interface{}) + + parameters := privatedns.RecordSet{ + Name: &name, + RecordSetProperties: &privatedns.RecordSetProperties{ + Metadata: tags.Expand(t), + TTL: &ttl, + CnameRecord: &privatedns.CnameRecord{ + Cname: &record, + }, + }, + } + + eTag := "" + ifNoneMatch := "" // set to empty to allow updates to records after creation + if _, err := client.CreateOrUpdate(ctx, resGroup, zoneName, privatedns.CNAME, name, parameters, eTag, ifNoneMatch); err != nil { + return fmt.Errorf("Error creating/updating Private DNS CNAME Record %q (Zone %q / Resource Group %q): %s", name, zoneName, resGroup, err) + } + + resp, err := client.Get(ctx, resGroup, zoneName, privatedns.CNAME, name) + if err != nil { + return fmt.Errorf("Error retrieving Private DNS CNAME Record %q (Zone %q / Resource Group %q): %s", name, zoneName, resGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read Private DNS CNAME Record %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*resp.ID) + + return resourceArmPrivateDnsCNameRecordRead(d, meta) +} + +func resourceArmPrivateDnsCNameRecordRead(d *schema.ResourceData, meta interface{}) error { + dnsClient := meta.(*ArmClient).privateDns.RecordSetsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["CNAME"] + zoneName := id.Path["privateDnsZones"] + + resp, err := dnsClient.Get(ctx, resGroup, zoneName, privatedns.CNAME, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error reading Private DNS CNAME record %s: %+v", name, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resGroup) + d.Set("zone_name", zoneName) + d.Set("ttl", resp.TTL) + + if props := resp.RecordSetProperties; props != nil { + if record := props.CnameRecord; record != nil { + d.Set("record", record.Cname) + } + } + + return tags.FlattenAndSet(d, resp.Metadata) +} + +func resourceArmPrivateDnsCNameRecordDelete(d *schema.ResourceData, meta interface{}) error { + dnsClient := meta.(*ArmClient).privateDns.RecordSetsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["CNAME"] + zoneName := id.Path["privateDnsZones"] + + _, err = dnsClient.Get(ctx, resGroup, zoneName, privatedns.CNAME, name) + if err != nil { + return fmt.Errorf("Error deleting Private DNS CNAME Record %s: %+v", name, err) + } + + return nil +} diff --git a/azurerm/resource_arm_private_dns_cname_record_test.go b/azurerm/resource_arm_private_dns_cname_record_test.go new file mode 100644 index 000000000000..a1ffbb7d40bd --- /dev/null +++ b/azurerm/resource_arm_private_dns_cname_record_test.go @@ -0,0 +1,349 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMPrivateDnsCNameRecord_basic(t *testing.T) { + resourceName := "azurerm_private_dns_cname_record.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMPrivateDnsCNameRecord_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsCNameRecordDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsCNameRecordExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsCNameRecord_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_private_dns_cname_record.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsCNameRecordDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMPrivateDnsCNameRecord_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsCNameRecordExists(resourceName), + ), + }, + { + Config: testAccAzureRMPrivateDnsCNameRecord_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_private_dns_cname_record"), + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsCNameRecord_subdomain(t *testing.T) { + resourceName := "azurerm_private_dns_cname_record.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMPrivateDnsCNameRecord_subdomain(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsCNameRecordDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsCNameRecordExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "record", "test.contoso.com"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsCNameRecord_updateRecords(t *testing.T) { + resourceName := "azurerm_private_dns_cname_record.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMPrivateDnsCNameRecord_basic(ri, location) + postConfig := testAccAzureRMPrivateDnsCNameRecord_updateRecords(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsCNameRecordDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsCNameRecordExists(resourceName), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsCNameRecordExists(resourceName), + ), + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsCNameRecord_withTags(t *testing.T) { + resourceName := "azurerm_private_dns_cname_record.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMPrivateDnsCNameRecord_withTags(ri, location) + postConfig := testAccAzureRMPrivateDnsCNameRecord_withTagsUpdate(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsCNameRecordDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsCNameRecordExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsCNameRecordExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMPrivateDnsCNameRecordExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + aName := rs.Primary.Attributes["name"] + zoneName := rs.Primary.Attributes["zone_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Private DNS CNAME record: %s", aName) + } + + conn := testAccProvider.Meta().(*ArmClient).privateDns.RecordSetsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, zoneName, privatedns.CNAME, aName) + if err != nil { + return fmt.Errorf("Bad: Get CNAME RecordSet: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Private DNS CNAME record %s (resource group: %s) does not exist", aName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMPrivateDnsCNameRecordDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).privateDns.RecordSetsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_private_dns_cname_record" { + continue + } + + aName := rs.Primary.Attributes["name"] + zoneName := rs.Primary.Attributes["zone_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, zoneName, privatedns.A, aName) + + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + + return err + } + + return fmt.Errorf("Private DNS CNAME record still exists:\n%#v", resp.RecordSetProperties) + } + + return nil +} + +func testAccAzureRMPrivateDnsCNameRecord_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_cname_record" "test" { + name = "acctestcname%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + record = "contoso.com" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPrivateDnsCNameRecord_requiresImport(rInt int, location string) string { + template := testAccAzureRMPrivateDnsCNameRecord_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_private_dns_cname_record" "import" { + name = "${azurerm_private_dns_cname_record.test.name}" + resource_group_name = "${azurerm_private_dns_cname_record.test.resource_group_name}" + zone_name = "${azurerm_private_dns_cname_record.test.zone_name}" + ttl = 300 + record = "contoso.com" +} +`, template) +} + +func testAccAzureRMPrivateDnsCNameRecord_subdomain(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_cname_record" "test" { + name = "acctestcname%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + record = "test.contoso.com" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPrivateDnsCNameRecord_updateRecords(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_cname_record" "test" { + name = "acctestcname%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + record = "contoso.com" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPrivateDnsCNameRecord_withTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_cname_record" "test" { + name = "acctestcname%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + record = "contoso.com" + + tags = { + environment = "Production" + cost_center = "MSFT" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPrivateDnsCNameRecord_withTagsUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_cname_record" "test" { + name = "acctestcname%d" + resource_group_name = "${azurerm_resource_group.test.name}" + zone_name = "${azurerm_private_dns_zone.test.name}" + ttl = 300 + record = "contoso.com" + + tags = { + environment = "staging" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_private_dns_zone.go b/azurerm/resource_arm_private_dns_zone.go new file mode 100644 index 000000000000..de8d1155ad62 --- /dev/null +++ b/azurerm/resource_arm_private_dns_zone.go @@ -0,0 +1,191 @@ +package azurerm + +import ( + "fmt" + + "time" + + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmPrivateDnsZone() *schema.Resource { + return &schema.Resource{ + Create: resourceArmPrivateDnsZoneCreateUpdate, + Read: resourceArmPrivateDnsZoneRead, + Update: resourceArmPrivateDnsZoneCreateUpdate, + Delete: resourceArmPrivateDnsZoneDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "number_of_record_sets": { + Type: schema.TypeInt, + Computed: true, + }, + + "max_number_of_record_sets": { + Type: schema.TypeInt, + Computed: true, + }, + + "max_number_of_virtual_network_links": { + Type: schema.TypeInt, + Computed: true, + }, + + "max_number_of_virtual_network_links_with_registration": { + Type: schema.TypeInt, + Computed: true, + }, + + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), + + "tags": tags.Schema(), + }, + } +} + +func resourceArmPrivateDnsZoneCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).privateDns.PrivateZonesClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resGroup, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("error checking for presence of existing Private DNS Zone %q (Resource Group %q): %s", name, resGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_private_dns_zone", *existing.ID) + } + } + + location := "global" + t := d.Get("tags").(map[string]interface{}) + + parameters := privatedns.PrivateZone{ + Location: &location, + Tags: tags.Expand(t), + } + + etag := "" + ifNoneMatch := "" // set to empty to allow updates to records after creation + + _, err := client.CreateOrUpdate(ctx, resGroup, name, parameters, etag, ifNoneMatch) + if err != nil { + return fmt.Errorf("error creating/updating Private DNS Zone %q (Resource Group %q): %s", name, resGroup, err) + } + + time.Sleep(time.Second * 10) // resource is slow to create / update, retry covers the create, sleeping to make update more reliable + if err := resource.Retry(120*time.Second, retryPrivateDnsZonesClientGet(resGroup, name, meta)); err != nil { + return fmt.Errorf("error waiting for Private DNS Zone %q to become available: %+v", name, err) + } + + resp, err := client.Get(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("error retrieving Private DNS Zone %q (Resource Group %q): %s", name, resGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("cannot read Private DNS Zone %q (Resource Group %q) ID", name, resGroup) + } + + d.SetId(*resp.ID) + + return resourceArmPrivateDnsZoneRead(d, meta) +} + +func retryPrivateDnsZonesClientGet(resGroup string, name string, meta interface{}) func() *resource.RetryError { + return func() *resource.RetryError { + client := meta.(*ArmClient).privateDns.PrivateZonesClient + ctx := meta.(*ArmClient).StopContext + + if _, err := client.Get(ctx, resGroup, name); err != nil { + return resource.RetryableError(err) + } + + return nil + } +} + +func resourceArmPrivateDnsZoneRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).privateDns.PrivateZonesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["privateDnsZones"] + + resp, err := client.Get(ctx, resGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("error reading Private DNS Zone %q (Resource Group %q): %+v", name, resGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resGroup) + d.Set("number_of_record_sets", resp.NumberOfRecordSets) + d.Set("max_number_of_record_sets", resp.MaxNumberOfRecordSets) + d.Set("max_number_of_virtual_network_links", resp.MaxNumberOfVirtualNetworkLinks) + d.Set("max_number_of_virtual_network_links_with_registration", resp.MaxNumberOfVirtualNetworkLinksWithRegistration) + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmPrivateDnsZoneDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).privateDns.PrivateZonesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["privateDnsZones"] + + etag := "" + future, err := client.Delete(ctx, resGroup, name, etag) + if err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + return fmt.Errorf("error deleting Private DNS Zone %s (resource group %s): %+v", name, resGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + return fmt.Errorf("error deleting Private DNS Zone %s (resource group %s): %+v", name, resGroup, err) + } + + return nil +} diff --git a/azurerm/resource_arm_private_dns_zone_test.go b/azurerm/resource_arm_private_dns_zone_test.go new file mode 100644 index 000000000000..514a75f82806 --- /dev/null +++ b/azurerm/resource_arm_private_dns_zone_test.go @@ -0,0 +1,220 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMPrivateDnsZone_basic(t *testing.T) { + resourceName := "azurerm_private_dns_zone.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMPrivateDnsZone_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsZoneDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsZoneExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsZone_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_private_dns_zone.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsZoneDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMPrivateDnsZone_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsZoneExists(resourceName), + ), + }, + { + Config: testAccAzureRMPrivateDnsZone_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_private_dns_zone"), + }, + }, + }) +} + +func TestAccAzureRMPrivateDnsZone_withTags(t *testing.T) { + resourceName := "azurerm_private_dns_zone.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMPrivateDnsZone_withTags(ri, location) + postConfig := testAccAzureRMPrivateDnsZone_withTagsUpdate(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPrivateDnsZoneDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsZoneExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPrivateDnsZoneExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMPrivateDnsZoneExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + zoneName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Private DNS zone: %s", zoneName) + } + + client := testAccProvider.Meta().(*ArmClient).privateDns.PrivateZonesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, zoneName) + if err != nil { + return fmt.Errorf("Bad: Get Private DNS zone: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Private DNS zone %s (resource group: %s) does not exist", zoneName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMPrivateDnsZoneDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).privateDns.PrivateZonesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_private_dns_zone" { + continue + } + + zoneName := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, zoneName) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + + return err + } + + return fmt.Errorf("Private DNS zone still exists:\n%#v", resp) + } + + return nil +} + +func testAccAzureRMPrivateDnsZone_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rInt) +} + +func testAccAzureRMPrivateDnsZone_requiresImport(rInt int, location string) string { + template := testAccAzureRMPrivateDnsZone_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_private_dns_zone" "import" { + name = "${azurerm_private_dns_zone.test.name}" + resource_group_name = "${azurerm_private_dns_zone.test.resource_group_name}" +} +`, template) +} + +func testAccAzureRMPrivateDnsZone_withTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Production" + cost_center = "MSFT" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMPrivateDnsZone_withTagsUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_private_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "staging" + } +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_public_ip.go b/azurerm/resource_arm_public_ip.go index de8f2446c0ab..870078876b27 100644 --- a/azurerm/resource_arm_public_ip.go +++ b/azurerm/resource_arm_public_ip.go @@ -5,13 +5,15 @@ import ( "log" "strings" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" - - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -24,7 +26,7 @@ func resourceArmPublicIp() *schema.Resource { Importer: &schema.ResourceImporter{ State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return nil, err } @@ -44,9 +46,9 @@ func resourceArmPublicIp() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "allocation_method": { Type: schema.TypeString, @@ -126,25 +128,32 @@ func resourceArmPublicIp() *schema.Resource { Computed: true, }, - "zones": singleZonesSchema(), + "public_ip_prefix_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, - "tags": tagsSchema(), + "zones": azure.SchemaSingleZone(), + + "tags": tags.Schema(), }, } } func resourceArmPublicIpCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).publicIPClient + client := meta.(*ArmClient).network.PublicIPsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Public IP creation.") name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resGroup := d.Get("resource_group_name").(string) sku := d.Get("sku").(string) - tags := d.Get("tags").(map[string]interface{}) - zones := expandZones(d.Get("zones").([]interface{})) + t := d.Get("tags").(map[string]interface{}) + zones := azure.ExpandZones(d.Get("zones").([]interface{})) idleTimeout := d.Get("idle_timeout_in_minutes").(int) ipVersion := network.IPVersion(d.Get("ip_version").(string)) @@ -169,7 +178,7 @@ func resourceArmPublicIpCreateUpdate(d *schema.ResourceData, meta interface{}) e } } - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -193,10 +202,18 @@ func resourceArmPublicIpCreateUpdate(d *schema.ResourceData, meta interface{}) e PublicIPAddressVersion: ipVersion, IdleTimeoutInMinutes: utils.Int32(int32(idleTimeout)), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), Zones: zones, } + publicIpPrefixId, publicIpPrefixIdOk := d.GetOk("public_ip_prefix_id") + + if publicIpPrefixIdOk { + publicIpPrefix := network.SubResource{} + publicIpPrefix.ID = utils.String(publicIpPrefixId.(string)) + publicIp.PublicIPAddressPropertiesFormat.PublicIPPrefix = &publicIpPrefix + } + dnl, dnlOk := d.GetOk("domain_name_label") rfqdn, rfqdnOk := d.GetOk("reverse_fqdn") @@ -237,10 +254,10 @@ func resourceArmPublicIpCreateUpdate(d *schema.ResourceData, meta interface{}) e } func resourceArmPublicIpRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).publicIPClient + client := meta.(*ArmClient).network.PublicIPsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -261,7 +278,7 @@ func resourceArmPublicIpRead(d *schema.ResourceData, meta interface{}) error { d.Set("resource_group_name", resGroup) d.Set("zones", resp.Zones) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { @@ -283,16 +300,14 @@ func resourceArmPublicIpRead(d *schema.ResourceData, meta interface{}) error { d.Set("idle_timeout_in_minutes", props.IdleTimeoutInMinutes) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmPublicIpDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).publicIPClient + client := meta.(*ArmClient).network.PublicIPsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_public_ip_prefix.go b/azurerm/resource_arm_public_ip_prefix.go new file mode 100644 index 000000000000..acdb36af224b --- /dev/null +++ b/azurerm/resource_arm_public_ip_prefix.go @@ -0,0 +1,178 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmPublicIpPrefix() *schema.Resource { + return &schema.Resource{ + Create: resourceArmPublicIpPrefixCreateUpdate, + Read: resourceArmPublicIpPrefixRead, + Update: resourceArmPublicIpPrefixCreateUpdate, + Delete: resourceArmPublicIpPrefixDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "location": azure.SchemaLocation(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "sku": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: string(network.Standard), + ValidateFunc: validation.StringInSlice([]string{ + string(network.Standard), + }, false), + }, + + "prefix_length": { + Type: schema.TypeInt, + Optional: true, + Default: 28, + ForceNew: true, + ValidateFunc: validation.IntBetween(24, 31), + }, + + "ip_prefix": { + Type: schema.TypeString, + Computed: true, + }, + + "zones": azure.SchemaSingleZone(), + + "tags": tags.Schema(), + }, + } +} + +func resourceArmPublicIpPrefixCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.PublicIPPrefixesClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for AzureRM Public IP Prefix creation.") + + name := d.Get("name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + resGroup := d.Get("resource_group_name").(string) + sku := d.Get("sku").(string) + prefix_length := d.Get("prefix_length").(int) + t := d.Get("tags").(map[string]interface{}) + zones := azure.ExpandZones(d.Get("zones").([]interface{})) + + publicIpPrefix := network.PublicIPPrefix{ + Name: &name, + Location: &location, + Sku: &network.PublicIPPrefixSku{ + Name: network.PublicIPPrefixSkuName(sku), + }, + PublicIPPrefixPropertiesFormat: &network.PublicIPPrefixPropertiesFormat{ + PrefixLength: utils.Int32(int32(prefix_length)), + }, + Tags: tags.Expand(t), + Zones: zones, + } + + future, err := client.CreateOrUpdate(ctx, resGroup, name, publicIpPrefix) + if err != nil { + return fmt.Errorf("Error Creating/Updating Public IP Prefix %q (Resource Group %q): %+v", name, resGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for completion of Public IP Prefix %q (Resource Group %q): %+v", name, resGroup, err) + } + + read, err := client.Get(ctx, resGroup, name, "") + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("Cannot read Public IP Prefix %q (resource group %q) ID", name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmPublicIpPrefixRead(d, meta) +} + +func resourceArmPublicIpPrefixRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.PublicIPPrefixesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["publicIPPrefixes"] + + resp, err := client.Get(ctx, resGroup, name, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Public IP Prefix %q (Resource Group %q): %+v", name, resGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + d.Set("zones", resp.Zones) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if sku := resp.Sku; sku != nil { + d.Set("sku", string(sku.Name)) + } + + if props := resp.PublicIPPrefixPropertiesFormat; props != nil { + d.Set("prefix_length", props.PrefixLength) + d.Set("ip_prefix", props.IPPrefix) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmPublicIpPrefixDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).network.PublicIPPrefixesClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["publicIPPrefixes"] + + future, err := client.Delete(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error deleting Public IP Prefix %q (Resource Group %q): %+v", name, resGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of Public IP Prefix %q (Resource Group %q): %+v", name, resGroup, err) + } + + return nil +} diff --git a/azurerm/resource_arm_public_ip_prefix_test.go b/azurerm/resource_arm_public_ip_prefix_test.go new file mode 100644 index 000000000000..fad8e039e701 --- /dev/null +++ b/azurerm/resource_arm_public_ip_prefix_test.go @@ -0,0 +1,276 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func testCheckAzureRMPublicIPPrefixExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + publicIpPrefixName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for public ip prefix: %s", publicIpPrefixName) + } + + client := testAccProvider.Meta().(*ArmClient).network.PublicIPPrefixesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, publicIpPrefixName, "") + if err != nil { + return fmt.Errorf("Bad: Get on publicIPPrefixClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Public IP Prefix %q (resource group: %q) does not exist", publicIpPrefixName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMPublicIPPrefixDisappears(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + publicIpPrefixName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for public ip prefix: %s", publicIpPrefixName) + } + + client := testAccProvider.Meta().(*ArmClient).network.PublicIPPrefixesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + future, err := client.Delete(ctx, resourceGroup, publicIpPrefixName) + if err != nil { + return fmt.Errorf("Error deleting Public IP Prefix %q (Resource Group %q): %+v", publicIpPrefixName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of Public IP Prefix %q (Resource Group %q): %+v", publicIpPrefixName, resourceGroup, err) + } + + return nil + } +} + +func testCheckAzureRMPublicIPPrefixDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).network.PublicIPPrefixesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_public_ip_prefix" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, name, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Public IP Prefix still exists:\n%#v", resp.PublicIPPrefixPropertiesFormat) + } + } + + return nil +} + +func TestAccAzureRMPublicIpPrefix_basic(t *testing.T) { + resourceName := "azurerm_public_ip_prefix.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMPublicIPPrefix_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIPPrefixDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIPPrefixExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "ip_prefix"), + resource.TestCheckResourceAttr(resourceName, "prefix_length", "28"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMPublicIpPrefix_prefixLength(t *testing.T) { + resourceName := "azurerm_public_ip_prefix.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMPublicIPPrefix_prefixLength(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIPPrefixDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIPPrefixExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "ip_prefix"), + resource.TestCheckResourceAttr(resourceName, "prefix_length", "31"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMPublicIpPrefix_update(t *testing.T) { + resourceName := "azurerm_public_ip_prefix.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMPublicIPPrefix_withTags(ri, location) + postConfig := testAccAzureRMPublicIPPrefix_withTagsUpdate(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIPPrefixDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIPPrefixExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "Production"), + resource.TestCheckResourceAttr(resourceName, "tags.cost_center", "MSFT"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIPPrefixExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "staging"), + ), + }, + }, + }) +} + +func TestAccAzureRMPublicIpPrefix_disappears(t *testing.T) { + resourceName := "azurerm_public_ip_prefix.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMPublicIPPrefix_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIPPrefixDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIPPrefixExists(resourceName), + testCheckAzureRMPublicIPPrefixDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccAzureRMPublicIPPrefix_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "acctestpublicipprefix-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rInt) +} + +func testAccAzureRMPublicIPPrefix_withTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "acctestpublicipprefix-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "Production" + cost_center = "MSFT" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMPublicIPPrefix_withTagsUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "acctestpublicipprefix-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags = { + environment = "staging" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMPublicIPPrefix_prefixLength(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "acctestpublicipprefix-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + prefix_length = 31 +} +`, rInt, location, rInt) +} diff --git a/azurerm/resource_arm_public_ip_test.go b/azurerm/resource_arm_public_ip_test.go index e5255a1c8aa2..eb7fa196f241 100644 --- a/azurerm/resource_arm_public_ip_test.go +++ b/azurerm/resource_arm_public_ip_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMPublicIpStatic_basic(t *testing.T) { @@ -40,7 +41,7 @@ func TestAccAzureRMPublicIpStatic_basic(t *testing.T) { } func TestAccAzureRMPublicIpStatic_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -400,6 +401,59 @@ func TestAccAzureRMPublicIpStatic_update(t *testing.T) { }) } +func TestAccAzureRMPublicIpStatic_standardPrefix(t *testing.T) { + resourceName := "azurerm_public_ip.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMPublicIPStatic_standardPrefix(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIpDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIpExists(resourceName), + ), + }, + }, + }) +} + +func TestAccAzureRMPublicIpStatic_standardPrefixWithTags(t *testing.T) { + resourceName := "azurerm_public_ip.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMPublicIPStatic_standardPrefixWithTags(ri, location) + postConfig := testAccAzureRMPublicIPStatic_standardPrefixWithTagsUpdate(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIpDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIpExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "Production"), + resource.TestCheckResourceAttr(resourceName, "tags.cost_center", "MSFT"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIpExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "staging"), + ), + }, + }, + }) +} + func TestAccAzureRMPublicIpDynamic_basic(t *testing.T) { resourceName := "azurerm_public_ip.test" ri := tf.AccRandTimeInt() @@ -489,7 +543,7 @@ func testCheckAzureRMPublicIpExists(resourceName string) resource.TestCheckFunc return fmt.Errorf("Bad: no resource group found in state for public ip: %s", publicIPName) } - client := testAccProvider.Meta().(*ArmClient).publicIPClient + client := testAccProvider.Meta().(*ArmClient).network.PublicIPsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, publicIPName, "") @@ -519,7 +573,7 @@ func testCheckAzureRMPublicIpDisappears(resourceName string) resource.TestCheckF return fmt.Errorf("Bad: no resource group found in state for public ip: %s", publicIpName) } - client := testAccProvider.Meta().(*ArmClient).publicIPClient + client := testAccProvider.Meta().(*ArmClient).network.PublicIPsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, publicIpName) if err != nil { @@ -535,7 +589,7 @@ func testCheckAzureRMPublicIpDisappears(resourceName string) resource.TestCheckF } func testCheckAzureRMPublicIpDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).publicIPClient + client := testAccProvider.Meta().(*ArmClient).network.PublicIPsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -673,6 +727,87 @@ resource "azurerm_public_ip" "test" { `, rInt, location, rInt) } +func testAccAzureRMPublicIPStatic_standardPrefix(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "acctestpublicipprefix-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_public_ip" "test" { + name = "acctestpublicip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" + sku = "Standard" + public_ip_prefix_id = "${azurerm_public_ip_prefix.test.id}" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPublicIPStatic_standardPrefixWithTags(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "acctestpublicipprefix-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_public_ip" "test" { + name = "acctestpublicip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" + sku = "Standard" + public_ip_prefix_id = "${azurerm_public_ip_prefix.test.id}" + + tags = { + environment = "Production" + cost_center = "MSFT" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMPublicIPStatic_standardPrefixWithTagsUpdate(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "acctestpublicipprefix-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_public_ip" "test" { + name = "acctestpublicip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" + sku = "Standard" + public_ip_prefix_id = "${azurerm_public_ip_prefix.test.id}" + + tags = { + environment = "staging" + } +} +`, rInt, location, rInt, rInt) +} + func testAccAzureRMPublicIPStatic_standard_withIPVersion(rInt int, location string, ipVersion string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/azurerm/resource_arm_recovery_services_fabric.go b/azurerm/resource_arm_recovery_services_fabric.go new file mode 100644 index 000000000000..39d23026e606 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_fabric.go @@ -0,0 +1,150 @@ +package azurerm + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2018-01-10/siterecovery" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmRecoveryServicesFabric() *schema.Resource { + return &schema.Resource{ + Create: resourceArmRecoveryServicesFabricCreate, + Read: resourceArmRecoveryServicesFabricRead, + Update: nil, + Delete: resourceArmRecoveryServicesFabricDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "resource_group_name": azure.SchemaResourceGroupName(), + + "recovery_vault_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, + }, + "location": azure.SchemaLocation(), + }, + } +} + +func resourceArmRecoveryServicesFabricCreate(d *schema.ResourceData, meta interface{}) error { + resGroup := d.Get("resource_group_name").(string) + vaultName := d.Get("recovery_vault_name").(string) + location := azure.NormalizeLocation(d.Get("location").(string)) + name := d.Get("name").(string) + + client := meta.(*ArmClient).recoveryServices.FabricClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing rec overy services fabric %s (vault %s): %+v", name, vaultName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_resource_group", azure.HandleAzureSdkForGoBug2824(*existing.ID)) + } + } + + parameters := siterecovery.FabricCreationInput{ + Properties: &siterecovery.FabricCreationInputProperties{ + CustomDetails: siterecovery.AzureFabricCreationInput{ + InstanceType: "Azure", + Location: &location, + }, + }, + } + + future, err := client.Create(ctx, name, parameters) + if err != nil { + return fmt.Errorf("Error creating recovery services fabric %s (vault %s): %+v", name, vaultName, err) + } + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error creating recovery services fabric %s (vault %s): %+v", name, vaultName, err) + } + + resp, err := client.Get(ctx, name) + if err != nil { + return fmt.Errorf("Error retrieving recovery services fabric %s (vault %s): %+v", name, vaultName, err) + } + + d.SetId(azure.HandleAzureSdkForGoBug2824(*resp.ID)) + + return resourceArmRecoveryServicesFabricRead(d, meta) +} + +func resourceArmRecoveryServicesFabricRead(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + name := id.Path["replicationFabrics"] + + client := meta.(*ArmClient).recoveryServices.FabricClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + resp, err := client.Get(ctx, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on recovery services fabric %s (vault %s): %+v", name, vaultName, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + if props := resp.Properties; props != nil { + if azureDetails, isAzureDetails := props.CustomDetails.AsAzureFabricSpecificDetails(); isAzureDetails { + d.Set("location", azureDetails.Location) + } + } + d.Set("recovery_vault_name", vaultName) + return nil +} + +func resourceArmRecoveryServicesFabricDelete(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + name := id.Path["replicationFabrics"] + + client := meta.(*ArmClient).recoveryServices.FabricClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + future, err := client.Delete(ctx, name) + if err != nil { + return fmt.Errorf("Error deleting recovery services fabric %s (vault %s): %+v", name, vaultName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of recovery services fabric %s (vault %s): %+v", name, vaultName, err) + } + + return nil +} diff --git a/azurerm/resource_arm_recovery_services_fabric_test.go b/azurerm/resource_arm_recovery_services_fabric_test.go new file mode 100644 index 000000000000..24e4ef885b8c --- /dev/null +++ b/azurerm/resource_arm_recovery_services_fabric_test.go @@ -0,0 +1,97 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMRecoveryFabric_basic(t *testing.T) { + resourceGroupName := "azurerm_resource_group.test" + vaultName := "azurerm_recovery_services_vault.test" + resourceName := "azurerm_recovery_services_fabric.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMResourceGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRecoveryFabric_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRecoveryFabricExists(resourceGroupName, vaultName, resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMRecoveryFabric_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_recovery_services_vault" "test" { + name = "acctest-vault-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-fabric-%d" + location = "${azurerm_resource_group.test.location}" +} +`, rInt, location, rInt, rInt) +} + +func testCheckAzureRMRecoveryFabricExists(resourceGroupStateName, vaultStateName string, resourceStateName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + resourceGroupState, ok := s.RootModule().Resources[resourceGroupStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceGroupStateName) + } + vaultState, ok := s.RootModule().Resources[vaultStateName] + if !ok { + return fmt.Errorf("Not found: %s", vaultStateName) + } + fabricState, ok := s.RootModule().Resources[resourceStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceStateName) + } + + resourceGroupName := resourceGroupState.Primary.Attributes["name"] + vaultName := vaultState.Primary.Attributes["name"] + fabricName := fabricState.Primary.Attributes["name"] + + // Ensure fabric exists in API + client := testAccProvider.Meta().(*ArmClient).recoveryServices.FabricClient(resourceGroupName, vaultName) + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName) + if err != nil { + return fmt.Errorf("Bad: Get on fabricClient: %+v", err) + } + + if resp.Response.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: fabric: %q does not exist", fabricName) + } + + return nil + } +} diff --git a/azurerm/resource_arm_recovery_services_network_mapping.go b/azurerm/resource_arm_recovery_services_network_mapping.go new file mode 100644 index 000000000000..5d9724bdf983 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_network_mapping.go @@ -0,0 +1,202 @@ +package azurerm + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2018-01-10/siterecovery" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmRecoveryServicesNetworkMapping() *schema.Resource { + return &schema.Resource{ + Create: resourceArmRecoveryNetworkMappingCreate, + Read: resourceArmRecoveryNetworkMappingRead, + Delete: resourceArmRecoveryNetworkMappingDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "resource_group_name": azure.SchemaResourceGroupName(), + + "recovery_vault_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, + }, + "source_recovery_fabric_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "target_recovery_fabric_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "source_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "target_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + }, + } +} + +func resourceArmRecoveryNetworkMappingCreate(d *schema.ResourceData, meta interface{}) error { + resGroup := d.Get("resource_group_name").(string) + vaultName := d.Get("recovery_vault_name").(string) + fabricName := d.Get("source_recovery_fabric_name").(string) + targetFabricName := d.Get("target_recovery_fabric_name").(string) + sourceNetworkId := d.Get("source_network_id").(string) + targetNetworkId := d.Get("target_network_id").(string) + name := d.Get("name").(string) + + client := meta.(*ArmClient).recoveryServices.NetworkMappingClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + //get network name from id + parsedSourceNetworkId, err := azure.ParseAzureResourceID(sourceNetworkId) + if err != nil { + return fmt.Errorf("[ERROR] Unable to parse source_network_id '%s' (network mapping %s): %+v", sourceNetworkId, name, err) + } + sourceNetworkName, hasName := parsedSourceNetworkId.Path["virtualNetworks"] + if !hasName { + sourceNetworkName, hasName = parsedSourceNetworkId.Path["virtualnetworks"] // Handle that different APIs return different ID casings + if !hasName { + return fmt.Errorf("[ERROR] parsed source_network_id '%s' doesn't contain 'virtualnetworks'", parsedSourceNetworkId) + } + } + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, fabricName, sourceNetworkName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing recovery services fabric %s (vault %s): %+v", name, vaultName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_recovery_network_mapping", azure.HandleAzureSdkForGoBug2824(*existing.ID)) + } + } + + var parameters = siterecovery.CreateNetworkMappingInput{ + Properties: &siterecovery.CreateNetworkMappingInputProperties{ + RecoveryNetworkID: &targetNetworkId, + RecoveryFabricName: &targetFabricName, + FabricSpecificDetails: siterecovery.AzureToAzureCreateNetworkMappingInput{ + PrimaryNetworkID: &sourceNetworkId, + }, + }, + } + future, err := client.Create(ctx, fabricName, sourceNetworkName, name, parameters) + if err != nil { + return fmt.Errorf("Error creating recovery network mapping %s (vault %s): %+v", name, vaultName, err) + } + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error creating recovery network mapping %s (vault %s): %+v", name, vaultName, err) + } + + resp, err := client.Get(ctx, fabricName, sourceNetworkName, name) + if err != nil { + return fmt.Errorf("Error retrieving recovery network mapping %s (vault %s): %+v", name, vaultName, err) + } + + d.SetId(azure.HandleAzureSdkForGoBug2824(*resp.ID)) + + return resourceArmRecoveryNetworkMappingRead(d, meta) +} + +func resourceArmRecoveryNetworkMappingRead(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + fabricName := id.Path["replicationFabrics"] + networkName := id.Path["replicationNetworks"] + name := id.Path["replicationNetworkMappings"] + + client := meta.(*ArmClient).recoveryServices.NetworkMappingClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName, networkName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on recovery services protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + + d.Set("resource_group_name", resGroup) + d.Set("recovery_vault_name", vaultName) + d.Set("source_recovery_fabric_name", fabricName) + d.Set("name", resp.Name) + if props := resp.Properties; props != nil { + d.Set("source_network_id", props.PrimaryNetworkID) + d.Set("target_network_id", props.RecoveryNetworkID) + + targetFabricId, err := azure.ParseAzureResourceID(azure.HandleAzureSdkForGoBug2824(*resp.Properties.RecoveryFabricArmID)) + if err != nil { + return err + } + d.Set("target_recovery_fabric_name", targetFabricId.Path["replicationFabrics"]) + } + + return nil +} + +func resourceArmRecoveryNetworkMappingDelete(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + fabricName := id.Path["replicationFabrics"] + networkName := id.Path["replicationNetworks"] + name := id.Path["replicationNetworkMappings"] + + client := meta.(*ArmClient).recoveryServices.NetworkMappingClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + future, err := client.Delete(ctx, fabricName, networkName, name) + if err != nil { + return fmt.Errorf("Error deleting recovery services protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of recovery services protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + + return nil +} diff --git a/azurerm/resource_arm_recovery_services_network_mapping_test.go b/azurerm/resource_arm_recovery_services_network_mapping_test.go new file mode 100644 index 000000000000..127663d57283 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_network_mapping_test.go @@ -0,0 +1,141 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMRecoveryNetworkMapping_basic(t *testing.T) { + resourceGroupName := "azurerm_resource_group.test" + vaultName := "azurerm_recovery_services_vault.test" + fabricName := "azurerm_recovery_services_fabric.test1" + networkName := "azurerm_virtual_network.test1" + resourceName := "azurerm_recovery_network_mapping.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMResourceGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRecoveryNetworkMapping_basic(ri, testLocation(), testAltLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRecoveryNetworkMappingExists(resourceGroupName, vaultName, fabricName, networkName, resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMRecoveryNetworkMapping_basic(rInt int, location string, altLocation string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG1-%d" + location = "%s" +} + +resource "azurerm_recovery_services_vault" "test" { + name = "acctest-vault-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "test1" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-fabric1-%d" + location = "${azurerm_resource_group.test.location}" +} + +resource "azurerm_recovery_services_fabric" "test2" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-fabric2-%d" + location = "%s" + depends_on = ["azurerm_recovery_services_fabric.test1"] +} + +resource "azurerm_virtual_network" "test1" { + name = "network1-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = [ "192.168.1.0/24" ] + location = "${azurerm_recovery_services_fabric.test1.location}" +} + +resource "azurerm_virtual_network" "test2" { + name = "network2-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = [ "192.168.2.0/24" ] + location = "${azurerm_recovery_services_fabric.test2.location}" +} + +resource "azurerm_recovery_network_mapping" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "mapping-%d" + source_recovery_fabric_name = "${azurerm_recovery_services_fabric.test1.name}" + target_recovery_fabric_name = "${azurerm_recovery_services_fabric.test2.name}" + source_network_id = "${azurerm_virtual_network.test1.id}" + target_network_id = "${azurerm_virtual_network.test2.id}" +} +`, rInt, location, rInt, rInt, rInt, altLocation, rInt, rInt, rInt) +} + +func testCheckAzureRMRecoveryNetworkMappingExists(resourceGroupStateName, vaultStateName string, fabricStateName string, networkStateName string, networkStateMappingName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + resourceGroupState, ok := s.RootModule().Resources[resourceGroupStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceGroupStateName) + } + vaultState, ok := s.RootModule().Resources[vaultStateName] + if !ok { + return fmt.Errorf("Not found: %s", vaultStateName) + } + fabricState, ok := s.RootModule().Resources[fabricStateName] + if !ok { + return fmt.Errorf("Not found: %s", fabricStateName) + } + networkState, ok := s.RootModule().Resources[networkStateName] + if !ok { + return fmt.Errorf("Not found: %s", fabricStateName) + } + networkMappingState, ok := s.RootModule().Resources[networkStateMappingName] + if !ok { + return fmt.Errorf("Not found: %s", networkStateMappingName) + } + + resourceGroupName := resourceGroupState.Primary.Attributes["name"] + vaultName := vaultState.Primary.Attributes["name"] + fabricName := fabricState.Primary.Attributes["name"] + networkName := networkState.Primary.Attributes["name"] + mappingName := networkMappingState.Primary.Attributes["name"] + + // Ensure mapping exists in API + client := testAccProvider.Meta().(*ArmClient).recoveryServices.NetworkMappingClient(resourceGroupName, vaultName) + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName, networkName, mappingName) + if err != nil { + return fmt.Errorf("Bad: Get on networkMappingClient: %+v", err) + } + + if resp.Response.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: networkMapping: %q does not exist", mappingName) + } + + return nil + } +} diff --git a/azurerm/resource_arm_recovery_services_protected_vm.go b/azurerm/resource_arm_recovery_services_protected_vm.go index b15aa0549243..7b3d87836550 100644 --- a/azurerm/resource_arm_recovery_services_protected_vm.go +++ b/azurerm/resource_arm_recovery_services_protected_vm.go @@ -4,17 +4,17 @@ import ( "context" "fmt" "log" - "regexp" "strings" "time" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2017-07-01/backup" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,16 +32,13 @@ func resourceArmRecoveryServicesProtectedVm() *schema.Resource { Schema: map[string]*schema.Schema{ - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "recovery_vault_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringMatch( - regexp.MustCompile("^[a-zA-Z][-a-zA-Z0-9]{1,49}$"), - "Recovery Service Vault name must be 2 - 50 characters long, start with a letter, contain only letters, numbers and hyphens.", - ), + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, }, "source_vm_id": { @@ -54,21 +51,20 @@ func resourceArmRecoveryServicesProtectedVm() *schema.Resource { "backup_policy_id": { Type: schema.TypeString, Required: true, - ForceNew: true, ValidateFunc: azure.ValidateResourceID, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmRecoveryServicesProtectedVmCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesProtectedItemsClient + client := meta.(*ArmClient).recoveryServices.ProtectedItemsClient ctx := meta.(*ArmClient).StopContext resourceGroup := d.Get("resource_group_name").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) vaultName := d.Get("recovery_vault_name").(string) vmId := d.Get("source_vm_id").(string) @@ -89,7 +85,7 @@ func resourceArmRecoveryServicesProtectedVmCreateUpdate(d *schema.ResourceData, log.Printf("[DEBUG] Creating/updating Recovery Service Protected VM %s (resource group %q)", protectedItemName, resourceGroup) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err2 := client.Get(ctx, vaultName, resourceGroup, "Azure", containerName, protectedItemName, "") if err2 != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -103,7 +99,7 @@ func resourceArmRecoveryServicesProtectedVmCreateUpdate(d *schema.ResourceData, } item := backup.ProtectedItemResource{ - Tags: expandTags(tags), + Tags: tags.Expand(t), Properties: &backup.AzureIaaSComputeVMProtectedItem{ PolicyID: &policyId, ProtectedItemType: backup.ProtectedItemTypeMicrosoftClassicComputevirtualMachines, @@ -118,21 +114,22 @@ func resourceArmRecoveryServicesProtectedVmCreateUpdate(d *schema.ResourceData, return fmt.Errorf("Error creating/updating Recovery Service Protected VM %q (Resource Group %q): %+v", protectedItemName, resourceGroup, err) } - resp, err := resourceArmRecoveryServicesProtectedVmWaitForState(client, ctx, true, vaultName, resourceGroup, containerName, protectedItemName) + resp, err := resourceArmRecoveryServicesProtectedVmWaitForState(client, ctx, true, vaultName, resourceGroup, containerName, protectedItemName, policyId, d.IsNewResource()) if err != nil { return err } - id := strings.Replace(*resp.ID, "Subscriptions", "subscriptions", 1) + + id := strings.Replace(*resp.ID, "Subscriptions", "subscriptions", 1) // This code is a workaround for this bug https://github.com/Azure/azure-sdk-for-go/issues/2824 d.SetId(id) return resourceArmRecoveryServicesProtectedVmRead(d, meta) } func resourceArmRecoveryServicesProtectedVmRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesProtectedItemsClient + client := meta.(*ArmClient).recoveryServices.ProtectedItemsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -167,16 +164,14 @@ func resourceArmRecoveryServicesProtectedVmRead(d *schema.ResourceData, meta int } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmRecoveryServicesProtectedVmDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesProtectedItemsClient + client := meta.(*ArmClient).recoveryServices.ProtectedItemsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -195,14 +190,14 @@ func resourceArmRecoveryServicesProtectedVmDelete(d *schema.ResourceData, meta i } } - if _, err := resourceArmRecoveryServicesProtectedVmWaitForState(client, ctx, false, vaultName, resourceGroup, containerName, protectedItemName); err != nil { + if _, err := resourceArmRecoveryServicesProtectedVmWaitForState(client, ctx, false, vaultName, resourceGroup, containerName, protectedItemName, "", false); err != nil { return err } return nil } -func resourceArmRecoveryServicesProtectedVmWaitForState(client backup.ProtectedItemsGroupClient, ctx context.Context, found bool, vaultName, resourceGroup, containerName, protectedItemName string) (backup.ProtectedItemResource, error) { +func resourceArmRecoveryServicesProtectedVmWaitForState(client *backup.ProtectedItemsGroupClient, ctx context.Context, found bool, vaultName, resourceGroup, containerName, protectedItemName string, policyId string, newResource bool) (backup.ProtectedItemResource, error) { state := &resource.StateChangeConf{ Timeout: 30 * time.Minute, MinTimeout: 30 * time.Second, @@ -216,8 +211,23 @@ func resourceArmRecoveryServicesProtectedVmWaitForState(client backup.ProtectedI } return resp, "Error", fmt.Errorf("Error making Read request on Recovery Service Protected VM %q (Resource Group %q): %+v", protectedItemName, resourceGroup, err) + } else if !newResource && policyId != "" { + if properties := resp.Properties; properties != nil { + if vm, ok := properties.AsAzureIaaSComputeVMProtectedItem(); ok { + if v := vm.PolicyID; v != nil { + if strings.Replace(*v, "Subscriptions", "subscriptions", 1) != policyId { + return resp, "NotFound", nil + } + } else { + return resp, "Error", fmt.Errorf("Error reading policy ID attribute nil on Recovery Service Protected VM %q (Resource Group %q)", protectedItemName, resourceGroup) + } + } else { + return resp, "Error", fmt.Errorf("Error reading properties on Recovery Service Protected VM %q (Resource Group %q)", protectedItemName, resourceGroup) + } + } else { + return resp, "Error", fmt.Errorf("Error reading properties on empty Recovery Service Protected VM %q (Resource Group %q)", protectedItemName, resourceGroup) + } } - return resp, "Found", nil }, } diff --git a/azurerm/resource_arm_recovery_services_protected_vm_test.go b/azurerm/resource_arm_recovery_services_protected_vm_test.go index 5f750fea9832..6abe04ee3e16 100644 --- a/azurerm/resource_arm_recovery_services_protected_vm_test.go +++ b/azurerm/resource_arm_recovery_services_protected_vm_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -42,7 +43,7 @@ func TestAccAzureRMRecoveryServicesProtectedVm_basic(t *testing.T) { } func TestAccAzureRMRecoveryServicesProtectedVm_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -103,6 +104,55 @@ func TestAccAzureRMRecoveryServicesProtectedVm_separateResourceGroups(t *testing }) } +func TestAccAzureRMRecoveryServicesProtectedVm_updateBackupPolicyId(t *testing.T) { + virtualMachine := "azurerm_virtual_machine.test" + protectedVmResourceName := "azurerm_recovery_services_protected_vm.test" + fBackupPolicyResourceName := "azurerm_recovery_services_protection_policy_vm.test" + sBackupPolicyResourceName := "azurerm_recovery_services_protection_policy_vm.test_change_backup" + + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRecoveryServicesProtectedVmDestroy, + Steps: []resource.TestStep{ + { // Create resources and link first backup policy id + ResourceName: fBackupPolicyResourceName, + Config: testAccAzureRMRecoveryServicesProtectedVm_linkFirstBackupPolicy(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(protectedVmResourceName, "backup_policy_id", fBackupPolicyResourceName, "id"), + ), + }, + { // Modify backup policy id to the second one + // Set Destroy false to prevent error from cleaning up dangling resource + ResourceName: sBackupPolicyResourceName, + Config: testAccAzureRMRecoveryServicesProtectedVm_linkSecondBackupPolicy(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(protectedVmResourceName, "backup_policy_id", sBackupPolicyResourceName, "id"), + ), + }, + { // Remove backup policy link + // Backup policy link will need to be removed first so the VM's backup policy subsequently reverts to Default + // Azure API is quite sensitive, adding the step to control resource cleanup order + ResourceName: fBackupPolicyResourceName, + Config: testAccAzureRMRecoveryServicesProtectedVm_withVM(ri, testLocation()), + Check: resource.ComposeTestCheckFunc(), + }, + { // Then VM can be removed + ResourceName: virtualMachine, + Config: testAccAzureRMRecoveryServicesProtectedVm_withSecondPolicy(ri, testLocation()), + Check: resource.ComposeTestCheckFunc(), + }, + { // Remove backup policies and vault + ResourceName: protectedVmResourceName, + Config: testAccAzureRMRecoveryServicesProtectedVm_basePolicyTest(ri, testLocation()), + Check: resource.ComposeTestCheckFunc(), + }, + }, + }) +} + func testCheckAzureRMRecoveryServicesProtectedVmDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_recovery_services_protected_vm" { @@ -125,7 +175,7 @@ func testCheckAzureRMRecoveryServicesProtectedVmDestroy(s *terraform.State) erro protectedItemName := fmt.Sprintf("VM;iaasvmcontainerv2;%s;%s", parsedVmId.ResourceGroup, vmName) containerName := fmt.Sprintf("iaasvmcontainer;iaasvmcontainerv2;%s;%s", parsedVmId.ResourceGroup, vmName) - client := testAccProvider.Meta().(*ArmClient).recoveryServicesProtectedItemsClient + client := testAccProvider.Meta().(*ArmClient).recoveryServices.ProtectedItemsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, vaultName, resourceGroup, "Azure", containerName, protectedItemName, "") @@ -172,7 +222,7 @@ func testCheckAzureRMRecoveryServicesProtectedVmExists(resourceName string) reso protectedItemName := fmt.Sprintf("VM;iaasvmcontainerv2;%s;%s", parsedVmId.ResourceGroup, vmName) containerName := fmt.Sprintf("iaasvmcontainer;iaasvmcontainerv2;%s;%s", parsedVmId.ResourceGroup, vmName) - client := testAccProvider.Meta().(*ArmClient).recoveryServicesProtectedItemsClient + client := testAccProvider.Meta().(*ArmClient).recoveryServices.ProtectedItemsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, vaultName, resourceGroup, "Azure", containerName, protectedItemName, "") @@ -331,6 +381,209 @@ resource "azurerm_recovery_services_protected_vm" "test" { `, testAccAzureRMRecoveryServicesProtectedVm_base(rInt, location)) } +// For update backup policy id test +func testAccAzureRMRecoveryServicesProtectedVm_basePolicyTest(rInt int, location string) string { + rstr := strconv.Itoa(rInt) + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_virtual_network" "test" { + name = "vnet" + location = "${azurerm_resource_group.test.location}" + address_space = ["10.0.0.0/16"] + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctest_subnet" + virtual_network_name = "${azurerm_virtual_network.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + address_prefix = "10.0.10.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctest_nic" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "acctestipconfig" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "Dynamic" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } +} + +resource "azurerm_public_ip" "test" { + name = "acctest-ip" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Dynamic" + domain_name_label = "acctestip%[1]d" +} + +resource "azurerm_storage_account" "test" { + name = "acctest%[3]s" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_managed_disk" "test" { + name = "acctest-datadisk" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_type = "Standard_LRS" + create_option = "Empty" + disk_size_gb = "1023" +} +`, rInt, location, rstr[len(rstr)-5:]) +} + +// For update backup policy id test +func testAccAzureRMRecoveryServicesProtectedVm_withVault(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_recovery_services_vault" "test" { + name = "acctest-%[2]d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} +`, testAccAzureRMRecoveryServicesProtectedVm_basePolicyTest(rInt, location), rInt) +} + +// For update backup policy id test +func testAccAzureRMRecoveryServicesProtectedVm_withFirstPolicy(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_recovery_services_protection_policy_vm" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + + backup { + frequency = "Daily" + time = "23:00" + } + + retention_daily { + count = 10 + } +} +`, testAccAzureRMRecoveryServicesProtectedVm_withVault(rInt, location), rInt) +} + +// For update backup policy id test +func testAccAzureRMRecoveryServicesProtectedVm_withSecondPolicy(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_recovery_services_protection_policy_vm" "test_change_backup" { + name = "acctest2-%[2]d" + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + + backup { + frequency = "Daily" + time = "23:00" + } + + retention_daily { + count = 15 + } +} +`, testAccAzureRMRecoveryServicesProtectedVm_withFirstPolicy(rInt, location), rInt) +} + +// For update backup policy id test +func testAccAzureRMRecoveryServicesProtectedVm_withVM(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_virtual_machine" "test" { + name = "acctestvm-%[2]d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + vm_size = "Standard_A0" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + delete_os_disk_on_termination = true + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "acctest-osdisk" + managed_disk_type = "Standard_LRS" + caching = "ReadWrite" + create_option = "FromImage" + } + + storage_data_disk { + name = "acctest-datadisk" + managed_disk_id = "${azurerm_managed_disk.test.id}" + managed_disk_type = "Standard_LRS" + disk_size_gb = "${azurerm_managed_disk.test.disk_size_gb}" + create_option = "Attach" + lun = 0 + } + + os_profile { + computer_name = "acctest" + admin_username = "vmadmin" + admin_password = "Password123!@#" + } + + os_profile_linux_config { + disable_password_authentication = false + } + + boot_diagnostics { + enabled = true + storage_uri = "${azurerm_storage_account.test.primary_blob_endpoint}" + } +} +`, testAccAzureRMRecoveryServicesProtectedVm_withSecondPolicy(rInt, location), rInt) +} + +// For update backup policy id test +func testAccAzureRMRecoveryServicesProtectedVm_linkFirstBackupPolicy(rInt int, location string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_recovery_services_protected_vm" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + source_vm_id = "${azurerm_virtual_machine.test.id}" + backup_policy_id = "${azurerm_recovery_services_protection_policy_vm.test.id}" +} +`, testAccAzureRMRecoveryServicesProtectedVm_withVM(rInt, location)) +} + +// For update backup policy id test +func testAccAzureRMRecoveryServicesProtectedVm_linkSecondBackupPolicy(rInt int, location string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_recovery_services_protected_vm" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + source_vm_id = "${azurerm_virtual_machine.test.id}" + backup_policy_id = "${azurerm_recovery_services_protection_policy_vm.test_change_backup.id}" +} +`, testAccAzureRMRecoveryServicesProtectedVm_withVM(rInt, location)) +} + func testAccAzureRMRecoveryServicesProtectedVm_requiresImport(rInt int, location string) string { return fmt.Sprintf(` %s diff --git a/azurerm/resource_arm_recovery_services_protection_container.go b/azurerm/resource_arm_recovery_services_protection_container.go new file mode 100644 index 000000000000..da6582dc86b2 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_protection_container.go @@ -0,0 +1,148 @@ +package azurerm + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2018-01-10/siterecovery" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmRecoveryServicesProtectionContainer() *schema.Resource { + return &schema.Resource{ + Create: resourceArmRecoveryServicesProtectionContainerCreate, + Read: resourceArmRecoveryServicesProtectionContainerRead, + Update: nil, + Delete: resourceArmSiteRecoveryProtectionContainerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "resource_group_name": azure.SchemaResourceGroupName(), + + "recovery_vault_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, + }, + "recovery_fabric_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + } +} + +func resourceArmRecoveryServicesProtectionContainerCreate(d *schema.ResourceData, meta interface{}) error { + resGroup := d.Get("resource_group_name").(string) + vaultName := d.Get("recovery_vault_name").(string) + fabricName := d.Get("recovery_fabric_name").(string) + name := d.Get("name").(string) + + client := meta.(*ArmClient).recoveryServices.ProtectionContainerClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, fabricName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing recovery services protection container %s (fabric %s): %+v", name, fabricName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_recovery_services_protection_container", azure.HandleAzureSdkForGoBug2824(*existing.ID)) + } + } + + parameters := siterecovery.CreateProtectionContainerInput{ + Properties: &siterecovery.CreateProtectionContainerInputProperties{}, + } + + future, err := client.Create(ctx, fabricName, name, parameters) + if err != nil { + return fmt.Errorf("Error creating recovery services protection container %s (fabric %s): %+v", name, fabricName, err) + } + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error creating recovery services protection container %s (fabric %s): %+v", name, fabricName, err) + } + + resp, err := client.Get(ctx, fabricName, name) + if err != nil { + return fmt.Errorf("Error retrieving site recovery protection container %s (fabric %s): %+v", name, fabricName, err) + } + + d.SetId(azure.HandleAzureSdkForGoBug2824(*resp.ID)) + + return resourceArmRecoveryServicesProtectionContainerRead(d, meta) +} + +func resourceArmRecoveryServicesProtectionContainerRead(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + fabricName := id.Path["replicationFabrics"] + name := id.Path["replicationProtectionContainers"] + + client := meta.(*ArmClient).recoveryServices.ProtectionContainerClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on recovery services protection container %s (fabric %s): %+v", name, fabricName, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + d.Set("recovery_vault_name", vaultName) + d.Set("recovery_fabric_name", fabricName) + return nil +} + +func resourceArmSiteRecoveryProtectionContainerDelete(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + fabricName := id.Path["replicationFabrics"] + name := id.Path["replicationProtectionContainers"] + + client := meta.(*ArmClient).recoveryServices.ProtectionContainerClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + future, err := client.Delete(ctx, fabricName, name) + if err != nil { + return fmt.Errorf("Error deleting recovery services protection container %s (fabric %s): %+v", name, fabricName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of recovery services protection container %s (fabric %s): %+v", name, fabricName, err) + } + + return nil +} diff --git a/azurerm/resource_arm_recovery_services_protection_container_mapping.go b/azurerm/resource_arm_recovery_services_protection_container_mapping.go new file mode 100644 index 000000000000..bbf0c9a98cc9 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_protection_container_mapping.go @@ -0,0 +1,191 @@ +package azurerm + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2018-01-10/siterecovery" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmRecoveryServicesProtectionContainerMapping() *schema.Resource { + return &schema.Resource{ + Create: resourceArmRecoveryServicesContainerMappingCreate, + Read: resourceArmRecoveryServicesContainerMappingRead, + Update: nil, + Delete: resourceArmSiteRecoveryServicesContainerMappingDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "resource_group_name": azure.SchemaResourceGroupName(), + + "recovery_vault_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, + }, + "recovery_fabric_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "recovery_replication_policy_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "recovery_source_protection_container_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "recovery_target_protection_container_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + }, + } +} + +func resourceArmRecoveryServicesContainerMappingCreate(d *schema.ResourceData, meta interface{}) error { + resGroup := d.Get("resource_group_name").(string) + vaultName := d.Get("recovery_vault_name").(string) + fabricName := d.Get("recovery_fabric_name").(string) + policyId := d.Get("recovery_replication_policy_id").(string) + protectionContainerName := d.Get("recovery_source_protection_container_name").(string) + targetContainerId := d.Get("recovery_target_protection_container_id").(string) + name := d.Get("name").(string) + + client := meta.(*ArmClient).recoveryServices.ContainerMappingClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, fabricName, protectionContainerName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing recovery services protection container mapping %s (fabric %s, container %s): %+v", name, fabricName, protectionContainerName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_recovery_services_protection_container_mapping", azure.HandleAzureSdkForGoBug2824(*existing.ID)) + } + } + + var parameters = siterecovery.CreateProtectionContainerMappingInput{ + Properties: &siterecovery.CreateProtectionContainerMappingInputProperties{ + TargetProtectionContainerID: &targetContainerId, + PolicyID: &policyId, + ProviderSpecificInput: siterecovery.ReplicationProviderSpecificContainerMappingInput{}, + }, + } + future, err := client.Create(ctx, fabricName, protectionContainerName, name, parameters) + if err != nil { + return fmt.Errorf("Error creating recovery services protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error creating recovery services protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + + resp, err := client.Get(ctx, fabricName, protectionContainerName, name) + if err != nil { + return fmt.Errorf("Error retrieving site recovery protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + + d.SetId(azure.HandleAzureSdkForGoBug2824(*resp.ID)) + + return resourceArmRecoveryServicesContainerMappingRead(d, meta) +} + +func resourceArmRecoveryServicesContainerMappingRead(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + fabricName := id.Path["replicationFabrics"] + protectionContainerName := id.Path["replicationProtectionContainers"] + name := id.Path["replicationProtectionContainerMappings"] + + client := meta.(*ArmClient).recoveryServices.ContainerMappingClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName, protectionContainerName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on recovery services protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + + d.Set("resource_group_name", resGroup) + d.Set("recovery_vault_name", vaultName) + d.Set("recovery_fabric_name", fabricName) + d.Set("recovery_source_protection_container_name", resp.Properties.SourceProtectionContainerFriendlyName) + d.Set("name", resp.Name) + d.Set("recovery_replication_policy_id", resp.Properties.PolicyID) + d.Set("recovery_target_protection_container_id", resp.Properties.TargetProtectionContainerID) + return nil +} + +func resourceArmSiteRecoveryServicesContainerMappingDelete(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + fabricName := id.Path["replicationFabrics"] + protectionContainerName := id.Path["replicationProtectionContainers"] + name := id.Path["replicationProtectionContainerMappings"] + instanceType := string(siterecovery.InstanceTypeBasicReplicationProviderSpecificContainerMappingInputInstanceTypeA2A) + + client := meta.(*ArmClient).recoveryServices.ContainerMappingClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + input := siterecovery.RemoveProtectionContainerMappingInput{ + Properties: &siterecovery.RemoveProtectionContainerMappingInputProperties{ + ProviderSpecificInput: &siterecovery.ReplicationProviderContainerUnmappingInput{ + InstanceType: &instanceType, + }, + }, + } + + future, err := client.Delete(ctx, fabricName, protectionContainerName, name, input) + if err != nil { + return fmt.Errorf("Error deleting recovery services protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of recovery services protection container mapping %s (vault %s): %+v", name, vaultName, err) + } + + return nil +} diff --git a/azurerm/resource_arm_recovery_services_protection_container_mapping_test.go b/azurerm/resource_arm_recovery_services_protection_container_mapping_test.go new file mode 100644 index 000000000000..0a9c0807c2b9 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_protection_container_mapping_test.go @@ -0,0 +1,149 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMRecoveryProtectionContainerMapping_basic(t *testing.T) { + resourceGroupName := "azurerm_resource_group.test1" + vaultName := "azurerm_recovery_services_vault.test" + fabricName := "azurerm_recovery_services_fabric.test1" + protectionContainerName := "azurerm_recovery_services_protection_container.test1" + resourceName := "azurerm_recovery_services_protection_container_mapping.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMResourceGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRecoveryProtectionContainerMapping_basic(ri, testLocation(), testAltLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRecoveryProtectionContainerMappingExists(resourceGroupName, vaultName, fabricName, protectionContainerName, resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMRecoveryProtectionContainerMapping_basic(rInt int, location string, altLocation string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test1" { + name = "acctestRG1-%d" + location = "%s" +} + +resource "azurerm_recovery_services_vault" "test" { + name = "acctest-vault-%d" + location = "${azurerm_resource_group.test1.location}" + resource_group_name = "${azurerm_resource_group.test1.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "test1" { + resource_group_name = "${azurerm_resource_group.test1.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-fabric1-%d" + location = "${azurerm_resource_group.test1.location}" +} + +resource "azurerm_recovery_services_fabric" "test2" { + resource_group_name = "${azurerm_resource_group.test1.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-fabric2-%d" + location = "%s" + depends_on = ["azurerm_recovery_services_fabric.test1"] +} + +resource "azurerm_recovery_services_protection_container" "test1" { + resource_group_name = "${azurerm_resource_group.test1.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.test1.name}" + name = "acctest-protection-cont1-%d" +} + +resource "azurerm_recovery_services_protection_container" "test2" { + resource_group_name = "${azurerm_resource_group.test1.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.test2.name}" + name = "acctest-protection-cont2-%d" +} + +resource "azurerm_recovery_services_replication_policy" "test" { + resource_group_name = "${azurerm_resource_group.test1.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-policy-%d" + recovery_point_retention_in_minutes = "${24 * 60}" + application_consistent_snapshot_frequency_in_minutes = "${4 * 60}" +} + +resource "azurerm_recovery_services_protection_container_mapping" "test" { + resource_group_name = "${azurerm_resource_group.test1.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.test1.name}" + recovery_source_protection_container_name = "${azurerm_recovery_services_protection_container.test1.name}" + recovery_target_protection_container_id = "${azurerm_recovery_services_protection_container.test2.id}" + recovery_replication_policy_id = "${azurerm_recovery_services_replication_policy.test.id}" + name = "mapping-%d" +} +`, rInt, location, rInt, rInt, rInt, altLocation, rInt, rInt, rInt, rInt) +} + +func testCheckAzureRMRecoveryProtectionContainerMappingExists(resourceGroupStateName, vaultStateName string, resourceStateName string, protectionContainerStateName string, protectionContainerStateMappingName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + resourceGroupState, ok := s.RootModule().Resources[resourceGroupStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceGroupStateName) + } + vaultState, ok := s.RootModule().Resources[vaultStateName] + if !ok { + return fmt.Errorf("Not found: %s", vaultStateName) + } + fabricState, ok := s.RootModule().Resources[resourceStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceStateName) + } + protectionContainerState, ok := s.RootModule().Resources[protectionContainerStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceStateName) + } + protectionContainerMappingState, ok := s.RootModule().Resources[protectionContainerStateMappingName] + if !ok { + return fmt.Errorf("Not found: %s", protectionContainerStateMappingName) + } + + resourceGroupName := resourceGroupState.Primary.Attributes["name"] + vaultName := vaultState.Primary.Attributes["name"] + fabricName := fabricState.Primary.Attributes["name"] + protectionContainerName := protectionContainerState.Primary.Attributes["name"] + mappingName := protectionContainerMappingState.Primary.Attributes["name"] + + // Ensure mapping exists in API + client := testAccProvider.Meta().(*ArmClient).recoveryServices.ContainerMappingClient(resourceGroupName, vaultName) + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName, protectionContainerName, mappingName) + if err != nil { + return fmt.Errorf("Bad: Get on fabricClient: %+v", err) + } + + if resp.Response.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: fabric: %q does not exist", fabricName) + } + + return nil + } +} diff --git a/azurerm/resource_arm_recovery_services_protection_container_test.go b/azurerm/resource_arm_recovery_services_protection_container_test.go new file mode 100644 index 000000000000..eb472cda58c2 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_protection_container_test.go @@ -0,0 +1,111 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMRecoveryProtectionContainer_basic(t *testing.T) { + resourceGroupName := "azurerm_resource_group.test" + vaultName := "azurerm_recovery_services_vault.test" + fabricName := "azurerm_recovery_services_fabric.test" + resourceName := "azurerm_recovery_services_protection_container.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMResourceGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRecoveryProtectionContainer_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRecoveryProtectionContainerExists(resourceGroupName, vaultName, fabricName, resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMRecoveryProtectionContainer_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_recovery_services_vault" "test" { + name = "acctest-vault-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-fabric-%d" + location = "${azurerm_resource_group.test.location}" +} + +resource "azurerm_recovery_services_protection_container" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.test.name}" + name = "acctest-protection-cont-%d" +} + +`, rInt, location, rInt, rInt, rInt) +} + +func testCheckAzureRMRecoveryProtectionContainerExists(resourceGroupStateName, vaultStateName string, resourceStateName string, protectionContainerStateName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + resourceGroupState, ok := s.RootModule().Resources[resourceGroupStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceGroupStateName) + } + vaultState, ok := s.RootModule().Resources[vaultStateName] + if !ok { + return fmt.Errorf("Not found: %s", vaultStateName) + } + fabricState, ok := s.RootModule().Resources[resourceStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceStateName) + } + protectionContainerState, ok := s.RootModule().Resources[protectionContainerStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceStateName) + } + + resourceGroupName := resourceGroupState.Primary.Attributes["name"] + vaultName := vaultState.Primary.Attributes["name"] + fabricName := fabricState.Primary.Attributes["name"] + protectionContainerName := protectionContainerState.Primary.Attributes["name"] + + // Ensure fabric exists in API + client := testAccProvider.Meta().(*ArmClient).recoveryServices.ProtectionContainerClient(resourceGroupName, vaultName) + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName, protectionContainerName) + if err != nil { + return fmt.Errorf("Bad: Get on fabricClient: %+v", err) + } + + if resp.Response.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: fabric: %q does not exist", fabricName) + } + + return nil + } +} diff --git a/azurerm/resource_arm_recovery_services_protection_policy_vm.go b/azurerm/resource_arm_recovery_services_protection_policy_vm.go index 8bbfb44b7c5d..f9e51db1f910 100644 --- a/azurerm/resource_arm_recovery_services_protection_policy_vm.go +++ b/azurerm/resource_arm_recovery_services_protection_policy_vm.go @@ -8,7 +8,10 @@ import ( "strings" "time" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2017-07-01/backup" @@ -45,16 +48,13 @@ func resourceArmRecoveryServicesProtectionPolicyVm() *schema.Resource { ), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "recovery_vault_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringMatch( - regexp.MustCompile("^[a-zA-Z][-a-zA-Z0-9]{1,49}$"), - "Recovery Service Vault name must be 2 - 50 characters long, start with a letter, contain only letters, numbers and hyphens.", - ), + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, }, "timezone": { @@ -241,7 +241,7 @@ func resourceArmRecoveryServicesProtectionPolicyVm() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, //if daily, we need daily retention @@ -278,13 +278,13 @@ func resourceArmRecoveryServicesProtectionPolicyVm() *schema.Resource { } func resourceArmRecoveryServicesProtectionPolicyVmCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesProtectionPoliciesClient + client := meta.(*ArmClient).recoveryServices.ProtectionPoliciesClient ctx := meta.(*ArmClient).StopContext policyName := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) vaultName := d.Get("recovery_vault_name").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) log.Printf("[DEBUG] Creating/updating Recovery Service Protection Policy %s (resource group %q)", policyName, resourceGroup) @@ -296,7 +296,7 @@ func resourceArmRecoveryServicesProtectionPolicyVmCreateUpdate(d *schema.Resourc } times := append(make([]date.Time, 0), date.Time{Time: dateOfDay}) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err2 := client.Get(ctx, vaultName, resourceGroup, policyName) if err2 != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -310,7 +310,7 @@ func resourceArmRecoveryServicesProtectionPolicyVmCreateUpdate(d *schema.Resourc } policy := backup.ProtectionPolicyResource{ - Tags: expandTags(tags), + Tags: tags.Expand(t), Properties: &backup.AzureIaaSVMProtectionPolicy{ TimeZone: utils.String(d.Get("timezone").(string)), BackupManagementType: backup.BackupManagementTypeAzureIaasVM, @@ -340,10 +340,10 @@ func resourceArmRecoveryServicesProtectionPolicyVmCreateUpdate(d *schema.Resourc } func resourceArmRecoveryServicesProtectionPolicyVmRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesProtectionPoliciesClient + client := meta.(*ArmClient).recoveryServices.ProtectionPoliciesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -414,16 +414,14 @@ func resourceArmRecoveryServicesProtectionPolicyVmRead(d *schema.ResourceData, m } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmRecoveryServicesProtectionPolicyVmDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesProtectionPoliciesClient + client := meta.(*ArmClient).recoveryServices.ProtectionPoliciesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -701,7 +699,7 @@ func flattenArmRecoveryServicesProtectionPolicyRetentionWeeklyFormat(retention * return weekdays, weeks } -func resourceArmRecoveryServicesProtectionPolicyWaitForState(client backup.ProtectionPoliciesClient, ctx context.Context, found bool, vaultName, resourceGroup, policyName string) (backup.ProtectionPolicyResource, error) { +func resourceArmRecoveryServicesProtectionPolicyWaitForState(client *backup.ProtectionPoliciesClient, ctx context.Context, found bool, vaultName, resourceGroup, policyName string) (backup.ProtectionPolicyResource, error) { state := &resource.StateChangeConf{ Timeout: 30 * time.Minute, MinTimeout: 30 * time.Second, diff --git a/azurerm/resource_arm_recovery_services_protection_policy_vm_test.go b/azurerm/resource_arm_recovery_services_protection_policy_vm_test.go index 27a94589c9cf..b05384019794 100644 --- a/azurerm/resource_arm_recovery_services_protection_policy_vm_test.go +++ b/azurerm/resource_arm_recovery_services_protection_policy_vm_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -34,7 +35,7 @@ func TestAccAzureRMRecoveryServicesProtectionPolicyVm_basicDaily(t *testing.T) { } func TestAccAzureRMRecoveryServicesProtectionPolicyVm_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -254,7 +255,7 @@ func TestAccAzureRMRecoveryServicesProtectionPolicyVm_updateWeeklyToPartial(t *t } func testCheckAzureRMRecoveryServicesProtectionPolicyVmDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).recoveryServicesProtectionPoliciesClient + client := testAccProvider.Meta().(*ArmClient).recoveryServices.ProtectionPoliciesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -283,7 +284,7 @@ func testCheckAzureRMRecoveryServicesProtectionPolicyVmDestroy(s *terraform.Stat func testCheckAzureRMRecoveryServicesProtectionPolicyVmExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).recoveryServicesProtectionPoliciesClient + client := testAccProvider.Meta().(*ArmClient).recoveryServices.ProtectionPoliciesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext // Ensure we have enough information in state to look up in API @@ -325,7 +326,7 @@ resource "azurerm_recovery_services_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku = "Standard" } -`, rInt, location, strconv.Itoa(rInt)[0:5]) +`, rInt, location, strconv.Itoa(rInt)[12:17]) } func testAccAzureRMRecoveryServicesProtectionPolicyVm_basicDaily(rInt int, location string) string { diff --git a/azurerm/resource_arm_recovery_services_replicated_vm.go b/azurerm/resource_arm_recovery_services_replicated_vm.go new file mode 100644 index 000000000000..8ec3282d096a --- /dev/null +++ b/azurerm/resource_arm_recovery_services_replicated_vm.go @@ -0,0 +1,341 @@ +package azurerm + +import ( + "bytes" + "fmt" + "strings" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2018-01-10/siterecovery" + "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmRecoveryServicesReplicatedVm() *schema.Resource { + return &schema.Resource{ + Create: resourceArmRecoveryReplicatedItemCreate, + Read: resourceArmRecoveryReplicatedItemRead, + Delete: resourceArmRecoveryReplicatedItemDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "resource_group_name": azure.SchemaResourceGroupName(), + + "recovery_vault_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, + }, + "source_recovery_fabric_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "source_vm_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "target_recovery_fabric_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "recovery_replication_policy_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "source_recovery_protection_container_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "target_recovery_protection_container_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "target_resource_group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "target_availability_set_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "managed_disk": { + Type: schema.TypeSet, + ConfigMode: schema.SchemaConfigModeAttr, + Optional: true, + ForceNew: true, + Set: resourceArmRecoveryReplicatedVmDiskHash, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disk_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + DiffSuppressFunc: suppress.CaseDifference, + }, + "staging_storage_account_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "target_resource_group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + DiffSuppressFunc: suppress.CaseDifference, + }, + "target_disk_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(compute.StandardLRS), + string(compute.PremiumLRS), + string(compute.StandardSSDLRS), + string(compute.UltraSSDLRS), + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + "target_replica_disk_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(compute.StandardLRS), + string(compute.PremiumLRS), + string(compute.StandardSSDLRS), + string(compute.UltraSSDLRS), + }, true), + DiffSuppressFunc: suppress.CaseDifference, + }, + }, + }, + }, + }, + } +} + +func resourceArmRecoveryReplicatedItemCreate(d *schema.ResourceData, meta interface{}) error { + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + vaultName := d.Get("recovery_vault_name").(string) + fabricName := d.Get("source_recovery_fabric_name").(string) + sourceVmId := d.Get("source_vm_id").(string) + policyId := d.Get("recovery_replication_policy_id").(string) + sourceProtectionContainerName := d.Get("source_recovery_protection_container_name").(string) + targetProtectionContainerId := d.Get("target_recovery_protection_container_id").(string) + targetResourceGroupId := d.Get("target_resource_group_id").(string) + + var targetAvailabilitySetID *string + if id, isSet := d.GetOk("target_availability_set_id"); isSet { + tmp := id.(string) + targetAvailabilitySetID = &tmp + } else { + targetAvailabilitySetID = nil + } + + client := meta.(*ArmClient).recoveryServices.ReplicationMigrationItemsClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, fabricName, sourceProtectionContainerName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing recovery services replicated vm %s (vault %s): %+v", name, vaultName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_recovery_replicated_vm", azure.HandleAzureSdkForGoBug2824(*existing.ID)) + } + } + + managedDisks := []siterecovery.A2AVMManagedDiskInputDetails{} + + for _, raw := range d.Get("managed_disk").(*schema.Set).List() { + diskInput := raw.(map[string]interface{}) + diskId := diskInput["disk_id"].(string) + primaryStagingAzureStorageAccountID := diskInput["staging_storage_account_id"].(string) + recoveryResourceGroupId := diskInput["target_resource_group_id"].(string) + targetReplicaDiskType := diskInput["target_replica_disk_type"].(string) + targetDiskType := diskInput["target_disk_type"].(string) + + managedDisks = append(managedDisks, siterecovery.A2AVMManagedDiskInputDetails{ + DiskID: &diskId, + PrimaryStagingAzureStorageAccountID: &primaryStagingAzureStorageAccountID, + RecoveryResourceGroupID: &recoveryResourceGroupId, + RecoveryReplicaDiskAccountType: &targetReplicaDiskType, + RecoveryTargetDiskAccountType: &targetDiskType, + }) + } + + var parameters = siterecovery.EnableProtectionInput{ + Properties: &siterecovery.EnableProtectionInputProperties{ + PolicyID: &policyId, + ProviderSpecificDetails: siterecovery.A2AEnableProtectionInput{ + FabricObjectID: &sourceVmId, + RecoveryContainerID: &targetProtectionContainerId, + RecoveryResourceGroupID: &targetResourceGroupId, + RecoveryAvailabilitySetID: targetAvailabilitySetID, + VMManagedDisks: &managedDisks, + }, + }, + } + future, err := client.Create(ctx, fabricName, sourceProtectionContainerName, name, parameters) + if err != nil { + return fmt.Errorf("Error creating replicated vm %s (vault %s): %+v", name, vaultName, err) + } + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error creating replicated vm %s (vault %s): %+v", name, vaultName, err) + } + + resp, err := client.Get(ctx, fabricName, sourceProtectionContainerName, name) + if err != nil { + return fmt.Errorf("Error retrieving replicated vm %s (vault %s): %+v", name, vaultName, err) + } + + d.SetId(azure.HandleAzureSdkForGoBug2824(*resp.ID)) + + return resourceArmRecoveryReplicatedItemRead(d, meta) +} + +func resourceArmRecoveryReplicatedItemRead(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + fabricName := id.Path["replicationFabrics"] + protectionContainerName := id.Path["replicationProtectionContainers"] + name := id.Path["replicationProtectedItems"] + + client := meta.(*ArmClient).recoveryServices.ReplicationMigrationItemsClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName, protectionContainerName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on recovery services replicated vm %s (vault %s): %+v", name, vaultName, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resGroup) + d.Set("recovery_vault_name", vaultName) + d.Set("source_recovery_fabric_name", fabricName) + d.Set("target_recovery_fabric_id", resp.Properties.RecoveryFabricID) + d.Set("recovery_replication_policy_id", resp.Properties.PolicyID) + d.Set("source_recovery_protection_container_name", protectionContainerName) + d.Set("target_recovery_protection_container_id", resp.Properties.RecoveryContainerID) + + if a2aDetails, isA2a := resp.Properties.ProviderSpecificDetails.AsA2AReplicationDetails(); isA2a { + d.Set("source_vm_id", a2aDetails.FabricObjectID) + d.Set("target_resource_group_id", a2aDetails.RecoveryAzureResourceGroupID) + d.Set("target_availability_set_id", a2aDetails.RecoveryAvailabilitySet) + if a2aDetails.ProtectedManagedDisks != nil { + disksOutput := make([]interface{}, 0) + for _, disk := range *a2aDetails.ProtectedManagedDisks { + diskOutput := make(map[string]interface{}) + diskOutput["disk_id"] = *disk.DiskID + diskOutput["staging_storage_account_id"] = *disk.PrimaryStagingAzureStorageAccountID + diskOutput["target_resource_group_id"] = *disk.RecoveryResourceGroupID + diskOutput["target_replica_disk_type"] = *disk.RecoveryReplicaDiskAccountType + diskOutput["target_disk_type"] = *disk.RecoveryTargetDiskAccountType + + disksOutput = append(disksOutput, diskOutput) + } + d.Set("managed_disk", schema.NewSet(resourceArmRecoveryReplicatedVmDiskHash, disksOutput)) + } + } + + return nil +} + +func resourceArmRecoveryReplicatedItemDelete(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + fabricName := id.Path["replicationFabrics"] + protectionContainerName := id.Path["replicationProtectionContainers"] + name := id.Path["replicationProtectedItems"] + + disableProtectionInput := siterecovery.DisableProtectionInput{ + Properties: &siterecovery.DisableProtectionInputProperties{ + DisableProtectionReason: siterecovery.NotSpecified, + ReplicationProviderInput: siterecovery.DisableProtectionProviderSpecificInput{}, + }, + } + + client := meta.(*ArmClient).recoveryServices.ReplicationMigrationItemsClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + future, err := client.Delete(ctx, fabricName, protectionContainerName, name, disableProtectionInput) + if err != nil { + return fmt.Errorf("Error deleting recovery services replicated vm %s (vault %s): %+v", name, vaultName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of recovery services replicated vm %s (vault %s): %+v", name, vaultName, err) + } + return nil +} + +func resourceArmRecoveryReplicatedVmDiskHash(v interface{}) int { + var buf bytes.Buffer + + if m, ok := v.(map[string]interface{}); ok { + if v, ok := m["disk_id"]; ok { + buf.WriteString(strings.ToLower(v.(string))) + } + } + + return hashcode.String(buf.String()) +} diff --git a/azurerm/resource_arm_recovery_services_replicated_vm_test.go b/azurerm/resource_arm_recovery_services_replicated_vm_test.go new file mode 100644 index 000000000000..2224e5fb2c32 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_replicated_vm_test.go @@ -0,0 +1,263 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMRecoveryReplicatedVm_basic(t *testing.T) { + resourceGroupName := "azurerm_resource_group.test2" + vaultName := "azurerm_recovery_services_vault.test" + fabricName := "azurerm_recovery_services_fabric.test1" + protectionContainerName := "azurerm_recovery_services_protection_container.test1" + replicationName := "azurerm_recovery_replicated_vm.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMResourceGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRecoveryReplicatedVm_basic(ri, testLocation(), testAltLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRecoveryReplicatedVmExists(resourceGroupName, vaultName, fabricName, protectionContainerName, replicationName), + ), + }, + { + ResourceName: replicationName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMRecoveryReplicatedVm_basic(rInt int, location string, altLocation string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG1-%d" + location = "%s" +} + +resource "azurerm_resource_group" "test2" { + name = "acctestRG2-%d" + location = "%s" +} + +resource "azurerm_recovery_services_vault" "test" { + name = "acctest-vault-%d" + location = "${azurerm_resource_group.test2.location}" + resource_group_name = "${azurerm_resource_group.test2.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "test1" { + resource_group_name = "${azurerm_resource_group.test2.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-fabric1-%d" + location = "${azurerm_resource_group.test.location}" +} + +resource "azurerm_recovery_services_fabric" "test2" { + resource_group_name = "${azurerm_resource_group.test2.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-fabric2-%d" + location = "${azurerm_resource_group.test2.location}" + depends_on = ["azurerm_recovery_services_fabric.test1"] +} + +resource "azurerm_recovery_services_protection_container" "test1" { + resource_group_name = "${azurerm_resource_group.test2.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.test1.name}" + name = "acctest-protection-cont1-%d" +} + +resource "azurerm_recovery_services_protection_container" "test2" { + resource_group_name = "${azurerm_resource_group.test2.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.test2.name}" + name = "acctest-protection-cont2-%d" +} + +resource "azurerm_recovery_services_replication_policy" "test" { + resource_group_name = "${azurerm_resource_group.test2.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-policy-%d" + recovery_point_retention_in_minutes = "${24 * 60}" + application_consistent_snapshot_frequency_in_minutes = "${4 * 60}" +} + +resource "azurerm_recovery_services_protection_container_mapping" "test" { + resource_group_name = "${azurerm_resource_group.test2.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.test1.name}" + recovery_source_protection_container_name = "${azurerm_recovery_services_protection_container.test1.name}" + recovery_target_protection_container_id = "${azurerm_recovery_services_protection_container.test2.id}" + recovery_replication_policy_id = "${azurerm_recovery_services_replication_policy.test.id}" + name = "mapping-%d" +} + +resource "azurerm_virtual_network" "test1" { + name = "net-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + address_space = [ "192.168.1.0/24" ] + location = "${azurerm_recovery_services_fabric.test1.location}" +} +resource "azurerm_subnet" "test1" { + name = "snet-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test1.name}" + address_prefix = "192.168.1.0/24" +} + + +resource "azurerm_virtual_network" "test2" { + name = "net-%d" + resource_group_name = "${azurerm_resource_group.test2.name}" + address_space = [ "192.168.2.0/24" ] + location = "${azurerm_recovery_services_fabric.test2.location}" +} + +resource "azurerm_recovery_network_mapping" "test" { + resource_group_name = "${azurerm_resource_group.test2.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "mapping-%d" + source_recovery_fabric_name = "${azurerm_recovery_services_fabric.test1.name}" + target_recovery_fabric_name = "${azurerm_recovery_services_fabric.test2.name}" + source_network_id = "${azurerm_virtual_network.test1.id}" + target_network_id = "${azurerm_virtual_network.test2.id}" +} + +resource "azurerm_network_interface" "test" { + name = "vm-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "vm-%d" + subnet_id = "${azurerm_subnet.test1.id}" + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "vm-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + vm_size = "Standard_B1s" + + storage_image_reference { + publisher = "OpenLogic" + offer = "CentOS" + sku = "7.5" + version = "latest" + } + + storage_os_disk { + name = "disk-%d" + os_type = "Linux" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Premium_LRS" + } + + os_profile { + admin_username = "testadmin" + admin_password = "Password1234!" + computer_name = "vm-%d" + } + + os_profile_linux_config { + disable_password_authentication = false + + } + network_interface_ids = ["${azurerm_network_interface.test.id}"] +} + +resource "azurerm_storage_account" "test" { + name = "acct%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_recovery_replicated_vm" "test" { + name = "repl-%d" + resource_group_name = "${azurerm_resource_group.test2.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + source_vm_id = "${azurerm_virtual_machine.test.id}" + source_recovery_fabric_name = "${azurerm_recovery_services_fabric.test1.name}" + recovery_replication_policy_id = "${azurerm_recovery_services_replication_policy.test.id}" + source_recovery_protection_container_name = "${azurerm_recovery_services_protection_container.test1.name}" + + target_resource_group_id = "${azurerm_resource_group.test2.id}" + target_recovery_fabric_id = "${azurerm_recovery_services_fabric.test2.id}" + target_recovery_protection_container_id = "${azurerm_recovery_services_protection_container.test2.id}" + + managed_disk { + disk_id = "${azurerm_virtual_machine.test.storage_os_disk.0.managed_disk_id}" + staging_storage_account_id = "${azurerm_storage_account.test.id}" + target_resource_group_id = "${azurerm_resource_group.test2.id}" + target_disk_type = "Premium_LRS" + target_replica_disk_type = "Premium_LRS" + } + depends_on = ["azurerm_recovery_services_protection_container_mapping.test", "azurerm_recovery_network_mapping.test"] +} +`, rInt, location, rInt, altLocation, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt) +} + +func testCheckAzureRMRecoveryReplicatedVmExists(resourceGroupStateName, vaultStateName string, resourceStateName string, protectionContainerStateName string, replicationStateName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + resourceGroupState, ok := s.RootModule().Resources[resourceGroupStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceGroupStateName) + } + vaultState, ok := s.RootModule().Resources[vaultStateName] + if !ok { + return fmt.Errorf("Not found: %s", vaultStateName) + } + fabricState, ok := s.RootModule().Resources[resourceStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceStateName) + } + protectionContainerState, ok := s.RootModule().Resources[protectionContainerStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceStateName) + } + replicationState, ok := s.RootModule().Resources[replicationStateName] + if !ok { + return fmt.Errorf("Not found: %s", replicationStateName) + } + + resourceGroupName := resourceGroupState.Primary.Attributes["name"] + vaultName := vaultState.Primary.Attributes["name"] + fabricName := fabricState.Primary.Attributes["name"] + protectionContainerName := protectionContainerState.Primary.Attributes["name"] + replicationName := replicationState.Primary.Attributes["name"] + + // Ensure mapping exists in API + client := testAccProvider.Meta().(*ArmClient).recoveryServices.ReplicationMigrationItemsClient(resourceGroupName, vaultName) + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, fabricName, protectionContainerName, replicationName) + if err != nil { + return fmt.Errorf("Bad: Get on replicationVmClient: %+v", err) + } + + if resp.Response.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: fabric: %q does not exist", fabricName) + } + + return nil + } +} diff --git a/azurerm/resource_arm_recovery_services_replication_policy.go b/azurerm/resource_arm_recovery_services_replication_policy.go new file mode 100644 index 000000000000..441a9347eb86 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_replication_policy.go @@ -0,0 +1,202 @@ +package azurerm + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + + "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2018-01-10/siterecovery" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmRecoveryServicesReplicationPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceArmRecoveryServicesReplicationPolicyCreate, + Read: resourceArmRecoveryServicesReplicationPolicyRead, + Update: resourceArmRecoveryServicesReplicationPolicyUpdate, + Delete: resourceArmSiteRecoveryReplicationPolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "resource_group_name": azure.SchemaResourceGroupName(), + + "recovery_vault_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, + }, + "recovery_point_retention_in_minutes": { + Type: schema.TypeInt, + Required: true, + ForceNew: false, + ValidateFunc: validation.IntBetween(1, 365*24*60), + }, + "application_consistent_snapshot_frequency_in_minutes": { + Type: schema.TypeInt, + Required: true, + ForceNew: false, + ValidateFunc: validation.IntBetween(1, 365*24*60), + }, + }, + } +} + +func resourceArmRecoveryServicesReplicationPolicyCreate(d *schema.ResourceData, meta interface{}) error { + resGroup := d.Get("resource_group_name").(string) + vaultName := d.Get("recovery_vault_name").(string) + name := d.Get("name").(string) + + client := meta.(*ArmClient).recoveryServices.ReplicationPoliciesClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing recovery services replication policy %s: %+v", name, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_recovery_services_replication_policy", azure.HandleAzureSdkForGoBug2824(*existing.ID)) + } + } + + recoveryPoint := int32(d.Get("recovery_point_retention_in_minutes").(int)) + appConsitency := int32(d.Get("application_consistent_snapshot_frequency_in_minutes").(int)) + var parameters = siterecovery.CreatePolicyInput{ + Properties: &siterecovery.CreatePolicyInputProperties{ + ProviderSpecificInput: &siterecovery.A2APolicyCreationInput{ + RecoveryPointHistory: &recoveryPoint, + AppConsistentFrequencyInMinutes: &appConsitency, + MultiVMSyncStatus: siterecovery.Enable, + InstanceType: siterecovery.InstanceTypeBasicPolicyProviderSpecificInputInstanceTypeA2A, + }, + }, + } + future, err := client.Create(ctx, name, parameters) + if err != nil { + return fmt.Errorf("Error creating recovery services replication policy %s (vault %s): %+v", name, vaultName, err) + } + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error creating recovery services replication policy %s (vault %s): %+v", name, vaultName, err) + } + + resp, err := client.Get(ctx, name) + if err != nil { + return fmt.Errorf("Error retrieving site recovery replication policy %s (vault %s): %+v", name, vaultName, err) + } + + d.SetId(azure.HandleAzureSdkForGoBug2824(*resp.ID)) + + return resourceArmRecoveryServicesReplicationPolicyRead(d, meta) +} + +func resourceArmRecoveryServicesReplicationPolicyUpdate(d *schema.ResourceData, meta interface{}) error { + resGroup := d.Get("resource_group_name").(string) + vaultName := d.Get("recovery_vault_name").(string) + name := d.Get("name").(string) + + client := meta.(*ArmClient).recoveryServices.ReplicationPoliciesClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + recoveryPoint := int32(d.Get("recovery_point_retention_in_minutes").(int)) + appConsitency := int32(d.Get("application_consistent_snapshot_frequency_in_minutes").(int)) + var parameters = siterecovery.UpdatePolicyInput{ + Properties: &siterecovery.UpdatePolicyInputProperties{ + ReplicationProviderSettings: &siterecovery.A2APolicyCreationInput{ + RecoveryPointHistory: &recoveryPoint, + AppConsistentFrequencyInMinutes: &appConsitency, + MultiVMSyncStatus: siterecovery.Enable, + InstanceType: siterecovery.InstanceTypeBasicPolicyProviderSpecificInputInstanceTypeA2A, + }, + }, + } + future, err := client.Update(ctx, name, parameters) + if err != nil { + return fmt.Errorf("Error updating recovery services replication policy %s (vault %s): %+v", name, vaultName, err) + } + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error updating recovery services replication policy %s (vault %s): %+v", name, vaultName, err) + } + + resp, err := client.Get(ctx, name) + if err != nil { + return fmt.Errorf("Error retrieving site recovery replication policy %s (vault %s): %+v", name, vaultName, err) + } + + d.SetId(azure.HandleAzureSdkForGoBug2824(*resp.ID)) + + return resourceArmRecoveryServicesReplicationPolicyRead(d, meta) +} + +func resourceArmRecoveryServicesReplicationPolicyRead(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + name := id.Path["replicationPolicies"] + + client := meta.(*ArmClient).recoveryServices.ReplicationPoliciesClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + resp, err := client.Get(ctx, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on recovery services replication policy %s (vault %s): %+v", name, vaultName, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + d.Set("recovery_vault_name", vaultName) + if a2APolicyDetails, isA2A := resp.Properties.ProviderSpecificDetails.AsA2APolicyDetails(); isA2A { + d.Set("recovery_point_retention_in_minutes", a2APolicyDetails.RecoveryPointHistory) + d.Set("application_consistent_snapshot_frequency_in_minutes", a2APolicyDetails.AppConsistentFrequencyInMinutes) + } + return nil +} + +func resourceArmSiteRecoveryReplicationPolicyDelete(d *schema.ResourceData, meta interface{}) error { + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + vaultName := id.Path["vaults"] + name := id.Path["replicationPolicies"] + + client := meta.(*ArmClient).recoveryServices.ReplicationPoliciesClient(resGroup, vaultName) + ctx := meta.(*ArmClient).StopContext + + future, err := client.Delete(ctx, name) + if err != nil { + return fmt.Errorf("Error deleting recovery services replication policy %s (vault %s): %+v", name, vaultName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for deletion of recovery services replication policy %s (vault %s): %+v", name, vaultName, err) + } + + return nil +} diff --git a/azurerm/resource_arm_recovery_services_replication_policy_test.go b/azurerm/resource_arm_recovery_services_replication_policy_test.go new file mode 100644 index 000000000000..cdd98e268d00 --- /dev/null +++ b/azurerm/resource_arm_recovery_services_replication_policy_test.go @@ -0,0 +1,99 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMRecoveryReplicationPolicy_basic(t *testing.T) { + resourceGroupName := "azurerm_resource_group.test" + vaultName := "azurerm_recovery_services_vault.test" + resourceName := "azurerm_recovery_services_replication_policy.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMResourceGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRecoveryReplicationPolicy_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRecoveryReplicationPolicyExists(resourceGroupName, vaultName, resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAzureRMRecoveryReplicationPolicy_basic(rInt int, location string) string { + + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_recovery_services_vault" "test" { + name = "acctest-vault-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_replication_policy" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.test.name}" + name = "acctest-policy-%d" + recovery_point_retention_in_minutes = "${24 * 60}" + application_consistent_snapshot_frequency_in_minutes = "${4 * 60}" +} +`, rInt, location, rInt, rInt) +} + +func testCheckAzureRMRecoveryReplicationPolicyExists(resourceGroupStateName, vaultStateName string, policyStateName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + resourceGroupState, ok := s.RootModule().Resources[resourceGroupStateName] + if !ok { + return fmt.Errorf("Not found: %s", resourceGroupStateName) + } + vaultState, ok := s.RootModule().Resources[vaultStateName] + if !ok { + return fmt.Errorf("Not found: %s", vaultStateName) + } + policyState, ok := s.RootModule().Resources[policyStateName] + if !ok { + return fmt.Errorf("Not found: %s", policyStateName) + } + + resourceGroupName := resourceGroupState.Primary.Attributes["name"] + vaultName := vaultState.Primary.Attributes["name"] + policyName := policyState.Primary.Attributes["name"] + + // Ensure fabric exists in API + client := testAccProvider.Meta().(*ArmClient).recoveryServices.ReplicationPoliciesClient(resourceGroupName, vaultName) + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, policyName) + if err != nil { + return fmt.Errorf("Bad: Get on fabricClient: %+v", err) + } + + if resp.Response.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: fabric: %q does not exist", policyName) + } + + return nil + } +} diff --git a/azurerm/resource_arm_recovery_services_vault.go b/azurerm/resource_arm_recovery_services_vault.go index daa97efa0b1b..3abaf8b23ed6 100644 --- a/azurerm/resource_arm_recovery_services_vault.go +++ b/azurerm/resource_arm_recovery_services_vault.go @@ -3,11 +3,13 @@ package azurerm import ( "fmt" "log" - "regexp" - - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2016-06-01/recoveryservices" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" @@ -27,25 +29,22 @@ func resourceArmRecoveryServicesVault() *schema.Resource { Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringMatch( - regexp.MustCompile("^[a-zA-Z][-a-zA-Z0-9]{1,49}$"), - "Recovery Service Vault name must be 2 - 50 characters long, start with a letter, contain only letters, numbers and hyphens.", - ), + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateRecoveryServicesVaultName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "tags": tagsSchema(), + "tags": tags.Schema(), "sku": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(recoveryservices.RS0), string(recoveryservices.Standard), @@ -56,17 +55,17 @@ func resourceArmRecoveryServicesVault() *schema.Resource { } func resourceArmRecoveryServicesVaultCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesVaultsClient + client := meta.(*ArmClient).recoveryServices.VaultsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) location := d.Get("location").(string) resourceGroup := d.Get("resource_group_name").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) log.Printf("[DEBUG] Creating/updating Recovery Service Vault %q (resource group %q)", name, resourceGroup) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -82,7 +81,7 @@ func resourceArmRecoveryServicesVaultCreateUpdate(d *schema.ResourceData, meta i //build vault struct vault := recoveryservices.Vault{ Location: utils.String(location), - Tags: expandTags(tags), + Tags: tags.Expand(t), Sku: &recoveryservices.Sku{ Name: recoveryservices.SkuName(d.Get("sku").(string)), }, @@ -101,10 +100,10 @@ func resourceArmRecoveryServicesVaultCreateUpdate(d *schema.ResourceData, meta i } func resourceArmRecoveryServicesVaultRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesVaultsClient + client := meta.(*ArmClient).recoveryServices.VaultsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -127,23 +126,21 @@ func resourceArmRecoveryServicesVaultRead(d *schema.ResourceData, meta interface d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { d.Set("sku", string(sku.Name)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmRecoveryServicesVaultDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).recoveryServicesVaultsClient + client := meta.(*ArmClient).recoveryServices.VaultsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_recovery_services_vault_test.go b/azurerm/resource_arm_recovery_services_vault_test.go index 6f2fad9e15f3..be756e58086c 100644 --- a/azurerm/resource_arm_recovery_services_vault_test.go +++ b/azurerm/resource_arm_recovery_services_vault_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -40,7 +41,7 @@ func TestAccAzureRMRecoveryServicesVault_basic(t *testing.T) { } func TestAccAzureRMRecoveryServicesVault_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -81,7 +82,7 @@ func testCheckAzureRMRecoveryServicesVaultDestroy(s *terraform.State) error { name := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).recoveryServicesVaultsClient + client := testAccProvider.Meta().(*ArmClient).recoveryServices.VaultsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -113,7 +114,7 @@ func testCheckAzureRMRecoveryServicesVaultExists(resourceName string) resource.T return fmt.Errorf("Bad: no resource group found in state for Recovery Services Vault: %q", name) } - client := testAccProvider.Meta().(*ArmClient).recoveryServicesVaultsClient + client := testAccProvider.Meta().(*ArmClient).recoveryServices.VaultsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_redis_cache.go b/azurerm/resource_arm_redis_cache.go index 0e348b834d84..8a99c8de7eb8 100644 --- a/azurerm/resource_arm_redis_cache.go +++ b/azurerm/resource_arm_redis_cache.go @@ -9,7 +9,11 @@ import ( "strings" "time" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" "github.com/hashicorp/terraform/helper/resource" @@ -42,12 +46,12 @@ func resourceArmRedisCache() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - StateFunc: azureRMNormalizeLocation, + StateFunc: azure.NormalizeLocation, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "zones": singleZonesSchema(), + "zones": azure.SchemaSingleZone(), "capacity": { Type: schema.TypeInt, @@ -58,7 +62,7 @@ func resourceArmRedisCache() *schema.Resource { Type: schema.TypeString, Required: true, ValidateFunc: validateRedisFamily, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "sku_name": { @@ -69,7 +73,18 @@ func resourceArmRedisCache() *schema.Resource { string(redis.Standard), string(redis.Premium), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, + }, + + "minimum_tls_version": { + Type: schema.TypeString, + Optional: true, + Default: redis.OneFullStopZero, + ValidateFunc: validation.StringInSlice([]string{ + string(redis.OneFullStopZero), + string(redis.OneFullStopOne), + string(redis.OneFullStopTwo), + }, false), }, "shard_count": { @@ -98,7 +113,8 @@ func resourceArmRedisCache() *schema.Resource { "redis_configuration": { Type: schema.TypeList, - Required: true, + Optional: true, + Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -136,24 +152,50 @@ func resourceArmRedisCache() *schema.Resource { Type: schema.TypeBool, Optional: true, }, + "rdb_backup_frequency": { Type: schema.TypeInt, Optional: true, ValidateFunc: validateRedisBackupFrequency, }, + "rdb_backup_max_snapshot_count": { Type: schema.TypeInt, Optional: true, }, + "rdb_storage_connection_string": { Type: schema.TypeString, Optional: true, Sensitive: true, }, + "notify_keyspace_events": { Type: schema.TypeString, Optional: true, }, + + "aof_backup_enabled": { + Type: schema.TypeBool, + Optional: true, + }, + + "aof_storage_connection_string_0": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + + "aof_storage_connection_string_1": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "enable_authentication": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, }, }, }, @@ -205,18 +247,18 @@ func resourceArmRedisCache() *schema.Resource { Sensitive: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmRedisCacheCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).redisClient + client := meta.(*ArmClient).redis.Client ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ARM Redis Cache creation.") name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resGroup := d.Get("resource_group_name").(string) enableNonSSLPort := d.Get("enable_non_ssl_port").(bool) @@ -225,10 +267,10 @@ func resourceArmRedisCacheCreate(d *schema.ResourceData, meta interface{}) error family := redis.SkuFamily(d.Get("family").(string)) sku := redis.SkuName(d.Get("sku_name").(string)) - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -246,6 +288,11 @@ func resourceArmRedisCacheCreate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error parsing Patch Schedule: %+v", err) } + redisConfiguration, err := expandRedisConfiguration(d) + if err != nil { + return fmt.Errorf("Error parsing Redis Configuration: %+v", err) + } + parameters := redis.CreateParameters{ Location: utils.String(location), CreateProperties: &redis.CreateProperties{ @@ -255,7 +302,8 @@ func resourceArmRedisCacheCreate(d *schema.ResourceData, meta interface{}) error Family: family, Name: sku, }, - RedisConfiguration: expandRedisConfiguration(d), + MinimumTLSVersion: redis.TLSVersion(d.Get("minimum_tls_version").(string)), + RedisConfiguration: redisConfiguration, }, Tags: expandedTags, } @@ -270,35 +318,35 @@ func resourceArmRedisCacheCreate(d *schema.ResourceData, meta interface{}) error } if v, ok := d.GetOk("subnet_id"); ok { - parsed, parseErr := parseAzureResourceID(v.(string)) + parsed, parseErr := azure.ParseAzureResourceID(v.(string)) if parseErr != nil { return fmt.Errorf("Error parsing Azure Resource ID %q", v.(string)) } subnetName := parsed.Path["subnets"] virtualNetworkName := parsed.Path["virtualNetworks"] - azureRMLockByName(subnetName, subnetResourceName) - defer azureRMUnlockByName(subnetName, subnetResourceName) - azureRMLockByName(virtualNetworkName, virtualNetworkResourceName) - defer azureRMUnlockByName(virtualNetworkName, virtualNetworkResourceName) + locks.ByName(subnetName, subnetResourceName) + defer locks.UnlockByName(subnetName, subnetResourceName) + locks.ByName(virtualNetworkName, virtualNetworkResourceName) + defer locks.UnlockByName(virtualNetworkName, virtualNetworkResourceName) parameters.SubnetID = utils.String(v.(string)) } if v, ok := d.GetOk("zones"); ok { - parameters.Zones = expandZones(v.([]interface{})) + parameters.Zones = azure.ExpandZones(v.([]interface{})) } future, err := client.Create(ctx, resGroup, name, parameters) if err != nil { - return fmt.Errorf("Error issuing create request for read Redis Cache %s (resource group %s) ID", name, resGroup) + return fmt.Errorf("Error issuing create request for Redis Cache %s (resource group %s): %v", name, resGroup, err) } if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting for Redis Cache %s (resource group %s)", name, resGroup) + return fmt.Errorf("Error waiting for the create of Redis Cache %s (resource group %s): %v", name, resGroup, err) } read, err := client.Get(ctx, resGroup, name) if err != nil { - return fmt.Errorf("Error retrieving Redis Cache %s (resource group %s) ID", name, resGroup) + return fmt.Errorf("Error reading Redis Cache %s (resource group %s): %v", name, resGroup, err) } if read.ID == nil { return fmt.Errorf("Cannot read Redis Cache %s (resource group %s) ID", name, resGroup) @@ -319,7 +367,7 @@ func resourceArmRedisCacheCreate(d *schema.ResourceData, meta interface{}) error d.SetId(*read.ID) if schedule := patchSchedule; schedule != nil { - patchClient := meta.(*ArmClient).redisPatchSchedulesClient + patchClient := meta.(*ArmClient).redis.PatchSchedulesClient _, err = patchClient.CreateOrUpdate(ctx, resGroup, name, *schedule) if err != nil { return fmt.Errorf("Error setting Redis Patch Schedule: %+v", err) @@ -330,7 +378,7 @@ func resourceArmRedisCacheCreate(d *schema.ResourceData, meta interface{}) error } func resourceArmRedisCacheUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).redisClient + client := meta.(*ArmClient).redis.Client ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ARM Redis Cache update.") @@ -343,12 +391,13 @@ func resourceArmRedisCacheUpdate(d *schema.ResourceData, meta interface{}) error family := redis.SkuFamily(d.Get("family").(string)) sku := redis.SkuName(d.Get("sku_name").(string)) - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) parameters := redis.UpdateParameters{ UpdateProperties: &redis.UpdateProperties{ - EnableNonSslPort: utils.Bool(enableNonSSLPort), + MinimumTLSVersion: redis.TLSVersion(d.Get("minimum_tls_version").(string)), + EnableNonSslPort: utils.Bool(enableNonSSLPort), Sku: &redis.Sku{ Capacity: utils.Int32(capacity), Family: family, @@ -366,7 +415,10 @@ func resourceArmRedisCacheUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("redis_configuration") { - redisConfiguration := expandRedisConfiguration(d) + redisConfiguration, err := expandRedisConfiguration(d) + if err != nil { + return fmt.Errorf("Error parsing Redis Configuration: %+v", err) + } parameters.RedisConfiguration = redisConfiguration } @@ -401,7 +453,7 @@ func resourceArmRedisCacheUpdate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error parsing Patch Schedule: %+v", err) } - patchClient := meta.(*ArmClient).redisPatchSchedulesClient + patchClient := meta.(*ArmClient).redis.PatchSchedulesClient if patchSchedule == nil || len(*patchSchedule.ScheduleEntries.ScheduleEntries) == 0 { _, err = patchClient.Delete(ctx, resGroup, name) if err != nil { @@ -418,10 +470,10 @@ func resourceArmRedisCacheUpdate(d *schema.ResourceData, meta interface{}) error } func resourceArmRedisCacheRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).redisClient + client := meta.(*ArmClient).redis.Client ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -445,7 +497,7 @@ func resourceArmRedisCacheRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error making ListKeys request on Azure Redis Cache %s: %s", name, err) } - patchSchedulesClient := meta.(*ArmClient).redisPatchSchedulesClient + patchSchedulesClient := meta.(*ArmClient).redis.PatchSchedulesClient schedule, err := patchSchedulesClient.Get(ctx, resGroup, name) if err == nil { @@ -458,7 +510,7 @@ func resourceArmRedisCacheRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if zones := resp.Zones; zones != nil { d.Set("zones", zones) @@ -473,6 +525,7 @@ func resourceArmRedisCacheRead(d *schema.ResourceData, meta interface{}) error { if props := resp.Properties; props != nil { d.Set("ssl_port", props.SslPort) d.Set("hostname", props.HostName) + d.Set("minimum_tls_version", string(props.MinimumTLSVersion)) d.Set("port", props.Port) d.Set("enable_non_ssl_port", props.EnableNonSslPort) if props.ShardCount != nil { @@ -493,23 +546,21 @@ func resourceArmRedisCacheRead(d *schema.ResourceData, meta interface{}) error { d.Set("primary_access_key", keysResp.PrimaryKey) d.Set("secondary_access_key", keysResp.SecondaryKey) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmRedisCacheDelete(d *schema.ResourceData, meta interface{}) error { - redisClient := meta.(*ArmClient).redisClient + client := meta.(*ArmClient).redis.Client ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } resGroup := id.ResourceGroup name := id.Path["Redis"] - read, err := redisClient.Get(ctx, resGroup, name) + read, err := client.Get(ctx, resGroup, name) if err != nil { return fmt.Errorf("Error retrieving Redis Cache %q (Resource Group %q): %+v", name, resGroup, err) } @@ -518,18 +569,18 @@ func resourceArmRedisCacheDelete(d *schema.ResourceData, meta interface{}) error } props := *read.Properties if subnetID := props.SubnetID; subnetID != nil { - parsed, parseErr := parseAzureResourceID(*subnetID) + parsed, parseErr := azure.ParseAzureResourceID(*subnetID) if parseErr != nil { return fmt.Errorf("Error parsing Azure Resource ID %q", *subnetID) } subnetName := parsed.Path["subnets"] virtualNetworkName := parsed.Path["virtualNetworks"] - azureRMLockByName(subnetName, subnetResourceName) - defer azureRMUnlockByName(subnetName, subnetResourceName) - azureRMLockByName(virtualNetworkName, virtualNetworkResourceName) - defer azureRMUnlockByName(virtualNetworkName, virtualNetworkResourceName) + locks.ByName(subnetName, subnetResourceName) + defer locks.UnlockByName(subnetName, subnetResourceName) + locks.ByName(virtualNetworkName, virtualNetworkResourceName) + defer locks.UnlockByName(virtualNetworkName, virtualNetworkResourceName) } - future, err := redisClient.Delete(ctx, resGroup, name) + future, err := client.Delete(ctx, resGroup, name) if err != nil { if response.WasNotFound(future.Response()) { return nil @@ -538,7 +589,7 @@ func resourceArmRedisCacheDelete(d *schema.ResourceData, meta interface{}) error return err } - if err = future.WaitForCompletionRef(ctx, redisClient.Client); err != nil { + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { if response.WasNotFound(future.Response()) { return nil } @@ -549,7 +600,7 @@ func resourceArmRedisCacheDelete(d *schema.ResourceData, meta interface{}) error return nil } -func redisStateRefreshFunc(ctx context.Context, client redis.Client, resourceGroupName string, sgName string) resource.StateRefreshFunc { +func redisStateRefreshFunc(ctx context.Context, client *redis.Client, resourceGroupName string, sgName string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, resourceGroupName, sgName) if err != nil { @@ -560,7 +611,7 @@ func redisStateRefreshFunc(ctx context.Context, client redis.Client, resourceGro } } -func expandRedisConfiguration(d *schema.ResourceData) map[string]*string { +func expandRedisConfiguration(d *schema.ResourceData) (map[string]*string, error) { output := make(map[string]*string) if v, ok := d.GetOk("redis_configuration.0.maxclients"); ok { @@ -587,7 +638,7 @@ func expandRedisConfiguration(d *schema.ResourceData) map[string]*string { output["maxfragmentationmemory-reserved"] = utils.String(delta) } - // Backup + // RDB Backup if v, ok := d.GetOk("redis_configuration.0.rdb_backup_enabled"); ok { delta := strconv.FormatBool(v.(bool)) output["rdb-backup-enabled"] = utils.String(delta) @@ -611,7 +662,35 @@ func expandRedisConfiguration(d *schema.ResourceData) map[string]*string { output["notify-keyspace-events"] = utils.String(v.(string)) } - return output + // AOF Backup + if v, ok := d.GetOk("redis_configuration.0.aof_backup_enabled"); ok { + delta := strconv.FormatBool(v.(bool)) + output["aof-backup-enabled"] = utils.String(delta) + } + + if v, ok := d.GetOk("redis_configuration.0.aof_storage_connection_string_0"); ok { + output["aof-storage-connection-string-0"] = utils.String(v.(string)) + } + + if v, ok := d.GetOk("redis_configuration.0.aof_storage_connection_string_1"); ok { + output["aof-storage-connection-string-1"] = utils.String(v.(string)) + } + + if v, ok := d.GetOkExists("redis_configuration.0.enable_authentication"); ok { + authEnabled := v.(bool) + _, isPrivate := d.GetOk("subnet_id") + + // Redis authentication can only be disabled if it is launched inside a VNET. + if !isPrivate { + if !authEnabled { + return nil, fmt.Errorf("Cannot set `enable_authentication` to `false` when `subnet_id` is not set") + } + } else { + value := isAuthNotRequiredAsString(authEnabled) + output["authnotrequired"] = utils.String(value) + } + } + return output, nil } func expandRedisPatchSchedule(d *schema.ResourceData) (*redis.PatchSchedule, error) { @@ -707,9 +786,46 @@ func flattenRedisConfiguration(input map[string]*string) ([]interface{}, error) outputs["notify_keyspace_events"] = *v } + if v := input["aof-backup-enabled"]; v != nil { + b, err := strconv.ParseBool(*v) + if err != nil { + return nil, fmt.Errorf("Error parsing `aof-backup-enabled` %q: %+v", *v, err) + } + outputs["aof_backup_enabled"] = b + } + if v := input["aof-storage-connection-string-0"]; v != nil { + outputs["aof_storage_connection_string_0"] = *v + } + if v := input["aof-storage-connection-string-1"]; v != nil { + outputs["aof_storage_connection_string_1"] = *v + } + + // `authnotrequired` is not set for instances launched outside a VNET + outputs["enable_authentication"] = true + if v := input["authnotrequired"]; v != nil { + outputs["enable_authentication"] = isAuthRequiredAsBool(*v) + } + return []interface{}{outputs}, nil } +func isAuthRequiredAsBool(not_required string) bool { + value := strings.ToLower(not_required) + output := map[string]bool{ + "yes": false, + "no": true, + } + return output[value] +} + +func isAuthNotRequiredAsString(auth_required bool) string { + output := map[bool]string{ + true: "no", + false: "yes", + } + return output[auth_required] +} + func flattenRedisPatchSchedules(schedule redis.PatchSchedule) []interface{} { outputs := make([]interface{}, 0) diff --git a/azurerm/resource_arm_redis_cache_test.go b/azurerm/resource_arm_redis_cache_test.go index 715e117234bb..bdf45ed23d56 100644 --- a/azurerm/resource_arm_redis_cache_test.go +++ b/azurerm/resource_arm_redis_cache_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMRedisCacheFamily_validation(t *testing.T) { @@ -117,6 +118,7 @@ func TestAccAzureRMRedisCache_basic(t *testing.T) { Config: testAccAzureRMRedisCache_basic(ri, testLocation()), Check: resource.ComposeTestCheckFunc( testCheckAzureRMRedisCacheExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "minimum_tls_version"), ), }, { @@ -129,7 +131,7 @@ func TestAccAzureRMRedisCache_basic(t *testing.T) { } func TestAccAzureRMRedisCache_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -372,6 +374,64 @@ func TestAccAzureRMRedisCache_BackupEnabledDisabled(t *testing.T) { }) } +func TestAccAzureRMRedisCache_AOFBackupEnabled(t *testing.T) { + resourceName := "azurerm_redis_cache.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + config := testAccAzureRMRedisCacheAOFBackupEnabled(ri, rs, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRedisCacheDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRedisCacheExists(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"redis_configuration.0.aof_storage_connection_string_0", "redis_configuration.0.aof_storage_connection_string_1"}, + }, + }, + }) +} + +func TestAccAzureRMRedisCache_AOFBackupEnabledDisabled(t *testing.T) { + resourceName := "azurerm_redis_cache.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + config := testAccAzureRMRedisCacheAOFBackupEnabled(ri, rs, location) + updatedConfig := testAccAzureRMRedisCacheAOFBackupDisabled(ri, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRedisCacheDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRedisCacheExists(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRedisCacheExists(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} func TestAccAzureRMRedisCache_PatchSchedule(t *testing.T) { resourceName := "azurerm_redis_cache.test" ri := tf.AccRandTimeInt() @@ -518,12 +578,12 @@ func testCheckAzureRMRedisCacheExists(resourceName string) resource.TestCheckFun return fmt.Errorf("Bad: no resource group found in state for Redis Instance: %s", redisName) } - conn := testAccProvider.Meta().(*ArmClient).redisClient + conn := testAccProvider.Meta().(*ArmClient).redis.Client ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, redisName) if err != nil { - return fmt.Errorf("Bad: Get on redisClient: %+v", err) + return fmt.Errorf("Bad: Get on redis.Client: %+v", err) } if resp.StatusCode == http.StatusNotFound { @@ -535,7 +595,7 @@ func testCheckAzureRMRedisCacheExists(resourceName string) resource.TestCheckFun } func testCheckAzureRMRedisCacheDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).redisClient + conn := testAccProvider.Meta().(*ArmClient).redis.Client ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -581,6 +641,27 @@ func TestAccAzureRMRedisCache_SubscribeAllEvents(t *testing.T) { }) } +func TestAccAzureRMRedisCache_WithoutAuth(t *testing.T) { + resourceName := "azurerm_redis_cache.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMRedisCacheWithoutAuth(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRedisCacheDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRedisCacheExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "redis_configuration.0.enable_authentication", "false"), + ), + }, + }, + }) +} + func testAccAzureRMRedisCache_basic(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -596,6 +677,7 @@ resource "azurerm_redis_cache" "test" { family = "C" sku_name = "Basic" enable_non_ssl_port = false + minimum_tls_version = "1.2" redis_configuration {} } @@ -805,6 +887,66 @@ resource "azurerm_redis_cache" "test" { `, rInt, location, rString, rInt) } +func testAccAzureRMRedisCacheAOFBackupDisabled(ri int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_redis_cache" "test" { + name = "acctestRedis-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + capacity = 3 + family = "P" + sku_name = "Premium" + enable_non_ssl_port = false + + redis_configuration { + aof_backup_enabled = false + } +} +`, ri, location, ri) +} + +func testAccAzureRMRedisCacheAOFBackupEnabled(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "GRS" + + tags = { + environment = "staging" + } +} + +resource "azurerm_redis_cache" "test" { + name = "acctestRedis-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + capacity = 1 + family = "P" + sku_name = "Premium" + enable_non_ssl_port = false + + redis_configuration { + aof_backup_enabled = true + aof_storage_connection_string_0 = "DefaultEndpointsProtocol=https;BlobEndpoint=${azurerm_storage_account.test.primary_blob_endpoint};AccountName=${azurerm_storage_account.test.name};AccountKey=${azurerm_storage_account.test.primary_access_key}" + aof_storage_connection_string_1 = "DefaultEndpointsProtocol=https;BlobEndpoint=${azurerm_storage_account.test.primary_blob_endpoint};AccountName=${azurerm_storage_account.test.name};AccountKey=${azurerm_storage_account.test.secondary_access_key}" + } +} +`, rInt, location, rString, rInt) +} + func testAccAzureRMRedisCachePatchSchedule(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -975,3 +1117,40 @@ resource "azurerm_redis_cache" "test" { } `, ri, location, ri, ri) } + +func testAccAzureRMRedisCacheWithoutAuth(ri int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestnw-%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "testsubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.1.0/24" +} + +resource "azurerm_redis_cache" "test" { + name = "acctestRedis-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + capacity = 1 + family = "P" + sku_name = "Premium" + enable_non_ssl_port = false + subnet_id = "${azurerm_subnet.test.id}" + redis_configuration { + enable_authentication = false + } +} +`, ri, location, ri, ri) +} diff --git a/azurerm/resource_arm_redis_firewall_rule.go b/azurerm/resource_arm_redis_firewall_rule.go index a1c061b43537..420a1760d58f 100644 --- a/azurerm/resource_arm_redis_firewall_rule.go +++ b/azurerm/resource_arm_redis_firewall_rule.go @@ -4,11 +4,14 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "regexp" "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +40,7 @@ func resourceArmRedisFirewallRule() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "start_ip": { Type: schema.TypeString, @@ -53,7 +56,7 @@ func resourceArmRedisFirewallRule() *schema.Resource { } func resourceArmRedisFirewallRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).redisFirewallClient + client := meta.(*ArmClient).redis.FirewallRulesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Redis Firewall Rule creation.") @@ -63,7 +66,7 @@ func resourceArmRedisFirewallRuleCreateUpdate(d *schema.ResourceData, meta inter startIP := d.Get("start_ip").(string) endIP := d.Get("end_ip").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, cacheName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -83,28 +86,31 @@ func resourceArmRedisFirewallRuleCreateUpdate(d *schema.ResourceData, meta inter }, } - if _, err := client.CreateOrUpdate(ctx, resourceGroup, cacheName, name, parameters); err != nil { - return err - } + return resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { - read, err := client.Get(ctx, resourceGroup, cacheName, name) - if err != nil { - return err - } - if read.ID == nil { - return fmt.Errorf("Cannot read Redis Firewall Rule %q (cache %q / resource group %q) ID", name, cacheName, resourceGroup) - } + if _, err := client.CreateOrUpdate(ctx, resourceGroup, cacheName, name, parameters); err != nil { + return resource.NonRetryableError(fmt.Errorf("Error creating the rule: %s", err)) + } + + read, err := client.Get(ctx, resourceGroup, cacheName, name) + if err != nil { + return resource.RetryableError(fmt.Errorf("Expected instance to be created but was in non existent state, retrying")) + } + if read.ID == nil { + return resource.NonRetryableError(fmt.Errorf("Cannot read Redis Firewall Rule %q (cache %q / resource group %q) ID", name, cacheName, resourceGroup)) + } - d.SetId(*read.ID) + d.SetId(*read.ID) - return resourceArmRedisFirewallRuleRead(d, meta) + return resource.NonRetryableError(resourceArmRedisFirewallRuleRead(d, meta)) + }) } func resourceArmRedisFirewallRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).redisFirewallClient + client := meta.(*ArmClient).redis.FirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -136,10 +142,10 @@ func resourceArmRedisFirewallRuleRead(d *schema.ResourceData, meta interface{}) } func resourceArmRedisFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).redisFirewallClient + client := meta.(*ArmClient).redis.FirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_redis_firewall_rule_test.go b/azurerm/resource_arm_redis_firewall_rule_test.go index 5bff79311539..a63c2161afff 100644 --- a/azurerm/resource_arm_redis_firewall_rule_test.go +++ b/azurerm/resource_arm_redis_firewall_rule_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -75,8 +76,39 @@ func TestAccAzureRMRedisFirewallRule_basic(t *testing.T) { }) } +func TestAccAzureRMRedisFirewallRule_multi(t *testing.T) { + ruleOne := "azurerm_redis_firewall_rule.test" + ruleTwo := "azurerm_redis_firewall_rule.double" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRedisFirewallRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRedisFirewallRule_multi(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRedisFirewallRuleExists(ruleOne), + testCheckAzureRMRedisFirewallRuleExists(ruleTwo), + ), + }, + { + ResourceName: ruleOne, + ImportState: true, + ImportStateVerify: true, + }, + { + ResourceName: ruleTwo, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMRedisFirewallRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -142,14 +174,14 @@ func testCheckAzureRMRedisFirewallRuleExists(resourceName string) resource.TestC cacheName := rs.Primary.Attributes["redis_cache_name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).redisFirewallClient + client := testAccProvider.Meta().(*ArmClient).redis.FirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, cacheName, name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { return fmt.Errorf("Bad: Firewall Rule %q (cache %q resource group: %q) does not exist", name, cacheName, resourceGroup) } - return fmt.Errorf("Bad: Get on redisFirewallClient: %+v", err) + return fmt.Errorf("Bad: Get on redis.FirewallRulesClient: %+v", err) } return nil @@ -157,7 +189,7 @@ func testCheckAzureRMRedisFirewallRuleExists(resourceName string) resource.TestC } func testCheckAzureRMRedisFirewallRuleDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).resourceGroupsClient + client := testAccProvider.Meta().(*ArmClient).resource.GroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -213,6 +245,20 @@ resource "azurerm_redis_firewall_rule" "test" { `, rInt, location, rInt, rInt) } +func testAccAzureRMRedisFirewallRule_multi(rInt int, location string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_redis_firewall_rule" "double" { + name = "fwruletwo%d" + redis_cache_name = "${azurerm_redis_cache.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + start_ip = "4.5.6.7" + end_ip = "8.9.0.1" +} +`, testAccAzureRMRedisFirewallRule_basic(rInt, location), rInt) +} + func testAccAzureRMRedisFirewallRule_requiresImport(rInt int, location string) string { return fmt.Sprintf(` %s diff --git a/azurerm/resource_arm_relay_namespace.go b/azurerm/resource_arm_relay_namespace.go index 8bf2a46f6bdb..e0b439f60df6 100644 --- a/azurerm/resource_arm_relay_namespace.go +++ b/azurerm/resource_arm_relay_namespace.go @@ -5,7 +5,11 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "time" @@ -35,20 +39,23 @@ func resourceArmRelayNamespace() *schema.Resource { ValidateFunc: validation.StringLenBetween(6, 50), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, + Type: schema.TypeList, + Optional: true, + Computed: true, + Deprecated: "This property has been deprecated in favour of the 'sku_name' property and will be removed in version 2.0 of the provider", + ConflictsWith: []string{"sku_name"}, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(relay.Standard), }, true), @@ -57,6 +64,16 @@ func resourceArmRelayNamespace() *schema.Resource { }, }, + "sku_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"sku"}, + ValidateFunc: validation.StringInSlice([]string{ + string(relay.Standard), + }, false), + }, + "metric_id": { Type: schema.TypeString, Computed: true, @@ -86,25 +103,48 @@ func resourceArmRelayNamespace() *schema.Resource { Sensitive: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmRelayNamespaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).relayNamespacesClient + client := meta.(*ArmClient).relay.NamespacesClient ctx := meta.(*ArmClient).StopContext + + // Remove in 2.0 + var sku relay.Sku + + if inputs := d.Get("sku").([]interface{}); len(inputs) != 0 { + input := inputs[0].(map[string]interface{}) + v := input["name"].(string) + + sku = relay.Sku{ + Name: utils.String(v), + Tier: relay.SkuTier(v), + } + } else { + // Keep in 2.0 + sku = relay.Sku{ + Name: utils.String(d.Get("sku_name").(string)), + Tier: relay.SkuTier(d.Get("sku_name").(string)), + } + } + + if *sku.Name == "" { + return fmt.Errorf("either 'sku_name' or 'sku' must be defined in the configuration file") + } + log.Printf("[INFO] preparing arguments for Relay Namespace creation.") name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resourceGroup := d.Get("resource_group_name").(string) - sku := expandRelayNamespaceSku(d) - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -119,7 +159,7 @@ func resourceArmRelayNamespaceCreateUpdate(d *schema.ResourceData, meta interfac parameters := relay.Namespace{ Location: utils.String(location), - Sku: sku, + Sku: &sku, NamespaceProperties: &relay.NamespaceProperties{}, Tags: expandedTags, } @@ -147,10 +187,10 @@ func resourceArmRelayNamespaceCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmRelayNamespaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).relayNamespacesClient + client := meta.(*ArmClient).relay.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -170,14 +210,20 @@ func resourceArmRelayNamespaceRead(d *schema.ResourceData, meta interface{}) err d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { - flattenedSku := flattenRelayNamespaceSku(sku) - if err = d.Set("sku", flattenedSku); err != nil { - return fmt.Errorf("Error setting `sku`: %+v", err) + // Remove in 2.0 + if err := d.Set("sku", flattenRelayNamespaceSku(sku)); err != nil { + return fmt.Errorf("Error setting 'sku': %+v", err) + } + + if err := d.Set("sku_name", *sku.Name); err != nil { + return fmt.Errorf("Error setting 'sku_name': %+v", err) } + } else { + return fmt.Errorf("Error making Read request on Relay Namespace %q (Resource Group %q): Unable to retrieve 'sku' value", name, resourceGroup) } if props := resp.NamespaceProperties; props != nil { @@ -194,16 +240,14 @@ func resourceArmRelayNamespaceRead(d *schema.ResourceData, meta interface{}) err d.Set("secondary_connection_string", keysResp.SecondaryConnectionString) d.Set("secondary_key", keysResp.SecondaryKey) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmRelayNamespaceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).relayNamespacesClient + client := meta.(*ArmClient).relay.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -235,7 +279,7 @@ func resourceArmRelayNamespaceDelete(d *schema.ResourceData, meta interface{}) e return nil } -func relayNamespaceDeleteRefreshFunc(ctx context.Context, client relay.NamespacesClient, resourceGroupName string, name string) resource.StateRefreshFunc { +func relayNamespaceDeleteRefreshFunc(ctx context.Context, client *relay.NamespacesClient, resourceGroupName string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { res, err := client.Get(ctx, resourceGroupName, name) if err != nil { @@ -250,18 +294,7 @@ func relayNamespaceDeleteRefreshFunc(ctx context.Context, client relay.Namespace } } -func expandRelayNamespaceSku(d *schema.ResourceData) *relay.Sku { - vs := d.Get("sku").([]interface{}) - v := vs[0].(map[string]interface{}) - - name := v["name"].(string) - - return &relay.Sku{ - Name: utils.String(name), - Tier: relay.SkuTier(name), - } -} - +// Remove in 2.0 func flattenRelayNamespaceSku(input *relay.Sku) []interface{} { if input == nil { return []interface{}{} diff --git a/azurerm/resource_arm_relay_namespace_test.go b/azurerm/resource_arm_relay_namespace_test.go index 196c1d04f2ab..d3d280e118e9 100644 --- a/azurerm/resource_arm_relay_namespace_test.go +++ b/azurerm/resource_arm_relay_namespace_test.go @@ -3,11 +3,13 @@ package azurerm import ( "fmt" "net/http" + "regexp" "testing" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMRelayNamespace_basic(t *testing.T) { @@ -28,6 +30,7 @@ func TestAccAzureRMRelayNamespace_basic(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "secondary_connection_string"), resource.TestCheckResourceAttrSet(resourceName, "primary_key"), resource.TestCheckResourceAttrSet(resourceName, "secondary_key"), + resource.TestCheckResourceAttr(resourceName, "sku_name", "Standard"), ), }, { @@ -38,8 +41,57 @@ func TestAccAzureRMRelayNamespace_basic(t *testing.T) { }, }) } + +// Remove in 2.0 +func TestAccAzureRMRelayNamespace_basicClassic(t *testing.T) { + resourceName := "azurerm_relay_namespace.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRelayNamespaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRelayNamespace_basicClassic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRelayNamespaceExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "metric_id"), + resource.TestCheckResourceAttrSet(resourceName, "primary_connection_string"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_connection_string"), + resource.TestCheckResourceAttrSet(resourceName, "primary_key"), + resource.TestCheckResourceAttrSet(resourceName, "secondary_key"), + resource.TestCheckResourceAttr(resourceName, "sku.0.name", "Standard"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +// Remove in 2.0 +func TestAccAzureRMRelayNamespace_basicNotDefined(t *testing.T) { + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRelayNamespaceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRelayNamespace_basicNotDefined(ri, testLocation()), + ExpectError: regexp.MustCompile("either 'sku_name' or 'sku' must be defined in the configuration file"), + }, + }, + }) +} + func TestAccAzureRMRelayNamespace_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -112,7 +164,7 @@ func testCheckAzureRMRelayNamespaceExists(resourceName string) resource.TestChec name := rs.Primary.Attributes["name"] // Ensure resource group exists in API - client := testAccProvider.Meta().(*ArmClient).relayNamespacesClient + client := testAccProvider.Meta().(*ArmClient).relay.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -129,7 +181,7 @@ func testCheckAzureRMRelayNamespaceExists(resourceName string) resource.TestChec } func testCheckAzureRMRelayNamespaceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).relayNamespacesClient + client := testAccProvider.Meta().(*ArmClient).relay.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -160,6 +212,24 @@ resource "azurerm_resource_group" "test" { location = "%s" } +resource "azurerm_relay_namespace" "test" { + name = "acctestrn-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku_name = "Standard" +} +`, rInt, location, rInt) +} + +// Remove in 2.0 +func testAccAzureRMRelayNamespace_basicClassic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + resource "azurerm_relay_namespace" "test" { name = "acctestrn-%d" location = "${azurerm_resource_group.test.location}" @@ -172,6 +242,21 @@ resource "azurerm_relay_namespace" "test" { `, rInt, location, rInt) } +func testAccAzureRMRelayNamespace_basicNotDefined(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_relay_namespace" "test" { + name = "acctestrn-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rInt) +} + func testAccAzureRMRelayNamespace_requiresImport(rInt int, location string) string { return fmt.Sprintf(` %s @@ -181,9 +266,7 @@ resource "azurerm_relay_namespace" "import" { location = "${azurerm_relay_namespace.test.location}" resource_group_name = "${azurerm_relay_namespace.test.resource_group_name}" - sku { - name = "Standard" - } + sku_name = "Standard" } `, testAccAzureRMRelayNamespace_basic(rInt, location)) } @@ -200,12 +283,10 @@ resource "azurerm_relay_namespace" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - sku { - name = "Standard" - } + sku_name = "Standard" tags = { - "Hello" = "World" + Hello = "World" } } `, rInt, location, rInt) diff --git a/azurerm/resource_arm_resource_group.go b/azurerm/resource_arm_resource_group.go index 5ccd3d59b0ff..d5e7af2b20d1 100644 --- a/azurerm/resource_arm_resource_group.go +++ b/azurerm/resource_arm_resource_group.go @@ -4,7 +4,10 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources" "github.com/hashicorp/terraform/helper/schema" @@ -24,24 +27,24 @@ func resourceArmResourceGroup() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "name": resourceGroupNameSchema(), + "name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmResourceGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).resourceGroupsClient + client := meta.(*ArmClient).resource.GroupsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -56,7 +59,7 @@ func resourceArmResourceGroupCreateUpdate(d *schema.ResourceData, meta interface parameters := resources.Group{ Location: utils.String(location), - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.CreateOrUpdate(ctx, name, parameters); err != nil { @@ -74,10 +77,10 @@ func resourceArmResourceGroupCreateUpdate(d *schema.ResourceData, meta interface } func resourceArmResourceGroupRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).resourceGroupsClient + client := meta.(*ArmClient).resource.GroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return fmt.Errorf("Error parsing Azure Resource ID %q: %+v", d.Id(), err) } @@ -97,18 +100,16 @@ func resourceArmResourceGroupRead(d *schema.ResourceData, meta interface{}) erro d.Set("name", resp.Name) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmResourceGroupExists(d *schema.ResourceData, meta interface{}) (bool, error) { - client := meta.(*ArmClient).resourceGroupsClient + client := meta.(*ArmClient).resource.GroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return false, fmt.Errorf("Error parsing Azure Resource ID %q: %+v", d.Id(), err) } @@ -128,10 +129,10 @@ func resourceArmResourceGroupExists(d *schema.ResourceData, meta interface{}) (b } func resourceArmResourceGroupDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).resourceGroupsClient + client := meta.(*ArmClient).resource.GroupsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return fmt.Errorf("Error parsing Azure Resource ID %q: %+v", d.Id(), err) } diff --git a/azurerm/resource_arm_resource_group_test.go b/azurerm/resource_arm_resource_group_test.go index bf636a7a2f55..c19ecc67bf2b 100644 --- a/azurerm/resource_arm_resource_group_test.go +++ b/azurerm/resource_arm_resource_group_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMResourceGroup_basic(t *testing.T) { @@ -35,7 +36,7 @@ func TestAccAzureRMResourceGroup_basic(t *testing.T) { } func TestAccAzureRMResourceGroup_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -137,7 +138,7 @@ func testCheckAzureRMResourceGroupExists(resourceName string) resource.TestCheck resourceGroup := rs.Primary.Attributes["name"] // Ensure resource group exists in API - client := testAccProvider.Meta().(*ArmClient).resourceGroupsClient + client := testAccProvider.Meta().(*ArmClient).resource.GroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup) @@ -164,7 +165,7 @@ func testCheckAzureRMResourceGroupDisappears(resourceName string) resource.TestC resourceGroup := rs.Primary.Attributes["name"] // Ensure resource group exists in API - client := testAccProvider.Meta().(*ArmClient).resourceGroupsClient + client := testAccProvider.Meta().(*ArmClient).resource.GroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext deleteFuture, err := client.Delete(ctx, resourceGroup) @@ -182,7 +183,7 @@ func testCheckAzureRMResourceGroupDisappears(resourceName string) resource.TestC } func testCheckAzureRMResourceGroupDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).resourceGroupsClient + client := testAccProvider.Meta().(*ArmClient).resource.GroupsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_role_assignment.go b/azurerm/resource_arm_role_assignment.go index 038202c8fdf4..788f0e9c2b93 100644 --- a/azurerm/resource_arm_role_assignment.go +++ b/azurerm/resource_arm_role_assignment.go @@ -7,10 +7,11 @@ import ( "time" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" - "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-01-01-preview/authorization" + "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-09-01-preview/authorization" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -50,12 +51,13 @@ func resourceArmRoleAssignment() *schema.Resource { }, "role_definition_name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ConflictsWith: []string{"role_definition_id"}, - ValidateFunc: validateRoleDefinitionName, + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"role_definition_id"}, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validateRoleDefinitionName, }, "principal_id": { @@ -68,8 +70,8 @@ func resourceArmRoleAssignment() *schema.Resource { } func resourceArmRoleAssignmentCreate(d *schema.ResourceData, meta interface{}) error { - roleAssignmentsClient := meta.(*ArmClient).roleAssignmentsClient - roleDefinitionsClient := meta.(*ArmClient).roleDefinitionsClient + roleAssignmentsClient := meta.(*ArmClient).authorization.RoleAssignmentsClient + roleDefinitionsClient := meta.(*ArmClient).authorization.RoleDefinitionsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -80,7 +82,7 @@ func resourceArmRoleAssignmentCreate(d *schema.ResourceData, meta interface{}) e roleDefinitionId = v.(string) } else if v, ok := d.GetOk("role_definition_name"); ok { roleName := v.(string) - roleDefinitions, err := roleDefinitionsClient.List(ctx, "", fmt.Sprintf("roleName eq '%s'", roleName)) + roleDefinitions, err := roleDefinitionsClient.List(ctx, scope, fmt.Sprintf("roleName eq '%s'", roleName)) if err != nil { return fmt.Errorf("Error loading Role Definition List: %+v", err) } @@ -104,11 +106,11 @@ func resourceArmRoleAssignmentCreate(d *schema.ResourceData, meta interface{}) e name = uuid } - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() { existing, err := roleAssignmentsClient.Get(ctx, scope, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of existing Role Assignment ID for %q (Scope %q)", name, scope) + return fmt.Errorf("Error checking for presence of existing Role Assignment ID for %q (Scope %q): %+v", name, scope, err) } } @@ -141,8 +143,8 @@ func resourceArmRoleAssignmentCreate(d *schema.ResourceData, meta interface{}) e } func resourceArmRoleAssignmentRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).roleAssignmentsClient - roleDefinitionsClient := meta.(*ArmClient).roleDefinitionsClient + client := meta.(*ArmClient).authorization.RoleAssignmentsClient + roleDefinitionsClient := meta.(*ArmClient).authorization.RoleDefinitionsClient ctx := meta.(*ArmClient).StopContext resp, err := client.GetByID(ctx, d.Id()) @@ -180,7 +182,7 @@ func resourceArmRoleAssignmentRead(d *schema.ResourceData, meta interface{}) err } func resourceArmRoleAssignmentDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).roleAssignmentsClient + client := meta.(*ArmClient).authorization.RoleAssignmentsClient ctx := meta.(*ArmClient).StopContext id, err := parseRoleAssignmentId(d.Id()) @@ -212,7 +214,7 @@ func validateRoleDefinitionName(i interface{}, k string) ([]string, []error) { func retryRoleAssignmentsClient(scope string, name string, properties authorization.RoleAssignmentCreateParameters, meta interface{}) func() *resource.RetryError { return func() *resource.RetryError { - roleAssignmentsClient := meta.(*ArmClient).roleAssignmentsClient + roleAssignmentsClient := meta.(*ArmClient).authorization.RoleAssignmentsClient ctx := meta.(*ArmClient).StopContext resp, err := roleAssignmentsClient.Create(ctx, scope, name, properties) diff --git a/azurerm/resource_arm_role_assignment_test.go b/azurerm/resource_arm_role_assignment_test.go index a2f1257a7dcc..4a477d507c77 100644 --- a/azurerm/resource_arm_role_assignment_test.go +++ b/azurerm/resource_arm_role_assignment_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -24,7 +25,11 @@ func TestAccAzureRMRoleAssignment(t *testing.T) { "requiresImport": testAccAzureRMRoleAssignment_requiresImport, }, "assignment": { - "sp": testAccAzureRMActiveDirectoryServicePrincipal_roleAssignment, + "sp": testAccAzureRMActiveDirectoryServicePrincipal_servicePrincipal, + "group": testAccAzureRMActiveDirectoryServicePrincipal_group, + }, + "management": { + "assign": testAccAzureRMRoleAssignment_managementGroup, }, } @@ -92,7 +97,7 @@ func testAccAzureRMRoleAssignment_roleName(t *testing.T) { } func testAccAzureRMRoleAssignment_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -196,6 +201,44 @@ func testAccAzureRMRoleAssignment_custom(t *testing.T) { }) } +func testAccAzureRMActiveDirectoryServicePrincipal_servicePrincipal(t *testing.T) { + ri := tf.AccRandTimeInt() + id := uuid.New().String() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRoleAssignmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRoleAssignment_servicePrincipal(ri, id), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRoleAssignmentExists("azurerm_role_assignment.test"), + ), + }, + }, + }) +} + +func testAccAzureRMActiveDirectoryServicePrincipal_group(t *testing.T) { + ri := tf.AccRandTimeInt() + id := uuid.New().String() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRoleAssignmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRoleAssignment_group(ri, id), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRoleAssignmentExists("azurerm_role_assignment.test"), + ), + }, + }, + }) +} + func testCheckAzureRMRoleAssignmentExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] @@ -206,7 +249,7 @@ func testCheckAzureRMRoleAssignmentExists(resourceName string) resource.TestChec scope := rs.Primary.Attributes["scope"] roleAssignmentName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).roleAssignmentsClient + client := testAccProvider.Meta().(*ArmClient).authorization.RoleAssignmentsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, scope, roleAssignmentName) @@ -230,7 +273,7 @@ func testCheckAzureRMRoleAssignmentDestroy(s *terraform.State) error { scope := rs.Primary.Attributes["scope"] roleAssignmentName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).roleAssignmentsClient + client := testAccProvider.Meta().(*ArmClient).authorization.RoleAssignmentsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, scope, roleAssignmentName) @@ -248,24 +291,18 @@ func testCheckAzureRMRoleAssignmentDestroy(s *terraform.State) error { return nil } -func testAccAzureRMActiveDirectoryServicePrincipal_roleAssignment(t *testing.T) { - resourceName := "azurerm_azuread_service_principal.test" +func testAccAzureRMRoleAssignment_managementGroup(t *testing.T) { + groupId := uuid.New().String() - ri := tf.AccRandTimeInt() - id := uuid.New().String() - - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMActiveDirectoryServicePrincipalDestroy, + CheckDestroy: testCheckAzureRMRoleAssignmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMActiveDirectoryServicePrincipal_roleAssignmentConfig(ri, id), + Config: testAccAzureRMRoleAssignment_managementGroupConfig(groupId), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMActiveDirectoryServicePrincipalExists(resourceName), testCheckAzureRMRoleAssignmentExists("azurerm_role_assignment.test"), - resource.TestCheckResourceAttrSet(resourceName, "display_name"), - resource.TestCheckResourceAttrSet(resourceName, "application_id"), ), }, }, @@ -383,23 +420,62 @@ resource "azurerm_role_assignment" "test" { `, roleDefinitionId, rInt, roleAssignmentId) } -func testAccAzureRMActiveDirectoryServicePrincipal_roleAssignmentConfig(rInt int, roleAssignmentID string) string { +func testAccAzureRMRoleAssignment_servicePrincipal(rInt int, roleAssignmentID string) string { return fmt.Sprintf(` data "azurerm_subscription" "current" {} -resource "azurerm_azuread_application" "test" { +resource "azuread_application" "test" { name = "acctestspa-%d" } -resource "azurerm_azuread_service_principal" "test" { - application_id = "${azurerm_azuread_application.test.application_id}" +resource "azuread_service_principal" "test" { + application_id = "${azuread_application.test.application_id}" +} + +resource "azurerm_role_assignment" "test" { + name = "%s" + scope = "${data.azurerm_subscription.current.id}" + role_definition_name = "Reader" + principal_id = "${azuread_service_principal.test.id}" +} +`, rInt, roleAssignmentID) +} + +func testAccAzureRMRoleAssignment_group(rInt int, roleAssignmentID string) string { + return fmt.Sprintf(` +data "azurerm_subscription" "current" {} + +resource "azuread_group" "test" { + name = "acctestspa-%d" } resource "azurerm_role_assignment" "test" { name = "%s" scope = "${data.azurerm_subscription.current.id}" role_definition_name = "Reader" - principal_id = "${azurerm_azuread_service_principal.test.id}" + principal_id = "${azuread_group.test.id}" } `, rInt, roleAssignmentID) } + +func testAccAzureRMRoleAssignment_managementGroupConfig(groupId string) string { + return fmt.Sprintf(` +data "azurerm_subscription" "primary" {} + +data "azurerm_client_config" "test" {} + +data "azurerm_role_definition" "test" { + name = "Monitoring Reader" +} + +resource "azurerm_management_group" "test" { + group_id = "%s" +} + +resource "azurerm_role_assignment" "test" { + scope = "${azurerm_management_group.test.id}" + role_definition_id = "${data.azurerm_role_definition.test.id}" + principal_id = "${data.azurerm_client_config.test.service_principal_object_id}" +} +`, groupId) +} diff --git a/azurerm/resource_arm_role_definition.go b/azurerm/resource_arm_role_definition.go index aec3f5c95b1b..6a6de5c886e6 100644 --- a/azurerm/resource_arm_role_definition.go +++ b/azurerm/resource_arm_role_definition.go @@ -6,8 +6,9 @@ import ( "strings" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" - "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-01-01-preview/authorization" + "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-09-01-preview/authorization" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" @@ -98,7 +99,7 @@ func resourceArmRoleDefinition() *schema.Resource { } func resourceArmRoleDefinitionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).roleDefinitionsClient + client := meta.(*ArmClient).authorization.RoleDefinitionsClient ctx := meta.(*ArmClient).StopContext roleDefinitionId := d.Get("role_definition_id").(string) @@ -118,7 +119,7 @@ func resourceArmRoleDefinitionCreateUpdate(d *schema.ResourceData, meta interfac permissions := expandRoleDefinitionPermissions(d) assignableScopes := expandRoleDefinitionAssignableScopes(d) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, scope, roleDefinitionId) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -158,7 +159,7 @@ func resourceArmRoleDefinitionCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmRoleDefinitionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).roleDefinitionsClient + client := meta.(*ArmClient).authorization.RoleDefinitionsClient ctx := meta.(*ArmClient).StopContext resp, err := client.GetByID(ctx, d.Id()) @@ -172,6 +173,16 @@ func resourceArmRoleDefinitionRead(d *schema.ResourceData, meta interface{}) err return fmt.Errorf("Error loading Role Definition %q: %+v", d.Id(), err) } + if id := resp.ID; id != nil { + roleDefinitionId, err := parseRoleDefinitionId(*id) + if err != nil { + return fmt.Errorf("Error parsing Role Definition ID: %+v", err) + } + if roleDefinitionId != nil { + d.Set("role_definition_id", roleDefinitionId.roleDefinitionId) + } + } + if props := resp.RoleDefinitionProperties; props != nil { d.Set("name", props.RoleName) d.Set("description", props.Description) @@ -191,7 +202,7 @@ func resourceArmRoleDefinitionRead(d *schema.ResourceData, meta interface{}) err } func resourceArmRoleDefinitionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).roleDefinitionsClient + client := meta.(*ArmClient).authorization.RoleDefinitionsClient ctx := meta.(*ArmClient).StopContext id, err := parseRoleDefinitionId(d.Id()) diff --git a/azurerm/resource_arm_role_definition_test.go b/azurerm/resource_arm_role_definition_test.go index 3a01f0f86204..d17b0de71ee0 100644 --- a/azurerm/resource_arm_role_definition_test.go +++ b/azurerm/resource_arm_role_definition_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMRoleDefinition_basic(t *testing.T) { } func TestAccAzureRMRoleDefinition_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -125,6 +126,40 @@ func TestAccAzureRMRoleDefinition_update(t *testing.T) { }) } +func TestAccAzureRMRoleDefinition_updateEmptyId(t *testing.T) { + resourceName := "azurerm_role_definition.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRoleDefinitionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMRoleDefinition_emptyId(ri), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRoleDefinitionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "permissions.#", "1"), + resource.TestCheckResourceAttr(resourceName, "permissions.0.actions.#", "1"), + resource.TestCheckResourceAttr(resourceName, "permissions.0.actions.0", "*"), + resource.TestCheckResourceAttr(resourceName, "permissions.0.not_actions.#", "0"), + ), + }, + { + Config: testAccAzureRMRoleDefinition_updateEmptyId(ri), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRoleDefinitionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "permissions.#", "1"), + resource.TestCheckResourceAttr(resourceName, "permissions.0.actions.#", "1"), + resource.TestCheckResourceAttr(resourceName, "permissions.0.actions.0", "*"), + resource.TestCheckResourceAttr(resourceName, "permissions.0.not_actions.#", "1"), + resource.TestCheckResourceAttr(resourceName, "permissions.0.not_actions.0", "Microsoft.Authorization/*/read"), + ), + }, + }, + }) +} + func TestAccAzureRMRoleDefinition_emptyName(t *testing.T) { resourceName := "azurerm_role_definition.test" ri := tf.AccRandTimeInt() @@ -156,7 +191,7 @@ func testCheckAzureRMRoleDefinitionExists(resourceName string) resource.TestChec scope := rs.Primary.Attributes["scope"] roleDefinitionId := rs.Primary.Attributes["role_definition_id"] - client := testAccProvider.Meta().(*ArmClient).roleDefinitionsClient + client := testAccProvider.Meta().(*ArmClient).authorization.RoleDefinitionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, scope, roleDefinitionId) @@ -180,7 +215,7 @@ func testCheckAzureRMRoleDefinitionDestroy(s *terraform.State) error { scope := rs.Primary.Attributes["scope"] roleDefinitionId := rs.Primary.Attributes["role_definition_id"] - client := testAccProvider.Meta().(*ArmClient).roleDefinitionsClient + client := testAccProvider.Meta().(*ArmClient).authorization.RoleDefinitionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, scope, roleDefinitionId) @@ -303,3 +338,23 @@ resource "azurerm_role_definition" "test" { } `, rInt) } + +func testAccAzureRMRoleDefinition_updateEmptyId(rInt int) string { + return fmt.Sprintf(` +data "azurerm_subscription" "primary" {} + +resource "azurerm_role_definition" "test" { + name = "acctestrd-%d" + scope = "${data.azurerm_subscription.primary.id}" + + permissions { + actions = ["*"] + not_actions = ["Microsoft.Authorization/*/read"] + } + + assignable_scopes = [ + "${data.azurerm_subscription.primary.id}", + ] +} +`, rInt) +} diff --git a/azurerm/resource_arm_route.go b/azurerm/resource_arm_route.go index 4b0ac7839e8a..34aaf452d1f7 100644 --- a/azurerm/resource_arm_route.go +++ b/azurerm/resource_arm_route.go @@ -3,9 +3,12 @@ package azurerm import ( "fmt" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" @@ -32,7 +35,7 @@ func resourceArmRoute() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "route_table_name": { Type: schema.TypeString, @@ -70,7 +73,7 @@ func resourceArmRoute() *schema.Resource { } func resourceArmRouteCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).routesClient + client := meta.(*ArmClient).network.RoutesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -80,7 +83,7 @@ func resourceArmRouteCreateUpdate(d *schema.ResourceData, meta interface{}) erro addressPrefix := d.Get("address_prefix").(string) nextHopType := d.Get("next_hop_type").(string) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, rtName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -93,8 +96,8 @@ func resourceArmRouteCreateUpdate(d *schema.ResourceData, meta interface{}) erro } } - azureRMLockByName(rtName, routeTableResourceName) - defer azureRMUnlockByName(rtName, routeTableResourceName) + locks.ByName(rtName, routeTableResourceName) + defer locks.UnlockByName(rtName, routeTableResourceName) route := network.Route{ Name: &name, @@ -130,10 +133,10 @@ func resourceArmRouteCreateUpdate(d *schema.ResourceData, meta interface{}) erro } func resourceArmRouteRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).routesClient + client := meta.(*ArmClient).network.RoutesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -164,10 +167,10 @@ func resourceArmRouteRead(d *schema.ResourceData, meta interface{}) error { } func resourceArmRouteDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).routesClient + client := meta.(*ArmClient).network.RoutesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -175,8 +178,8 @@ func resourceArmRouteDelete(d *schema.ResourceData, meta interface{}) error { rtName := id.Path["routeTables"] routeName := id.Path["routes"] - azureRMLockByName(rtName, routeTableResourceName) - defer azureRMUnlockByName(rtName, routeTableResourceName) + locks.ByName(rtName, routeTableResourceName) + defer locks.UnlockByName(rtName, routeTableResourceName) future, err := client.Delete(ctx, resGroup, rtName, routeName) if err != nil { diff --git a/azurerm/resource_arm_route_table.go b/azurerm/resource_arm_route_table.go index fb32bef96529..73ce0b32c8d4 100644 --- a/azurerm/resource_arm_route_table.go +++ b/azurerm/resource_arm_route_table.go @@ -4,9 +4,12 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" - "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" @@ -36,14 +39,15 @@ func resourceArmRouteTable() *schema.Resource { ValidateFunc: validate.NoEmptyStrings, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "route": { - Type: schema.TypeList, - Optional: true, - Computed: true, + Type: schema.TypeList, + ConfigMode: schema.SchemaConfigModeAttr, + Optional: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { @@ -93,23 +97,23 @@ func resourceArmRouteTable() *schema.Resource { Set: schema.HashString, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmRouteTableCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).routeTablesClient + client := meta.(*ArmClient).network.RouteTablesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Route Table creation.") name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resGroup := d.Get("resource_group_name").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -129,7 +133,7 @@ func resourceArmRouteTableCreateUpdate(d *schema.ResourceData, meta interface{}) Routes: expandRouteTableRoutes(d), DisableBgpRoutePropagation: utils.Bool(d.Get("disable_bgp_route_propagation").(bool)), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resGroup, name, routeSet) @@ -155,10 +159,10 @@ func resourceArmRouteTableCreateUpdate(d *schema.ResourceData, meta interface{}) } func resourceArmRouteTableRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).routeTablesClient + client := meta.(*ArmClient).network.RouteTablesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -177,7 +181,7 @@ func resourceArmRouteTableRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.RouteTablePropertiesFormat; props != nil { @@ -191,16 +195,14 @@ func resourceArmRouteTableRead(d *schema.ResourceData, meta interface{}) error { } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmRouteTableDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).routeTablesClient + client := meta.(*ArmClient).network.RouteTablesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_route_table_test.go b/azurerm/resource_arm_route_table_test.go index 600fb9b3e67e..9e5c2879d170 100644 --- a/azurerm/resource_arm_route_table_test.go +++ b/azurerm/resource_arm_route_table_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,7 +39,7 @@ func TestAccAzureRMRouteTable_basic(t *testing.T) { } func TestAccAzureRMRouteTable_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -159,7 +160,8 @@ func TestAccAzureRMRouteTable_removeRoute(t *testing.T) { resourceName := "azurerm_route_table.test" ri := tf.AccRandTimeInt() config := testAccAzureRMRouteTable_singleRoute(ri, testLocation()) - updatedConfig := testAccAzureRMRouteTable_singleRouteRemoved(ri, testLocation()) + noBlocksConfig := testAccAzureRMRouteTable_noRouteBlocks(ri, testLocation()) + blocksEmptyConfig := testAccAzureRMRouteTable_singleRouteRemoved(ri, testLocation()) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -167,6 +169,7 @@ func TestAccAzureRMRouteTable_removeRoute(t *testing.T) { CheckDestroy: testCheckAzureRMRouteTableDestroy, Steps: []resource.TestStep{ { + // This configuration includes a single explicit route block Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMRouteTableExists(resourceName), @@ -174,9 +177,23 @@ func TestAccAzureRMRouteTable_removeRoute(t *testing.T) { ), }, { - Config: updatedConfig, + // This configuration has no route blocks at all. + Config: noBlocksConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMRouteTableExists(resourceName), + // The route from the first step is preserved because no + // blocks at all means "ignore existing blocks". + resource.TestCheckResourceAttr(resourceName, "route.#", "1"), + ), + }, + { + // This configuration sets route to [] explicitly using the + // attribute syntax. + Config: blocksEmptyConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRouteTableExists(resourceName), + // The route from the first step is now removed, leaving us + // with no routes at all. resource.TestCheckResourceAttr(resourceName, "route.#", "0"), ), }, @@ -325,7 +342,7 @@ func testCheckAzureRMRouteTableExists(resourceName string) resource.TestCheckFun return fmt.Errorf("Bad: no resource group found in state for route table: %q", name) } - client := testAccProvider.Meta().(*ArmClient).routeTablesClient + client := testAccProvider.Meta().(*ArmClient).network.RouteTablesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name, "") @@ -354,7 +371,7 @@ func testCheckAzureRMRouteTableDisappears(resourceName string) resource.TestChec return fmt.Errorf("Bad: no resource group found in state for route table: %q", name) } - client := testAccProvider.Meta().(*ArmClient).routeTablesClient + client := testAccProvider.Meta().(*ArmClient).network.RouteTablesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, name) @@ -373,7 +390,7 @@ func testCheckAzureRMRouteTableDisappears(resourceName string) resource.TestChec } func testCheckAzureRMRouteTableDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).routeTablesClient + client := testAccProvider.Meta().(*ArmClient).network.RouteTablesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -492,6 +509,21 @@ resource "azurerm_route_table" "test" { `, rInt, location, rInt) } +func testAccAzureRMRouteTable_noRouteBlocks(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_route_table" "test" { + name = "acctestrt%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rInt) +} + func testAccAzureRMRouteTable_singleRouteRemoved(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -503,6 +535,8 @@ resource "azurerm_route_table" "test" { name = "acctestrt%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" + + route = [] } `, rInt, location, rInt) } diff --git a/azurerm/resource_arm_route_test.go b/azurerm/resource_arm_route_test.go index d92551122711..732acfb32ed7 100644 --- a/azurerm/resource_arm_route_test.go +++ b/azurerm/resource_arm_route_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +36,7 @@ func TestAccAzureRMRoute_basic(t *testing.T) { } func TestAccAzureRMRoute_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -163,7 +164,7 @@ func testCheckAzureRMRouteExists(resourceName string) resource.TestCheckFunc { return fmt.Errorf("Bad: no resource group found in state for route: %q", name) } - client := testAccProvider.Meta().(*ArmClient).routesClient + client := testAccProvider.Meta().(*ArmClient).network.RoutesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, rtName, name) @@ -193,7 +194,7 @@ func testCheckAzureRMRouteDisappears(resourceName string) resource.TestCheckFunc return fmt.Errorf("Bad: no resource group found in state for route: %s", name) } - client := testAccProvider.Meta().(*ArmClient).routesClient + client := testAccProvider.Meta().(*ArmClient).network.RoutesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, rtName, name) @@ -210,7 +211,7 @@ func testCheckAzureRMRouteDisappears(resourceName string) resource.TestCheckFunc } func testCheckAzureRMRouteDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).routesClient + client := testAccProvider.Meta().(*ArmClient).network.RoutesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_scheduler_job.go b/azurerm/resource_arm_scheduler_job.go index 63942ad1b6ad..3db000aab554 100644 --- a/azurerm/resource_arm_scheduler_job.go +++ b/azurerm/resource_arm_scheduler_job.go @@ -10,7 +10,9 @@ import ( "strings" "time" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/azure-sdk-for-go/services/scheduler/mgmt/2016-03-01/scheduler" "github.com/Azure/go-autorest/autorest/date" @@ -51,7 +53,7 @@ func resourceArmSchedulerJob() *schema.Resource { ), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "job_collection_name": { Type: schema.TypeString, @@ -462,14 +464,14 @@ func resourceArmSchedulerJobCustomizeDiff(diff *schema.ResourceDiff, _ interface } func resourceArmSchedulerJobCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).schedulerJobsClient + client := meta.(*ArmClient).scheduler.JobsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) jobCollection := d.Get("job_collection_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, jobCollection, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -519,10 +521,10 @@ func resourceArmSchedulerJobCreateUpdate(d *schema.ResourceData, meta interface{ } func resourceArmSchedulerJobRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).schedulerJobsClient + client := meta.(*ArmClient).scheduler.JobsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -613,10 +615,10 @@ func resourceArmSchedulerJobRead(d *schema.ResourceData, meta interface{}) error } func resourceArmSchedulerJobDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).schedulerJobsClient + client := meta.(*ArmClient).scheduler.JobsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_scheduler_job_collection.go b/azurerm/resource_arm_scheduler_job_collection.go index 85689ee3daf9..e7e843ce5be8 100644 --- a/azurerm/resource_arm_scheduler_job_collection.go +++ b/azurerm/resource_arm_scheduler_job_collection.go @@ -7,7 +7,11 @@ import ( "log" "regexp" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/scheduler/mgmt/2016-03-01/scheduler" @@ -41,16 +45,16 @@ func resourceArmSchedulerJobCollection() *schema.Resource { ), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "tags": tagsSchema(), + "tags": tags.Schema(), "sku": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(scheduler.Free), string(scheduler.Standard), @@ -64,7 +68,7 @@ func resourceArmSchedulerJobCollection() *schema.Resource { Type: schema.TypeString, Optional: true, Default: string(scheduler.Enabled), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(scheduler.Enabled), string(scheduler.Suspended), @@ -90,7 +94,7 @@ func resourceArmSchedulerJobCollection() *schema.Resource { "max_recurrence_frequency": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(scheduler.Minute), string(scheduler.Hour), @@ -123,17 +127,17 @@ func resourceArmSchedulerJobCollection() *schema.Resource { } func resourceArmSchedulerJobCollectionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).schedulerJobCollectionsClient + client := meta.(*ArmClient).scheduler.JobCollectionsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resourceGroup := d.Get("resource_group_name").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) log.Printf("[DEBUG] Creating/updating Scheduler Job Collection %q (resource group %q)", name, resourceGroup) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -148,7 +152,7 @@ func resourceArmSchedulerJobCollectionCreateUpdate(d *schema.ResourceData, meta collection := scheduler.JobCollectionDefinition{ Location: utils.String(location), - Tags: expandTags(tags), + Tags: tags.Expand(t), Properties: &scheduler.JobCollectionProperties{ Sku: &scheduler.Sku{ Name: scheduler.SkuDefinition(d.Get("sku").(string)), @@ -179,10 +183,10 @@ func resourceArmSchedulerJobCollectionCreateUpdate(d *schema.ResourceData, meta } func resourceArmSchedulerJobCollectionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).schedulerJobCollectionsClient + client := meta.(*ArmClient).scheduler.JobCollectionsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -206,9 +210,8 @@ func resourceArmSchedulerJobCollectionRead(d *schema.ResourceData, meta interfac d.Set("name", collection.Name) d.Set("resource_group_name", resourceGroup) if location := collection.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } - flattenAndSetTags(d, collection.Tags) //resource specific if properties := collection.Properties; properties != nil { @@ -222,14 +225,14 @@ func resourceArmSchedulerJobCollectionRead(d *schema.ResourceData, meta interfac } } - return nil + return tags.FlattenAndSet(d, collection.Tags) } func resourceArmSchedulerJobCollectionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).schedulerJobCollectionsClient + client := meta.(*ArmClient).scheduler.JobCollectionsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_scheduler_job_collection_test.go b/azurerm/resource_arm_scheduler_job_collection_test.go index 49411f8fee71..b9f87f2b8a53 100644 --- a/azurerm/resource_arm_scheduler_job_collection_test.go +++ b/azurerm/resource_arm_scheduler_job_collection_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMSchedulerJobCollection_basic(t *testing.T) { } func TestAccAzureRMSchedulerJobCollection_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -97,7 +98,7 @@ func testCheckAzureRMSchedulerJobCollectionDestroy(s *terraform.State) error { name := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).schedulerJobCollectionsClient + client := testAccProvider.Meta().(*ArmClient).scheduler.JobCollectionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -130,7 +131,7 @@ func testCheckAzureRMSchedulerJobCollectionExists(resourceName string) resource. return fmt.Errorf("Bad: no resource group found in state for Scheduler Job Collection: %q", name) } - client := testAccProvider.Meta().(*ArmClient).schedulerJobCollectionsClient + client := testAccProvider.Meta().(*ArmClient).scheduler.JobCollectionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -172,7 +173,8 @@ resource "azurerm_scheduler_job_collection" "import" { location = "${azurerm_scheduler_job_collection.test.location}" resource_group_name = "${azurerm_scheduler_job_collection.test.resource_group_name}" sku = "${azurerm_scheduler_job_collection.test.sku}" - %s + + %s } `, testAccAzureRMSchedulerJobCollection_basic(rInt, location, additional), additional) } diff --git a/azurerm/resource_arm_scheduler_job_test.go b/azurerm/resource_arm_scheduler_job_test.go index 4fd27e2f3c0f..d544c2318e4a 100644 --- a/azurerm/resource_arm_scheduler_job_test.go +++ b/azurerm/resource_arm_scheduler_job_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -41,7 +42,7 @@ func TestAccAzureRMSchedulerJob_web_basic(t *testing.T) { } func TestAccAzureRMSchedulerJob_web_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -514,7 +515,7 @@ func testCheckAzureRMSchedulerJobDestroy(s *terraform.State) error { resourceGroup := rs.Primary.Attributes["resource_group_name"] jobCollection := rs.Primary.Attributes["job_collection_name"] - client := testAccProvider.Meta().(*ArmClient).schedulerJobsClient + client := testAccProvider.Meta().(*ArmClient).scheduler.JobsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, jobCollection, name) @@ -548,7 +549,7 @@ func testCheckAzureRMSchedulerJobExists(resourceName string) resource.TestCheckF return fmt.Errorf("Bad: no resource group found in state for Scheduler Job: %q", name) } - client := testAccProvider.Meta().(*ArmClient).schedulerJobsClient + client := testAccProvider.Meta().(*ArmClient).scheduler.JobsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, jobCollection, name) @@ -668,7 +669,7 @@ resource "azurerm_scheduler_job" "test" { method = "get" authentication_certificate { - pfx = "${base64encode(file("testdata/application_gateway_test.pfx"))}" + pfx = "${filebase64("testdata/application_gateway_test.pfx")}" password = "terraform" } } @@ -920,7 +921,7 @@ resource "azurerm_scheduler_job" "test" { message = "storage message" } } -`, testAccAzureRMSchedulerJob_template(rInt, location), strconv.Itoa(rInt)[0:5], rInt) +`, testAccAzureRMSchedulerJob_template(rInt, location), strconv.Itoa(rInt)[12:17], rInt) } func testAccAzureRMSchedulerJob_storageQueue_errorAction(rInt int, location string) string { @@ -957,5 +958,5 @@ resource "azurerm_scheduler_job" "test" { message = "storage message" } } -`, testAccAzureRMSchedulerJob_template(rInt, location), strconv.Itoa(rInt)[0:5], rInt) +`, testAccAzureRMSchedulerJob_template(rInt, location), strconv.Itoa(rInt)[12:17], rInt) } diff --git a/azurerm/resource_arm_search_service.go b/azurerm/resource_arm_search_service.go index 651d6bf1c8e6..23a714cdde7d 100644 --- a/azurerm/resource_arm_search_service.go +++ b/azurerm/resource_arm_search_service.go @@ -4,7 +4,10 @@ import ( "fmt" "log" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/search/mgmt/2015-08-19/search" "github.com/hashicorp/terraform/helper/schema" @@ -16,6 +19,7 @@ func resourceArmSearchService() *schema.Resource { return &schema.Resource{ Create: resourceArmSearchServiceCreateUpdate, Read: resourceArmSearchServiceRead, + Update: resourceArmSearchServiceCreateUpdate, Delete: resourceArmSearchServiceDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -28,9 +32,9 @@ func resourceArmSearchService() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeString, @@ -69,22 +73,22 @@ func resourceArmSearchService() *schema.Resource { Computed: true, }, - "tags": tagsForceNewSchema(), + "tags": tags.Schema(), }, } } func resourceArmSearchServiceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).searchServicesClient + client := meta.(*ArmClient).search.ServicesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resourceGroup := d.Get("resource_group_name").(string) skuName := d.Get("sku").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name, nil) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -103,7 +107,7 @@ func resourceArmSearchServiceCreateUpdate(d *schema.ResourceData, meta interface Name: search.SkuName(skuName), }, ServiceProperties: &search.ServiceProperties{}, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if v, ok := d.GetOk("replica_count"); ok { @@ -131,10 +135,10 @@ func resourceArmSearchServiceCreateUpdate(d *schema.ResourceData, meta interface } func resourceArmSearchServiceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).searchServicesClient + client := meta.(*ArmClient).search.ServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -155,7 +159,7 @@ func resourceArmSearchServiceRead(d *schema.ResourceData, meta interface{}) erro d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { @@ -172,23 +176,21 @@ func resourceArmSearchServiceRead(d *schema.ResourceData, meta interface{}) erro } } - adminKeysClient := meta.(*ArmClient).searchAdminKeysClient + adminKeysClient := meta.(*ArmClient).search.AdminKeysClient adminKeysResp, err := adminKeysClient.Get(ctx, resourceGroup, name, nil) if err == nil { d.Set("primary_key", adminKeysResp.PrimaryKey) d.Set("secondary_key", adminKeysResp.SecondaryKey) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSearchServiceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).searchServicesClient + client := meta.(*ArmClient).search.ServicesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_search_service_test.go b/azurerm/resource_arm_search_service_test.go index 43a3d3e6b5f0..5943258667a4 100644 --- a/azurerm/resource_arm_search_service_test.go +++ b/azurerm/resource_arm_search_service_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMSearchService_basic(t *testing.T) { } func TestAccAzureRMSearchService_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -92,6 +93,35 @@ func TestAccAzureRMSearchService_complete(t *testing.T) { }) } +func TestAccAzureRMSearchService_tagUpdate(t *testing.T) { + resourceName := "azurerm_search_service.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSearchServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSearchService_withCustomTagValue(ri, testLocation(), "staging"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSearchServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "staging"), + ), + }, + { + Config: testAccAzureRMSearchService_withCustomTagValue(ri, testLocation(), "production"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSearchServiceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.environment", "production"), + ), + }, + }, + }) +} + func testCheckAzureRMSearchServiceExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -103,7 +133,7 @@ func testCheckAzureRMSearchServiceExists(resourceName string) resource.TestCheck resourceGroup := rs.Primary.Attributes["resource_group_name"] searchName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).searchServicesClient + client := testAccProvider.Meta().(*ArmClient).search.ServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, searchName, nil) @@ -128,7 +158,7 @@ func testCheckAzureRMSearchServiceDestroy(s *terraform.State) error { resourceGroup := rs.Primary.Attributes["resource_group_name"] searchName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).searchServicesClient + client := testAccProvider.Meta().(*ArmClient).search.ServicesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, searchName, nil) @@ -146,7 +176,7 @@ func testCheckAzureRMSearchServiceDestroy(s *terraform.State) error { return nil } -func testAccAzureRMSearchService_basic(rInt int, location string) string { +func testAccAzureRMSearchService_withCustomTagValue(rInt int, location string, tagValue string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -160,10 +190,14 @@ resource "azurerm_search_service" "test" { sku = "standard" tags = { - environment = "staging" + environment = "%s" } } -`, rInt, location, rInt) +`, rInt, location, rInt, tagValue) +} + +func testAccAzureRMSearchService_basic(rInt int, location string) string { + return testAccAzureRMSearchService_withCustomTagValue(rInt, location, "staging") } func testAccAzureRMSearchService_requiresImport(rInt int, location string) string { diff --git a/azurerm/resource_arm_security_center_contact.go b/azurerm/resource_arm_security_center_contact.go index 7f5e056aa2ae..b93ae7b884bc 100644 --- a/azurerm/resource_arm_security_center_contact.go +++ b/azurerm/resource_arm_security_center_contact.go @@ -5,8 +5,9 @@ import ( "log" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" - "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" + "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v1.0/security" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" @@ -38,7 +39,7 @@ func resourceArmSecurityCenterContact() *schema.Resource { "phone": { Type: schema.TypeString, - Required: true, + Optional: true, ValidateFunc: validate.NoEmptyStrings, }, @@ -56,12 +57,12 @@ func resourceArmSecurityCenterContact() *schema.Resource { } func resourceArmSecurityCenterContactCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).securityCenterContactsClient + client := meta.(*ArmClient).securityCenter.ContactsClient ctx := meta.(*ArmClient).StopContext name := securityCenterContactName - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -118,7 +119,7 @@ func resourceArmSecurityCenterContactCreateUpdate(d *schema.ResourceData, meta i } func resourceArmSecurityCenterContactRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).securityCenterContactsClient + client := meta.(*ArmClient).securityCenter.ContactsClient ctx := meta.(*ArmClient).StopContext name := securityCenterContactName @@ -145,7 +146,7 @@ func resourceArmSecurityCenterContactRead(d *schema.ResourceData, meta interface } func resourceArmSecurityCenterContactDelete(_ *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).securityCenterContactsClient + client := meta.(*ArmClient).securityCenter.ContactsClient ctx := meta.(*ArmClient).StopContext name := securityCenterContactName diff --git a/azurerm/resource_arm_security_center_contact_test.go b/azurerm/resource_arm_security_center_contact_test.go index 6ae8599c4842..9b4f70009c56 100644 --- a/azurerm/resource_arm_security_center_contact_test.go +++ b/azurerm/resource_arm_security_center_contact_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -16,6 +17,7 @@ func TestAccAzureRMSecurityCenter_contact(t *testing.T) { "basic": testAccAzureRMSecurityCenterContact_basic, "update": testAccAzureRMSecurityCenterContact_update, "requiresImport": testAccAzureRMSecurityCenterContact_requiresImport, + "phoneOptional": testAccAzureRMSecurityCenterContact_phoneOptional, }, } @@ -60,7 +62,7 @@ func testAccAzureRMSecurityCenterContact_basic(t *testing.T) { } func testAccAzureRMSecurityCenterContact_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -127,9 +129,36 @@ func testAccAzureRMSecurityCenterContact_update(t *testing.T) { }) } +func testAccAzureRMSecurityCenterContact_phoneOptional(t *testing.T) { + resourceName := "azurerm_security_center_contact.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSecurityCenterContactDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSecurityCenterContact_templateWithoutPhone("basic@example.com", true, true), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSecurityCenterContactExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "email", "basic@example.com"), + resource.TestCheckResourceAttr(resourceName, "phone", ""), + resource.TestCheckResourceAttr(resourceName, "alert_notifications", "true"), + resource.TestCheckResourceAttr(resourceName, "alerts_to_admins", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMSecurityCenterContactExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).securityCenterContactsClient + client := testAccProvider.Meta().(*ArmClient).securityCenter.ContactsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext rs, ok := s.RootModule().Resources[resourceName] @@ -153,7 +182,7 @@ func testCheckAzureRMSecurityCenterContactExists(resourceName string) resource.T } func testCheckAzureRMSecurityCenterContactDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).securityCenterContactsClient + client := testAccProvider.Meta().(*ArmClient).securityCenter.ContactsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, res := range s.RootModule().Resources { if res.Type != "azurerm_security_center_contact" { @@ -183,6 +212,17 @@ resource "azurerm_security_center_contact" "test" { `, email, phone, notifications, adminAlerts) } +func testAccAzureRMSecurityCenterContact_templateWithoutPhone(email string, notifications, adminAlerts bool) string { + return fmt.Sprintf(` +resource "azurerm_security_center_contact" "test" { + email = "%s" + + alert_notifications = %t + alerts_to_admins = %t +} +`, email, notifications, adminAlerts) +} + func testAccAzureRMSecurityCenterContact_requiresImportCfg(email, phone string, notifications, adminAlerts bool) string { return fmt.Sprintf(` %s diff --git a/azurerm/resource_arm_security_center_subscription_pricing.go b/azurerm/resource_arm_security_center_subscription_pricing.go index 61142507197d..2960c4fc50ac 100644 --- a/azurerm/resource_arm_security_center_subscription_pricing.go +++ b/azurerm/resource_arm_security_center_subscription_pricing.go @@ -4,7 +4,7 @@ import ( "fmt" "log" - "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" + "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v1.0/security" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" @@ -39,7 +39,7 @@ func resourceArmSecurityCenterSubscriptionPricing() *schema.Resource { } func resourceArmSecurityCenterSubscriptionPricingUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).securityCenterPricingClient + client := meta.(*ArmClient).securityCenter.PricingClient ctx := meta.(*ArmClient).StopContext name := securityCenterSubscriptionPricingName @@ -71,7 +71,7 @@ func resourceArmSecurityCenterSubscriptionPricingUpdate(d *schema.ResourceData, } func resourceArmSecurityCenterSubscriptionPricingRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).securityCenterPricingClient + client := meta.(*ArmClient).securityCenter.PricingClient ctx := meta.(*ArmClient).StopContext resp, err := client.GetSubscriptionPricing(ctx, securityCenterSubscriptionPricingName) diff --git a/azurerm/resource_arm_security_center_subscription_pricing_test.go b/azurerm/resource_arm_security_center_subscription_pricing_test.go index 38a9235b83e9..8f66d43ec451 100644 --- a/azurerm/resource_arm_security_center_subscription_pricing_test.go +++ b/azurerm/resource_arm_security_center_subscription_pricing_test.go @@ -46,7 +46,7 @@ func testAccAzureRMSecurityCenterSubscriptionPricing_update(t *testing.T) { func testCheckAzureRMSecurityCenterSubscriptionPricingExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).securityCenterPricingClient + client := testAccProvider.Meta().(*ArmClient).securityCenter.PricingClient ctx := testAccProvider.Meta().(*ArmClient).StopContext rs, ok := s.RootModule().Resources[resourceName] diff --git a/azurerm/resource_arm_security_center_workspace.go b/azurerm/resource_arm_security_center_workspace.go index 79c487b58c68..aa65d276f8f2 100644 --- a/azurerm/resource_arm_security_center_workspace.go +++ b/azurerm/resource_arm_security_center_workspace.go @@ -5,13 +5,13 @@ import ( "log" "time" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" - - "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" + "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v1.0/security" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -47,13 +47,13 @@ func resourceArmSecurityCenterWorkspace() *schema.Resource { } func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - priceClient := meta.(*ArmClient).securityCenterPricingClient - client := meta.(*ArmClient).securityCenterWorkspaceClient + priceClient := meta.(*ArmClient).securityCenter.PricingClient + client := meta.(*ArmClient).securityCenter.WorkspaceClient ctx := meta.(*ArmClient).StopContext name := securityCenterWorkspaceName - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -133,7 +133,7 @@ func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta } func resourceArmSecurityCenterWorkspaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).securityCenterWorkspaceClient + client := meta.(*ArmClient).securityCenter.WorkspaceClient ctx := meta.(*ArmClient).StopContext resp, err := client.Get(ctx, securityCenterWorkspaceName) @@ -156,7 +156,7 @@ func resourceArmSecurityCenterWorkspaceRead(d *schema.ResourceData, meta interfa } func resourceArmSecurityCenterWorkspaceDelete(_ *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).securityCenterWorkspaceClient + client := meta.(*ArmClient).securityCenter.WorkspaceClient ctx := meta.(*ArmClient).StopContext resp, err := client.Delete(ctx, securityCenterWorkspaceName) diff --git a/azurerm/resource_arm_security_center_workspace_test.go b/azurerm/resource_arm_security_center_workspace_test.go index f2b4747ed1d0..4ff0bc74210a 100644 --- a/azurerm/resource_arm_security_center_workspace_test.go +++ b/azurerm/resource_arm_security_center_workspace_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -43,7 +44,7 @@ func testAccAzureRMSecurityCenterWorkspace_basic(t *testing.T) { } func testAccAzureRMSecurityCenterWorkspace_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -116,7 +117,7 @@ func testAccAzureRMSecurityCenterWorkspace_update(t *testing.T) { func testCheckAzureRMSecurityCenterWorkspaceExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).securityCenterWorkspaceClient + client := testAccProvider.Meta().(*ArmClient).securityCenter.WorkspaceClient ctx := testAccProvider.Meta().(*ArmClient).StopContext rs, ok := s.RootModule().Resources[resourceName] @@ -140,7 +141,7 @@ func testCheckAzureRMSecurityCenterWorkspaceExists(resourceName string) resource } func testCheckAzureRMSecurityCenterWorkspaceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).securityCenterWorkspaceClient + client := testAccProvider.Meta().(*ArmClient).securityCenter.WorkspaceClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, res := range s.RootModule().Resources { diff --git a/azurerm/resource_arm_service_fabric_cluster.go b/azurerm/resource_arm_service_fabric_cluster.go index 778e3c6f8e8f..9aa132a72dc6 100644 --- a/azurerm/resource_arm_service_fabric_cluster.go +++ b/azurerm/resource_arm_service_fabric_cluster.go @@ -7,17 +7,20 @@ import ( "github.com/Azure/azure-sdk-for-go/services/servicefabric/mgmt/2018-02-01/servicefabric" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func resourceArmServiceFabricCluster() *schema.Resource { return &schema.Resource{ - Create: resourceArmServiceFabricClusterCreate, + Create: resourceArmServiceFabricClusterCreateUpdate, Read: resourceArmServiceFabricClusterRead, - Update: resourceArmServiceFabricClusterUpdate, + Update: resourceArmServiceFabricClusterCreateUpdate, Delete: resourceArmServiceFabricClusterDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -30,9 +33,9 @@ func resourceArmServiceFabricCluster() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "reliability_level": { Type: schema.TypeString, @@ -50,8 +53,8 @@ func resourceArmServiceFabricCluster() *schema.Resource { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{ - string(servicefabric.Automatic), - string(servicefabric.Manual), + string(servicefabric.UpgradeModeAutomatic), + string(servicefabric.UpgradeModeManual), }, false), }, @@ -83,33 +86,33 @@ func resourceArmServiceFabricCluster() *schema.Resource { "azure_active_directory": { Type: schema.TypeList, Optional: true, - ForceNew: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "tenant_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.UUID, }, "cluster_application_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.UUID, }, "client_application_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.UUID, }, }, }, }, "certificate": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ConflictsWith: []string{"certificate_common_names"}, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "thumbprint": { @@ -128,6 +131,41 @@ func resourceArmServiceFabricCluster() *schema.Resource { }, }, + "certificate_common_names": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ConflictsWith: []string{"certificate"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "common_names": { + Type: schema.TypeSet, + Required: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "certificate_common_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "certificate_issuer_thumbprint": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + "x509_store_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + "reverse_proxy_certificate": { Type: schema.TypeList, Optional: true, @@ -171,34 +209,28 @@ func resourceArmServiceFabricCluster() *schema.Resource { "diagnostics_config": { Type: schema.TypeList, Optional: true, - ForceNew: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "storage_account_name": { Type: schema.TypeString, Required: true, - ForceNew: true, }, "protected_account_key_name": { Type: schema.TypeString, Required: true, - ForceNew: true, }, "blob_endpoint": { Type: schema.TypeString, Required: true, - ForceNew: true, }, "queue_endpoint": { Type: schema.TypeString, Required: true, - ForceNew: true, }, "table_endpoint": { Type: schema.TypeString, Required: true, - ForceNew: true, }, }, }, @@ -229,7 +261,6 @@ func resourceArmServiceFabricCluster() *schema.Resource { "name": { Type: schema.TypeString, Required: true, - ForceNew: true, }, "placement_properties": { Type: schema.TypeMap, @@ -246,17 +277,14 @@ func resourceArmServiceFabricCluster() *schema.Resource { "is_primary": { Type: schema.TypeBool, Required: true, - ForceNew: true, }, "client_endpoint_port": { Type: schema.TypeInt, Required: true, - ForceNew: true, }, "http_endpoint_port": { Type: schema.TypeInt, Required: true, - ForceNew: true, }, "reverse_proxy_endpoint_port": { Type: schema.TypeInt, @@ -267,7 +295,6 @@ func resourceArmServiceFabricCluster() *schema.Resource { Type: schema.TypeString, Optional: true, Default: string(servicefabric.Bronze), - ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ string(servicefabric.Bronze), string(servicefabric.Gold), @@ -278,7 +305,6 @@ func resourceArmServiceFabricCluster() *schema.Resource { "application_ports": { Type: schema.TypeList, Optional: true, - ForceNew: true, Computed: true, MaxItems: 1, Elem: &schema.Resource{ @@ -286,12 +312,10 @@ func resourceArmServiceFabricCluster() *schema.Resource { "start_port": { Type: schema.TypeInt, Required: true, - ForceNew: true, }, "end_port": { Type: schema.TypeInt, Required: true, - ForceNew: true, }, }, }, @@ -300,7 +324,6 @@ func resourceArmServiceFabricCluster() *schema.Resource { "ephemeral_ports": { Type: schema.TypeList, Optional: true, - ForceNew: true, Computed: true, MaxItems: 1, Elem: &schema.Resource{ @@ -308,12 +331,10 @@ func resourceArmServiceFabricCluster() *schema.Resource { "start_port": { Type: schema.TypeInt, Required: true, - ForceNew: true, }, "end_port": { Type: schema.TypeInt, Required: true, - ForceNew: true, }, }, }, @@ -322,7 +343,7 @@ func resourceArmServiceFabricCluster() *schema.Resource { }, }, - "tags": tagsSchema(), + "tags": tags.Schema(), "cluster_endpoint": { Type: schema.TypeString, @@ -332,8 +353,8 @@ func resourceArmServiceFabricCluster() *schema.Resource { } } -func resourceArmServiceFabricClusterCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceFabricClustersClient +func resourceArmServiceFabricClusterCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).serviceFabric.ClustersClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Service Fabric Cluster creation.") @@ -346,9 +367,9 @@ func resourceArmServiceFabricClusterCreate(d *schema.ResourceData, meta interfac upgradeMode := d.Get("upgrade_mode").(string) clusterCodeVersion := d.Get("cluster_code_version").(string) vmImage := d.Get("vm_image").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -367,9 +388,6 @@ func resourceArmServiceFabricClusterCreate(d *schema.ResourceData, meta interfac azureActiveDirectoryRaw := d.Get("azure_active_directory").([]interface{}) azureActiveDirectory := expandServiceFabricClusterAzureActiveDirectory(azureActiveDirectoryRaw) - certificateRaw := d.Get("certificate").([]interface{}) - certificate := expandServiceFabricClusterCertificate(certificateRaw) - reverseProxyCertificateRaw := d.Get("reverse_proxy_certificate").([]interface{}) reverseProxyCertificate := expandServiceFabricClusterReverseProxyCertificate(reverseProxyCertificateRaw) @@ -387,11 +405,11 @@ func resourceArmServiceFabricClusterCreate(d *schema.ResourceData, meta interfac cluster := servicefabric.Cluster{ Location: utils.String(location), - Tags: expandTags(tags), + Tags: tags.Expand(t), ClusterProperties: &servicefabric.ClusterProperties{ AddOnFeatures: addOnFeatures, AzureActiveDirectory: azureActiveDirectory, - Certificate: certificate, + CertificateCommonNames: expandServiceFabricClusterCertificateCommonNames(d), ReverseProxyCertificate: reverseProxyCertificate, ClientCertificateThumbprints: clientCertificateThumbprints, DiagnosticsStorageAccountConfig: diagnostics, @@ -404,6 +422,11 @@ func resourceArmServiceFabricClusterCreate(d *schema.ResourceData, meta interfac }, } + if certificateRaw, ok := d.GetOk("certificate"); ok { + certificate := expandServiceFabricClusterCertificate(certificateRaw.([]interface{})) + cluster.ClusterProperties.Certificate = certificate + } + if clusterCodeVersion != "" { cluster.ClusterProperties.ClusterCodeVersion = utils.String(clusterCodeVersion) } @@ -430,72 +453,11 @@ func resourceArmServiceFabricClusterCreate(d *schema.ResourceData, meta interfac return resourceArmServiceFabricClusterRead(d, meta) } -func resourceArmServiceFabricClusterUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceFabricClustersClient - ctx := meta.(*ArmClient).StopContext - - log.Printf("[INFO] preparing arguments for Service Fabric Cluster update.") - - resourceGroup := d.Get("resource_group_name").(string) - name := d.Get("name").(string) - reliabilityLevel := d.Get("reliability_level").(string) - upgradeMode := d.Get("upgrade_mode").(string) - clusterCodeVersion := d.Get("cluster_code_version").(string) - tags := d.Get("tags").(map[string]interface{}) - - addOnFeaturesRaw := d.Get("add_on_features").(*schema.Set).List() - addOnFeatures := expandServiceFabricClusterAddOnFeatures(addOnFeaturesRaw) - - certificateRaw := d.Get("certificate").([]interface{}) - certificate := expandServiceFabricClusterCertificate(certificateRaw) - - reverseProxyCertificateRaw := d.Get("reverse_proxy_certificate").([]interface{}) - reverseProxyCertificate := expandServiceFabricClusterReverseProxyCertificate(reverseProxyCertificateRaw) - - clientCertificateThumbprintsRaw := d.Get("client_certificate_thumbprint").([]interface{}) - clientCertificateThumbprints := expandServiceFabricClusterClientCertificateThumbprints(clientCertificateThumbprintsRaw) - - fabricSettingsRaw := d.Get("fabric_settings").([]interface{}) - fabricSettings := expandServiceFabricClusterFabricSettings(fabricSettingsRaw) - - nodeTypesRaw := d.Get("node_type").([]interface{}) - nodeTypes := expandServiceFabricClusterNodeTypes(nodeTypesRaw) - - parameters := servicefabric.ClusterUpdateParameters{ - ClusterPropertiesUpdateParameters: &servicefabric.ClusterPropertiesUpdateParameters{ - AddOnFeatures: addOnFeatures, - Certificate: certificate, - ReverseProxyCertificate: reverseProxyCertificate, - ClientCertificateThumbprints: clientCertificateThumbprints, - FabricSettings: fabricSettings, - NodeTypes: nodeTypes, - ReliabilityLevel: servicefabric.ReliabilityLevel1(reliabilityLevel), - UpgradeMode: servicefabric.UpgradeMode1(upgradeMode), - }, - Tags: expandTags(tags), - } - - if clusterCodeVersion != "" { - parameters.ClusterPropertiesUpdateParameters.ClusterCodeVersion = utils.String(clusterCodeVersion) - } - - future, err := client.Update(ctx, resourceGroup, name, parameters) - if err != nil { - return fmt.Errorf("Error updating Service Fabric Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) - } - - if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting for update of Service Fabric Cluster %q (Resource Group %q): %+v", name, resourceGroup, err) - } - - return resourceArmServiceFabricClusterRead(d, meta) -} - func resourceArmServiceFabricClusterRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceFabricClustersClient + client := meta.(*ArmClient).serviceFabric.ClustersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -517,7 +479,7 @@ func resourceArmServiceFabricClusterRead(d *schema.ResourceData, meta interface{ d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.ClusterProperties; props != nil { @@ -543,6 +505,11 @@ func resourceArmServiceFabricClusterRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("Error setting `certificate`: %+v", err) } + certificateCommonNames := flattenServiceFabricClusterCertificateCommonNames(props.CertificateCommonNames) + if err := d.Set("certificate_common_names", certificateCommonNames); err != nil { + return fmt.Errorf("Error setting `certificate_common_names`: %+v", err) + } + reverseProxyCertificate := flattenServiceFabricClusterReverseProxyCertificate(props.ReverseProxyCertificate) if err := d.Set("reverse_proxy_certificate", reverseProxyCertificate); err != nil { return fmt.Errorf("Error setting `reverse_proxy_certificate`: %+v", err) @@ -569,16 +536,14 @@ func resourceArmServiceFabricClusterRead(d *schema.ResourceData, meta interface{ } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmServiceFabricClusterDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceFabricClustersClient + client := meta.(*ArmClient).serviceFabric.ClustersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -705,6 +670,70 @@ func flattenServiceFabricClusterCertificate(input *servicefabric.CertificateDesc return results } +func expandServiceFabricClusterCertificateCommonNames(d *schema.ResourceData) *servicefabric.ServerCertificateCommonNames { + i := d.Get("certificate_common_names").([]interface{}) + if len(i) <= 0 || i[0] == nil { + return nil + } + input := i[0].(map[string]interface{}) + + commonNamesRaw := input["common_names"].(*schema.Set).List() + commonNames := make([]servicefabric.ServerCertificateCommonName, 0) + + for _, commonName := range commonNamesRaw { + commonNameDetails := commonName.(map[string]interface{}) + certificateCommonName := commonNameDetails["certificate_common_name"].(string) + certificateIssuerThumbprint := commonNameDetails["certificate_issuer_thumbprint"].(string) + + commonName := servicefabric.ServerCertificateCommonName{ + CertificateCommonName: &certificateCommonName, + CertificateIssuerThumbprint: &certificateIssuerThumbprint, + } + + commonNames = append(commonNames, commonName) + } + + x509StoreName := input["x509_store_name"].(string) + + output := servicefabric.ServerCertificateCommonNames{ + CommonNames: &commonNames, + X509StoreName: servicefabric.X509StoreName1(x509StoreName), + } + + return &output +} + +func flattenServiceFabricClusterCertificateCommonNames(in *servicefabric.ServerCertificateCommonNames) []interface{} { + if in == nil { + return []interface{}{} + } + + output := make(map[string]interface{}) + + if commonNames := in.CommonNames; commonNames != nil { + common_names := make([]map[string]interface{}, 0) + for _, i := range *commonNames { + commonName := make(map[string]interface{}) + + if i.CertificateCommonName != nil { + commonName["certificate_common_name"] = *i.CertificateCommonName + } + + if i.CertificateIssuerThumbprint != nil { + commonName["certificate_issuer_thumbprint"] = *i.CertificateIssuerThumbprint + } + + common_names = append(common_names, commonName) + } + + output["common_names"] = common_names + } + + output["x509_store_name"] = string(in.X509StoreName) + + return []interface{}{output} +} + func expandServiceFabricClusterReverseProxyCertificate(input []interface{}) *servicefabric.CertificateDescription { if len(input) == 0 { return nil diff --git a/azurerm/resource_arm_service_fabric_cluster_test.go b/azurerm/resource_arm_service_fabric_cluster_test.go index 027d444baf89..20de98d8e91f 100644 --- a/azurerm/resource_arm_service_fabric_cluster_test.go +++ b/azurerm/resource_arm_service_fabric_cluster_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMServiceFabricCluster_basic(t *testing.T) { @@ -45,8 +46,59 @@ func TestAccAzureRMServiceFabricCluster_basic(t *testing.T) { }) } +func TestAccAzureRMServiceFabricCluster_basicNodeTypeUpdate(t *testing.T) { + resourceName := "azurerm_service_fabric_cluster.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMServiceFabricClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMServiceFabricCluster_basic(ri, testLocation(), 3), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceFabricClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "management_endpoint", "http://example:80"), + resource.TestCheckResourceAttr(resourceName, "add_on_features.#", "0"), + resource.TestCheckResourceAttr(resourceName, "certificate.#", "0"), + resource.TestCheckResourceAttr(resourceName, "reverse_proxy_certificate.#", "0"), + resource.TestCheckResourceAttr(resourceName, "client_certificate_thumbprint.#", "0"), + resource.TestCheckResourceAttr(resourceName, "azure_active_directory.#", "0"), + resource.TestCheckResourceAttr(resourceName, "diagnostics_config.#", "0"), + resource.TestCheckResourceAttr(resourceName, "node_type.#", "1"), + resource.TestCheckResourceAttr(resourceName, "node_type.0.is_primary", "true"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + Config: testAccAzureRMServiceFabricCluster_basicNodeTypeUpdate(ri, testLocation(), 3, 3), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceFabricClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "management_endpoint", "http://example:80"), + resource.TestCheckResourceAttr(resourceName, "add_on_features.#", "0"), + resource.TestCheckResourceAttr(resourceName, "certificate.#", "0"), + resource.TestCheckResourceAttr(resourceName, "reverse_proxy_certificate.#", "0"), + resource.TestCheckResourceAttr(resourceName, "client_certificate_thumbprint.#", "0"), + resource.TestCheckResourceAttr(resourceName, "azure_active_directory.#", "0"), + resource.TestCheckResourceAttr(resourceName, "diagnostics_config.#", "0"), + resource.TestCheckResourceAttr(resourceName, "node_type.#", "2"), + resource.TestCheckResourceAttr(resourceName, "node_type.0.is_primary", "true"), + resource.TestCheckResourceAttr(resourceName, "node_type.1.is_primary", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMServiceFabricCluster_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -404,6 +456,35 @@ func TestAccAzureRMServiceFabricCluster_readerAdminClientCertificateThumbprint(t }) } +func TestAccAzureRMServiceFabricCluster_certificateCommonNames(t *testing.T) { + resourceName := "azurerm_service_fabric_cluster.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMServiceFabricClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMServiceFabricCluster_certificateCommonNames(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceFabricClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "certificate_common_names.0.common_names.2962847220.certificate_common_name", "example"), + resource.TestCheckResourceAttr(resourceName, "certificate_common_names.0.x509_store_name", "My"), + resource.TestCheckResourceAttr(resourceName, "fabric_settings.0.name", "Security"), + resource.TestCheckResourceAttr(resourceName, "fabric_settings.0.parameters.ClusterProtectionLevel", "EncryptAndSign"), + resource.TestCheckResourceAttr(resourceName, "management_endpoint", "https://example:80"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMServiceFabricCluster_azureActiveDirectory(t *testing.T) { resourceName := "azurerm_service_fabric_cluster.test" ri := tf.AccRandTimeInt() @@ -426,7 +507,54 @@ func TestAccAzureRMServiceFabricCluster_azureActiveDirectory(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "azure_active_directory.0.client_application_id"), resource.TestCheckResourceAttr(resourceName, "fabric_settings.0.name", "Security"), resource.TestCheckResourceAttr(resourceName, "fabric_settings.0.parameters.ClusterProtectionLevel", "EncryptAndSign"), - resource.TestCheckResourceAttr(resourceName, "management_endpoint", "https://example:80"), + resource.TestCheckResourceAttr(resourceName, "management_endpoint", "https://example:19080"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMServiceFabricCluster_azureActiveDirectoryDelete(t *testing.T) { + resourceName := "azurerm_service_fabric_cluster.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMServiceFabricClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMServiceFabricCluster_azureActiveDirectory(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceFabricClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "certificate.#", "1"), + resource.TestCheckResourceAttr(resourceName, "certificate.0.thumbprint", "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE"), + resource.TestCheckResourceAttr(resourceName, "certificate.0.x509_store_name", "My"), + resource.TestCheckResourceAttr(resourceName, "azure_active_directory.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "azure_active_directory.0.tenant_id"), + resource.TestCheckResourceAttrSet(resourceName, "azure_active_directory.0.cluster_application_id"), + resource.TestCheckResourceAttrSet(resourceName, "azure_active_directory.0.client_application_id"), + resource.TestCheckResourceAttr(resourceName, "fabric_settings.0.name", "Security"), + resource.TestCheckResourceAttr(resourceName, "fabric_settings.0.parameters.ClusterProtectionLevel", "EncryptAndSign"), + resource.TestCheckResourceAttr(resourceName, "management_endpoint", "https://example:19080"), + ), + }, + { + Config: testAccAzureRMServiceFabricCluster_azureActiveDirectoryDelete(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceFabricClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "certificate.#", "1"), + resource.TestCheckResourceAttr(resourceName, "certificate.0.thumbprint", "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE"), + resource.TestCheckResourceAttr(resourceName, "certificate.0.x509_store_name", "My"), + resource.TestCheckResourceAttr(resourceName, "azure_active_directory.#", "0"), + resource.TestCheckResourceAttr(resourceName, "fabric_settings.0.name", "Security"), + resource.TestCheckResourceAttr(resourceName, "fabric_settings.0.parameters.ClusterProtectionLevel", "EncryptAndSign"), + resource.TestCheckResourceAttr(resourceName, "management_endpoint", "https://example:19080"), ), }, { @@ -469,6 +597,44 @@ func TestAccAzureRMServiceFabricCluster_diagnosticsConfig(t *testing.T) { }) } +func TestAccAzureRMServiceFabricCluster_diagnosticsConfigDelete(t *testing.T) { + resourceName := "azurerm_service_fabric_cluster.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMServiceFabricClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMServiceFabricCluster_diagnosticsConfig(ri, rs, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceFabricClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "diagnostics_config.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "diagnostics_config.0.storage_account_name"), + resource.TestCheckResourceAttrSet(resourceName, "diagnostics_config.0.protected_account_key_name"), + resource.TestCheckResourceAttrSet(resourceName, "diagnostics_config.0.blob_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "diagnostics_config.0.queue_endpoint"), + resource.TestCheckResourceAttrSet(resourceName, "diagnostics_config.0.table_endpoint"), + ), + }, + { + Config: testAccAzureRMServiceFabricCluster_diagnosticsConfigDelete(ri, rs, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceFabricClusterExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "diagnostics_config.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMServiceFabricCluster_fabricSettings(t *testing.T) { resourceName := "azurerm_service_fabric_cluster.test" ri := tf.AccRandTimeInt() @@ -669,7 +835,7 @@ func TestAccAzureRMServiceFabricCluster_tags(t *testing.T) { } func testCheckAzureRMServiceFabricClusterDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).serviceFabricClustersClient + client := testAccProvider.Meta().(*ArmClient).serviceFabric.ClustersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -708,7 +874,7 @@ func testCheckAzureRMServiceFabricClusterExists(resourceName string) resource.Te return fmt.Errorf("Bad: no resource group found in state for Service Fabric Cluster %q", clusterName) } - client := testAccProvider.Meta().(*ArmClient).serviceFabricClustersClient + client := testAccProvider.Meta().(*ArmClient).serviceFabric.ClustersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, clusterName) @@ -738,8 +904,8 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "http://example:80" - + management_endpoint = "http://example:80" + node_type { name = "first" instance_count = %d @@ -751,6 +917,41 @@ resource "azurerm_service_fabric_cluster" "test" { `, rInt, location, rInt, count) } +func testAccAzureRMServiceFabricCluster_basicNodeTypeUpdate(rInt int, location string, count int, secondary_count int) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_service_fabric_cluster" "test" { + name = "acctest-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + reliability_level = "Bronze" + upgrade_mode = "Automatic" + vm_image = "Windows" + management_endpoint = "http://example:80" + + node_type { + name = "first" + instance_count = %d + is_primary = true + client_endpoint_port = 2020 + http_endpoint_port = 80 + } + + node_type { + name = "second" + instance_count = %d + is_primary = false + client_endpoint_port = 2020 + http_endpoint_port = 80 + } +} +`, rInt, location, rInt, count, secondary_count) +} + func testAccAzureRMServiceFabricCluster_requiresImport(rInt int, location string, count int) string { return fmt.Sprintf(` %s @@ -762,8 +963,8 @@ resource "azurerm_service_fabric_cluster" "import" { reliability_level = "${azurerm_service_fabric_cluster.test.reliability_level}" upgrade_mode = "${azurerm_service_fabric_cluster.test.upgrade_mode}" vm_image = "${azurerm_service_fabric_cluster.test.vm_image}" - management_endpoint = "${azurerm_service_fabric_cluster.test.management_endpoint}" - + management_endpoint = "${azurerm_service_fabric_cluster.test.management_endpoint}" + node_type { name = "first" instance_count = %d @@ -790,8 +991,8 @@ resource "azurerm_service_fabric_cluster" "test" { upgrade_mode = "Manual" cluster_code_version = "%[3]s" vm_image = "Windows" - management_endpoint = "http://example:80" - + management_endpoint = "http://example:80" + node_type { name = "first" instance_count = 3 @@ -818,8 +1019,8 @@ resource "azurerm_service_fabric_cluster" "test" { upgrade_mode = "Automatic" vm_image = "Windows" management_endpoint = "http://example:80" - add_on_features = ["DnsService", "RepairManager"] - + add_on_features = ["DnsService", "RepairManager"] + node_type { name = "first" instance_count = 3 @@ -845,21 +1046,21 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "https://example:80" - + management_endpoint = "https://example:80" + certificate { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" x509_store_name = "My" - } - + } + fabric_settings { - name = "Security" - + name = "Security" + parameters = { "ClusterProtectionLevel" = "EncryptAndSign" } - } - + } + node_type { name = "first" instance_count = 3 @@ -885,26 +1086,26 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "https://example:80" - + management_endpoint = "https://example:80" + certificate { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" x509_store_name = "My" - } - + } + reverse_proxy_certificate { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" x509_store_name = "My" - } - + } + fabric_settings { - name = "Security" - + name = "Security" + parameters = { "ClusterProtectionLevel" = "EncryptAndSign" } - } - + } + node_type { name = "first" instance_count = 3 @@ -931,26 +1132,26 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "https://example:80" - + management_endpoint = "https://example:80" + certificate { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" x509_store_name = "My" - } - + } + client_certificate_thumbprint { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" is_admin = true - } - + } + fabric_settings { - name = "Security" - + name = "Security" + parameters = { "ClusterProtectionLevel" = "EncryptAndSign" } - } - + } + node_type { name = "first" instance_count = 3 @@ -976,31 +1177,74 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "https://example:80" - + management_endpoint = "https://example:80" + certificate { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" x509_store_name = "My" - } - + } + client_certificate_thumbprint { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" is_admin = true - } - + } + client_certificate_thumbprint { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" is_admin = false - } - + } + fabric_settings { - name = "Security" - + name = "Security" + parameters = { "ClusterProtectionLevel" = "EncryptAndSign" } - } - + } + + node_type { + name = "first" + instance_count = 3 + is_primary = true + client_endpoint_port = 2020 + http_endpoint_port = 80 + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMServiceFabricCluster_certificateCommonNames(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_service_fabric_cluster" "test" { + name = "acctest-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + reliability_level = "Bronze" + upgrade_mode = "Automatic" + vm_image = "Windows" + management_endpoint = "https://example:80" + + certificate_common_names { + common_names { + certificate_common_name = "example" + } + + x509_store_name = "My" + } + + fabric_settings { + name = "Security" + + parameters = { + "ClusterProtectionLevel" = "EncryptAndSign" + } + } + node_type { name = "first" instance_count = 3 @@ -1021,13 +1265,60 @@ resource "azurerm_resource_group" "test" { data "azurerm_client_config" "current" {} -resource "azurerm_azuread_application" "test" { - name = "${azurerm_resource_group.test.name}-AAD" - homepage = "https://example:80/Explorer/index.html" - identifier_uris = ["https://acctestAAD-app"] - reply_urls = ["https://acctestAAD-app"] +resource "azuread_application" "cluster_explorer" { + name = "${azurerm_resource_group.test.name}-explorer-AAD" + homepage = "https://example:19080/Explorer/index.html" + identifier_uris = ["https://example:19080/Explorer/index.html"] + reply_urls = ["https://example:19080/Explorer/index.html"] available_to_other_tenants = false oauth2_allow_implicit_flow = true + + # https://blogs.msdn.microsoft.com/aaddevsup/2018/06/06/guid-table-for-windows-azure-active-directory-permissions/ + # https://shawntabrizi.com/aad/common-microsoft-resources-azure-active-directory/ + required_resource_access { + resource_app_id = "00000002-0000-0000-c000-000000000000" + + resource_access { + id = "311a71cc-e848-46a1-bdf8-97ff7156d8e6" + type = "Scope" + } + } +} + +resource "azuread_service_principal" "cluster_explorer" { + application_id = "${azuread_application.cluster_explorer.application_id}" +} + +resource "azuread_application" "cluster_console" { + name = "${azurerm_resource_group.test.name}-console-AAD" + type = "native" + reply_urls = ["urn:ietf:wg:oauth:2.0:oob"] + available_to_other_tenants = false + oauth2_allow_implicit_flow = true + + # https://blogs.msdn.microsoft.com/aaddevsup/2018/06/06/guid-table-for-windows-azure-active-directory-permissions/ + # https://shawntabrizi.com/aad/common-microsoft-resources-azure-active-directory/ + required_resource_access { + resource_app_id = "00000002-0000-0000-c000-000000000000" + + resource_access { + id = "311a71cc-e848-46a1-bdf8-97ff7156d8e6" + type = "Scope" + } + } + + required_resource_access { + resource_app_id = "${azuread_application.cluster_explorer.application_id}" + + resource_access { + id = "${azuread_application.cluster_explorer.oauth2_permissions.0.id}" + type = "Scope" + } + } +} + +resource "azuread_service_principal" "cluster_console" { + application_id = "${azuread_application.cluster_console.application_id}" } resource "azurerm_service_fabric_cluster" "test" { @@ -1037,33 +1328,75 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "https://example:80" - + management_endpoint = "https://example:19080" + certificate { thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" x509_store_name = "My" - } - + } + azure_active_directory { tenant_id = "${data.azurerm_client_config.current.tenant_id}" - cluster_application_id = "${azurerm_azuread_application.test.application_id}" - client_application_id = "00000000-0000-0000-0000-000000000000" - } - + cluster_application_id = "${azuread_application.cluster_explorer.application_id}" + client_application_id = "${azuread_application.cluster_console.application_id}" + } + fabric_settings { - name = "Security" - + name = "Security" + parameters = { "ClusterProtectionLevel" = "EncryptAndSign" } - } - + } + node_type { - name = "first" + name = "system" instance_count = 3 is_primary = true - client_endpoint_port = 2020 - http_endpoint_port = 80 + client_endpoint_port = 19000 + http_endpoint_port = 19080 + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMServiceFabricCluster_azureActiveDirectoryDelete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_service_fabric_cluster" "test" { + name = "acctest-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + reliability_level = "Bronze" + upgrade_mode = "Automatic" + vm_image = "Windows" + management_endpoint = "https://example:19080" + + certificate { + thumbprint = "33:41:DB:6C:F2:AF:72:C6:11:DF:3B:E3:72:1A:65:3A:F1:D4:3E:CD:50:F5:84:F8:28:79:3D:BE:91:03:C3:EE" + x509_store_name = "My" + } + + fabric_settings { + name = "Security" + + parameters = { + "ClusterProtectionLevel" = "EncryptAndSign" + } + } + + node_type { + name = "system" + instance_count = 3 + is_primary = true + client_endpoint_port = 19000 + http_endpoint_port = 19080 } } `, rInt, location, rInt) @@ -1091,16 +1424,51 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "http://example:80" - + management_endpoint = "http://example:80" + diagnostics_config { storage_account_name = "${azurerm_storage_account.test.name}" protected_account_key_name = "StorageAccountKey1" blob_endpoint = "${azurerm_storage_account.test.primary_blob_endpoint}" queue_endpoint = "${azurerm_storage_account.test.primary_queue_endpoint}" table_endpoint = "${azurerm_storage_account.test.primary_table_endpoint}" - } - + } + + node_type { + name = "first" + instance_count = 3 + is_primary = true + client_endpoint_port = 2020 + http_endpoint_port = 80 + } +} +`, rInt, location, rString, rInt) +} + +func testAccAzureRMServiceFabricCluster_diagnosticsConfigDelete(rInt int, rString, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "GRS" +} + +resource "azurerm_service_fabric_cluster" "test" { + name = "acctest-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + reliability_level = "Bronze" + upgrade_mode = "Automatic" + vm_image = "Windows" + management_endpoint = "http://example:80" + node_type { name = "first" instance_count = 3 @@ -1126,16 +1494,16 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "http://example:80" - + management_endpoint = "http://example:80" + fabric_settings { - name = "Security" - + name = "Security" + parameters = { "ClusterProtectionLevel" = "None" } - } - + } + node_type { name = "first" instance_count = 3 @@ -1161,20 +1529,20 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "http://example:80" - + management_endpoint = "http://example:80" + node_type { name = "first" instance_count = 3 is_primary = true client_endpoint_port = 2020 - http_endpoint_port = 80 - + http_endpoint_port = 80 + application_ports { start_port = 20000 end_port = 29999 - } - + } + ephemeral_ports { start_port = 30000 end_port = 39999 @@ -1198,16 +1566,16 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "http://example:80" - + management_endpoint = "http://example:80" + node_type { name = "first" instance_count = 3 is_primary = true client_endpoint_port = 2020 http_endpoint_port = 80 - } - + } + node_type { name = "second" instance_count = 4 @@ -1225,6 +1593,7 @@ resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } + resource "azurerm_service_fabric_cluster" "test" { name = "acctest-%d" resource_group_name = "${azurerm_resource_group.test.name}" @@ -1233,22 +1602,27 @@ resource "azurerm_service_fabric_cluster" "test" { upgrade_mode = "Automatic" vm_image = "Windows" management_endpoint = "http://example:80" + node_type { - name = "first" - placement_properties = { - "HasSSD" = "true" - } - capacities = { - "ClientConnections" = "20000" - "MemoryGB" = "8" - } + name = "first" + + placement_properties = { + "HasSSD" = "true" + } + + capacities = { + "ClientConnections" = "20000" + "MemoryGB" = "8" + } + instance_count = 3 is_primary = true client_endpoint_port = 2020 - http_endpoint_port = 80 + http_endpoint_port = 80 } + tags = { - "Hello" = "World" + Hello = "World" } } `, rInt, location, rInt) @@ -1268,18 +1642,18 @@ resource "azurerm_service_fabric_cluster" "test" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "http://example:80" - + management_endpoint = "http://example:80" + node_type { name = "first" instance_count = 3 is_primary = true client_endpoint_port = 2020 http_endpoint_port = 80 - } - + } + tags = { - "Hello" = "World" + Hello = "World" } } `, rInt, location, rInt) diff --git a/azurerm/resource_arm_servicebus_namespace.go b/azurerm/resource_arm_servicebus_namespace.go index 8a71454fdf9d..9915d1f0d29f 100644 --- a/azurerm/resource_arm_servicebus_namespace.go +++ b/azurerm/resource_arm_servicebus_namespace.go @@ -6,7 +6,11 @@ import ( "regexp" "strings" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/servicebus/mgmt/2017-04-01/servicebus" "github.com/hashicorp/terraform/helper/schema" @@ -45,9 +49,9 @@ func resourceArmServiceBusNamespace() *schema.Resource { ), }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeString, @@ -58,7 +62,7 @@ func resourceArmServiceBusNamespace() *schema.Resource { string(servicebus.Standard), string(servicebus.Premium), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "capacity": { @@ -92,24 +96,24 @@ func resourceArmServiceBusNamespace() *schema.Resource { Sensitive: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmServiceBusNamespaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusNamespacesClient + client := meta.(*ArmClient).servicebus.NamespacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM ServiceBus Namespace creation.") name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resourceGroup := d.Get("resource_group_name").(string) sku := d.Get("sku").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -128,7 +132,7 @@ func resourceArmServiceBusNamespaceCreateUpdate(d *schema.ResourceData, meta int Name: servicebus.SkuName(sku), Tier: servicebus.SkuTier(sku), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if capacity := d.Get("capacity"); capacity != nil { @@ -165,10 +169,10 @@ func resourceArmServiceBusNamespaceCreateUpdate(d *schema.ResourceData, meta int } func resourceArmServiceBusNamespaceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusNamespacesClient + client := meta.(*ArmClient).servicebus.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -187,7 +191,7 @@ func resourceArmServiceBusNamespaceRead(d *schema.ResourceData, meta interface{} d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if sku := resp.Sku; sku != nil { @@ -205,16 +209,14 @@ func resourceArmServiceBusNamespaceRead(d *schema.ResourceData, meta interface{} d.Set("default_secondary_key", keys.SecondaryKey) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmServiceBusNamespaceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusNamespacesClient + client := meta.(*ArmClient).servicebus.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_servicebus_namespace_authorization_rule.go b/azurerm/resource_arm_servicebus_namespace_authorization_rule.go index 5e581b4916d1..47e966c61dba 100644 --- a/azurerm/resource_arm_servicebus_namespace_authorization_rule.go +++ b/azurerm/resource_arm_servicebus_namespace_authorization_rule.go @@ -5,6 +5,7 @@ import ( "log" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/azure-sdk-for-go/services/servicebus/mgmt/2017-04-01/servicebus" "github.com/hashicorp/terraform/helper/schema" @@ -39,7 +40,7 @@ func resourceArmServiceBusNamespaceAuthorizationRule() *schema.Resource { ValidateFunc: azure.ValidateServiceBusNamespaceName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), }), CustomizeDiff: azure.ServiceBusAuthorizationRuleCustomizeDiff, @@ -47,7 +48,7 @@ func resourceArmServiceBusNamespaceAuthorizationRule() *schema.Resource { } func resourceArmServiceBusNamespaceAuthorizationRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusNamespacesClient + client := meta.(*ArmClient).servicebus.NamespacesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM ServiceBus Namespace Authorization Rule creation.") @@ -56,7 +57,7 @@ func resourceArmServiceBusNamespaceAuthorizationRuleCreateUpdate(d *schema.Resou resourceGroup := d.Get("resource_group_name").(string) namespaceName := d.Get("namespace_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.GetAuthorizationRule(ctx, resourceGroup, namespaceName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -95,10 +96,10 @@ func resourceArmServiceBusNamespaceAuthorizationRuleCreateUpdate(d *schema.Resou } func resourceArmServiceBusNamespaceAuthorizationRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusNamespacesClient + client := meta.(*ArmClient).servicebus.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -141,10 +142,10 @@ func resourceArmServiceBusNamespaceAuthorizationRuleRead(d *schema.ResourceData, } func resourceArmServiceBusNamespaceAuthorizationRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusNamespacesClient + client := meta.(*ArmClient).servicebus.NamespacesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_servicebus_namespace_authorization_rule_test.go b/azurerm/resource_arm_servicebus_namespace_authorization_rule_test.go index b6b0324430a0..8e96fc105189 100644 --- a/azurerm/resource_arm_servicebus_namespace_authorization_rule_test.go +++ b/azurerm/resource_arm_servicebus_namespace_authorization_rule_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -102,7 +103,7 @@ func TestAccAzureRMServiceBusNamespaceAuthorizationRule_rightsUpdate(t *testing. }) } func TestAccAzureRMServiceBusNamespaceAuthorizationRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -132,7 +133,7 @@ func TestAccAzureRMServiceBusNamespaceAuthorizationRule_requiresImport(t *testin } func testCheckAzureRMServiceBusNamespaceAuthorizationRuleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).serviceBusNamespacesClient + conn := testAccProvider.Meta().(*ArmClient).servicebus.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -170,7 +171,7 @@ func testCheckAzureRMServiceBusNamespaceAuthorizationRuleExists(resourceName str return fmt.Errorf("Bad: no resource group found in state for ServiceBus Namespace: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).serviceBusNamespacesClient + conn := testAccProvider.Meta().(*ArmClient).servicebus.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.GetAuthorizationRule(ctx, resourceGroup, namespaceName, name) if err != nil { diff --git a/azurerm/resource_arm_servicebus_namespace_test.go b/azurerm/resource_arm_servicebus_namespace_test.go index 8406213041c3..5e742410a14e 100644 --- a/azurerm/resource_arm_servicebus_namespace_test.go +++ b/azurerm/resource_arm_servicebus_namespace_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMServiceBusNamespace_basic(t *testing.T) { @@ -36,7 +37,7 @@ func TestAccAzureRMServiceBusNamespace_basic(t *testing.T) { }) } func TestAccAzureRMServiceBusNamespace_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -181,7 +182,7 @@ func TestAccAzureRMServiceBusNamespace_premiumCapacity(t *testing.T) { } func testCheckAzureRMServiceBusNamespaceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).serviceBusNamespacesClient + client := testAccProvider.Meta().(*ArmClient).servicebus.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -220,7 +221,7 @@ func testCheckAzureRMServiceBusNamespaceExists(resourceName string) resource.Tes return fmt.Errorf("Bad: no resource group found in state for Service Bus Namespace: %s", namespaceName) } - client := testAccProvider.Meta().(*ArmClient).serviceBusNamespacesClient + client := testAccProvider.Meta().(*ArmClient).servicebus.NamespacesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, namespaceName) diff --git a/azurerm/resource_arm_servicebus_queue.go b/azurerm/resource_arm_servicebus_queue.go index 30f9e23a358e..519d4a0c563e 100644 --- a/azurerm/resource_arm_servicebus_queue.go +++ b/azurerm/resource_arm_servicebus_queue.go @@ -9,6 +9,8 @@ import ( "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,29 +39,29 @@ func resourceArmServiceBusQueue() *schema.Resource { ValidateFunc: azure.ValidateServiceBusNamespaceName(), }, - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "auto_delete_on_idle": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "default_message_ttl": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "duplicate_detection_history_time_window": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "enable_express": { @@ -132,7 +134,7 @@ func resourceArmServiceBusQueue() *schema.Resource { } func resourceArmServiceBusQueueCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusQueuesClient + client := meta.(*ArmClient).servicebus.QueuesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM ServiceBus Queue creation/update.") @@ -148,7 +150,7 @@ func resourceArmServiceBusQueueCreateUpdate(d *schema.ResourceData, meta interfa requiresSession := d.Get("requires_session").(bool) deadLetteringOnMessageExpiration := d.Get("dead_lettering_on_message_expiration").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, namespaceName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -192,7 +194,7 @@ func resourceArmServiceBusQueueCreateUpdate(d *schema.ResourceData, meta interfa // We need to retrieve the namespace because Premium namespace works differently from Basic and Standard, // so it needs different rules applied to it. - namespacesClient := meta.(*ArmClient).serviceBusNamespacesClient + namespacesClient := meta.(*ArmClient).servicebus.NamespacesClient namespace, err := namespacesClient.Get(ctx, resourceGroup, namespaceName) if err != nil { return fmt.Errorf("Error retrieving ServiceBus Namespace %q (Resource Group %q): %+v", resourceGroup, namespaceName, err) @@ -222,10 +224,10 @@ func resourceArmServiceBusQueueCreateUpdate(d *schema.ResourceData, meta interfa } func resourceArmServiceBusQueueRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusQueuesClient + client := meta.(*ArmClient).servicebus.QueuesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -265,7 +267,7 @@ func resourceArmServiceBusQueueRead(d *schema.ResourceData, meta interface{}) er // If the queue is NOT in a premium namespace (ie. it is Basic or Standard) and partitioning is enabled // then the max size returned by the API will be 16 times greater than the value set. if *props.EnablePartitioning { - namespacesClient := meta.(*ArmClient).serviceBusNamespacesClient + namespacesClient := meta.(*ArmClient).servicebus.NamespacesClient namespace, err := namespacesClient.Get(ctx, resourceGroup, namespaceName) if err != nil { return err @@ -285,10 +287,10 @@ func resourceArmServiceBusQueueRead(d *schema.ResourceData, meta interface{}) er } func resourceArmServiceBusQueueDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusQueuesClient + client := meta.(*ArmClient).servicebus.QueuesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_servicebus_queue_authorization_rule.go b/azurerm/resource_arm_servicebus_queue_authorization_rule.go index b154f16ea2ae..d8501cdfcfe0 100644 --- a/azurerm/resource_arm_servicebus_queue_authorization_rule.go +++ b/azurerm/resource_arm_servicebus_queue_authorization_rule.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -44,7 +45,7 @@ func resourceArmServiceBusQueueAuthorizationRule() *schema.Resource { ValidateFunc: azure.ValidateServiceBusQueueName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), }), CustomizeDiff: azure.ServiceBusAuthorizationRuleCustomizeDiff, @@ -52,7 +53,7 @@ func resourceArmServiceBusQueueAuthorizationRule() *schema.Resource { } func resourceArmServiceBusQueueAuthorizationRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusQueuesClient + client := meta.(*ArmClient).servicebus.QueuesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM ServiceBus Queue Authorization Rule creation.") @@ -62,7 +63,7 @@ func resourceArmServiceBusQueueAuthorizationRuleCreateUpdate(d *schema.ResourceD namespaceName := d.Get("namespace_name").(string) queueName := d.Get("queue_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.GetAuthorizationRule(ctx, resourceGroup, namespaceName, queueName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -101,10 +102,10 @@ func resourceArmServiceBusQueueAuthorizationRuleCreateUpdate(d *schema.ResourceD } func resourceArmServiceBusQueueAuthorizationRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusQueuesClient + client := meta.(*ArmClient).servicebus.QueuesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -150,10 +151,10 @@ func resourceArmServiceBusQueueAuthorizationRuleRead(d *schema.ResourceData, met } func resourceArmServiceBusQueueAuthorizationRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusQueuesClient + client := meta.(*ArmClient).servicebus.QueuesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_servicebus_queue_authorization_rule_test.go b/azurerm/resource_arm_servicebus_queue_authorization_rule_test.go index bfe9b028994b..7bcf5358efdd 100644 --- a/azurerm/resource_arm_servicebus_queue_authorization_rule_test.go +++ b/azurerm/resource_arm_servicebus_queue_authorization_rule_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -102,7 +103,7 @@ func TestAccAzureRMServiceBusQueueAuthorizationRule_rightsUpdate(t *testing.T) { }) } func TestAccAzureRMServiceBusQueueAuthorizationRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -132,7 +133,7 @@ func TestAccAzureRMServiceBusQueueAuthorizationRule_requiresImport(t *testing.T) } func testCheckAzureRMServiceBusQueueAuthorizationRuleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).serviceBusQueuesClient + conn := testAccProvider.Meta().(*ArmClient).servicebus.QueuesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -172,7 +173,7 @@ func testCheckAzureRMServiceBusQueueAuthorizationRuleExists(resourceName string) return fmt.Errorf("Bad: no resource group found in state for ServiceBus Queue Authorization Rule: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).serviceBusQueuesClient + conn := testAccProvider.Meta().(*ArmClient).servicebus.QueuesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.GetAuthorizationRule(ctx, resourceGroup, namespaceName, queueName, name) diff --git a/azurerm/resource_arm_servicebus_queue_test.go b/azurerm/resource_arm_servicebus_queue_test.go index 4f4e17aba940..7c0359380c6b 100644 --- a/azurerm/resource_arm_servicebus_queue_test.go +++ b/azurerm/resource_arm_servicebus_queue_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMServiceBusQueue_basic(t *testing.T) { }) } func TestAccAzureRMServiceBusQueue_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -354,7 +355,7 @@ func TestAccAzureRMServiceBusQueue_maxDeliveryCount(t *testing.T) { } func testCheckAzureRMServiceBusQueueDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).serviceBusQueuesClient + client := testAccProvider.Meta().(*ArmClient).servicebus.QueuesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -397,7 +398,7 @@ func testCheckAzureRMServiceBusQueueExists(resourceName string) resource.TestChe return fmt.Errorf("Bad: no resource group found in state for queue: %s", queueName) } - client := testAccProvider.Meta().(*ArmClient).serviceBusQueuesClient + client := testAccProvider.Meta().(*ArmClient).servicebus.QueuesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, namespaceName, queueName) diff --git a/azurerm/resource_arm_servicebus_subscription.go b/azurerm/resource_arm_servicebus_subscription.go index 71c99e0e6b7a..ab20c9cd7c9d 100644 --- a/azurerm/resource_arm_servicebus_subscription.go +++ b/azurerm/resource_arm_servicebus_subscription.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -43,9 +44,9 @@ func resourceArmServiceBusSubscription() *schema.Resource { ValidateFunc: azure.ValidateServiceBusTopicName(), }, - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "auto_delete_on_idle": { Type: schema.TypeString, @@ -103,7 +104,7 @@ func resourceArmServiceBusSubscription() *schema.Resource { } func resourceArmServiceBusSubscriptionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusSubscriptionsClient + client := meta.(*ArmClient).servicebus.SubscriptionsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ARM ServiceBus Subscription creation.") @@ -117,7 +118,7 @@ func resourceArmServiceBusSubscriptionCreateUpdate(d *schema.ResourceData, meta maxDeliveryCount := int32(d.Get("max_delivery_count").(int)) requiresSession := d.Get("requires_session").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, namespaceName, topicName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -173,10 +174,10 @@ func resourceArmServiceBusSubscriptionCreateUpdate(d *schema.ResourceData, meta } func resourceArmServiceBusSubscriptionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusSubscriptionsClient + client := meta.(*ArmClient).servicebus.SubscriptionsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -217,10 +218,10 @@ func resourceArmServiceBusSubscriptionRead(d *schema.ResourceData, meta interfac } func resourceArmServiceBusSubscriptionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusSubscriptionsClient + client := meta.(*ArmClient).servicebus.SubscriptionsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_servicebus_subscription_rule.go b/azurerm/resource_arm_servicebus_subscription_rule.go index e1a3c83b317c..010c9d8c8486 100644 --- a/azurerm/resource_arm_servicebus_subscription_rule.go +++ b/azurerm/resource_arm_servicebus_subscription_rule.go @@ -9,7 +9,9 @@ import ( "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -31,7 +33,7 @@ func resourceArmServiceBusSubscriptionRule() *schema.Resource { ValidateFunc: validation.StringLenBetween(1, 50), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "namespace_name": { Type: schema.TypeString, @@ -61,7 +63,7 @@ func resourceArmServiceBusSubscriptionRule() *schema.Resource { string(servicebus.FilterTypeSQLFilter), string(servicebus.FilterTypeCorrelationFilter), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "action": { @@ -121,7 +123,7 @@ func resourceArmServiceBusSubscriptionRule() *schema.Resource { } func resourceArmServiceBusSubscriptionRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusSubscriptionRulesClient + client := meta.(*ArmClient).servicebus.SubscriptionRulesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure Service Bus Subscription Rule creation.") @@ -132,7 +134,7 @@ func resourceArmServiceBusSubscriptionRuleCreateUpdate(d *schema.ResourceData, m resourceGroup := d.Get("resource_group_name").(string) filterType := d.Get("filter_type").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, namespaceName, topicName, subscriptionName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -191,10 +193,10 @@ func resourceArmServiceBusSubscriptionRuleCreateUpdate(d *schema.ResourceData, m } func resourceArmServiceBusSubscriptionRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusSubscriptionRulesClient + client := meta.(*ArmClient).servicebus.SubscriptionRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -240,10 +242,10 @@ func resourceArmServiceBusSubscriptionRuleRead(d *schema.ResourceData, meta inte } func resourceArmServiceBusSubscriptionRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusSubscriptionRulesClient + client := meta.(*ArmClient).servicebus.SubscriptionRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_servicebus_subscription_rule_test.go b/azurerm/resource_arm_servicebus_subscription_rule_test.go index 6ef35206df5c..617d346ade5b 100644 --- a/azurerm/resource_arm_servicebus_subscription_rule_test.go +++ b/azurerm/resource_arm_servicebus_subscription_rule_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -29,7 +30,7 @@ func TestAccAzureRMServiceBusSubscriptionRule_basicSqlFilter(t *testing.T) { }) } func TestAccAzureRMServiceBusSubscriptionRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -218,7 +219,7 @@ func testCheckAzureRMServiceBusSubscriptionRuleExists(resourceName string) resou return fmt.Errorf("Bad: no resource group found in state for Subscription Rule: %q", ruleName) } - client := testAccProvider.Meta().(*ArmClient).serviceBusSubscriptionRulesClient + client := testAccProvider.Meta().(*ArmClient).servicebus.SubscriptionRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, namespaceName, topicName, subscriptionName, ruleName) diff --git a/azurerm/resource_arm_servicebus_subscription_test.go b/azurerm/resource_arm_servicebus_subscription_test.go index 414b4ea7ce2e..da9a6c3f489c 100644 --- a/azurerm/resource_arm_servicebus_subscription_test.go +++ b/azurerm/resource_arm_servicebus_subscription_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMServiceBusSubscription_basic(t *testing.T) { } func TestAccAzureRMServiceBusSubscription_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -190,7 +191,7 @@ func TestAccAzureRMServiceBusSubscription_updateForwardTo(t *testing.T) { } func testCheckAzureRMServiceBusSubscriptionDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).serviceBusSubscriptionsClient + client := testAccProvider.Meta().(*ArmClient).servicebus.SubscriptionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -235,7 +236,7 @@ func testCheckAzureRMServiceBusSubscriptionExists(resourceName string) resource. return fmt.Errorf("Bad: no resource group found in state for subscription: %q", topicName) } - client := testAccProvider.Meta().(*ArmClient).serviceBusSubscriptionsClient + client := testAccProvider.Meta().(*ArmClient).servicebus.SubscriptionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, namespaceName, topicName, subscriptionName) diff --git a/azurerm/resource_arm_servicebus_topic.go b/azurerm/resource_arm_servicebus_topic.go index e3e8ddde1f60..245c551b04f8 100644 --- a/azurerm/resource_arm_servicebus_topic.go +++ b/azurerm/resource_arm_servicebus_topic.go @@ -8,7 +8,10 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,9 +41,9 @@ func resourceArmServiceBusTopic() *schema.Resource { ValidateFunc: azure.ValidateServiceBusNamespaceName(), }, - "location": deprecatedLocationSchema(), + "location": azure.SchemaLocationDeprecated(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "status": { Type: schema.TypeString, @@ -50,28 +53,28 @@ func resourceArmServiceBusTopic() *schema.Resource { string(servicebus.Active), string(servicebus.Disabled), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "auto_delete_on_idle": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "default_message_ttl": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "duplicate_detection_history_time_window": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateIso8601Duration(), + ValidateFunc: validate.ISO8601Duration, }, "enable_batched_operations": { @@ -118,7 +121,7 @@ func resourceArmServiceBusTopic() *schema.Resource { } func resourceArmServiceBusTopicCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusTopicsClient + client := meta.(*ArmClient).servicebus.TopicsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Azure ServiceBus Topic creation.") @@ -134,7 +137,7 @@ func resourceArmServiceBusTopicCreateUpdate(d *schema.ResourceData, meta interfa requiresDuplicateDetection := d.Get("requires_duplicate_detection").(bool) supportOrdering := d.Get("support_ordering").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, namespaceName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -190,10 +193,10 @@ func resourceArmServiceBusTopicCreateUpdate(d *schema.ResourceData, meta interfa } func resourceArmServiceBusTopicRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusTopicsClient + client := meta.(*ArmClient).servicebus.TopicsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -235,7 +238,7 @@ func resourceArmServiceBusTopicRead(d *schema.ResourceData, meta interface{}) er // if the topic is in a premium namespace and partitioning is enabled then the // max size returned by the API will be 16 times greater than the value set if partitioning := props.EnablePartitioning; partitioning != nil && *partitioning { - namespacesClient := meta.(*ArmClient).serviceBusNamespacesClient + namespacesClient := meta.(*ArmClient).servicebus.NamespacesClient namespace, err := namespacesClient.Get(ctx, resourceGroup, namespaceName) if err != nil { return err @@ -255,10 +258,10 @@ func resourceArmServiceBusTopicRead(d *schema.ResourceData, meta interface{}) er } func resourceArmServiceBusTopicDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusTopicsClient + client := meta.(*ArmClient).servicebus.TopicsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_servicebus_topic_authorization_rule.go b/azurerm/resource_arm_servicebus_topic_authorization_rule.go index 6e42f9ba6cbe..946d87f5c9a3 100644 --- a/azurerm/resource_arm_servicebus_topic_authorization_rule.go +++ b/azurerm/resource_arm_servicebus_topic_authorization_rule.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -45,7 +46,7 @@ func resourceArmServiceBusTopicAuthorizationRule() *schema.Resource { ValidateFunc: azure.ValidateServiceBusTopicName(), }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), }), CustomizeDiff: azure.ServiceBusAuthorizationRuleCustomizeDiff, @@ -53,7 +54,7 @@ func resourceArmServiceBusTopicAuthorizationRule() *schema.Resource { } func resourceArmServiceBusTopicAuthorizationRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusTopicsClient + client := meta.(*ArmClient).servicebus.TopicsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM ServiceBus Topic Authorization Rule creation.") @@ -62,7 +63,7 @@ func resourceArmServiceBusTopicAuthorizationRuleCreateUpdate(d *schema.ResourceD topicName := d.Get("topic_name").(string) resourceGroup := d.Get("resource_group_name").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.GetAuthorizationRule(ctx, resourceGroup, namespaceName, topicName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -101,10 +102,10 @@ func resourceArmServiceBusTopicAuthorizationRuleCreateUpdate(d *schema.ResourceD } func resourceArmServiceBusTopicAuthorizationRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusTopicsClient + client := meta.(*ArmClient).servicebus.TopicsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -149,10 +150,10 @@ func resourceArmServiceBusTopicAuthorizationRuleRead(d *schema.ResourceData, met } func resourceArmServiceBusTopicAuthorizationRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).serviceBusTopicsClient + client := meta.(*ArmClient).servicebus.TopicsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_servicebus_topic_authorization_rule_test.go b/azurerm/resource_arm_servicebus_topic_authorization_rule_test.go index 15b73ec7f860..21a72e3cdd48 100644 --- a/azurerm/resource_arm_servicebus_topic_authorization_rule_test.go +++ b/azurerm/resource_arm_servicebus_topic_authorization_rule_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -60,7 +61,7 @@ func testAccAzureRMServiceBusTopicAuthorizationRule(t *testing.T, listen, send, } func TestAccAzureRMServiceBusTopicAuthorizationRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -132,7 +133,7 @@ func TestAccAzureRMServiceBusTopicAuthorizationRule_rightsUpdate(t *testing.T) { } func testCheckAzureRMServiceBusTopicAuthorizationRuleDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).serviceBusTopicsClient + conn := testAccProvider.Meta().(*ArmClient).servicebus.TopicsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -172,7 +173,7 @@ func testCheckAzureRMServiceBusTopicAuthorizationRuleExists(resourceName string) return fmt.Errorf("Bad: no resource group found in state for ServiceBus Topic: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).serviceBusTopicsClient + conn := testAccProvider.Meta().(*ArmClient).servicebus.TopicsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.GetAuthorizationRule(ctx, resourceGroup, namespaceName, topicName, name) if err != nil { diff --git a/azurerm/resource_arm_servicebus_topic_test.go b/azurerm/resource_arm_servicebus_topic_test.go index 3d57e3dfc2e3..81dc6f0f4d6c 100644 --- a/azurerm/resource_arm_servicebus_topic_test.go +++ b/azurerm/resource_arm_servicebus_topic_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +36,7 @@ func TestAccAzureRMServiceBusTopic_basic(t *testing.T) { }) } func TestAccAzureRMServiceBusTopic_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -280,7 +281,7 @@ func TestAccAzureRMServiceBusTopic_isoTimeSpanAttributes(t *testing.T) { } func testCheckAzureRMServiceBusTopicDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).serviceBusTopicsClient + client := testAccProvider.Meta().(*ArmClient).servicebus.TopicsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -323,7 +324,7 @@ func testCheckAzureRMServiceBusTopicExists(resourceName string) resource.TestChe return fmt.Errorf("Bad: no resource group found in state for topic: %s", topicName) } - client := testAccProvider.Meta().(*ArmClient).serviceBusTopicsClient + client := testAccProvider.Meta().(*ArmClient).servicebus.TopicsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, namespaceName, topicName) diff --git a/azurerm/resource_arm_shared_image.go b/azurerm/resource_arm_shared_image.go index 460fdedf811b..3cd9cf909777 100644 --- a/azurerm/resource_arm_shared_image.go +++ b/azurerm/resource_arm_shared_image.go @@ -7,9 +7,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -38,9 +41,9 @@ func resourceArmSharedImage() *schema.Resource { ValidateFunc: validate.SharedImageGalleryName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "os_type": { Type: schema.TypeString, @@ -93,13 +96,13 @@ func resourceArmSharedImage() *schema.Resource { Optional: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmSharedImageCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleryImagesClient + client := meta.(*ArmClient).compute.GalleryImagesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Shared Image creation.") @@ -107,7 +110,7 @@ func resourceArmSharedImageCreateUpdate(d *schema.ResourceData, meta interface{} name := d.Get("name").(string) galleryName := d.Get("gallery_name").(string) resourceGroup := d.Get("resource_group_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) description := d.Get("description").(string) eula := d.Get("eula").(string) @@ -115,9 +118,9 @@ func resourceArmSharedImageCreateUpdate(d *schema.ResourceData, meta interface{} releaseNoteURI := d.Get("release_note_uri").(string) osType := d.Get("os_type").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, galleryName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -143,7 +146,7 @@ func resourceArmSharedImageCreateUpdate(d *schema.ResourceData, meta interface{} OsType: compute.OperatingSystemTypes(osType), OsState: compute.Generalized, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resourceGroup, galleryName, name, image) @@ -170,10 +173,10 @@ func resourceArmSharedImageCreateUpdate(d *schema.ResourceData, meta interface{} } func resourceArmSharedImageRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleryImagesClient + client := meta.(*ArmClient).compute.GalleryImagesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -197,7 +200,7 @@ func resourceArmSharedImageRead(d *schema.ResourceData, meta interface{}) error d.Set("gallery_name", galleryName) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.GalleryImageProperties; props != nil { @@ -213,16 +216,14 @@ func resourceArmSharedImageRead(d *schema.ResourceData, meta interface{}) error } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSharedImageDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleryImagesClient + client := meta.(*ArmClient).compute.GalleryImagesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_shared_image_gallery.go b/azurerm/resource_arm_shared_image_gallery.go index a0c18f622134..7d86a849a378 100644 --- a/azurerm/resource_arm_shared_image_gallery.go +++ b/azurerm/resource_arm_shared_image_gallery.go @@ -6,9 +6,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,16 +33,16 @@ func resourceArmSharedImageGallery() *schema.Resource { ValidateFunc: validate.SharedImageGalleryName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "description": { Type: schema.TypeString, Optional: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), "unique_name": { Type: schema.TypeString, @@ -50,7 +53,7 @@ func resourceArmSharedImageGallery() *schema.Resource { } func resourceArmSharedImageGalleryCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleriesClient + client := meta.(*ArmClient).compute.GalleriesClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for Image Gallery creation.") @@ -58,11 +61,11 @@ func resourceArmSharedImageGalleryCreateUpdate(d *schema.ResourceData, meta inte // TODO: support for Timeouts/Requiring Import name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) description := d.Get("description").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -80,7 +83,7 @@ func resourceArmSharedImageGalleryCreateUpdate(d *schema.ResourceData, meta inte GalleryProperties: &compute.GalleryProperties{ Description: utils.String(description), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resourceGroup, name, gallery) @@ -107,10 +110,10 @@ func resourceArmSharedImageGalleryCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmSharedImageGalleryRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleriesClient + client := meta.(*ArmClient).compute.GalleriesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -132,7 +135,7 @@ func resourceArmSharedImageGalleryRead(d *schema.ResourceData, meta interface{}) d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.GalleryProperties; props != nil { @@ -142,16 +145,14 @@ func resourceArmSharedImageGalleryRead(d *schema.ResourceData, meta interface{}) } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSharedImageGalleryDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleriesClient + client := meta.(*ArmClient).compute.GalleriesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_shared_image_gallery_test.go b/azurerm/resource_arm_shared_image_gallery_test.go index b0b07d2c067d..5819877553a7 100644 --- a/azurerm/resource_arm_shared_image_gallery_test.go +++ b/azurerm/resource_arm_shared_image_gallery_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -37,7 +38,7 @@ func TestAccAzureRMSharedImageGallery_basic(t *testing.T) { }) } func TestAccAzureRMSharedImageGallery_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -93,7 +94,7 @@ func TestAccAzureRMSharedImageGallery_complete(t *testing.T) { } func testCheckAzureRMSharedImageGalleryDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).galleriesClient + client := testAccProvider.Meta().(*ArmClient).compute.GalleriesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -134,7 +135,7 @@ func testCheckAzureRMSharedImageGalleryExists(resourceName string) resource.Test return fmt.Errorf("Bad: no resource group found in state for Shared Image Gallery: %s", galleryName) } - client := testAccProvider.Meta().(*ArmClient).galleriesClient + client := testAccProvider.Meta().(*ArmClient).compute.GalleriesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, galleryName) diff --git a/azurerm/resource_arm_shared_image_test.go b/azurerm/resource_arm_shared_image_test.go index 50e44af12ce9..7a18f6b874fd 100644 --- a/azurerm/resource_arm_shared_image_test.go +++ b/azurerm/resource_arm_shared_image_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMSharedImage_basic(t *testing.T) { }) } func TestAccAzureRMSharedImage_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -95,7 +96,7 @@ func TestAccAzureRMSharedImage_complete(t *testing.T) { } func testCheckAzureRMSharedImageDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).galleryImagesClient + client := testAccProvider.Meta().(*ArmClient).compute.GalleryImagesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -138,7 +139,7 @@ func testCheckAzureRMSharedImageExists(resourceName string) resource.TestCheckFu return fmt.Errorf("Bad: no resource group found in state for Shared Image: %s", imageName) } - client := testAccProvider.Meta().(*ArmClient).galleryImagesClient + client := testAccProvider.Meta().(*ArmClient).compute.GalleryImagesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, galleryName, imageName) diff --git a/azurerm/resource_arm_shared_image_version.go b/azurerm/resource_arm_shared_image_version.go index 416330107678..023ebe9e0cbd 100644 --- a/azurerm/resource_arm_shared_image_version.go +++ b/azurerm/resource_arm_shared_image_version.go @@ -6,9 +6,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -44,9 +47,9 @@ func resourceArmSharedImageVersion() *schema.Resource { ValidateFunc: validate.SharedImageName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "managed_image_id": { Type: schema.TypeString, @@ -62,8 +65,8 @@ func resourceArmSharedImageVersion() *schema.Resource { "name": { Type: schema.TypeString, Required: true, - StateFunc: azureRMNormalizeLocation, - DiffSuppressFunc: azureRMSuppressLocationDiff, + StateFunc: azure.NormalizeLocation, + DiffSuppressFunc: azure.SuppressLocationDiff, }, "regional_replica_count": { @@ -80,24 +83,24 @@ func resourceArmSharedImageVersion() *schema.Resource { Default: false, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmSharedImageVersionCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleryImageVersionsClient + client := meta.(*ArmClient).compute.GalleryImageVersionsClient ctx := meta.(*ArmClient).StopContext imageVersion := d.Get("name").(string) imageName := d.Get("image_name").(string) galleryName := d.Get("gallery_name").(string) resourceGroup := d.Get("resource_group_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) managedImageId := d.Get("managed_image_id").(string) excludeFromLatest := d.Get("exclude_from_latest").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, galleryName, imageName, imageVersion, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -111,7 +114,7 @@ func resourceArmSharedImageVersionCreateUpdate(d *schema.ResourceData, meta inte } targetRegions := expandSharedImageVersionTargetRegions(d) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) version := compute.GalleryImageVersion{ Location: utils.String(location), @@ -126,7 +129,7 @@ func resourceArmSharedImageVersionCreateUpdate(d *schema.ResourceData, meta inte }, }, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resourceGroup, galleryName, imageName, imageVersion, version) @@ -151,10 +154,10 @@ func resourceArmSharedImageVersionCreateUpdate(d *schema.ResourceData, meta inte } func resourceArmSharedImageVersionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleryImageVersionsClient + client := meta.(*ArmClient).compute.GalleryImageVersionsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -180,7 +183,7 @@ func resourceArmSharedImageVersionRead(d *schema.ResourceData, meta interface{}) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.GalleryImageVersionProperties; props != nil { @@ -200,16 +203,14 @@ func resourceArmSharedImageVersionRead(d *schema.ResourceData, meta interface{}) } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSharedImageVersionDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).galleryImageVersionsClient + client := meta.(*ArmClient).compute.GalleryImageVersionsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -264,7 +265,7 @@ func flattenSharedImageVersionTargetRegions(input *[]compute.TargetRegion) []int output := make(map[string]interface{}) if v.Name != nil { - output["name"] = azureRMNormalizeLocation(*v.Name) + output["name"] = azure.NormalizeLocation(*v.Name) } if v.RegionalReplicaCount != nil { diff --git a/azurerm/resource_arm_shared_image_version_test.go b/azurerm/resource_arm_shared_image_version_test.go index 6d577cfef795..b765b74050e6 100644 --- a/azurerm/resource_arm_shared_image_version_test.go +++ b/azurerm/resource_arm_shared_image_version_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -61,7 +62,7 @@ func TestAccAzureRMSharedImageVersion_basic(t *testing.T) { }) } func TestAccAzureRMSharedImageVersion_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -105,7 +106,7 @@ func TestAccAzureRMSharedImageVersion_requiresImport(t *testing.T) { } func testCheckAzureRMSharedImageVersionDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).galleryImageVersionsClient + client := testAccProvider.Meta().(*ArmClient).compute.GalleryImageVersionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -149,7 +150,7 @@ func testCheckAzureRMSharedImageVersionExists(resourceName string) resource.Test return fmt.Errorf("Bad: no resource group found in state for Shared Image Version: %s", imageName) } - client := testAccProvider.Meta().(*ArmClient).galleryImageVersionsClient + client := testAccProvider.Meta().(*ArmClient).compute.GalleryImageVersionsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, galleryName, imageName, imageVersion, "") @@ -166,11 +167,11 @@ func testCheckAzureRMSharedImageVersionExists(resourceName string) resource.Test } func testAccAzureRMSharedImageVersion_setup(rInt int, location, username, password, hostname string) string { - return testAccAzureRMImage_standaloneImage_setup(rInt, username, password, hostname, location) + return testAccAzureRMImage_standaloneImage_setup(rInt, username, password, hostname, location, "LRS") } func testAccAzureRMSharedImageVersion_provision(rInt int, location, username, password, hostname string) string { - template := testAccAzureRMImage_standaloneImage_provision(rInt, username, password, hostname, location) + template := testAccAzureRMImage_standaloneImage_provision(rInt, username, password, hostname, location, "LRS") return fmt.Sprintf(` %s diff --git a/azurerm/resource_arm_signalr_service.go b/azurerm/resource_arm_signalr_service.go index d5276f4e7f44..99be92468490 100644 --- a/azurerm/resource_arm_signalr_service.go +++ b/azurerm/resource_arm_signalr_service.go @@ -7,9 +7,12 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/signalr/mgmt/2018-03-01-preview/signalr" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,9 +35,9 @@ func resourceArmSignalRService() *schema.Resource { ValidateFunc: validation.NoZeroValues, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "sku": { Type: schema.TypeList, @@ -104,24 +107,24 @@ func resourceArmSignalRService() *schema.Resource { Sensitive: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmSignalRServiceCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).signalRClient + client := meta.(*ArmClient).signalr.Client ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resourceGroup := d.Get("resource_group_name").(string) sku := d.Get("sku").([]interface{}) - tags := d.Get("tags").(map[string]interface{}) - expandedTags := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + expandedTags := tags.Expand(t) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -161,10 +164,10 @@ func resourceArmSignalRServiceCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmSignalRServiceRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).signalRClient + client := meta.(*ArmClient).signalr.Client ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -189,7 +192,7 @@ func resourceArmSignalRServiceRead(d *schema.ResourceData, meta interface{}) err d.Set("name", name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if err = d.Set("sku", flattenSignalRServiceSku(resp.Sku)); err != nil { @@ -208,16 +211,14 @@ func resourceArmSignalRServiceRead(d *schema.ResourceData, meta interface{}) err d.Set("secondary_access_key", keys.SecondaryKey) d.Set("secondary_connection_string", keys.SecondaryConnectionString) - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSignalRServiceDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).signalRClient + client := meta.(*ArmClient).signalr.Client ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_signalr_service_test.go b/azurerm/resource_arm_signalr_service_test.go index 70d28700d354..628914a3cd21 100644 --- a/azurerm/resource_arm_signalr_service_test.go +++ b/azurerm/resource_arm_signalr_service_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMSignalRService_basic(t *testing.T) { @@ -44,7 +45,7 @@ func TestAccAzureRMSignalRService_basic(t *testing.T) { }) } func TestAccAzureRMSignalRService_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -398,7 +399,7 @@ resource "azurerm_signalr_service" "test" { } func testCheckAzureRMSignalRServiceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).signalRClient + conn := testAccProvider.Meta().(*ArmClient).signalr.Client ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_signalr_service" { @@ -433,7 +434,7 @@ func testCheckAzureRMSignalRServiceExists(resourceName string) resource.TestChec return fmt.Errorf("Bad: no resource group found in state for SignalR service: %s", name) } - conn := testAccProvider.Meta().(*ArmClient).signalRClient + conn := testAccProvider.Meta().(*ArmClient).signalr.Client ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, name) diff --git a/azurerm/resource_arm_snapshot.go b/azurerm/resource_arm_snapshot.go index 99eb68e0e59b..cf9a502fcb11 100644 --- a/azurerm/resource_arm_snapshot.go +++ b/azurerm/resource_arm_snapshot.go @@ -8,7 +8,11 @@ import ( "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -30,9 +34,9 @@ func resourceArmSnapshot() *schema.Resource { ValidateFunc: validateSnapshotName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "create_option": { Type: schema.TypeString, @@ -41,7 +45,7 @@ func resourceArmSnapshot() *schema.Resource { string(compute.Copy), string(compute.Import), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "source_uri": { @@ -70,22 +74,22 @@ func resourceArmSnapshot() *schema.Resource { "encryption_settings": encryptionSettingsSchema(), - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmSnapshotCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).snapshotsClient + client := meta.(*ArmClient).compute.SnapshotsClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) createOption := d.Get("create_option").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -105,7 +109,7 @@ func resourceArmSnapshotCreateUpdate(d *schema.ResourceData, meta interface{}) e CreateOption: compute.DiskCreateOption(createOption), }, }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if v, ok := d.GetOk("source_uri"); ok { @@ -151,10 +155,10 @@ func resourceArmSnapshotCreateUpdate(d *schema.ResourceData, meta interface{}) e } func resourceArmSnapshotRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).snapshotsClient + client := meta.(*ArmClient).compute.SnapshotsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -176,7 +180,7 @@ func resourceArmSnapshotRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if props := resp.SnapshotProperties; props != nil { @@ -198,16 +202,14 @@ func resourceArmSnapshotRead(d *schema.ResourceData, meta interface{}) error { } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSnapshotDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).snapshotsClient + client := meta.(*ArmClient).compute.SnapshotsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_snapshot_test.go b/azurerm/resource_arm_snapshot_test.go index 0ede0ed26da3..67a1a116954b 100644 --- a/azurerm/resource_arm_snapshot_test.go +++ b/azurerm/resource_arm_snapshot_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -84,7 +85,7 @@ func TestAccAzureRMSnapshot_fromManagedDisk(t *testing.T) { }) } func TestAccAzureRMSnapshot_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -234,7 +235,7 @@ func testCheckAzureRMSnapshotDestroy(s *terraform.State) error { name := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - client := testAccProvider.Meta().(*ArmClient).snapshotsClient + client := testAccProvider.Meta().(*ArmClient).compute.SnapshotsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) if err != nil { @@ -264,7 +265,7 @@ func testCheckAzureRMSnapshotExists(resourceName string) resource.TestCheckFunc return fmt.Errorf("Bad: no resource group found in state for Snapshot: %q", name) } - client := testAccProvider.Meta().(*ArmClient).snapshotsClient + client := testAccProvider.Meta().(*ArmClient).compute.SnapshotsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, name) @@ -344,7 +345,7 @@ resource "azurerm_snapshot" "test" { source_uri = "${azurerm_managed_disk.test.id}" tags = { - "Hello" = "World" + Hello = "World" } } `, rInt, location, rInt, rInt) diff --git a/azurerm/resource_arm_sql_administrator.go b/azurerm/resource_arm_sql_administrator.go index 08172e75e328..2ed4d73a8ad5 100644 --- a/azurerm/resource_arm_sql_administrator.go +++ b/azurerm/resource_arm_sql_administrator.go @@ -7,7 +7,10 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" "github.com/hashicorp/terraform/helper/schema" uuid "github.com/satori/go.uuid" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -28,7 +31,7 @@ func resourceArmSqlAdministrator() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "login": { Type: schema.TypeString, @@ -38,20 +41,20 @@ func resourceArmSqlAdministrator() *schema.Resource { "object_id": { Type: schema.TypeString, Required: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, "tenant_id": { Type: schema.TypeString, Required: true, - ValidateFunc: validateUUID, + ValidateFunc: validate.UUID, }, }, } } func resourceArmSqlActiveDirectoryAdministratorCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlServerAzureADAdministratorsClient + client := meta.(*ArmClient).sql.ServerAzureADAdministratorsClient ctx := meta.(*ArmClient).StopContext serverName := d.Get("server_name").(string) @@ -60,7 +63,7 @@ func resourceArmSqlActiveDirectoryAdministratorCreateUpdate(d *schema.ResourceDa objectId := uuid.FromStringOrNil(d.Get("object_id").(string)) tenantId := uuid.FromStringOrNil(d.Get("tenant_id").(string)) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, serverName) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -102,10 +105,10 @@ func resourceArmSqlActiveDirectoryAdministratorCreateUpdate(d *schema.ResourceDa } func resourceArmSqlActiveDirectoryAdministratorRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlServerAzureADAdministratorsClient + client := meta.(*ArmClient).sql.ServerAzureADAdministratorsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -134,10 +137,10 @@ func resourceArmSqlActiveDirectoryAdministratorRead(d *schema.ResourceData, meta } func resourceArmSqlActiveDirectoryAdministratorDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlServerAzureADAdministratorsClient + client := meta.(*ArmClient).sql.ServerAzureADAdministratorsClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_sql_administrator_test.go b/azurerm/resource_arm_sql_administrator_test.go index 9ee58735a84f..768e35951d02 100644 --- a/azurerm/resource_arm_sql_administrator_test.go +++ b/azurerm/resource_arm_sql_administrator_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -42,7 +43,7 @@ func TestAccAzureRMSqlAdministrator_basic(t *testing.T) { }) } func TestAccAzureRMSqlAdministrator_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -101,7 +102,7 @@ func testCheckAzureRMSqlAdministratorExists(resourceName string) resource.TestCh resourceGroup := rs.Primary.Attributes["resource_group_name"] serverName := rs.Primary.Attributes["server_name"] - client := testAccProvider.Meta().(*ArmClient).sqlServerAzureADAdministratorsClient + client := testAccProvider.Meta().(*ArmClient).sql.ServerAzureADAdministratorsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext _, err := client.Get(ctx, resourceGroup, serverName) @@ -119,7 +120,7 @@ func testCheckAzureRMSqlAdministratorDisappears(resourceName string) resource.Te resourceGroup := rs.Primary.Attributes["resource_group_name"] serverName := rs.Primary.Attributes["server_name"] - client := testAccProvider.Meta().(*ArmClient).sqlServerAzureADAdministratorsClient + client := testAccProvider.Meta().(*ArmClient).sql.ServerAzureADAdministratorsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext if _, err := client.Delete(ctx, resourceGroup, serverName); err != nil { @@ -139,7 +140,7 @@ func testCheckAzureRMSqlAdministratorDestroy(s *terraform.State) error { resourceGroup := rs.Primary.Attributes["resource_group_name"] serverName := rs.Primary.Attributes["server_name"] - client := testAccProvider.Meta().(*ArmClient).sqlServerAzureADAdministratorsClient + client := testAccProvider.Meta().(*ArmClient).sql.ServerAzureADAdministratorsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName) diff --git a/azurerm/resource_arm_sql_database.go b/azurerm/resource_arm_sql_database.go index 2786d9adae54..05002eace981 100644 --- a/azurerm/resource_arm_sql_database.go +++ b/azurerm/resource_arm_sql_database.go @@ -6,9 +6,11 @@ import ( "strings" "time" - "github.com/satori/go.uuid" + uuid "github.com/satori/go.uuid" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" "github.com/Azure/go-autorest/autorest/date" @@ -38,9 +40,9 @@ func resourceArmSqlDatabase() *schema.Resource { ValidateFunc: azure.ValidateMsSqlDatabaseName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -141,17 +143,28 @@ func resourceArmSqlDatabase() *schema.Resource { DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ string(sql.Basic), - string(sql.Standard), - string(sql.Premium), + string(sql.Business), + string(sql.BusinessCritical), string(sql.DataWarehouse), + string(sql.Free), + string(sql.GeneralPurpose), + string(sql.Hyperscale), + string(sql.Premium), + string(sql.PremiumRS), + string(sql.Standard), + string(sql.Stretch), + string(sql.System), + string(sql.System2), + string(sql.Web), }, true), }, "collation": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, + Type: schema.TypeString, + DiffSuppressFunc: suppress.CaseDifference, + Optional: true, + Computed: true, + ForceNew: true, }, "max_size_bytes": { @@ -291,7 +304,13 @@ func resourceArmSqlDatabase() *schema.Resource { }, }, - "tags": tagsSchema(), + "read_scale": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "tags": tags.Schema(), }, CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error { @@ -316,17 +335,17 @@ func resourceArmSqlDatabase() *schema.Resource { } func resourceArmSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlDatabasesClient + client := meta.(*ArmClient).sql.DatabasesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) serverName := d.Get("server_name").(string) resourceGroup := d.Get("resource_group_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) createMode := d.Get("create_mode").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serverName, name, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -349,7 +368,7 @@ func resourceArmSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface{} DatabaseProperties: &sql.DatabaseProperties{ CreateMode: sql.CreateMode(createMode), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), } if v, ok := d.GetOk("source_database_id"); ok { @@ -415,6 +434,15 @@ func resourceArmSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface{} } } + if v, ok := d.GetOk("read_scale"); ok { + readScale := v.(bool) + if readScale { + properties.DatabaseProperties.ReadScale = sql.ReadScaleEnabled + } else { + properties.DatabaseProperties.ReadScale = sql.ReadScaleDisabled + } + } + // The requested Service Objective Name does not match the requested Service Objective Id. if d.HasChange("requested_service_objective_name") && !d.HasChange("requested_service_objective_id") { properties.DatabaseProperties.RequestedServiceObjectiveID = nil @@ -456,7 +484,7 @@ func resourceArmSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface{} d.SetId(*resp.ID) - threatDetectionClient := meta.(*ArmClient).sqlDatabaseThreatDetectionPoliciesClient + threatDetectionClient := meta.(*ArmClient).sql.DatabaseThreatDetectionPoliciesClient if _, err = threatDetectionClient.CreateOrUpdate(ctx, resourceGroup, serverName, name, *threatDetection); err != nil { return fmt.Errorf("Error setting database threat detection policy: %+v", err) } @@ -465,10 +493,10 @@ func resourceArmSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface{} } func resourceArmSqlDatabaseRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlDatabasesClient + client := meta.(*ArmClient).sql.DatabasesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -488,7 +516,7 @@ func resourceArmSqlDatabaseRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error making Read request on Sql Database %s: %+v", name, err) } - threatDetectionClient := meta.(*ArmClient).sqlDatabaseThreatDetectionPoliciesClient + threatDetectionClient := meta.(*ArmClient).sql.DatabaseThreatDetectionPoliciesClient threatDetection, err := threatDetectionClient.Get(ctx, resourceGroup, serverName, name) if err == nil { flattenedThreatDetection := flattenArmSqlServerThreatDetectionPolicy(d, threatDetection) @@ -500,7 +528,7 @@ func resourceArmSqlDatabaseRead(d *schema.ResourceData, meta interface{}) error d.Set("name", resp.Name) d.Set("resource_group_name", resourceGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("server_name", serverName) @@ -533,18 +561,23 @@ func resourceArmSqlDatabaseRead(d *schema.ResourceData, meta interface{}) error } d.Set("encryption", flattenEncryptionStatus(props.TransparentDataEncryption)) - } - flattenAndSetTags(d, resp.Tags) + readScale := props.ReadScale + if readScale == sql.ReadScaleEnabled { + d.Set("read_scale", true) + } else { + d.Set("read_scale", false) + } + } - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSqlDatabaseDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlDatabasesClient + client := meta.(*ArmClient).sql.DatabasesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_sql_database_test.go b/azurerm/resource_arm_sql_database_test.go index 6a3522da6e7c..ba5f1242580d 100644 --- a/azurerm/resource_arm_sql_database_test.go +++ b/azurerm/resource_arm_sql_database_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -36,7 +37,7 @@ func TestAccAzureRMSqlDatabase_basic(t *testing.T) { }) } func TestAccAzureRMSqlDatabase_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -298,6 +299,36 @@ func TestAccAzureRMSqlDatabase_threatDetectionPolicy(t *testing.T) { }) } +func TestAccAzureRMSqlDatabase_readScale(t *testing.T) { + resourceName := "azurerm_sql_database.test" + ri := tf.AccRandTimeInt() + location := testLocation() + preConfig := testAccAzureRMSqlDatabase_readScale(ri, location, true) + postConfig := testAccAzureRMSqlDatabase_readScale(ri, location, false) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSqlDatabaseDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlDatabaseExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "read_scale", "true"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlDatabaseExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "read_scale", "false"), + ), + }, + }, + }) +} + func testCheckAzureRMSqlDatabaseExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -310,7 +341,7 @@ func testCheckAzureRMSqlDatabaseExists(resourceName string) resource.TestCheckFu serverName := rs.Primary.Attributes["server_name"] databaseName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).sql.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, databaseName, "") @@ -336,7 +367,7 @@ func testCheckAzureRMSqlDatabaseDestroy(s *terraform.State) error { serverName := rs.Primary.Attributes["server_name"] databaseName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).sql.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, databaseName, "") @@ -366,7 +397,7 @@ func testCheckAzureRMSqlDatabaseDisappears(resourceName string) resource.TestChe serverName := rs.Primary.Attributes["server_name"] databaseName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlDatabasesClient + client := testAccProvider.Meta().(*ArmClient).sql.DatabasesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext if _, err := client.Delete(ctx, resourceGroup, serverName, databaseName); err != nil { @@ -789,3 +820,32 @@ resource "azurerm_sql_database" "test" { } `, rInt, location, rInt, rInt, rInt, state) } + +func testAccAzureRMSqlDatabase_readScale(rInt int, location string, readScale bool) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "readscaletestRG-%d" + location = "%s" +} + +resource "azurerm_sql_server" "test" { + name = "readscaletestsqlserver%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + +resource "azurerm_sql_database" "test" { + name = "readscaletestdb%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test.name}" + location = "${azurerm_resource_group.test.location}" + edition = "Premium" + collation = "SQL_Latin1_General_CP1_CI_AS" + max_size_bytes = "1073741824" + read_scale = %t +} +`, rInt, location, rInt, rInt, readScale) +} diff --git a/azurerm/resource_arm_sql_elasticpool.go b/azurerm/resource_arm_sql_elasticpool.go index 6aa3ff035e5b..0eae83f52190 100644 --- a/azurerm/resource_arm_sql_elasticpool.go +++ b/azurerm/resource_arm_sql_elasticpool.go @@ -7,6 +7,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" "github.com/hashicorp/terraform/helper/schema" @@ -32,9 +34,9 @@ func resourceArmSqlElasticPool() *schema.Resource { ForceNew: true, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -78,24 +80,24 @@ func resourceArmSqlElasticPool() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlElasticPoolsClient + client := meta.(*ArmClient).sql.ElasticPoolsClient ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for SQL ElasticPool creation.") name := d.Get("name").(string) serverName := d.Get("server_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) resGroup := d.Get("resource_group_name").(string) - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -112,7 +114,7 @@ func resourceArmSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interfac Name: &name, Location: &location, ElasticPoolProperties: getArmSqlElasticPoolProperties(d), - Tags: expandTags(tags), + Tags: tags.Expand(t), } future, err := client.CreateOrUpdate(ctx, resGroup, serverName, name, elasticPool) @@ -138,7 +140,7 @@ func resourceArmSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interfac } func resourceArmSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlElasticPoolsClient + client := meta.(*ArmClient).sql.ElasticPoolsClient ctx := meta.(*ArmClient).StopContext resGroup, serverName, name, err := parseArmSqlElasticPoolId(d.Id()) @@ -158,7 +160,7 @@ func resourceArmSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) err d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("server_name", serverName) @@ -174,13 +176,11 @@ func resourceArmSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) err } } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSqlElasticPoolDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlElasticPoolsClient + client := meta.(*ArmClient).sql.ElasticPoolsClient ctx := meta.(*ArmClient).StopContext resGroup, serverName, name, err := parseArmSqlElasticPoolId(d.Id()) @@ -221,7 +221,7 @@ func getArmSqlElasticPoolProperties(d *schema.ResourceData) *sql.ElasticPoolProp } func parseArmSqlElasticPoolId(sqlElasticPoolId string) (string, string, string, error) { - id, err := parseAzureResourceID(sqlElasticPoolId) + id, err := azure.ParseAzureResourceID(sqlElasticPoolId) if err != nil { return "", "", "", fmt.Errorf("[ERROR] Unable to parse SQL ElasticPool ID %q: %+v", sqlElasticPoolId, err) } diff --git a/azurerm/resource_arm_sql_elasticpool_test.go b/azurerm/resource_arm_sql_elasticpool_test.go index a6d3bfb8a6d3..ff2a34accc1c 100644 --- a/azurerm/resource_arm_sql_elasticpool_test.go +++ b/azurerm/resource_arm_sql_elasticpool_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) func TestAccAzureRMSqlElasticPool_basic(t *testing.T) { @@ -34,7 +35,7 @@ func TestAccAzureRMSqlElasticPool_basic(t *testing.T) { }) } func TestAccAzureRMSqlElasticPool_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -124,7 +125,7 @@ func testCheckAzureRMSqlElasticPoolExists(resourceName string) resource.TestChec serverName := rs.Primary.Attributes["server_name"] poolName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlElasticPoolsClient + client := testAccProvider.Meta().(*ArmClient).sql.ElasticPoolsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, poolName) @@ -141,7 +142,7 @@ func testCheckAzureRMSqlElasticPoolExists(resourceName string) resource.TestChec } func testCheckAzureRMSqlElasticPoolDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*ArmClient).sqlElasticPoolsClient + client := testAccProvider.Meta().(*ArmClient).sql.ElasticPoolsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -179,7 +180,7 @@ func testCheckAzureRMSqlElasticPoolDisappears(resourceName string) resource.Test serverName := rs.Primary.Attributes["server_name"] poolName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlElasticPoolsClient + client := testAccProvider.Meta().(*ArmClient).sql.ElasticPoolsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext if _, err := client.Delete(ctx, resourceGroup, serverName, poolName); err != nil { diff --git a/azurerm/resource_arm_sql_failover_group.go b/azurerm/resource_arm_sql_failover_group.go new file mode 100644 index 000000000000..9b725da78f1d --- /dev/null +++ b/azurerm/resource_arm_sql_failover_group.go @@ -0,0 +1,361 @@ +package azurerm + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + + "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func resourceArmSqlFailoverGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceArmSqlFailoverGroupCreateUpdate, + Read: resourceArmSqlFailoverGroupRead, + Update: resourceArmSqlFailoverGroupCreateUpdate, + Delete: resourceArmSqlFailoverGroupDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateMsSqlFailoverGroupName, + }, + + "location": azure.SchemaLocationForDataSource(), + + "resource_group_name": azure.SchemaResourceGroupName(), + + "server_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateMsSqlServerName, + }, + + "databases": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Set: schema.HashString, + }, + + "partner_servers": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "location": azure.SchemaLocationForDataSource(), + + "role": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "readonly_endpoint_failover_policy": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(sql.ReadOnlyEndpointFailoverPolicyDisabled), + string(sql.ReadOnlyEndpointFailoverPolicyEnabled), + }, false), + }, + }, + }, + }, + + "read_write_endpoint_failover_policy": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(sql.Automatic), + string(sql.Manual), + }, false), + }, + "grace_minutes": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(0), + }, + }, + }, + }, + + "role": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmSqlFailoverGroupCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).sql.FailoverGroupsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + serverName := d.Get("server_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing SQL Failover Group %q (Resource Group %q, Server %q): %+v", name, resourceGroup, serverName, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_sql_failover_group", *existing.ID) + } + } + + t := d.Get("tags").(map[string]interface{}) + + properties := sql.FailoverGroup{ + FailoverGroupProperties: &sql.FailoverGroupProperties{ + ReadOnlyEndpoint: expandSqlFailoverGroupReadOnlyPolicy(d), + ReadWriteEndpoint: expandSqlFailoverGroupReadWritePolicy(d), + PartnerServers: expandSqlFailoverGroupPartnerServers(d), + }, + Tags: tags.Expand(t), + } + + if r, ok := d.Get("databases").(*schema.Set); ok && r.Len() > 0 { + var databases []string + for _, v := range r.List() { + s := v.(string) + databases = append(databases, s) + } + + properties.Databases = &databases + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, serverName, name, properties) + if err != nil { + return fmt.Errorf("Error issuing create/update request for SQL Failover Group %q (Resource Group %q, Server %q): %+v", name, resourceGroup, serverName, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for SQL Failover Group %q (Resource Group %q, Server %q): %+v", name, resourceGroup, serverName, err) + } + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + return fmt.Errorf("Error issuing get request for SQL Failover Group %q (Resource Group %q, Server %q): %+v", name, resourceGroup, serverName, err) + } + + d.SetId(*resp.ID) + + return resourceArmSqlFailoverGroupRead(d, meta) +} + +func resourceArmSqlFailoverGroupRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).sql.FailoverGroupsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["failoverGroups"] + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request for SQL Failover Group %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("server_name", serverName) + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.FailoverGroupProperties; props != nil { + if err := d.Set("read_write_endpoint_failover_policy", flattenSqlFailoverGroupReadWritePolicy(props.ReadWriteEndpoint)); err != nil { + return fmt.Errorf("Error setting `read_write_endpoint_failover_policy`: %+v", err) + } + + if err := d.Set("readonly_endpoint_failover_policy", flattenSqlFailoverGroupReadOnlyPolicy(props.ReadOnlyEndpoint)); err != nil { + return fmt.Errorf("Error setting `read_only_endpoint_failover_policy`: %+v", err) + } + + if props.Databases != nil { + d.Set("databases", set.FromStringSlice(*props.Databases)) + } + d.Set("role", string(props.ReplicationRole)) + + if err := d.Set("partner_servers", flattenSqlFailoverGroupPartnerServers(props.PartnerServers)); err != nil { + return fmt.Errorf("Error setting `partner_servers`: %+v", err) + } + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmSqlFailoverGroupDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).sql.FailoverGroupsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["failoverGroups"] + + future, err := client.Delete(ctx, resourceGroup, serverName, name) + if err != nil { + return fmt.Errorf("Error deleting SQL Failover Group %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error deleting SQL Failover Group %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + return err +} + +func expandSqlFailoverGroupReadWritePolicy(d *schema.ResourceData) *sql.FailoverGroupReadWriteEndpoint { + vs := d.Get("read_write_endpoint_failover_policy").([]interface{}) + v := vs[0].(map[string]interface{}) + + mode := sql.ReadWriteEndpointFailoverPolicy(v["mode"].(string)) + graceMins := int32(v["grace_minutes"].(int)) + + policy := &sql.FailoverGroupReadWriteEndpoint{ + FailoverPolicy: mode, + } + + if mode != sql.Manual { + policy.FailoverWithDataLossGracePeriodMinutes = utils.Int32(graceMins) + } + + return policy +} + +func flattenSqlFailoverGroupReadWritePolicy(input *sql.FailoverGroupReadWriteEndpoint) []interface{} { + if input == nil { + return []interface{}{} + } + + policy := make(map[string]interface{}) + + policy["mode"] = string(input.FailoverPolicy) + + if input.FailoverWithDataLossGracePeriodMinutes != nil { + policy["grace_minutes"] = *input.FailoverWithDataLossGracePeriodMinutes + } + return []interface{}{policy} +} + +func expandSqlFailoverGroupReadOnlyPolicy(d *schema.ResourceData) *sql.FailoverGroupReadOnlyEndpoint { + vs := d.Get("readonly_endpoint_failover_policy").([]interface{}) + if len(vs) == 0 { + return nil + } + + v := vs[0].(map[string]interface{}) + mode := sql.ReadOnlyEndpointFailoverPolicy(v["mode"].(string)) + + return &sql.FailoverGroupReadOnlyEndpoint{ + FailoverPolicy: mode, + } +} + +func flattenSqlFailoverGroupReadOnlyPolicy(input *sql.FailoverGroupReadOnlyEndpoint) []interface{} { + if input == nil { + return []interface{}{} + } + + policy := make(map[string]interface{}) + policy["mode"] = string(input.FailoverPolicy) + + return []interface{}{policy} +} + +func expandSqlFailoverGroupPartnerServers(d *schema.ResourceData) *[]sql.PartnerInfo { + servers := d.Get("partner_servers").([]interface{}) + partners := make([]sql.PartnerInfo, 0) + + for _, server := range servers { + info := server.(map[string]interface{}) + + id := info["id"].(string) + partners = append(partners, sql.PartnerInfo{ + ID: &id, + }) + } + + return &partners +} + +func flattenSqlFailoverGroupPartnerServers(input *[]sql.PartnerInfo) []map[string]interface{} { + result := make([]map[string]interface{}, 0) + + if input != nil { + for _, server := range *input { + info := make(map[string]interface{}) + + if v := server.ID; v != nil { + info["id"] = *v + } + if v := server.Location; v != nil { + info["location"] = *v + } + info["role"] = string(server.ReplicationRole) + + result = append(result, info) + } + } + return result +} diff --git a/azurerm/resource_arm_sql_failover_group_test.go b/azurerm/resource_arm_sql_failover_group_test.go new file mode 100644 index 000000000000..c16762a88722 --- /dev/null +++ b/azurerm/resource_arm_sql_failover_group_test.go @@ -0,0 +1,386 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMSqlFailoverGroup_basic(t *testing.T) { + resourceName := "azurerm_sql_failover_group.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSqlFailoverGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSqlFailoverGroup_basic(ri, testLocation(), testAltLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlFailoverGroupExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMSqlFailoverGroup_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skiiping since resources aren't required to be imported") + return + } + resourceName := "azurerm_sql_failover_group.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSqlFailoverGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSqlFailoverGroup_basic(ri, testLocation(), testAltLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlFailoverGroupExists(resourceName), + ), + }, + { + Config: testAccAzureRMSqlFailoverGroup_requiresImport(ri, testLocation(), testAltLocation()), + ExpectError: testRequiresImportError("azurerm_sql_failover_group"), + }, + }, + }) +} + +func TestAccAzureRMSqlFailoverGroup_disappears(t *testing.T) { + resourceName := "azurerm_sql_failover_group.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSqlFailoverGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSqlFailoverGroup_basic(ri, testLocation(), testAltLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlFailoverGroupExists(resourceName), + testCheckAzureRMSqlFailoverGroupDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAzureRMSqlFailoverGroup_withTags(t *testing.T) { + resourceName := "azurerm_sql_failover_group.test" + ri := tf.AccRandTimeInt() + location := testLocation() + altLocation := testAltLocation() + preConfig := testAccAzureRMSqlFailoverGroup_withTags(ri, location, altLocation) + postConfig := testAccAzureRMSqlFailoverGroup_withTagsUpdate(ri, location, altLocation) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSqlFailoverGroupDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlFailoverGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlFailoverGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + ), + }, + }, + }) +} + +func testCheckAzureRMSqlFailoverGroupExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + name := rs.Primary.Attributes["name"] + + client := testAccProvider.Meta().(*ArmClient).sql.FailoverGroupsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("SQL Failover Group %q (server %q / resource group %q) was not found", name, serverName, resourceGroup) + } + + return err + } + + return nil + } +} + +func testCheckAzureRMSqlFailoverGroupDisappears(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + name := rs.Primary.Attributes["name"] + + client := testAccProvider.Meta().(*ArmClient).sql.FailoverGroupsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + future, err := client.Delete(ctx, resourceGroup, serverName, name) + if err != nil { + return fmt.Errorf("Bad: Delete on sqlFailoverGroupsClient: %+v", err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error deleting SQL Failover Group %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + return nil + } +} + +func testCheckAzureRMSqlFailoverGroupDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_sql_failover_group" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + + client := testAccProvider.Meta().(*ArmClient).sql.FailoverGroupsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return fmt.Errorf("SQL Failover Group %q (server %q / resource group %q) still exists: %+v", name, serverName, resourceGroup, resp) + } + + return nil +} + +func testAccAzureRMSqlFailoverGroup_basic(rInt int, location, altlocation string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_sql_server" "test_primary" { + name = "acctestmssql%[1]d-primary" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + +resource "azurerm_sql_server" "test_secondary" { + name = "acctestmssql%[1]d-secondary" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "%[3]s" + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + +resource "azurerm_sql_database" "test" { + name = "acctestdb%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test_primary.name}" + location = "${azurerm_resource_group.test.location}" + edition = "Standard" + collation = "SQL_Latin1_General_CP1_CI_AS" + max_size_bytes = "1073741824" + requested_service_objective_name = "S0" +} + +resource "azurerm_sql_failover_group" "test" { + name = "acctestsfg%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test_primary.name}" + databases = ["${azurerm_sql_database.test.id}"] + + partner_servers { + id = "${azurerm_sql_server.test_secondary.id}" + } + + read_write_endpoint_failover_policy { + mode = "Automatic" + grace_minutes = 60 + } +} +`, rInt, location, altlocation) +} + +func testAccAzureRMSqlFailoverGroup_requiresImport(rInt int, location, altlocation string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_sql_failover_group" "import" { + name = "${azurerm_sql_failover_group.test.name}" + resource_group_name = "${azurerm_sql_failover_group.test.resource_group_name}" + server_name = "${azurerm_sql_failover_group.test.server_name}" + databases = "${azurerm_sql_failover_group.test.databases}" + + partner_servers { + id = "${azurerm_sql_failover_group.test.partner_servers.0.id}" + } + + read_write_endpoint_failover_policy { + mode = "${azurerm_sql_failover_group.test.read_write_endpoint_failover_policy.0.mode}" + grace_minutes = "${azurerm_sql_failover_group.test.read_write_endpoint_failover_policy.0.grace_minutes}" + } + } +`, testAccAzureRMSqlFailoverGroup_basic(rInt, location, altlocation)) +} + +func testAccAzureRMSqlFailoverGroup_withTags(rInt int, location, altlocation string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_sql_server" "test_primary" { + name = "acctestmssql%[1]d-primary" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + +resource "azurerm_sql_server" "test_secondary" { + name = "acctestmssql%[1]d-secondary" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "%[3]s" + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + +resource "azurerm_sql_database" "test" { + name = "acctestdb%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test_primary.name}" + location = "${azurerm_resource_group.test.location}" + edition = "Standard" + collation = "SQL_Latin1_General_CP1_CI_AS" + max_size_bytes = "1073741824" + requested_service_objective_name = "S0" +} + +resource "azurerm_sql_failover_group" "test" { + name = "acctestsfg%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test_primary.name}" + databases = ["${azurerm_sql_database.test.id}"] + + partner_servers { + id = "${azurerm_sql_server.test_secondary.id}" + } + read_write_endpoint_failover_policy { + mode = "Automatic" + grace_minutes = 60 + } + tags = { + environment = "staging" + database = "test" + } +} +`, rInt, location, altlocation) +} + +func testAccAzureRMSqlFailoverGroup_withTagsUpdate(rInt int, location, altlocation string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_sql_server" "test_primary" { + name = "acctestmssql%[1]d-primary" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + +resource "azurerm_sql_server" "test_secondary" { + name = "acctestmssql%[1]d-secondary" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "%[3]s" + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" +} + +resource "azurerm_sql_database" "test" { + name = "acctestdb%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test_primary.name}" + location = "${azurerm_resource_group.test.location}" + edition = "Standard" + collation = "SQL_Latin1_General_CP1_CI_AS" + max_size_bytes = "1073741824" + requested_service_objective_name = "S0" +} + +resource "azurerm_sql_failover_group" "test" { + name = "acctestsfg%[1]d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test_primary.name}" + databases = ["${azurerm_sql_database.test.id}"] + + partner_servers { + id = "${azurerm_sql_server.test_secondary.id}" + } + read_write_endpoint_failover_policy { + mode = "Automatic" + grace_minutes = 60 + } + tags = { + environment = "production" + } +} +`, rInt, location, altlocation) +} diff --git a/azurerm/resource_arm_sql_firewall_rule.go b/azurerm/resource_arm_sql_firewall_rule.go index 941378f4ad5e..310668183e75 100644 --- a/azurerm/resource_arm_sql_firewall_rule.go +++ b/azurerm/resource_arm_sql_firewall_rule.go @@ -6,6 +6,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" "github.com/hashicorp/terraform/helper/schema" @@ -30,7 +31,7 @@ func resourceArmSqlFirewallRule() *schema.Resource { ForceNew: true, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -55,7 +56,7 @@ func resourceArmSqlFirewallRule() *schema.Resource { } func resourceArmSqlFirewallRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlFirewallRulesClient + client := meta.(*ArmClient).sql.FirewallRulesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -64,7 +65,7 @@ func resourceArmSqlFirewallRuleCreateUpdate(d *schema.ResourceData, meta interfa startIPAddress := d.Get("start_ip_address").(string) endIPAddress := d.Get("end_ip_address").(string) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -99,10 +100,10 @@ func resourceArmSqlFirewallRuleCreateUpdate(d *schema.ResourceData, meta interfa } func resourceArmSqlFirewallRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlFirewallRulesClient + client := meta.(*ArmClient).sql.FirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -132,10 +133,10 @@ func resourceArmSqlFirewallRuleRead(d *schema.ResourceData, meta interface{}) er } func resourceArmSqlFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlFirewallRulesClient + client := meta.(*ArmClient).sql.FirewallRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_sql_firewall_rule_test.go b/azurerm/resource_arm_sql_firewall_rule_test.go index 3e5370be9206..f5148bd096b8 100644 --- a/azurerm/resource_arm_sql_firewall_rule_test.go +++ b/azurerm/resource_arm_sql_firewall_rule_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -44,7 +45,7 @@ func TestAccAzureRMSqlFirewallRule_basic(t *testing.T) { }) } func TestAccAzureRMSqlFirewallRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -104,7 +105,7 @@ func testCheckAzureRMSqlFirewallRuleExists(resourceName string) resource.TestChe serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlFirewallRulesClient + client := testAccProvider.Meta().(*ArmClient).sql.FirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) @@ -130,7 +131,7 @@ func testCheckAzureRMSqlFirewallRuleDestroy(s *terraform.State) error { serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlFirewallRulesClient + client := testAccProvider.Meta().(*ArmClient).sql.FirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) @@ -160,7 +161,7 @@ func testCheckAzureRMSqlFirewallRuleDisappears(resourceName string) resource.Tes serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlFirewallRulesClient + client := testAccProvider.Meta().(*ArmClient).sql.FirewallRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Delete(ctx, resourceGroup, serverName, ruleName) diff --git a/azurerm/resource_arm_sql_server.go b/azurerm/resource_arm_sql_server.go index 177ce78897b7..93aeac49fb6d 100644 --- a/azurerm/resource_arm_sql_server.go +++ b/azurerm/resource_arm_sql_server.go @@ -10,6 +10,8 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -32,17 +34,17 @@ func resourceArmSqlServer() *schema.Resource { ValidateFunc: azure.ValidateMsSqlServerName, }, - "location": locationSchema(), + "location": azure.SchemaLocation(), - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "version": { Type: schema.TypeString, Required: true, ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ - string("2.0"), - string("12.0"), + "2.0", + "12.0", }, true), }, @@ -63,25 +65,25 @@ func resourceArmSqlServer() *schema.Resource { Computed: true, }, - "tags": tagsSchema(), + "tags": tags.Schema(), }, } } func resourceArmSqlServerCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlServersClient + client := meta.(*ArmClient).sql.ServersClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) resGroup := d.Get("resource_group_name").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) + location := azure.NormalizeLocation(d.Get("location").(string)) adminUsername := d.Get("administrator_login").(string) version := d.Get("version").(string) - tags := d.Get("tags").(map[string]interface{}) - metadata := expandTags(tags) + t := d.Get("tags").(map[string]interface{}) + metadata := tags.Expand(t) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -114,7 +116,6 @@ func resourceArmSqlServerCreateUpdate(d *schema.ResourceData, meta interface{}) } if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - if response.WasConflict(future.Response()) { return fmt.Errorf("SQL Server names need to be globally unique and %q is already in use.", name) } @@ -133,10 +134,10 @@ func resourceArmSqlServerCreateUpdate(d *schema.ResourceData, meta interface{}) } func resourceArmSqlServerRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlServersClient + client := meta.(*ArmClient).sql.ServersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -158,7 +159,7 @@ func resourceArmSqlServerRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } if serverProperties := resp.ServerProperties; serverProperties != nil { @@ -167,16 +168,14 @@ func resourceArmSqlServerRead(d *schema.ResourceData, meta interface{}) error { d.Set("fully_qualified_domain_name", serverProperties.FullyQualifiedDomainName) } - flattenAndSetTags(d, resp.Tags) - - return nil + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmSqlServerDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlServersClient + client := meta.(*ArmClient).sql.ServersClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } diff --git a/azurerm/resource_arm_sql_server_test.go b/azurerm/resource_arm_sql_server_test.go index 6de4e4c90113..945bea3c7bca 100644 --- a/azurerm/resource_arm_sql_server_test.go +++ b/azurerm/resource_arm_sql_server_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -35,7 +36,7 @@ func TestAccAzureRMSqlServer_basic(t *testing.T) { }) } func TestAccAzureRMSqlServer_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -133,7 +134,7 @@ func testCheckAzureRMSqlServerExists(resourceName string) resource.TestCheckFunc return fmt.Errorf("Bad: no resource group found in state for SQL Server: %s", sqlServerName) } - conn := testAccProvider.Meta().(*ArmClient).sqlServersClient + conn := testAccProvider.Meta().(*ArmClient).sql.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := conn.Get(ctx, resourceGroup, sqlServerName) if err != nil { @@ -148,7 +149,7 @@ func testCheckAzureRMSqlServerExists(resourceName string) resource.TestCheckFunc } func testCheckAzureRMSqlServerDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*ArmClient).sqlServersClient + conn := testAccProvider.Meta().(*ArmClient).sql.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, rs := range s.RootModule().Resources { @@ -187,7 +188,7 @@ func testCheckAzureRMSqlServerDisappears(resourceName string) resource.TestCheck resourceGroup := rs.Primary.Attributes["resource_group_name"] serverName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlServersClient + client := testAccProvider.Meta().(*ArmClient).sql.ServersClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, serverName) diff --git a/azurerm/resource_arm_sql_virtual_network_rule.go b/azurerm/resource_arm_sql_virtual_network_rule.go index d975bd072935..3d05a8643445 100644 --- a/azurerm/resource_arm_sql_virtual_network_rule.go +++ b/azurerm/resource_arm_sql_virtual_network_rule.go @@ -9,6 +9,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" "github.com/hashicorp/terraform/helper/resource" @@ -36,7 +37,7 @@ func resourceArmSqlVirtualNetworkRule() *schema.Resource { ValidateFunc: validateSqlVirtualNetworkRuleName, }, - "resource_group_name": resourceGroupNameSchema(), + "resource_group_name": azure.SchemaResourceGroupName(), "server_name": { Type: schema.TypeString, @@ -60,7 +61,7 @@ func resourceArmSqlVirtualNetworkRule() *schema.Resource { } func resourceArmSqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlVirtualNetworkRulesClient + client := meta.(*ArmClient).sql.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) @@ -69,7 +70,7 @@ func resourceArmSqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta i virtualNetworkSubnetId := d.Get("subnet_id").(string) ignoreMissingVnetServiceEndpoint := d.Get("ignore_missing_vnet_service_endpoint").(bool) - if requireResourcesToBeImported && d.IsNewResource() { + if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroup, serverName, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { @@ -119,10 +120,10 @@ func resourceArmSqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta i } func resourceArmSqlVirtualNetworkRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlVirtualNetworkRulesClient + client := meta.(*ArmClient).sql.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -155,10 +156,10 @@ func resourceArmSqlVirtualNetworkRuleRead(d *schema.ResourceData, meta interface } func resourceArmSqlVirtualNetworkRuleDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).sqlVirtualNetworkRulesClient + client := meta.(*ArmClient).sql.VirtualNetworkRulesClient ctx := meta.(*ArmClient).StopContext - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -241,7 +242,7 @@ func validateSqlVirtualNetworkRuleName(v interface{}, k string) (warnings []stri * Ready * ResponseNotFound (Custom state in case of 404) */ -func sqlVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client sql.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc { +func sqlVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client *sql.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc { return func() (interface{}, string, error) { resp, err := client.Get(ctx, resourceGroup, serverName, name) diff --git a/azurerm/resource_arm_sql_virtual_network_rule_test.go b/azurerm/resource_arm_sql_virtual_network_rule_test.go index 444604b334e1..027b3becff56 100644 --- a/azurerm/resource_arm_sql_virtual_network_rule_test.go +++ b/azurerm/resource_arm_sql_virtual_network_rule_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -51,7 +52,7 @@ func TestAccAzureRMSqlVirtualNetworkRule_basic(t *testing.T) { } func TestAccAzureRMSqlVirtualNetworkRule_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -358,7 +359,7 @@ func testCheckAzureRMSqlVirtualNetworkRuleExists(resourceName string) resource.T serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).sql.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) @@ -387,7 +388,7 @@ func testCheckAzureRMSqlVirtualNetworkRuleDestroy(s *terraform.State) error { serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).sql.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) @@ -420,7 +421,7 @@ func testCheckAzureRMSqlVirtualNetworkRuleDisappears(resourceName string) resour serverName := rs.Primary.Attributes["server_name"] ruleName := rs.Primary.Attributes["name"] - client := testAccProvider.Meta().(*ArmClient).sqlVirtualNetworkRulesClient + client := testAccProvider.Meta().(*ArmClient).sql.VirtualNetworkRulesClient ctx := testAccProvider.Meta().(*ArmClient).StopContext future, err := client.Delete(ctx, resourceGroup, serverName, ruleName) diff --git a/azurerm/resource_arm_storage_account.go b/azurerm/resource_arm_storage_account.go index 012ccf98cdf7..da29c7567583 100644 --- a/azurerm/resource_arm_storage_account.go +++ b/azurerm/resource_arm_storage_account.go @@ -6,13 +6,21 @@ import ( "regexp" "strings" - "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-02-01/storage" + "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v1.0/security" + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage" "github.com/hashicorp/go-getter/helper/url" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/locks" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/queue/queues" ) const blobStorageAccountDefaultAccessTier = "Hot" @@ -24,11 +32,12 @@ func resourceArmStorageAccount() *schema.Resource { Update: resourceArmStorageAccountUpdate, Delete: resourceArmStorageAccountDelete, + MigrateState: resourceStorageAccountMigrateState, + SchemaVersion: 2, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - MigrateState: resourceStorageAccountMigrateState, - SchemaVersion: 2, Schema: map[string]*schema.Schema{ "name": { @@ -38,9 +47,9 @@ func resourceArmStorageAccount() *schema.Resource { ValidateFunc: validateArmStorageAccountName, }, - "resource_group_name": resourceGroupNameDiffSuppressSchema(), + "resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(), - "location": locationSchema(), + "location": azure.SchemaLocation(), "account_kind": { Type: schema.TypeString, @@ -49,6 +58,8 @@ func resourceArmStorageAccount() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{ string(storage.Storage), string(storage.BlobStorage), + string(storage.BlockBlobStorage), + string(storage.FileStorage), string(storage.StorageV2), }, true), Default: string(storage.Storage), @@ -60,7 +71,7 @@ func resourceArmStorageAccount() *schema.Resource { Computed: true, Deprecated: "This field has been split into `account_tier` and `account_replication_type`", ValidateFunc: validateArmStorageAccountType, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "account_tier": { @@ -71,7 +82,7 @@ func resourceArmStorageAccount() *schema.Resource { "Standard", "Premium", }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "account_replication_type": { @@ -83,7 +94,7 @@ func resourceArmStorageAccount() *schema.Resource { "GRS", "RAGRS", }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, // Only valid for BlobStorage & StorageV2 accounts, defaults to "Hot" in create function @@ -105,7 +116,7 @@ func resourceArmStorageAccount() *schema.Resource { string(storage.MicrosoftKeyvault), string(storage.MicrosoftStorage), }, true), - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, }, "custom_domain": { @@ -152,10 +163,17 @@ func resourceArmStorageAccount() *schema.Resource { ForceNew: true, }, + "enable_advanced_threat_protection": { + Type: schema.TypeBool, + Optional: true, + Default: false, // TODO remove this in 2.0 so we can use GetOkExists to guard the ATP client use + }, + "network_rules": { Type: schema.TypeList, - MaxItems: 1, Optional: true, + Computed: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "bypass": { @@ -173,18 +191,31 @@ func resourceArmStorageAccount() *schema.Resource { }, Set: schema.HashString, }, + "ip_rules": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, + "virtual_network_subnet_ids": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, + + "default_action": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(storage.DefaultActionAllow), + string(storage.DefaultActionDeny), + }, false), + }, }, }, }, @@ -259,7 +290,46 @@ func resourceArmStorageAccount() *schema.Resource { Computed: true, }, - // NOTE: The API does not appear to expose a secondary file endpoint + "primary_web_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "primary_web_host": { + Type: schema.TypeString, + Computed: true, + }, + + "secondary_web_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "secondary_web_host": { + Type: schema.TypeString, + Computed: true, + }, + + "primary_dfs_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "primary_dfs_host": { + Type: schema.TypeString, + Computed: true, + }, + + "secondary_dfs_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "secondary_dfs_host": { + Type: schema.TypeString, + Computed: true, + }, + "primary_file_endpoint": { Type: schema.TypeString, Computed: true, @@ -270,6 +340,16 @@ func resourceArmStorageAccount() *schema.Resource { Computed: true, }, + "secondary_file_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + + "secondary_file_host": { + Type: schema.TypeString, + Computed: true, + }, + "primary_access_key": { Type: schema.TypeString, Sensitive: true, @@ -316,7 +396,7 @@ func resourceArmStorageAccount() *schema.Resource { "type": { Type: schema.TypeString, Required: true, - DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ "SystemAssigned", }, true), @@ -339,6 +419,162 @@ func resourceArmStorageAccount() *schema.Resource { Computed: true, ValidateFunc: validateAzureRMStorageAccountTags, }, + + "queue_properties": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cors_rule": { + Type: schema.TypeList, + Optional: true, + MaxItems: 5, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "allowed_origins": { + Type: schema.TypeList, + Required: true, + MaxItems: 64, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + "exposed_headers": { + Type: schema.TypeList, + Required: true, + MaxItems: 64, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + "allowed_headers": { + Type: schema.TypeList, + Required: true, + MaxItems: 64, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + "allowed_methods": { + Type: schema.TypeList, + Required: true, + MaxItems: 64, + Elem: &schema.Schema{ + Type: schema.TypeString, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + "DELETE", + "GET", + "HEAD", + "MERGE", + "POST", + "OPTIONS", + "PUT"}, false), + }, + }, + }, + "max_age_in_seconds": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 2000000000), + }, + }, + }, + }, + "logging": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "delete": { + Type: schema.TypeBool, + Required: true, + }, + "read": { + Type: schema.TypeBool, + Required: true, + }, + "write": { + Type: schema.TypeBool, + Required: true, + }, + "retention_policy_days": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 365), + }, + }, + }, + }, + "hour_metrics": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + "include_apis": { + Type: schema.TypeBool, + Optional: true, + }, + "retention_policy_days": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 365), + }, + }, + }, + }, + "minute_metrics": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + "include_apis": { + Type: schema.TypeBool, + Optional: true, + }, + "retention_policy_days": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntBetween(1, 365), + }, + }, + }, + }, + }, + }, + }, }, } } @@ -347,7 +583,7 @@ func validateAzureRMStorageAccountTags(v interface{}, _ string) (warnings []stri tagsMap := v.(map[string]interface{}) if len(tagsMap) > 15 { - errors = append(errors, fmt.Errorf("a maximum of 15 tags can be applied to each ARM resource")) + errors = append(errors, fmt.Errorf("a maximum of 15 tags can be applied to storage account ARM resource")) } for k, v := range tagsMap { @@ -355,7 +591,7 @@ func validateAzureRMStorageAccountTags(v interface{}, _ string) (warnings []stri errors = append(errors, fmt.Errorf("the maximum length for a tag key is 128 characters: %q is %d characters", k, len(k))) } - value, err := tagValueToString(v) + value, err := tags.TagValueToString(v) if err != nil { errors = append(errors, err) } else if len(value) > 256 { @@ -368,13 +604,14 @@ func validateAzureRMStorageAccountTags(v interface{}, _ string) (warnings []stri func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).storageServiceClient + client := meta.(*ArmClient).storage.AccountsClient + advancedThreatProtectionClient := meta.(*ArmClient).securityCenter.AdvancedThreatProtectionClient storageAccountName := d.Get("name").(string) resourceGroupName := d.Get("resource_group_name").(string) - if requireResourcesToBeImported { - existing, err := client.GetProperties(ctx, resourceGroupName, storageAccountName) + if features.ShouldResourcesBeImported() { + existing, err := client.GetProperties(ctx, resourceGroupName, storageAccountName, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { return fmt.Errorf("Error checking for presence of existing Storage Account %q (Resource Group %q): %s", storageAccountName, resourceGroupName, err) @@ -387,8 +624,8 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e } accountKind := d.Get("account_kind").(string) - location := azureRMNormalizeLocation(d.Get("location").(string)) - tags := d.Get("tags").(map[string]interface{}) + location := azure.NormalizeLocation(d.Get("location").(string)) + t := d.Get("tags").(map[string]interface{}) enableBlobEncryption := d.Get("enable_blob_encryption").(bool) enableFileEncryption := d.Get("enable_file_encryption").(bool) enableHTTPSTrafficOnly := d.Get("enable_https_traffic_only").(bool) @@ -399,14 +636,12 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e storageType := fmt.Sprintf("%s_%s", accountTier, replicationType) storageAccountEncryptionSource := d.Get("account_encryption_source").(string) - networkRules := expandStorageAccountNetworkRules(d) - parameters := storage.AccountCreateParameters{ Location: &location, Sku: &storage.Sku{ Name: storage.SkuName(storageType), }, - Tags: expandTags(tags), + Tags: tags.Expand(t), Kind: storage.Kind(accountKind), AccountPropertiesCreateParameters: &storage.AccountPropertiesCreateParameters{ Encryption: &storage.Encryption{ @@ -420,7 +655,7 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e KeySource: storage.KeySource(storageAccountEncryptionSource), }, EnableHTTPSTrafficOnly: &enableHTTPSTrafficOnly, - NetworkRuleSet: networkRules, + NetworkRuleSet: expandStorageAccountNetworkRules(d), IsHnsEnabled: &isHnsEnabled, }, } @@ -441,8 +676,8 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e } } - // AccessTier is only valid for BlobStorage and StorageV2 accounts - if accountKind == string(storage.BlobStorage) || accountKind == string(storage.StorageV2) { + // AccessTier is only valid for BlobStorage, StorageV2, and FileStorage accounts + if accountKind == string(storage.BlobStorage) || accountKind == string(storage.StorageV2) || accountKind == string(storage.FileStorage) { accessTier, ok := d.GetOk("access_tier") if !ok { // default to "Hot" @@ -456,6 +691,13 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e } } + // AccountTier must be Premium for FileStorage + if accountKind == string(storage.FileStorage) { + if string(parameters.Sku.Tier) == string(storage.StandardLRS) { + return fmt.Errorf("A `account_tier` of `Standard` is not supported for FileStorage accounts.") + } + } + // Create future, err := client.Create(ctx, resourceGroupName, storageAccountName, parameters) if err != nil { @@ -466,7 +708,7 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("Error waiting for Azure Storage Account %q to be created: %+v", storageAccountName, err) } - account, err := client.GetProperties(ctx, resourceGroupName, storageAccountName) + account, err := client.GetProperties(ctx, resourceGroupName, storageAccountName, "") if err != nil { return fmt.Errorf("Error retrieving Azure Storage Account %q: %+v", storageAccountName, err) } @@ -478,6 +720,37 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e log.Printf("[INFO] storage account %q ID: %q", storageAccountName, *account.ID) d.SetId(*account.ID) + // as this is not available in all regions, and presumably off by default + // lets only try to set this value when true + // TODO in 2.0 switch to guarding this with d.GetOkExists() ? + if v := d.Get("enable_advanced_threat_protection").(bool); v { + advancedThreatProtectionSetting := security.AdvancedThreatProtectionSetting{ + AdvancedThreatProtectionProperties: &security.AdvancedThreatProtectionProperties{ + IsEnabled: utils.Bool(v), + }, + } + + if _, err = advancedThreatProtectionClient.Create(ctx, d.Id(), advancedThreatProtectionSetting); err != nil { + return fmt.Errorf("Error updating Azure Storage Account enable_advanced_threat_protection %q: %+v", storageAccountName, err) + } + } + + if val, ok := d.GetOk("queue_properties"); ok { + queueClient, err := meta.(*ArmClient).storage.QueuesClient(ctx, resourceGroupName, storageAccountName) + if err != nil { + return fmt.Errorf("Error building Queues Client: %s", err) + } + + queueProperties, err := expandQueueProperties(val.([]interface{})) + if err != nil { + return fmt.Errorf("Error expanding `queue_properties` for Azure Storage Account %q: %+v", storageAccountName, err) + } + + if _, err = queueClient.SetServiceProperties(ctx, storageAccountName, queueProperties); err != nil { + return fmt.Errorf("Error updating Azure Storage Account `queue_properties` %q: %+v", storageAccountName, err) + } + } + return resourceArmStorageAccountRead(d, meta) } @@ -486,8 +759,10 @@ func resourceArmStorageAccountCreate(d *schema.ResourceData, meta interface{}) e // available requires a call to Update per parameter... func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).storageServiceClient - id, err := parseAzureResourceID(d.Id()) + client := meta.(*ArmClient).storage.AccountsClient + advancedThreatProtectionClient := meta.(*ArmClient).securityCenter.AdvancedThreatProtectionClient + + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } @@ -540,10 +815,10 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e } if d.HasChange("tags") { - tags := d.Get("tags").(map[string]interface{}) + t := d.Get("tags").(map[string]interface{}) opts := storage.AccountUpdateParameters{ - Tags: expandTags(tags), + Tags: tags.Expand(t), } if _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts); err != nil { @@ -582,17 +857,15 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e d.SetPartial("enable_file_encryption") } - _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts) - if err != nil { + if _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts); err != nil { return fmt.Errorf("Error updating Azure Storage Account Encryption %q: %+v", storageAccountName, err) } } if d.HasChange("custom_domain") { - customDomain := expandStorageAccountCustomDomain(d) opts := storage.AccountUpdateParameters{ AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ - CustomDomain: customDomain, + CustomDomain: expandStorageAccountCustomDomain(d), }, } @@ -618,10 +891,8 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e } if d.HasChange("identity") { - storageAccountIdentity := expandAzureRmStorageAccountIdentity(d) - opts := storage.AccountUpdateParameters{ - Identity: storageAccountIdentity, + Identity: expandAzureRmStorageAccountIdentity(d), } if _, err := client.Update(ctx, resourceGroupName, storageAccountName, opts); err != nil { @@ -630,11 +901,9 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e } if d.HasChange("network_rules") { - networkRules := expandStorageAccountNetworkRules(d) - opts := storage.AccountUpdateParameters{ AccountPropertiesUpdateParameters: &storage.AccountPropertiesUpdateParameters{ - NetworkRuleSet: networkRules, + NetworkRuleSet: expandStorageAccountNetworkRules(d), }, } @@ -645,23 +914,57 @@ func resourceArmStorageAccountUpdate(d *schema.ResourceData, meta interface{}) e d.SetPartial("network_rules") } + if d.HasChange("enable_advanced_threat_protection") { + + opts := security.AdvancedThreatProtectionSetting{ + AdvancedThreatProtectionProperties: &security.AdvancedThreatProtectionProperties{ + IsEnabled: utils.Bool(d.Get("enable_advanced_threat_protection").(bool)), + }, + } + + if _, err := advancedThreatProtectionClient.Create(ctx, d.Id(), opts); err != nil { + return fmt.Errorf("Error updating Azure Storage Account enable_advanced_threat_protection %q: %+v", storageAccountName, err) + } + + d.SetPartial("enable_advanced_threat_protection") + } + + if d.HasChange("queue_properties") { + queueClient, err := meta.(*ArmClient).storage.QueuesClient(ctx, resourceGroupName, storageAccountName) + if err != nil { + return fmt.Errorf("Error building Queues Client: %s", err) + } + + queueProperties, err := expandQueueProperties(d.Get("queue_properties").([]interface{})) + if err != nil { + return fmt.Errorf("Error expanding `queue_properties` for Azure Storage Account %q: %+v", storageAccountName, err) + } + + if _, err = queueClient.SetServiceProperties(ctx, storageAccountName, queueProperties); err != nil { + return fmt.Errorf("Error updating Azure Storage Account `queue_properties` %q: %+v", storageAccountName, err) + } + + d.SetPartial("queue_properties") + } + d.Partial(false) return resourceArmStorageAccountRead(d, meta) } func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).storageServiceClient + client := meta.(*ArmClient).storage.AccountsClient + advancedThreatProtectionClient := meta.(*ArmClient).securityCenter.AdvancedThreatProtectionClient endpointSuffix := meta.(*ArmClient).environment.StorageEndpointSuffix - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } name := id.Path["storageAccounts"] resGroup := id.ResourceGroup - resp, err := client.GetProperties(ctx, resGroup, name) + resp, err := client.GetProperties(ctx, resGroup, name, "") if err != nil { if utils.ResponseWasNotFound(resp.Response) { d.SetId("") @@ -679,7 +982,7 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err d.Set("name", resp.Name) d.Set("resource_group_name", resGroup) if location := resp.Location; location != nil { - d.Set("location", azureRMNormalizeLocation(*location)) + d.Set("location", azure.NormalizeLocation(*location)) } d.Set("account_kind", resp.Kind) @@ -746,8 +1049,7 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err } d.Set("secondary_blob_connection_string", secondaryBlobConnectStr) - networkRules := props.NetworkRuleSet - if networkRules != nil { + if networkRules := props.NetworkRuleSet; networkRules != nil { if err := d.Set("network_rules", flattenStorageAccountNetworkRules(networkRules)); err != nil { return fmt.Errorf("Error setting `network_rules`: %+v", err) } @@ -762,23 +1064,52 @@ func resourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) err return err } - flattenAndSetTags(d, resp.Tags) + // TODO in 2.0 switch to guarding this with d.GetOkExists() + atp, err := advancedThreatProtectionClient.Get(ctx, d.Id()) + if err != nil { + msg := err.Error() + if !strings.Contains(msg, "No registered resource provider found for location '") { + if !strings.Contains(msg, "' and API version '2017-08-01-preview' for type ") { + return fmt.Errorf("Error reading the advanced threat protection settings of AzureRM Storage Account %q: %+v", name, err) + } + } + } else { + if atpp := atp.AdvancedThreatProtectionProperties; atpp != nil { + d.Set("enable_advanced_threat_protection", atpp.IsEnabled) + } + } - return nil + queueClient, err := meta.(*ArmClient).storage.QueuesClient(ctx, resGroup, name) + if err != nil { + return fmt.Errorf("Error building Queues Client: %s", err) + } + + queueProps, err := queueClient.GetServiceProperties(ctx, name) + if err != nil { + if queueProps.Response.Response != nil && !utils.ResponseWasNotFound(queueProps.Response) { + return fmt.Errorf("Error reading queue properties for AzureRM Storage Account %q: %+v", name, err) + } + } + + if err := d.Set("queue_properties", flattenQueueProperties(queueProps)); err != nil { + return fmt.Errorf("Error setting `queue_properties `for AzureRM Storage Account %q: %+v", name, err) + } + + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmStorageAccountDelete(d *schema.ResourceData, meta interface{}) error { ctx := meta.(*ArmClient).StopContext - client := meta.(*ArmClient).storageServiceClient + client := meta.(*ArmClient).storage.AccountsClient - id, err := parseAzureResourceID(d.Id()) + id, err := azure.ParseAzureResourceID(d.Id()) if err != nil { return err } name := id.Path["storageAccounts"] resourceGroup := id.ResourceGroup - read, err := client.GetProperties(ctx, resourceGroup, name) + read, err := client.GetProperties(ctx, resourceGroup, name, "") if err != nil { if utils.ResponseWasNotFound(read.Response) { return nil @@ -797,7 +1128,7 @@ func resourceArmStorageAccountDelete(d *schema.ResourceData, meta interface{}) e continue } - id, err2 := parseAzureResourceID(*v.VirtualNetworkResourceID) + id, err2 := azure.ParseAzureResourceID(*v.VirtualNetworkResourceID) if err2 != nil { return err2 } @@ -809,8 +1140,8 @@ func resourceArmStorageAccountDelete(d *schema.ResourceData, meta interface{}) e } } - azureRMLockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) - defer azureRMUnlockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) + locks.MultipleByName(&virtualNetworkNames, virtualNetworkResourceName) + defer locks.UnlockMultipleByName(&virtualNetworkNames, virtualNetworkResourceName) resp, err := client.Delete(ctx, resourceGroup, name) if err != nil { @@ -858,13 +1189,15 @@ func expandStorageAccountNetworkRules(d *schema.ResourceData) *storage.NetworkRu } networkRule := networkRules[0].(map[string]interface{}) - networkRuleSet := &storage.NetworkRuleSet{} + networkRuleSet := &storage.NetworkRuleSet{ + IPRules: expandStorageAccountIPRules(networkRule), + VirtualNetworkRules: expandStorageAccountVirtualNetworks(networkRule), + Bypass: expandStorageAccountBypass(networkRule), + } - networkRuleSet.IPRules = expandStorageAccountIPRules(networkRule) - networkRuleSet.VirtualNetworkRules = expandStorageAccountVirtualNetworks(networkRule) - networkRuleSet.Bypass = expandStorageAccountBypass(networkRule) - // Default Access is disabled when network rules are set. - networkRuleSet.DefaultAction = storage.DefaultActionDeny + if v := networkRule["default_action"]; v != nil { + networkRuleSet.DefaultAction = storage.DefaultAction(v.(string)) + } return networkRuleSet } @@ -912,6 +1245,113 @@ func expandStorageAccountBypass(networkRule map[string]interface{}) storage.Bypa return storage.Bypass(strings.Join(bypassValues, ", ")) } +func expandQueueProperties(input []interface{}) (queues.StorageServiceProperties, error) { + var err error + properties := queues.StorageServiceProperties{} + if len(input) == 0 { + return properties, nil + } + + attrs := input[0].(map[string]interface{}) + + properties.Cors = expandQueuePropertiesCors(attrs["cors_rule"].([]interface{})) + properties.Logging = expandQueuePropertiesLogging(attrs["logging"].([]interface{})) + properties.MinuteMetrics, err = expandQueuePropertiesMetrics(attrs["minute_metrics"].([]interface{})) + if err != nil { + return properties, fmt.Errorf("Error expanding `minute_metrics`: %+v", err) + } + properties.HourMetrics, err = expandQueuePropertiesMetrics(attrs["hour_metrics"].([]interface{})) + if err != nil { + return properties, fmt.Errorf("Error expanding `hour_metrics`: %+v", err) + } + + return properties, nil +} + +func expandQueuePropertiesMetrics(input []interface{}) (*queues.MetricsConfig, error) { + if len(input) == 0 { + return &queues.MetricsConfig{}, nil + } + + metricsAttr := input[0].(map[string]interface{}) + + metrics := &queues.MetricsConfig{ + Version: metricsAttr["version"].(string), + Enabled: metricsAttr["enabled"].(bool), + } + + if v, ok := metricsAttr["retention_policy_days"]; ok { + if days := v.(int); days > 0 { + metrics.RetentionPolicy = queues.RetentionPolicy{ + Days: days, + Enabled: true, + } + } + } + + if v, ok := metricsAttr["include_apis"]; ok { + includeAPIs := v.(bool) + if metrics.Enabled { + metrics.IncludeAPIs = &includeAPIs + } else if includeAPIs { + return nil, fmt.Errorf("`include_apis` may only be set when `enabled` is true") + } + } + + return metrics, nil +} + +func expandQueuePropertiesLogging(input []interface{}) *queues.LoggingConfig { + if len(input) == 0 { + return &queues.LoggingConfig{} + } + + loggingAttr := input[0].(map[string]interface{}) + logging := &queues.LoggingConfig{ + Version: loggingAttr["version"].(string), + Delete: loggingAttr["delete"].(bool), + Read: loggingAttr["read"].(bool), + Write: loggingAttr["write"].(bool), + } + + if v, ok := loggingAttr["retention_policy_days"]; ok { + if days := v.(int); days > 0 { + logging.RetentionPolicy = queues.RetentionPolicy{ + Days: days, + Enabled: true, + } + } + } + + return logging + +} + +func expandQueuePropertiesCors(input []interface{}) *queues.Cors { + if len(input) == 0 { + return &queues.Cors{} + } + + corsRules := make([]queues.CorsRule, 0) + for _, attr := range input { + corsRuleAttr := attr.(map[string]interface{}) + corsRule := queues.CorsRule{} + + corsRule.AllowedOrigins = strings.Join(*utils.ExpandStringSlice(corsRuleAttr["allowed_origins"].([]interface{})), ",") + corsRule.ExposedHeaders = strings.Join(*utils.ExpandStringSlice(corsRuleAttr["exposed_headers"].([]interface{})), ",") + corsRule.AllowedHeaders = strings.Join(*utils.ExpandStringSlice(corsRuleAttr["allowed_headers"].([]interface{})), ",") + corsRule.AllowedMethods = strings.Join(*utils.ExpandStringSlice(corsRuleAttr["allowed_methods"].([]interface{})), ",") + corsRule.MaxAgeInSeconds = corsRuleAttr["max_age_in_seconds"].(int) + + corsRules = append(corsRules, corsRule) + } + + cors := &queues.Cors{ + CorsRule: corsRules, + } + return cors +} + func flattenStorageAccountNetworkRules(input *storage.NetworkRuleSet) []interface{} { if len(*input.IPRules) == 0 && len(*input.VirtualNetworkRules) == 0 { return []interface{}{} @@ -921,6 +1361,7 @@ func flattenStorageAccountNetworkRules(input *storage.NetworkRuleSet) []interfac networkRules["ip_rules"] = schema.NewSet(schema.HashString, flattenStorageAccountIPRules(input.IPRules)) networkRules["virtual_network_subnet_ids"] = schema.NewSet(schema.HashString, flattenStorageAccountVirtualNetworks(input.VirtualNetworkRules)) networkRules["bypass"] = schema.NewSet(schema.HashString, flattenStorageAccountBypass(input.Bypass)) + networkRules["default_action"] = string(input.DefaultAction) return []interface{}{networkRules} } @@ -948,6 +1389,106 @@ func flattenStorageAccountVirtualNetworks(input *[]storage.VirtualNetworkRule) [ return virtualNetworks } +func flattenQueueProperties(input queues.StorageServicePropertiesResponse) []interface{} { + if input.Response.Response == nil { + return []interface{}{} + } + + queueProperties := make(map[string]interface{}) + + if cors := input.Cors; cors != nil { + if len(cors.CorsRule) > 0 { + if cors.CorsRule[0].AllowedOrigins != "" { + queueProperties["cors_rule"] = flattenQueuePropertiesCorsRule(input.Cors.CorsRule) + } + } + } + + if logging := input.Logging; logging != nil { + if logging.Version != "" { + queueProperties["logging"] = flattenQueuePropertiesLogging(*logging) + } + } + + if hourMetrics := input.HourMetrics; hourMetrics != nil { + if hourMetrics.Version != "" { + queueProperties["hour_metrics"] = flattenQueuePropertiesMetrics(*hourMetrics) + } + } + + if minuteMetrics := input.MinuteMetrics; minuteMetrics != nil { + if minuteMetrics.Version != "" { + queueProperties["minute_metrics"] = flattenQueuePropertiesMetrics(*minuteMetrics) + } + } + + if len(queueProperties) == 0 { + return []interface{}{} + } + return []interface{}{queueProperties} +} + +func flattenQueuePropertiesMetrics(input queues.MetricsConfig) []interface{} { + metrics := make(map[string]interface{}) + + metrics["version"] = input.Version + metrics["enabled"] = input.Enabled + + if input.IncludeAPIs != nil { + metrics["include_apis"] = *input.IncludeAPIs + } + + if input.RetentionPolicy.Enabled { + metrics["retention_policy_days"] = input.RetentionPolicy.Days + } + + return []interface{}{metrics} +} + +func flattenQueuePropertiesCorsRule(input []queues.CorsRule) []interface{} { + corsRules := make([]interface{}, 0) + + for _, corsRule := range input { + attr := make(map[string]interface{}) + + attr["allowed_origins"] = flattenCorsProperty(corsRule.AllowedOrigins) + attr["allowed_methods"] = flattenCorsProperty(corsRule.AllowedMethods) + attr["allowed_headers"] = flattenCorsProperty(corsRule.AllowedHeaders) + attr["exposed_headers"] = flattenCorsProperty(corsRule.ExposedHeaders) + attr["max_age_in_seconds"] = corsRule.MaxAgeInSeconds + + corsRules = append(corsRules, attr) + } + + return corsRules +} + +func flattenQueuePropertiesLogging(input queues.LoggingConfig) []interface{} { + logging := make(map[string]interface{}) + + logging["version"] = input.Version + logging["delete"] = input.Delete + logging["read"] = input.Read + logging["write"] = input.Write + + if input.RetentionPolicy.Enabled { + logging["retention_policy_days"] = input.RetentionPolicy.Days + } + + return []interface{}{logging} +} + +func flattenCorsProperty(input string) []interface{} { + results := make([]interface{}, 0, len(input)) + + origins := strings.Split(input, ",") + for _, origin := range origins { + results = append(results, origin) + } + + return results +} + func flattenStorageAccountBypass(input storage.Bypass) []interface{} { bypassValues := strings.Split(string(input), ", ") bypass := make([]interface{}, len(bypassValues)) @@ -1033,118 +1574,71 @@ func getBlobConnectionString(blobEndpoint *string, acctName *string, acctKey *st } func flattenAndSetAzureRmStorageAccountPrimaryEndpoints(d *schema.ResourceData, primary *storage.Endpoints) error { - var blobEndpoint, blobHost string - if primary != nil { - if v := primary.Blob; v != nil { - blobEndpoint = *v - - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) - } - blobHost = u.Host - } + if primary == nil { + return fmt.Errorf("primary endpoints should not be empty") } - d.Set("primary_blob_endpoint", blobEndpoint) - d.Set("primary_blob_host", blobHost) - - var queueEndpoint, queueHost string - if primary != nil { - if v := primary.Queue; v != nil { - queueEndpoint = *v - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) - } - queueHost = u.Host - } + if err := setEndpointAndHost(d, "primary", primary.Blob, "blob"); err != nil { + return err } - d.Set("primary_queue_endpoint", queueEndpoint) - d.Set("primary_queue_host", queueHost) - - var tableEndpoint, tableHost string - if primary != nil { - if v := primary.Table; v != nil { - tableEndpoint = *v - - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid table endpoint for parsing: %q", *v) - } - tableHost = u.Host - } + if err := setEndpointAndHost(d, "primary", primary.Dfs, "dfs"); err != nil { + return err } - d.Set("primary_table_endpoint", tableEndpoint) - d.Set("primary_table_host", tableHost) - - var fileEndpoint, fileHost string - if primary != nil { - if v := primary.File; v != nil { - fileEndpoint = *v - - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid file endpoint for parsing: %q", *v) - } - fileHost = u.Host - } + if err := setEndpointAndHost(d, "primary", primary.File, "file"); err != nil { + return err } - d.Set("primary_file_endpoint", fileEndpoint) - d.Set("primary_file_host", fileHost) - - if primary == nil { - return fmt.Errorf("primary endpoints should not be empty") + if err := setEndpointAndHost(d, "primary", primary.Queue, "queue"); err != nil { + return err + } + if err := setEndpointAndHost(d, "primary", primary.Table, "table"); err != nil { + return err + } + if err := setEndpointAndHost(d, "primary", primary.Web, "web"); err != nil { + return err } return nil } func flattenAndSetAzureRmStorageAccountSecondaryEndpoints(d *schema.ResourceData, secondary *storage.Endpoints) error { - var blobEndpoint, blobHost string - if secondary != nil { - if v := secondary.Blob; v != nil { - blobEndpoint = *v - - if u, err := url.Parse(*v); err == nil { - blobHost = u.Host - } else { - return fmt.Errorf("invalid blob endpoint for parsing: %q", *v) - } - } + if secondary == nil { + return nil } - d.Set("secondary_blob_endpoint", blobEndpoint) - d.Set("secondary_blob_host", blobHost) - - var queueEndpoint, queueHost string - if secondary != nil { - if v := secondary.Queue; v != nil { - queueEndpoint = *v - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid queue endpoint for parsing: %q", *v) - } - queueHost = u.Host - } + if err := setEndpointAndHost(d, "secondary", secondary.Blob, "blob"); err != nil { + return err + } + if err := setEndpointAndHost(d, "secondary", secondary.Dfs, "dfs"); err != nil { + return err + } + if err := setEndpointAndHost(d, "secondary", secondary.File, "file"); err != nil { + return err + } + if err := setEndpointAndHost(d, "secondary", secondary.Queue, "queue"); err != nil { + return err } - d.Set("secondary_queue_endpoint", queueEndpoint) - d.Set("secondary_queue_host", queueHost) + if err := setEndpointAndHost(d, "secondary", secondary.Table, "table"); err != nil { + return err + } + if err := setEndpointAndHost(d, "secondary", secondary.Web, "web"); err != nil { + return err + } + return nil +} - var tableEndpoint, tableHost string - if secondary != nil { - if v := secondary.Table; v != nil { - tableEndpoint = *v +func setEndpointAndHost(d *schema.ResourceData, ordinalString string, endpointType *string, typeString string) error { + var endpoint, host string + if v := endpointType; v != nil { + endpoint = *v - u, err := url.Parse(*v) - if err != nil { - return fmt.Errorf("invalid table endpoint for parsing: %q", *v) - } - tableHost = u.Host + u, err := url.Parse(*v) + if err != nil { + return fmt.Errorf("invalid %s endpoint for parsing: %q", typeString, *v) } + host = u.Host } - d.Set("secondary_table_endpoint", tableEndpoint) - d.Set("secondary_table_host", tableHost) + d.Set(fmt.Sprintf("%s_%s_endpoint", ordinalString, typeString), endpoint) + d.Set(fmt.Sprintf("%s_%s_host", ordinalString, typeString), host) return nil } diff --git a/azurerm/resource_arm_storage_account_migration.go b/azurerm/resource_arm_storage_account_migration.go index 152746678a93..8b08dae524fb 100644 --- a/azurerm/resource_arm_storage_account_migration.go +++ b/azurerm/resource_arm_storage_account_migration.go @@ -5,7 +5,7 @@ import ( "log" "strings" - "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-02-01/storage" + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage" "github.com/hashicorp/terraform/terraform" ) diff --git a/azurerm/resource_arm_storage_account_test.go b/azurerm/resource_arm_storage_account_test.go index 4b75e988c10f..b9ada44df9a6 100644 --- a/azurerm/resource_arm_storage_account_test.go +++ b/azurerm/resource_arm_storage_account_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" @@ -98,7 +99,7 @@ func TestAccAzureRMStorageAccount_basic(t *testing.T) { } func TestAccAzureRMStorageAccount_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -397,6 +398,72 @@ func TestAccAzureRMStorageAccount_blobStorageWithUpdate(t *testing.T) { }) } +func TestAccAzureRMStorageAccount_blockBlobStorage(t *testing.T) { + resourceName := "azurerm_storage_account.testsa" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageAccount_blockBlobStorage(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "account_kind", "BlockBlobStorage"), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "access_tier", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMStorageAccount_fileStorageWithUpdate(t *testing.T) { + resourceName := "azurerm_storage_account.testsa" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + preConfig := testAccAzureRMStorageAccount_fileStorage(ri, rs, location) + postConfig := testAccAzureRMStorageAccount_fileStorageUpdate(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "account_kind", "FileStorage"), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "account_tier", "Premium"), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "access_tier", "Hot"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "account_tier", "Premium"), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "access_tier", "Cool"), + ), + }, + }, + }) +} func TestAccAzureRMStorageAccount_storageV2WithUpdate(t *testing.T) { resourceName := "azurerm_storage_account.testsa" ri := tf.AccRandTimeInt() @@ -543,6 +610,7 @@ func TestAccAzureRMStorageAccount_networkRules(t *testing.T) { Config: preConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_rules.0.default_action", "Deny"), resource.TestCheckResourceAttr(resourceName, "network_rules.0.ip_rules.#", "1"), resource.TestCheckResourceAttr(resourceName, "network_rules.0.virtual_network_subnet_ids.#", "1"), ), @@ -556,8 +624,9 @@ func TestAccAzureRMStorageAccount_networkRules(t *testing.T) { Config: postConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_rules.0.default_action", "Deny"), resource.TestCheckResourceAttr(resourceName, "network_rules.0.ip_rules.#", "2"), - resource.TestCheckResourceAttr(resourceName, "network_rules.0.virtual_network_subnet_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "network_rules.0.virtual_network_subnet_ids.#", "1"), resource.TestCheckResourceAttr(resourceName, "network_rules.0.bypass.#", "2"), ), }, @@ -571,7 +640,7 @@ func TestAccAzureRMStorageAccount_networkRulesDeleted(t *testing.T) { rs := acctest.RandString(4) location := testLocation() preConfig := testAccAzureRMStorageAccount_networkRules(ri, rs, location) - postConfig := testAccAzureRMStorageAccount_basic(ri, rs, location) + postConfig := testAccAzureRMStorageAccount_networkRulesReverted(ri, rs, location) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -582,6 +651,7 @@ func TestAccAzureRMStorageAccount_networkRulesDeleted(t *testing.T) { Config: preConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "network_rules.0.default_action", "Deny"), resource.TestCheckResourceAttr(resourceName, "network_rules.0.ip_rules.#", "1"), resource.TestCheckResourceAttr(resourceName, "network_rules.0.virtual_network_subnet_ids.#", "1"), ), @@ -590,9 +660,89 @@ func TestAccAzureRMStorageAccount_networkRulesDeleted(t *testing.T) { Config: postConfig, Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageAccountExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "network_rules.#", "0"), + resource.TestCheckResourceAttr(resourceName, "network_rules.0.default_action", "Allow"), + ), + }, + }, + }) +} + +func TestAccAzureRMStorageAccount_enableAdvancedThreatProtection(t *testing.T) { + resourceName := "azurerm_storage_account.testsa" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + preConfig := testAccAzureRMStorageAccount_enableAdvancedThreatProtection(ri, rs, location) + postConfig := testAccAzureRMStorageAccount_enableAdvancedThreatProtectionDisabled(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "enable_advanced_threat_protection", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + resource.TestCheckResourceAttr("azurerm_storage_account.testsa", "enable_advanced_threat_protection", "false"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMStorageAccount_queueProperties(t *testing.T) { + resourceName := "azurerm_storage_account.testsa" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + location := testLocation() + preConfig := testAccAzureRMStorageAccount_queueProperties(ri, rs, location) + postConfig := testAccAzureRMStorageAccount_queuePropertiesUpdated(ri, rs, location) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageAccountDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageAccountExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -610,9 +760,9 @@ func testCheckAzureRMStorageAccountExists(resourceName string) resource.TestChec // Ensure resource group exists in API ctx := testAccProvider.Meta().(*ArmClient).StopContext - conn := testAccProvider.Meta().(*ArmClient).storageServiceClient + conn := testAccProvider.Meta().(*ArmClient).storage.AccountsClient - resp, err := conn.GetProperties(ctx, resourceGroup, storageAccount) + resp, err := conn.GetProperties(ctx, resourceGroup, storageAccount, "") if err != nil { return fmt.Errorf("Bad: Get on storageServiceClient: %+v", err) } @@ -638,7 +788,7 @@ func testCheckAzureRMStorageAccountDisappears(resourceName string) resource.Test // Ensure resource group exists in API ctx := testAccProvider.Meta().(*ArmClient).StopContext - conn := testAccProvider.Meta().(*ArmClient).storageServiceClient + conn := testAccProvider.Meta().(*ArmClient).storage.AccountsClient if _, err := conn.Delete(ctx, resourceGroup, storageAccount); err != nil { return fmt.Errorf("Bad: Delete on storageServiceClient: %+v", err) @@ -650,7 +800,7 @@ func testCheckAzureRMStorageAccountDisappears(resourceName string) resource.Test func testCheckAzureRMStorageAccountDestroy(s *terraform.State) error { ctx := testAccProvider.Meta().(*ArmClient).StopContext - conn := testAccProvider.Meta().(*ArmClient).storageServiceClient + conn := testAccProvider.Meta().(*ArmClient).storage.AccountsClient for _, rs := range s.RootModule().Resources { if rs.Type != "azurerm_storage_account" { @@ -660,7 +810,7 @@ func testCheckAzureRMStorageAccountDestroy(s *terraform.State) error { name := rs.Primary.Attributes["name"] resourceGroup := rs.Primary.Attributes["resource_group_name"] - resp, err := conn.GetProperties(ctx, resourceGroup, name) + resp, err := conn.GetProperties(ctx, resourceGroup, name, "") if err != nil { return nil } @@ -903,11 +1053,11 @@ resource "azurerm_storage_account" "testsa" { name = "unlikely23exst2acct%s" resource_group_name = "${azurerm_resource_group.testrg.name}" - location = "${azurerm_resource_group.testrg.location}" - account_kind = "StorageV2" - account_tier = "Standard" - account_replication_type = "LRS" - is_hns_enabled = true + location = "${azurerm_resource_group.testrg.location}" + account_kind = "StorageV2" + account_tier = "Standard" + account_replication_type = "LRS" + is_hns_enabled = true } `, rInt, location, rString) } @@ -923,11 +1073,11 @@ resource "azurerm_storage_account" "testsa" { name = "unlikely23exst2acct%s" resource_group_name = "${azurerm_resource_group.testrg.name}" - location = "${azurerm_resource_group.testrg.location}" - account_kind = "StorageV2" - account_tier = "Standard" - account_replication_type = "LRS" - is_hns_enabled = false + location = "${azurerm_resource_group.testrg.location}" + account_kind = "StorageV2" + account_tier = "Standard" + account_replication_type = "LRS" + is_hns_enabled = false } `, rInt, location, rString) } @@ -979,6 +1129,77 @@ resource "azurerm_storage_account" "testsa" { `, rInt, location, rString) } +func testAccAzureRMStorageAccount_blockBlobStorage(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestAzureRMSA-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_kind = "BlockBlobStorage" + account_tier = "Premium" + account_replication_type = "LRS" + + tags = { + environment = "production" + } +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccount_fileStorage(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestAzureRMSA-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_kind = "FileStorage" + account_tier = "Premium" + account_replication_type = "LRS" + access_tier = "Hot" + + tags = { + environment = "production" + } +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccount_fileStorageUpdate(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestAzureRMSA-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_kind = "FileStorage" + account_tier = "Premium" + account_replication_type = "LRS" + access_tier = "Cool" + + tags = { + environment = "production" + } +} +`, rInt, location, rString) +} + func testAccAzureRMStorageAccount_storageV2(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "testrg" { @@ -1103,6 +1324,7 @@ resource "azurerm_storage_account" "testsa" { account_replication_type = "LRS" network_rules { + default_action = "Deny" ip_rules = ["127.0.0.1"] virtual_network_subnet_ids = ["${azurerm_subnet.test.id}"] } @@ -1144,8 +1366,51 @@ resource "azurerm_storage_account" "testsa" { account_replication_type = "LRS" network_rules { - ip_rules = ["127.0.0.1", "127.0.0.2"] - bypass = ["Logging", "Metrics"] + default_action = "Deny" + ip_rules = ["127.0.0.1", "127.0.0.2"] + bypass = ["Logging", "Metrics"] + } + + tags = { + environment = "production" + } +} +`, rInt, location, rInt, rInt, rString) +} + +func testAccAzureRMStorageAccount_networkRulesReverted(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestAzureRMSA-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.testrg.location}" + resource_group_name = "${azurerm_resource_group.testrg.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.testrg.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + service_endpoints = ["Microsoft.Storage"] +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + network_rules { + default_action = "Allow" + ip_rules = ["127.0.0.1"] + virtual_network_subnet_ids = ["${azurerm_subnet.test.id}"] } tags = { @@ -1154,3 +1419,143 @@ resource "azurerm_storage_account" "testsa" { } `, rInt, location, rInt, rInt, rString) } + +func testAccAzureRMStorageAccount_enableAdvancedThreatProtection(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestAzureRMSA-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + enable_advanced_threat_protection = true +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccount_enableAdvancedThreatProtectionDisabled(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestAzureRMSA-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + enable_advanced_threat_protection = false +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccount_queueProperties(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestAzureRMSA-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + queue_properties { + cors_rule { + allowed_origins = ["http://www.example.com"] + exposed_headers = ["x-tempo-*"] + allowed_headers = ["x-tempo-*"] + allowed_methods = ["GET", "PUT"] + max_age_in_seconds = "500" + } + + logging { + version = "1.0" + delete = true + read = true + write = true + retention_policy_days = 7 + } + + hour_metrics { + version = "1.0" + enabled = false + retention_policy_days = 7 + } + + minute_metrics { + version = "1.0" + enabled = false + retention_policy_days = 7 + } + } +} +`, rInt, location, rString) +} + +func testAccAzureRMStorageAccount_queuePropertiesUpdated(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "testrg" { + name = "acctestAzureRMSA-%d" + location = "%s" +} + +resource "azurerm_storage_account" "testsa" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.testrg.name}" + + location = "${azurerm_resource_group.testrg.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + queue_properties { + cors_rule { + allowed_origins = ["http://www.example.com"] + exposed_headers = ["x-tempo-*", "x-method-*"] + allowed_headers = ["*"] + allowed_methods = ["GET"] + max_age_in_seconds = "2000000000" + } + cors_rule { + allowed_origins = ["http://www.test.com"] + exposed_headers = ["x-tempo-*"] + allowed_headers = ["*"] + allowed_methods = ["PUT"] + max_age_in_seconds = "1000" + } + logging { + version = "1.0" + delete = true + read = true + write = true + retention_policy_days = 7 + } + + hour_metrics { + version = "1.0" + enabled = true + retention_policy_days = 7 + include_apis = true + } + + minute_metrics { + version = "1.0" + enabled = true + include_apis = false + retention_policy_days = 7 + } + } +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_storage_blob.go b/azurerm/resource_arm_storage_blob.go index 9dd53a057da1..f122d83b236e 100644 --- a/azurerm/resource_arm_storage_blob.go +++ b/azurerm/resource_arm_storage_blob.go @@ -1,28 +1,19 @@ package azurerm import ( - "bytes" - "crypto/rand" - "encoding/base64" "fmt" - "io" "log" - "net/url" - "os" - "runtime" "strings" - "sync" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" - - "github.com/hashicorp/terraform/helper/validation" - + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" - - "github.com/Azure/azure-sdk-for-go/storage" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/hashicorp/terraform/helper/schema" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs" ) func resourceArmStorageBlob() *schema.Resource { @@ -42,20 +33,21 @@ func resourceArmStorageBlob() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, + // TODO: add validation }, - "resource_group_name": resourceGroupNameSchema(), - "storage_account_name": { Type: schema.TypeString, Required: true, ForceNew: true, + // TODO: add validation }, "storage_container_name": { Type: schema.TypeString, Required: true, ForceNew: true, + // TODO: add validation }, "type": { @@ -74,10 +66,9 @@ func resourceArmStorageBlob() *schema.Resource { }, "content_type": { - Type: schema.TypeString, - Optional: true, - Default: "application/octet-stream", - ConflictsWith: []string{"source_uri"}, + Type: schema.TypeString, + Optional: true, + Default: "application/octet-stream", }, "source": { @@ -100,6 +91,7 @@ func resourceArmStorageBlob() *schema.Resource { }, "parallelism": { + // TODO: @tombuildsstuff - a note this only works for Page blobs Type: schema.TypeInt, Optional: true, Default: 8, @@ -107,626 +99,225 @@ func resourceArmStorageBlob() *schema.Resource { ValidateFunc: validation.IntAtLeast(1), }, + "metadata": storage.MetaDataSchema(), + + // Deprecated fields "attempts": { Type: schema.TypeInt, Optional: true, Default: 1, ForceNew: true, + Deprecated: "Retries are now handled by the Azure SDK as such this field is no longer necessary and will be removed in v2.0 of the Azure Provider", ValidateFunc: validation.IntAtLeast(1), }, + + "resource_group_name": azure.SchemaResourceGroupNameDeprecated(), }, } } func resourceArmStorageBlobCreate(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext - env := armClient.environment - - resourceGroupName := d.Get("resource_group_name").(string) - storageAccountName := d.Get("storage_account_name").(string) + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroupName, storageAccountName) - if err != nil { - return err - } - if !accountExists { - return fmt.Errorf("Storage Account %q Not Found", storageAccountName) - } - - name := d.Get("name").(string) - blobType := d.Get("type").(string) + accountName := d.Get("storage_account_name").(string) containerName := d.Get("storage_container_name").(string) - sourceUri := d.Get("source_uri").(string) - contentType := d.Get("content_type").(string) - - log.Printf("[INFO] Creating blob %q in container %q within storage account %q", name, containerName, storageAccountName) - container := blobClient.GetContainerReference(containerName) - blob := container.GetBlobReference(name) - - // gives us https://example.blob.core.windows.net/container/file.vhd - id := fmt.Sprintf("https://%s.blob.%s/%s/%s", storageAccountName, env.StorageEndpointSuffix, containerName, name) - if requireResourcesToBeImported && d.IsNewResource() { - exists, err := blob.Exists() - if err != nil { - return fmt.Errorf("Error checking if Blob %q exists (Container %q / Account %q / Resource Group %q): %s", name, containerName, storageAccountName, resourceGroupName, err) - } - - if exists { - return tf.ImportAsExistsError("azurerm_storage_blob", id) - } - } - - if sourceUri != "" { - options := &storage.CopyOptions{} - if err := blob.Copy(sourceUri, options); err != nil { - return fmt.Errorf("Error creating storage blob on Azure: %s", err) - } - } else { - switch strings.ToLower(blobType) { - case "block": - options := &storage.PutBlobOptions{} - if err := blob.CreateBlockBlob(options); err != nil { - return fmt.Errorf("Error creating storage blob on Azure: %s", err) - } - - source := d.Get("source").(string) - if source != "" { - parallelism := d.Get("parallelism").(int) - attempts := d.Get("attempts").(int) - - if err := resourceArmStorageBlobBlockUploadFromSource(containerName, name, source, contentType, blobClient, parallelism, attempts); err != nil { - return fmt.Errorf("Error creating storage blob on Azure: %s", err) - } - } - case "page": - source := d.Get("source").(string) - if source != "" { - parallelism := d.Get("parallelism").(int) - attempts := d.Get("attempts").(int) - - if err := resourceArmStorageBlobPageUploadFromSource(containerName, name, source, contentType, blobClient, parallelism, attempts); err != nil { - return fmt.Errorf("Error creating storage blob on Azure: %s", err) - } - } else { - size := int64(d.Get("size").(int)) - options := &storage.PutBlobOptions{} - - blob.Properties.ContentLength = size - blob.Properties.ContentType = contentType - if err := blob.PutPageBlob(options); err != nil { - return fmt.Errorf("Error creating storage blob on Azure: %s", err) - } - } - } - } - - d.SetId(id) - return resourceArmStorageBlobRead(d, meta) -} - -type resourceArmStorageBlobPage struct { - offset int64 - section *io.SectionReader -} - -func resourceArmStorageBlobPageUploadFromSource(container, name, source, contentType string, client *storage.BlobStorageClient, parallelism, attempts int) error { - workerCount := parallelism * runtime.NumCPU() - - file, err := os.Open(source) - if err != nil { - return fmt.Errorf("Error opening source file for upload %q: %s", source, err) - } - defer utils.IoCloseAndLogError(file, fmt.Sprintf("Error closing Storage Blob `%s` file `%s` after upload", name, source)) - - blobSize, pageList, err := resourceArmStorageBlobPageSplit(file) - if err != nil { - return fmt.Errorf("Error splitting source file %q into pages: %s", source, err) - } + name := d.Get("name").(string) - options := &storage.PutBlobOptions{} - containerRef := client.GetContainerReference(container) - blob := containerRef.GetBlobReference(name) - blob.Properties.ContentLength = blobSize - blob.Properties.ContentType = contentType - err = blob.PutPageBlob(options) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return fmt.Errorf("Error creating storage blob on Azure: %s", err) - } - - pages := make(chan resourceArmStorageBlobPage, len(pageList)) - errors := make(chan error, len(pageList)) - wg := &sync.WaitGroup{} - wg.Add(len(pageList)) - - total := int64(0) - for _, page := range pageList { - total += page.section.Size() - pages <- page - } - close(pages) - - for i := 0; i < workerCount; i++ { - go resourceArmStorageBlobPageUploadWorker(resourceArmStorageBlobPageUploadContext{ - container: container, - name: name, - source: source, - blobSize: blobSize, - client: client, - pages: pages, - errors: errors, - wg: wg, - attempts: attempts, - }) + return fmt.Errorf("Error locating Resource Group for Storage Account %q: %s", accountName, err) } - - wg.Wait() - - if len(errors) > 0 { - return fmt.Errorf("Error while uploading source file %q: %s", source, <-errors) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Blob %q (Container %q / Account %q)", name, containerName, accountName) } - return nil -} - -func resourceArmStorageBlobPageSplit(file *os.File) (int64, []resourceArmStorageBlobPage, error) { - const ( - minPageSize int64 = 4 * 1024 - maxPageSize int64 = 4 * 1024 * 1024 - ) - - info, err := file.Stat() + blobsClient, err := storageClient.BlobsClient(ctx, *resourceGroup, accountName) if err != nil { - return int64(0), nil, fmt.Errorf("Could not stat file %q: %s", file.Name(), err) + return fmt.Errorf("Error building Blobs Client: %s", err) } - blobSize := info.Size() - if info.Size()%minPageSize != 0 { - blobSize = info.Size() + (minPageSize - (info.Size() % minPageSize)) - } - - emptyPage := make([]byte, minPageSize) - - type byteRange struct { - offset int64 - length int64 - } - - var nonEmptyRanges []byteRange - var currentRange byteRange - for i := int64(0); i < blobSize; i += minPageSize { - pageBuf := make([]byte, minPageSize) - _, err = file.ReadAt(pageBuf, i) - if err != nil && err != io.EOF { - return int64(0), nil, fmt.Errorf("Could not read chunk at %d: %s", i, err) - } - - if bytes.Equal(pageBuf, emptyPage) { - if currentRange.length != 0 { - nonEmptyRanges = append(nonEmptyRanges, currentRange) - } - currentRange = byteRange{ - offset: i + minPageSize, - } - } else { - currentRange.length += minPageSize - if currentRange.length == maxPageSize || (currentRange.offset+currentRange.length == blobSize) { - nonEmptyRanges = append(nonEmptyRanges, currentRange) - currentRange = byteRange{ - offset: i + minPageSize, - } - } - } - } - - var pages []resourceArmStorageBlobPage - for _, nonEmptyRange := range nonEmptyRanges { - pages = append(pages, resourceArmStorageBlobPage{ - offset: nonEmptyRange.offset, - section: io.NewSectionReader(file, nonEmptyRange.offset, nonEmptyRange.length), - }) - } - - return info.Size(), pages, nil -} - -type resourceArmStorageBlobPageUploadContext struct { - container string - name string - source string - blobSize int64 - client *storage.BlobStorageClient - pages chan resourceArmStorageBlobPage - errors chan error - wg *sync.WaitGroup - attempts int -} - -func resourceArmStorageBlobPageUploadWorker(ctx resourceArmStorageBlobPageUploadContext) { - for page := range ctx.pages { - start := page.offset - end := page.offset + page.section.Size() - 1 - if end > ctx.blobSize-1 { - end = ctx.blobSize - 1 - } - size := end - start + 1 - - chunk := make([]byte, size) - _, err := page.section.Read(chunk) - if err != nil && err != io.EOF { - ctx.errors <- fmt.Errorf("Error reading source file %q at offset %d: %s", ctx.source, page.offset, err) - ctx.wg.Done() - continue - } - - for x := 0; x < ctx.attempts; x++ { - container := ctx.client.GetContainerReference(ctx.container) - blob := container.GetBlobReference(ctx.name) - blobRange := storage.BlobRange{ - Start: uint64(start), - End: uint64(end), - } - options := &storage.PutPageOptions{} - reader := bytes.NewReader(chunk) - err = blob.WriteRange(blobRange, reader, options) - if err == nil { - break + id := blobsClient.GetResourceID(accountName, containerName, name) + if features.ShouldResourcesBeImported() && d.IsNewResource() { + input := blobs.GetPropertiesInput{} + props, err := blobsClient.GetProperties(ctx, accountName, containerName, name, input) + if err != nil { + if !utils.ResponseWasNotFound(props.Response) { + return fmt.Errorf("Error checking if Blob %q exists (Container %q / Account %q / Resource Group %q): %s", name, containerName, accountName, *resourceGroup, err) } } - if err != nil { - ctx.errors <- fmt.Errorf("Error writing page at offset %d for file %q: %s", page.offset, ctx.source, err) - ctx.wg.Done() - continue + if !utils.ResponseWasNotFound(props.Response) { + return tf.ImportAsExistsError("azurerm_storage_blob", id) } - - ctx.wg.Done() - } -} - -type resourceArmStorageBlobBlock struct { - section *io.SectionReader - id string -} - -func resourceArmStorageBlobBlockUploadFromSource(container, name, source, contentType string, client *storage.BlobStorageClient, parallelism, attempts int) error { - workerCount := parallelism * runtime.NumCPU() - - file, err := os.Open(source) - if err != nil { - return fmt.Errorf("Error opening source file for upload %q: %s", source, err) - } - defer utils.IoCloseAndLogError(file, fmt.Sprintf("Error closing Storage Blob `%s` file `%s` after upload", name, source)) - - blockList, parts, err := resourceArmStorageBlobBlockSplit(file) - if err != nil { - return fmt.Errorf("Error reading and splitting source file for upload %q: %s", source, err) - } - - wg := &sync.WaitGroup{} - blocks := make(chan resourceArmStorageBlobBlock, len(parts)) - errors := make(chan error, len(parts)) - - wg.Add(len(parts)) - for _, p := range parts { - blocks <- p - } - close(blocks) - - for i := 0; i < workerCount; i++ { - go resourceArmStorageBlobBlockUploadWorker(resourceArmStorageBlobBlockUploadContext{ - client: client, - source: source, - container: container, - name: name, - blocks: blocks, - errors: errors, - wg: wg, - attempts: attempts, - }) } - wg.Wait() + log.Printf("[DEBUG] Creating Blob %q in Container %q within Storage Account %q..", name, containerName, accountName) + metaDataRaw := d.Get("metadata").(map[string]interface{}) + blobInput := storage.BlobUpload{ + AccountName: accountName, + ContainerName: containerName, + BlobName: name, + Client: blobsClient, - if len(errors) > 0 { - return fmt.Errorf("Error while uploading source file %q: %s", source, <-errors) + BlobType: d.Get("type").(string), + ContentType: d.Get("content_type").(string), + MetaData: storage.ExpandMetaData(metaDataRaw), + Parallelism: d.Get("parallelism").(int), + Size: d.Get("size").(int), + Source: d.Get("source").(string), + SourceUri: d.Get("source_uri").(string), } - - containerReference := client.GetContainerReference(container) - blobReference := containerReference.GetBlobReference(name) - blobReference.Properties.ContentType = contentType - options := &storage.PutBlockListOptions{} - err = blobReference.PutBlockList(blockList, options) - if err != nil { - return fmt.Errorf("Error updating block list for source file %q: %s", source, err) - } - - return nil -} - -func resourceArmStorageBlobBlockSplit(file *os.File) ([]storage.Block, []resourceArmStorageBlobBlock, error) { - const ( - idSize = 64 - blockSize int64 = 4 * 1024 * 1024 - ) - var parts []resourceArmStorageBlobBlock - var blockList []storage.Block - - info, err := file.Stat() - if err != nil { - return nil, nil, fmt.Errorf("Error stating source file %q: %s", file.Name(), err) - } - - for i := int64(0); i < info.Size(); i = i + blockSize { - entropy := make([]byte, idSize) - _, err = rand.Read(entropy) - if err != nil { - return nil, nil, fmt.Errorf("Error generating a random block ID for source file %q: %s", file.Name(), err) - } - - sectionSize := blockSize - remainder := info.Size() - i - if remainder < blockSize { - sectionSize = remainder - } - - block := storage.Block{ - ID: base64.StdEncoding.EncodeToString(entropy), - Status: storage.BlockStatusUncommitted, - } - - blockList = append(blockList, block) - - parts = append(parts, resourceArmStorageBlobBlock{ - id: block.ID, - section: io.NewSectionReader(file, i, sectionSize), - }) + if err := blobInput.Create(ctx); err != nil { + return fmt.Errorf("Error creating Blob %q (Container %q / Account %q): %s", name, containerName, accountName, err) } + log.Printf("[DEBUG] Created Blob %q in Container %q within Storage Account %q.", name, containerName, accountName) - return blockList, parts, nil -} - -type resourceArmStorageBlobBlockUploadContext struct { - client *storage.BlobStorageClient - container string - name string - source string - attempts int - blocks chan resourceArmStorageBlobBlock - errors chan error - wg *sync.WaitGroup -} - -func resourceArmStorageBlobBlockUploadWorker(ctx resourceArmStorageBlobBlockUploadContext) { - for block := range ctx.blocks { - buffer := make([]byte, block.section.Size()) - - _, err := block.section.Read(buffer) - if err != nil { - ctx.errors <- fmt.Errorf("Error reading source file %q: %s", ctx.source, err) - ctx.wg.Done() - continue - } - - for i := 0; i < ctx.attempts; i++ { - container := ctx.client.GetContainerReference(ctx.container) - blob := container.GetBlobReference(ctx.name) - options := &storage.PutBlockOptions{} - if err = blob.PutBlock(block.id, buffer, options); err == nil { - break - } - } - if err != nil { - ctx.errors <- fmt.Errorf("Error uploading block %q for source file %q: %s", block.id, ctx.source, err) - ctx.wg.Done() - continue - } + d.SetId(id) - ctx.wg.Done() - } + return resourceArmStorageBlobUpdate(d, meta) } func resourceArmStorageBlobUpdate(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext - id, err := parseStorageBlobID(d.Id(), armClient.environment) + id, err := blobs.ParseResourceID(d.Id()) if err != nil { - return err + return fmt.Errorf("Error parsing %q: %s", d.Id(), err) } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Account %q: %s", id.AccountName, err) } - if resourceGroup == nil { - return fmt.Errorf("Unable to determine Resource Group for Storage Account %q", id.storageAccountName) + return fmt.Errorf("Unable to locate Resource Group for Blob %q (Container %q / Account %q)", id.BlobName, id.ContainerName, id.AccountName) } - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) + blobsClient, err := storageClient.BlobsClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return fmt.Errorf("Error getting storage account %s: %+v", id.storageAccountName, err) - } - if !accountExists { - return fmt.Errorf("Storage account %s not found in resource group %s", id.storageAccountName, *resourceGroup) + return fmt.Errorf("Error building Blobs Client: %s", err) } - container := blobClient.GetContainerReference(id.containerName) - blob := container.GetBlobReference(id.blobName) + // TODO: changing the access tier if d.HasChange("content_type") { - blob.Properties.ContentType = d.Get("content_type").(string) + log.Printf("[DEBUG] Updating Properties for Blob %q (Container %q / Account %q)...", id.BlobName, id.ContainerName, id.AccountName) + input := blobs.SetPropertiesInput{ + ContentType: utils.String(d.Get("content_type").(string)), + } + if _, err := blobsClient.SetProperties(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("Error updating Properties for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + } + log.Printf("[DEBUG] Updated Properties for Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) } - options := &storage.SetBlobPropertiesOptions{} - err = blob.SetProperties(options) - if err != nil { - return fmt.Errorf("Error setting properties of blob %s (container %s, storage account %s): %+v", id.blobName, id.containerName, id.storageAccountName, err) + if d.HasChange("metadata") { + log.Printf("[DEBUG] Updating MetaData for Blob %q (Container %q / Account %q)...", id.BlobName, id.ContainerName, id.AccountName) + metaDataRaw := d.Get("metadata").(map[string]interface{}) + input := blobs.SetMetaDataInput{ + MetaData: storage.ExpandMetaData(metaDataRaw), + } + if _, err := blobsClient.SetMetaData(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("Error updating MetaData for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + } + log.Printf("[DEBUG] Updated MetaData for Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) } return nil } func resourceArmStorageBlobRead(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext - id, err := parseStorageBlobID(d.Id(), armClient.environment) + id, err := blobs.ParseResourceID(d.Id()) if err != nil { - return err + return fmt.Errorf("Error parsing %q: %s", d.Id(), err) } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Account %q: %s", id.AccountName, err) } - if resourceGroup == nil { - return fmt.Errorf("Unable to determine Resource Group for Storage Account %q", id.storageAccountName) - } - - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) - if err != nil { - return err - } - if !accountExists { - log.Printf("[DEBUG] Storage account %q not found, removing blob %q from state", id.storageAccountName, d.Id()) + log.Printf("[DEBUG] Unable to locate Resource Group for Blob %q (Container %q / Account %q) - assuming removed & removing from state!", id.BlobName, id.ContainerName, id.AccountName) d.SetId("") return nil } - log.Printf("[INFO] Checking for existence of storage blob %q in container %q.", id.blobName, id.containerName) - container := blobClient.GetContainerReference(id.containerName) - blob := container.GetBlobReference(id.blobName) - exists, err := blob.Exists() + blobsClient, err := storageClient.BlobsClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return fmt.Errorf("error checking for existence of storage blob %q: %s", id.blobName, err) + return fmt.Errorf("Error building Blobs Client: %s", err) } - if !exists { - log.Printf("[INFO] Storage blob %q no longer exists, removing from state...", id.blobName) - d.SetId("") - return nil - } - - options := &storage.GetBlobPropertiesOptions{} - err = blob.GetProperties(options) + log.Printf("[INFO] Retrieving Storage Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + input := blobs.GetPropertiesInput{} + props, err := blobsClient.GetProperties(ctx, id.AccountName, id.ContainerName, id.BlobName, input) if err != nil { - return fmt.Errorf("Error getting properties of blob %s (container %s, storage account %s): %+v", id.blobName, id.containerName, id.storageAccountName, err) + if utils.ResponseWasNotFound(props.Response) { + log.Printf("[INFO] Blob %q was not found in Container %q / Account %q - assuming removed & removing from state...", id.BlobName, id.ContainerName, id.AccountName) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving properties for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) } - d.Set("name", id.blobName) - d.Set("storage_container_name", id.containerName) - d.Set("storage_account_name", id.storageAccountName) + d.Set("name", id.BlobName) + d.Set("storage_container_name", id.ContainerName) + d.Set("storage_account_name", id.AccountName) d.Set("resource_group_name", resourceGroup) - d.Set("content_type", blob.Properties.ContentType) + d.Set("content_type", props.ContentType) - d.Set("source_uri", blob.Properties.CopySource) + // The CopySource is only returned if the blob hasn't been modified (e.g. metadata configured etc) + // as such, we need to conditionally set this to ensure it's trackable if possible + if props.CopySource != "" { + d.Set("source_uri", props.CopySource) + } - blobType := strings.ToLower(strings.Replace(string(blob.Properties.BlobType), "Blob", "", 1)) + blobType := strings.ToLower(strings.Replace(string(props.BlobType), "Blob", "", 1)) d.Set("type", blobType) - u := blob.GetURL() - if u == "" { - log.Printf("[INFO] URL for %q is empty", id.blobName) + d.Set("url", d.Id()) + + if err := d.Set("metadata", storage.FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("Error setting `metadata`: %+v", err) } - d.Set("url", u) return nil } func resourceArmStorageBlobDelete(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext - id, err := parseStorageBlobID(d.Id(), armClient.environment) + id, err := blobs.ParseResourceID(d.Id()) if err != nil { - return err + return fmt.Errorf("Error parsing %q: %s", d.Id(), err) } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return fmt.Errorf("Unable to determine Resource Group for Storage Account %q: %+v", id.storageAccountName, err) + return fmt.Errorf("Error locating Resource Group for Storage Account %q: %s", id.AccountName, err) } if resourceGroup == nil { - log.Printf("[INFO] Resource Group doesn't exist so the blob won't exist") - return nil + return fmt.Errorf("Unable to locate Resource Group for Storage Account %q!", id.AccountName) } - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) + blobsClient, err := storageClient.BlobsClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return err - } - if !accountExists { - log.Printf("[INFO] Storage Account %q doesn't exist so the blob won't exist", id.storageAccountName) - return nil + return fmt.Errorf("Error building Blobs Client: %s", err) } - log.Printf("[INFO] Deleting storage blob %q", id.blobName) - options := &storage.DeleteBlobOptions{} - container := blobClient.GetContainerReference(id.containerName) - blob := container.GetBlobReference(id.blobName) - _, err = blob.DeleteIfExists(options) - if err != nil { - return fmt.Errorf("Error deleting storage blob %q: %s", id.blobName, err) + log.Printf("[INFO] Deleting Blob %q from Container %q / Storage Account %q", id.BlobName, id.ContainerName, id.AccountName) + input := blobs.DeleteInput{ + DeleteSnapshots: true, } - - return nil -} - -type storageBlobId struct { - storageAccountName string - containerName string - blobName string -} - -func parseStorageBlobID(input string, environment azure.Environment) (*storageBlobId, error) { - uri, err := url.Parse(input) - if err != nil { - return nil, fmt.Errorf("Error parsing %q as URI: %+v", input, err) - } - - // trim the leading `/` - segments := strings.Split(strings.TrimPrefix(uri.Path, "/"), "/") - if len(segments) < 2 { - return nil, fmt.Errorf("Expected number of segments in the path to be < 2 but got %d", len(segments)) - } - - storageAccountName := strings.Replace(uri.Host, fmt.Sprintf(".blob.%s", environment.StorageEndpointSuffix), "", 1) - containerName := segments[0] - blobName := strings.TrimPrefix(uri.Path, fmt.Sprintf("/%s/", containerName)) - - id := storageBlobId{ - storageAccountName: storageAccountName, - containerName: containerName, - blobName: blobName, + if _, err := blobsClient.Delete(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("Error deleting Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) } - return &id, nil -} - -func determineResourceGroupForStorageAccount(accountName string, client *ArmClient) (*string, error) { - storageClient := client.storageServiceClient - ctx := client.StopContext - - // first locate which resource group the storage account is in - groupsResp, err := storageClient.List(ctx) - if err != nil { - return nil, fmt.Errorf("Error loading the Resource Groups for Storage Account %q: %+v", accountName, err) - } - - if groups := groupsResp.Value; groups != nil { - for _, group := range *groups { - if group.Name != nil && *group.Name == accountName { - groupId, err := parseAzureResourceID(*group.ID) - if err != nil { - return nil, err - } - return &groupId.ResourceGroup, nil - } - } - } - - return nil, nil + return nil } diff --git a/azurerm/resource_arm_storage_blob_migration_test.go b/azurerm/resource_arm_storage_blob_migration_test.go index bb21ddc25578..8c941c799984 100644 --- a/azurerm/resource_arm_storage_blob_migration_test.go +++ b/azurerm/resource_arm_storage_blob_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMStorageBlobMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false, "") + client, err := getArmClient(config, false, "", true) if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/azurerm/resource_arm_storage_blob_test.go b/azurerm/resource_arm_storage_blob_test.go index 33035fee4eeb..1e2ea6399252 100644 --- a/azurerm/resource_arm_storage_blob_test.go +++ b/azurerm/resource_arm_storage_blob_test.go @@ -3,20 +3,51 @@ package azurerm import ( "crypto/rand" "fmt" - "io" "io/ioutil" - "testing" - + "os" "strings" + "testing" "github.com/Azure/azure-sdk-for-go/storage" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" ) -func TestAccAzureRMStorageBlob_basic(t *testing.T) { +// TODO: with the new SDK: changing the Tier of Blobs. Content type for Block blobs + +var supportsNewStorageFeatures = false + +func TestAccAzureRMStorageBlob_disappears(t *testing.T) { + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_blockEmpty(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + testCheckAzureRMStorageBlobDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAzureRMStorageBlob_appendEmpty(t *testing.T) { + if !supportsNewStorageFeatures { + t.Skip("Resource doesn't support Append Blobs Yet..") + } + resourceName := "azurerm_storage_blob.test" ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) @@ -28,7 +59,7 @@ func TestAccAzureRMStorageBlob_basic(t *testing.T) { CheckDestroy: testCheckAzureRMStorageBlobDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMStorageBlob_basic(ri, rs, location), + Config: testAccAzureRMStorageBlob_appendEmpty(ri, rs, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageBlobExists(resourceName), ), @@ -42,10 +73,10 @@ func TestAccAzureRMStorageBlob_basic(t *testing.T) { }, }) } -func TestAccAzureRMStorageBlob_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { - t.Skip("Skipping since resources aren't required to be imported") - return + +func TestAccAzureRMStorageBlob_appendEmptyMetaData(t *testing.T) { + if !supportsNewStorageFeatures { + t.Skip("Resource doesn't support Append Blobs Yet..") } resourceName := "azurerm_storage_blob.test" @@ -59,24 +90,26 @@ func TestAccAzureRMStorageBlob_requiresImport(t *testing.T) { CheckDestroy: testCheckAzureRMStorageBlobDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMStorageBlob_basic(ri, rs, location), + Config: testAccAzureRMStorageBlob_appendEmptyMetaData(ri, rs, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageBlobExists(resourceName), ), }, { - Config: testAccAzureRMStorageBlob_requiresImport(ri, rs, location), - ExpectError: testRequiresImportError("azurerm_storage_blob"), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, }, }, }) } -func TestAccAzureRMStorageBlob_disappears(t *testing.T) { +func TestAccAzureRMStorageBlob_blockEmpty(t *testing.T) { resourceName := "azurerm_storage_blob.test" ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - config := testAccAzureRMStorageBlob_basic(ri, rs, testLocation()) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -84,36 +117,80 @@ func TestAccAzureRMStorageBlob_disappears(t *testing.T) { CheckDestroy: testCheckAzureRMStorageBlobDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageBlob_blockEmpty(ri, rs, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageBlobExists(resourceName), - testCheckAzureRMStorageBlobDisappears(resourceName), ), - ExpectNonEmptyPlan: true, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, }, }, }) } -func TestAccAzureRMStorageBlobBlock_source(t *testing.T) { +func TestAccAzureRMStorageBlob_blockEmptyMetaData(t *testing.T) { + resourceName := "azurerm_storage_blob.test" ri := tf.AccRandTimeInt() - rs1 := strings.ToLower(acctest.RandString(11)) - sourceBlob, err := ioutil.TempFile("", "") - if err != nil { - t.Fatalf("Failed to create local source blob file") - } + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() - _, err = io.CopyN(sourceBlob, rand.Reader, 25*1024*1024) - if err != nil { - t.Fatalf("Failed to write random test to source blob") - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_blockEmptyMetaData(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, + }, + }, + }) +} - err = sourceBlob.Close() - if err != nil { - t.Fatalf("Failed to close source blob") - } +func TestAccAzureRMStorageBlob_blockFromPublicBlob(t *testing.T) { + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_blockFromPublicBlob(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "source_uri", "type"}, + }, + }, + }) +} - config := testAccAzureRMStorageBlobBlock_source(ri, rs1, sourceBlob.Name(), testLocation()) +func TestAccAzureRMStorageBlob_blockFromPublicFile(t *testing.T) { + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -121,59 +198,156 @@ func TestAccAzureRMStorageBlobBlock_source(t *testing.T) { CheckDestroy: testCheckAzureRMStorageBlobDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageBlob_blockFromPublicFile(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageBlobMatchesFile("azurerm_storage_blob.source", storage.BlobTypeBlock, sourceBlob.Name()), + testCheckAzureRMStorageBlobExists(resourceName), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "source_uri", "type"}, + }, }, }) } -func TestAccAzureRMStorageBlobPage_source(t *testing.T) { - resourceName := "azurerm_storage_blob.source" +func TestAccAzureRMStorageBlob_blockFromExistingBlob(t *testing.T) { + resourceName := "azurerm_storage_blob.test" ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_blockFromExistingBlob(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "source_uri", "type"}, + }, + }, + }) +} + +func TestAccAzureRMStorageBlob_blockFromLocalFile(t *testing.T) { sourceBlob, err := ioutil.TempFile("", "") if err != nil { t.Fatalf("Failed to create local source blob file") } - err = sourceBlob.Truncate(25*1024*1024 + 512) - if err != nil { - t.Fatalf("Failed to truncate file to 25M") + if err := testAccAzureRMStorageBlob_populateTempFile(sourceBlob); err != nil { + t.Fatalf("Error populating temp file: %s", err) } - for i := int64(0); i < 20; i = i + 2 { - randomBytes := make([]byte, 1*1024*1024) - _, err = rand.Read(randomBytes) - if err != nil { - t.Fatalf("Failed to read random bytes") - } + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() - _, err = sourceBlob.WriteAt(randomBytes, i*1024*1024) - if err != nil { - t.Fatalf("Failed to write random bytes to file") - } - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_blockFromLocalBlob(ri, rs, location, sourceBlob.Name()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + testCheckAzureRMStorageBlobMatchesFile(resourceName, storage.BlobTypeBlock, sourceBlob.Name()), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "source", "type"}, + }, + }, + }) +} - randomBytes := make([]byte, 5*1024*1024) - _, err = rand.Read(randomBytes) - if err != nil { - t.Fatalf("Failed to read random bytes") - } +func TestAccAzureRMStorageBlob_contentType(t *testing.T) { + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() - _, err = sourceBlob.WriteAt(randomBytes, 20*1024*1024) - if err != nil { - t.Fatalf("Failed to write random bytes to file") - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_contentType(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, + }, + { + Config: testAccAzureRMStorageBlob_contentTypeUpdated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, + }, + }, + }) +} - err = sourceBlob.Close() - if err != nil { - t.Fatalf("Failed to close source blob") - } +func TestAccAzureRMStorageBlob_pageEmpty(t *testing.T) { + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_pageEmpty(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, + }, + }, + }) +} - config := testAccAzureRMStorageBlobPage_source(ri, rs, sourceBlob.Name(), testLocation()) +func TestAccAzureRMStorageBlob_pageEmptyMetaData(t *testing.T) { + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -181,35 +355,62 @@ func TestAccAzureRMStorageBlobPage_source(t *testing.T) { CheckDestroy: testCheckAzureRMStorageBlobDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageBlob_pageEmptyMetaData(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageBlobMatchesFile(resourceName, storage.BlobTypePage, sourceBlob.Name()), + testCheckAzureRMStorageBlobExists(resourceName), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, + }, }, }) } -func TestAccAzureRMStorageBlob_source_uri(t *testing.T) { - resourceName := "azurerm_storage_blob.destination" +func TestAccAzureRMStorageBlob_pageFromExistingBlob(t *testing.T) { + resourceName := "azurerm_storage_blob.test" ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_pageFromExistingBlob(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "source_uri", "type"}, + }, + }, + }) +} + +func TestAccAzureRMStorageBlob_pageFromLocalFile(t *testing.T) { sourceBlob, err := ioutil.TempFile("", "") if err != nil { t.Fatalf("Failed to create local source blob file") } - _, err = io.CopyN(sourceBlob, rand.Reader, 25*1024*1024) - if err != nil { - t.Fatalf("Failed to write random test to source blob") - } - - err = sourceBlob.Close() - if err != nil { - t.Fatalf("Failed to close source blob") + if err := testAccAzureRMStorageBlob_populateTempFile(sourceBlob); err != nil { + t.Fatalf("Error populating temp file: %s", err) } - config := testAccAzureRMStorageBlob_source_uri(ri, rs, sourceBlob.Name(), testLocation()) + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -217,42 +418,61 @@ func TestAccAzureRMStorageBlob_source_uri(t *testing.T) { CheckDestroy: testCheckAzureRMStorageBlobDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageBlob_pageFromLocalBlob(ri, rs, location, sourceBlob.Name()), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageBlobMatchesFile(resourceName, storage.BlobTypeBlock, sourceBlob.Name()), + testCheckAzureRMStorageBlobExists(resourceName), + testCheckAzureRMStorageBlobMatchesFile(resourceName, storage.BlobTypePage, sourceBlob.Name()), ), }, { ResourceName: resourceName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "source", "type"}, }, }, }) } -func TestAccAzureRMStorageBlobBlock_blockContentType(t *testing.T) { - resourceName := "azurerm_storage_blob.source" - ri := tf.AccRandTimeInt() - rs1 := strings.ToLower(acctest.RandString(11)) - sourceBlob, err := ioutil.TempFile("", "") - if err != nil { - t.Fatalf("Failed to create local source blob file") +func TestAccAzureRMStorageBlob_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return } - _, err = io.CopyN(sourceBlob, rand.Reader, 25*1024*1024) - if err != nil { - t.Fatalf("Failed to write random test to source blob") - } + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() - err = sourceBlob.Close() - if err != nil { - t.Fatalf("Failed to close source blob") + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageBlobDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageBlob_blockFromPublicBlob(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageBlobExists(resourceName), + ), + }, + { + Config: testAccAzureRMStorageBlob_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_storage_blob"), + }, + }, + }) +} + +func TestAccAzureRMStorageBlob_update(t *testing.T) { + if !supportsNewStorageFeatures { + t.Skip("Current implementation doesn't support updating the Content Type..") } - config := testAccAzureRMStorageBlobPage_blockContentType(ri, rs1, testLocation(), sourceBlob.Name(), "text/plain") - updateConfig := testAccAzureRMStorageBlobPage_blockContentType(ri, rs1, testLocation(), sourceBlob.Name(), "text/vnd.terraform.acctest.tmpfile") + resourceName := "azurerm_storage_blob.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -260,19 +480,29 @@ func TestAccAzureRMStorageBlobBlock_blockContentType(t *testing.T) { CheckDestroy: testCheckAzureRMStorageBlobDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageBlob_update(ri, rs, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageBlobExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "content_type", "text/plain"), ), }, { - Config: updateConfig, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, + }, + { + Config: testAccAzureRMStorageBlob_updateUpdated(ri, rs, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageBlobExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "content_type", "text/vnd.terraform.acctest.tmpfile"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"attempts", "parallelism", "size", "type"}, + }, }, }) } @@ -288,14 +518,11 @@ func testCheckAzureRMStorageBlobExists(resourceName string) resource.TestCheckFu name := rs.Primary.Attributes["name"] storageAccountName := rs.Primary.Attributes["storage_account_name"] storageContainerName := rs.Primary.Attributes["storage_container_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage blob: %s", name) - } + resourceGroup := rs.Primary.Attributes["resource_group_name"] armClient := testAccProvider.Meta().(*ArmClient) ctx := armClient.StopContext - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroup, storageAccountName) + blobClient, accountExists, err := armClient.storage.LegacyBlobClient(ctx, resourceGroup, storageAccountName) if err != nil { return err } @@ -329,14 +556,11 @@ func testCheckAzureRMStorageBlobDisappears(resourceName string) resource.TestChe name := rs.Primary.Attributes["name"] storageAccountName := rs.Primary.Attributes["storage_account_name"] storageContainerName := rs.Primary.Attributes["storage_container_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage blob: %s", name) - } + resourceGroup := rs.Primary.Attributes["resource_group_name"] armClient := testAccProvider.Meta().(*ArmClient) ctx := armClient.StopContext - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroup, storageAccountName) + blobClient, accountExists, err := armClient.storage.LegacyBlobClient(ctx, resourceGroup, storageAccountName) if err != nil { return err } @@ -363,14 +587,11 @@ func testCheckAzureRMStorageBlobMatchesFile(resourceName string, kind storage.Bl name := rs.Primary.Attributes["name"] storageAccountName := rs.Primary.Attributes["storage_account_name"] storageContainerName := rs.Primary.Attributes["storage_container_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage blob: %s", name) - } + resourceGroup := rs.Primary.Attributes["resource_group_name"] armClient := testAccProvider.Meta().(*ArmClient) ctx := armClient.StopContext - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroup, storageAccountName) + blobClient, accountExists, err := armClient.storage.LegacyBlobClient(ctx, resourceGroup, storageAccountName) if err != nil { return err } @@ -433,7 +654,7 @@ func testCheckAzureRMStorageBlobDestroy(s *terraform.State) error { armClient := testAccProvider.Meta().(*ArmClient) ctx := armClient.StopContext - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroup, storageAccountName) + blobClient, accountExists, err := armClient.storage.LegacyBlobClient(ctx, resourceGroup, storageAccountName) if err != nil { return nil } @@ -456,231 +677,390 @@ func testCheckAzureRMStorageBlobDestroy(s *terraform.State) error { return nil } -func testAccAzureRMStorageBlob_basic(rInt int, rString string, location string) string { +func testAccAzureRMStorageBlob_appendEmpty(rInt int, rString string, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" +%s + +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "append" +} +`, template) } -resource "azurerm_storage_account" "test" { - name = "acctestacc%s" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "LRS" +func testAccAzureRMStorageBlob_appendEmptyMetaData(rInt int, rString string, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s + +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "append" - tags = { - environment = "staging" + metadata = { + hello = "world" } } +`, template) +} -resource "azurerm_storage_container" "test" { - name = "vhds" +func testAccAzureRMStorageBlob_blockEmpty(rInt int, rString string, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s + +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" +} +`, template) +} + +func testAccAzureRMStorageBlob_blockEmptyMetaData(rInt int, rString string, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s + +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" + + metadata = { + hello = "world" + } +} +`, template) +} + +func testAccAzureRMStorageBlob_blockFromPublicBlob(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "blob") + return fmt.Sprintf(` +%s + +resource "azurerm_storage_blob" "source" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" + source_uri = "http://releases.ubuntu.com/18.04.3/ubuntu-18.04.3-desktop-amd64.iso" + content_type = "application/x-iso9660-image" +} + +resource "azurerm_storage_container" "second" { + name = "second" resource_group_name = "${azurerm_resource_group.test.name}" storage_account_name = "${azurerm_storage_account.test.name}" container_access_type = "private" } resource "azurerm_storage_blob" "test" { - name = "herpderp1.vhd" + name = "copied.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.second.name}" + type = "block" + source_uri = "${azurerm_storage_blob.source.id}" + content_type = "${azurerm_storage_blob.source.content_type}" +} +`, template) +} + +func testAccAzureRMStorageBlob_blockFromPublicFile(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s +resource "azurerm_storage_blob" "test" { + name = "example.vhd" resource_group_name = "${azurerm_resource_group.test.name}" storage_account_name = "${azurerm_storage_account.test.name}" storage_container_name = "${azurerm_storage_container.test.name}" - - type = "page" - size = 5120 + type = "block" + source_uri = "http://releases.ubuntu.com/18.04.3/ubuntu-18.04.3-desktop-amd64.iso" + content_type = "application/x-iso9660-image" } -`, rInt, location, rString) +`, template) } -func testAccAzureRMStorageBlob_requiresImport(rInt int, rString string, location string) string { - template := testAccAzureRMStorageBlob_basic(rInt, rString, location) +func testAccAzureRMStorageBlob_blockFromExistingBlob(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") return fmt.Sprintf(` %s -resource "azurerm_storage_blob" "import" { - name = "${azurerm_storage_blob.test.name}" - resource_group_name = "${azurerm_storage_blob.test.resource_group_name}" - storage_account_name = "${azurerm_storage_blob.test.storage_account_name}" - storage_container_name = "${azurerm_storage_blob.test.storage_container_name}" - type = "${azurerm_storage_blob.test.type}" - size = "${azurerm_storage_blob.test.size}" +resource "azurerm_storage_blob" "source" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" + source_uri = "http://releases.ubuntu.com/18.04.3/ubuntu-18.04.3-desktop-amd64.iso" + content_type = "application/x-iso9660-image" +} + +resource "azurerm_storage_blob" "test" { + name = "copied.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" + source_uri = "${azurerm_storage_blob.source.id}" + content_type = "${azurerm_storage_blob.source.content_type}" } `, template) } -func testAccAzureRMStorageBlobBlock_source(rInt int, rString string, sourceBlobName string, location string) string { +func testAccAzureRMStorageBlob_blockFromLocalBlob(rInt int, rString, location, fileName string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" +%s + +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" + source = "%s" +} +`, template, fileName) } -resource "azurerm_storage_account" "source" { - name = "acctestacc%s" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "LRS" +func testAccAzureRMStorageBlob_contentType(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s - tags = { - environment = "staging" - } +resource "azurerm_storage_blob" "test" { + name = "example.ext" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "page" + size = 5120 + content_type = "image/png" } - -resource "azurerm_storage_container" "source" { - name = "source" - resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - container_access_type = "blob" +`, template) } -resource "azurerm_storage_blob" "source" { - name = "source.vhd" +func testAccAzureRMStorageBlob_contentTypeUpdated(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s +resource "azurerm_storage_blob" "test" { + name = "example.ext" resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - storage_container_name = "${azurerm_storage_container.source.name}" - - type = "block" - source = "%s" - parallelism = 4 - attempts = 2 + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "page" + size = 5120 + content_type = "image/gif" } -`, rInt, location, rString, sourceBlobName) +`, template) } -func testAccAzureRMStorageBlobPage_source(rInt int, rString string, sourceBlobName string, location string) string { +func testAccAzureRMStorageBlob_pageEmpty(rInt int, rString string, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" +%s + +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "page" + size = 5120 +} +`, template) } -resource "azurerm_storage_account" "source" { - name = "acctestacc%s" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "LRS" +func testAccAzureRMStorageBlob_pageEmptyMetaData(rInt int, rString string, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s + +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "page" + size = 5120 - tags = { - environment = "staging" + metadata = { + hello = "world" } } - -resource "azurerm_storage_container" "source" { - name = "source" - resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - container_access_type = "blob" +`, template) } -resource "azurerm_storage_blob" "source" { - name = "source.vhd" +func testAccAzureRMStorageBlob_pageFromExistingBlob(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s +resource "azurerm_storage_blob" "source" { + name = "example.vhd" resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - storage_container_name = "${azurerm_storage_container.source.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "page" + size = 5120 + content_type = "application/x-iso9660-image" +} - type = "page" - source = "%s" - parallelism = 3 - attempts = 3 +resource "azurerm_storage_blob" "test" { + name = "copied.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "page" + source_uri = "${azurerm_storage_blob.source.id}" + content_type = "${azurerm_storage_blob.source.content_type}" } -`, rInt, location, rString, sourceBlobName) +`, template) } -func testAccAzureRMStorageBlob_source_uri(rInt int, rString string, sourceBlobName string, location string) string { +func testAccAzureRMStorageBlob_pageFromLocalBlob(rInt int, rString, location, fileName string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" +%s + +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "page" + source = "%s" +} +`, template, fileName) } -resource "azurerm_storage_account" "source" { - name = "acctestacc%s" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "LRS" +func testAccAzureRMStorageBlob_populateTempFile(input *os.File) error { + if err := input.Truncate(25*1024*1024 + 512); err != nil { + return fmt.Errorf("Failed to truncate file to 25M") + } - tags = { - environment = "staging" - } -} + for i := int64(0); i < 20; i = i + 2 { + randomBytes := make([]byte, 1*1024*1024) + if _, err := rand.Read(randomBytes); err != nil { + return fmt.Errorf("Failed to read random bytes") + } -resource "azurerm_storage_container" "source" { - name = "source" - resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - container_access_type = "blob" -} + if _, err := input.WriteAt(randomBytes, i*1024*1024); err != nil { + return fmt.Errorf("Failed to write random bytes to file") + } + } -resource "azurerm_storage_blob" "source" { - name = "source.vhd" + randomBytes := make([]byte, 5*1024*1024) + if _, err := rand.Read(randomBytes); err != nil { + return fmt.Errorf("Failed to read random bytes") + } - resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - storage_container_name = "${azurerm_storage_container.source.name}" + if _, err := input.WriteAt(randomBytes, 20*1024*1024); err != nil { + return fmt.Errorf("Failed to write random bytes to file") + } + + if err := input.Close(); err != nil { + return fmt.Errorf("Failed to close source blob") + } - type = "block" - source = "%s" - parallelism = 4 - attempts = 2 + return nil } -resource "azurerm_storage_blob" "destination" { - name = "destination.vhd" - resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - storage_container_name = "${azurerm_storage_container.source.name}" - source_uri = "${azurerm_storage_blob.source.url}" - type = "block" +func testAccAzureRMStorageBlob_requiresImport(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_blockFromPublicBlob(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_blob" "import" { + name = "${azurerm_storage_blob.test.name}" + resource_group_name = "${azurerm_storage_blob.test.resource_group_name}" + storage_account_name = "${azurerm_storage_blob.test.storage_account_name}" + storage_container_name = "${azurerm_storage_blob.test.storage_container_name}" + type = "${azurerm_storage_blob.test.type}" + size = "${azurerm_storage_blob.test.size}" } -`, rInt, location, rString, sourceBlobName) +`, template) } -func testAccAzureRMStorageBlobPage_blockContentType(rInt int, rString, location string, sourceBlobName, contentType string) string { +func testAccAzureRMStorageBlob_template(rInt int, rString, location, accessLevel string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } -resource "azurerm_storage_account" "source" { +resource "azurerm_storage_account" "test" { name = "acctestacc%s" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" account_tier = "Standard" account_replication_type = "LRS" - - tags = { - environment = "staging" - } } -resource "azurerm_storage_container" "source" { - name = "source" +resource "azurerm_storage_container" "test" { + name = "test" resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - container_access_type = "blob" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "%s" +} +`, rInt, location, rString, accessLevel) } -resource "azurerm_storage_blob" "source" { - name = "source.vhd" +func testAccAzureRMStorageBlob_update(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s +resource "azurerm_storage_blob" "test" { + name = "example.vhd" resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.source.name}" - storage_container_name = "${azurerm_storage_container.source.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" + size = 5120 + content_type = "vnd/panda+pops" + metadata = { + hello = "world" + } +} +`, template) +} + +func testAccAzureRMStorageBlob_updateUpdated(rInt int, rString, location string) string { + template := testAccAzureRMStorageBlob_template(rInt, rString, location, "private") + return fmt.Sprintf(` +%s - type = "page" - source = "%s" - content_type = "%s" - parallelism = 3 - attempts = 3 +resource "azurerm_storage_blob" "test" { + name = "example.vhd" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" + size = 5120 + content_type = "vnd/mountain-mover-3000" + metadata = { + hello = "world" + panda = "pops" + } } -`, rInt, location, rString, sourceBlobName, contentType) +`, template) } diff --git a/azurerm/resource_arm_storage_container.go b/azurerm/resource_arm_storage_container.go index e3f271a5151a..a028722b6f08 100644 --- a/azurerm/resource_arm_storage_container.go +++ b/azurerm/resource_arm_storage_container.go @@ -3,26 +3,27 @@ package azurerm import ( "fmt" "log" - "net/url" "regexp" - "strings" - "time" - "github.com/Azure/azure-sdk-for-go/storage" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/containers" ) func resourceArmStorageContainer() *schema.Resource { return &schema.Resource{ - Create: resourceArmStorageContainerCreateUpdate, + Create: resourceArmStorageContainerCreate, Read: resourceArmStorageContainerRead, Delete: resourceArmStorageContainerDelete, - Update: resourceArmStorageContainerCreateUpdate, + Update: resourceArmStorageContainerUpdate, MigrateState: resourceStorageContainerMigrateState, SchemaVersion: 1, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -34,277 +35,284 @@ func resourceArmStorageContainer() *schema.Resource { ForceNew: true, ValidateFunc: validateArmStorageContainerName, }, - "resource_group_name": resourceGroupNameSchema(), + "storage_account_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageAccountName, }, + "container_access_type": { - Type: schema.TypeString, - Optional: true, - Default: "private", - ValidateFunc: validateArmStorageContainerAccessType, + Type: schema.TypeString, + Optional: true, + Default: "private", + ValidateFunc: validation.StringInSlice([]string{ + string(containers.Blob), + string(containers.Container), + "private", + }, false), }, - "properties": { - Type: schema.TypeMap, + "metadata": storage.MetaDataComputedSchema(), + + // TODO: support for ACL's, Legal Holds and Immutability Policies + "has_immutability_policy": { + Type: schema.TypeBool, + Computed: true, + }, + "has_legal_hold": { + Type: schema.TypeBool, Computed: true, }, - }, - } -} -//Following the naming convention as laid out in the docs -func validateArmStorageContainerName(v interface{}, k string) (warnings []string, errors []error) { - value := v.(string) - if !regexp.MustCompile(`^\$root$|^[0-9a-z-]+$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "only lowercase alphanumeric characters and hyphens allowed in %q: %q", - k, value)) - } - if len(value) < 3 || len(value) > 63 { - errors = append(errors, fmt.Errorf( - "%q must be between 3 and 63 characters: %q", k, value)) - } - if regexp.MustCompile(`^-`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q cannot begin with a hyphen: %q", k, value)) + "resource_group_name": azure.SchemaResourceGroupNameDeprecated(), + "properties": { + Type: schema.TypeMap, + Computed: true, + Deprecated: "This field will be removed in version 2.0 of the Azure Provider", + }, + }, } - return warnings, errors } -func validateArmStorageContainerAccessType(v interface{}, _ string) (warnings []string, errors []error) { - value := strings.ToLower(v.(string)) - validTypes := map[string]struct{}{ - "private": {}, - "blob": {}, - "container": {}, - } - - if _, ok := validTypes[value]; !ok { - errors = append(errors, fmt.Errorf("Storage container access type %q is invalid, must be %q, %q or %q", value, "private", "blob", "page")) - } - return warnings, errors -} +func resourceArmStorageContainerCreate(d *schema.ResourceData, meta interface{}) error { + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext -func resourceArmStorageContainerCreateUpdate(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + containerName := d.Get("name").(string) + accountName := d.Get("storage_account_name").(string) + accessLevelRaw := d.Get("container_access_type").(string) + accessLevel := expandStorageContainerAccessLevel(accessLevelRaw) - name := d.Get("name").(string) - resourceGroupName := d.Get("resource_group_name").(string) - storageAccountName := d.Get("storage_account_name").(string) + metaDataRaw := d.Get("metadata").(map[string]interface{}) + metaData := storage.ExpandMetaData(metaDataRaw) - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Container %q (Account %s): %s", containerName, accountName, err) } - if !accountExists { - return fmt.Errorf("Storage Account %q Not Found", storageAccountName) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Container %q (Account %s)", containerName, accountName) } - var accessType storage.ContainerAccessType - if d.Get("container_access_type").(string) == "private" { - accessType = storage.ContainerAccessType("") - } else { - accessType = storage.ContainerAccessType(d.Get("container_access_type").(string)) + client, err := storageClient.ContainersClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building Containers Client: %s", err) } - reference := blobClient.GetContainerReference(name) - id := fmt.Sprintf("https://%s.blob.%s/%s", storageAccountName, armClient.environment.StorageEndpointSuffix, name) - if requireResourcesToBeImported && d.IsNewResource() { - exists, e := reference.Exists() - if e != nil { - return fmt.Errorf("Error checking if Storage Container %q exists (Account %q / Resource Group %q): %s", name, storageAccountName, resourceGroupName, e) + id := client.GetResourceID(accountName, containerName) + if features.ShouldResourcesBeImported() { + existing, err := client.GetProperties(ctx, accountName, containerName) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for existence of existing Container %q (Account %q / Resource Group %q): %+v", containerName, accountName, *resourceGroup, err) + } } - if exists { + if !utils.ResponseWasNotFound(existing.Response) { return tf.ImportAsExistsError("azurerm_storage_container", id) } } - log.Printf("[INFO] Creating container %q in storage account %q.", name, storageAccountName) - err = resource.Retry(120*time.Second, checkContainerIsCreated(reference)) - if err != nil { - return fmt.Errorf("Error creating container %q in storage account %q: %s", name, storageAccountName, err) + log.Printf("[INFO] Creating Container %q in Storage Account %q", containerName, accountName) + input := containers.CreateInput{ + AccessLevel: accessLevel, + MetaData: metaData, } - - permissions := storage.ContainerPermissions{ - AccessType: accessType, - } - permissionOptions := &storage.SetContainerPermissionOptions{} - err = reference.SetPermissions(permissions, permissionOptions) - if err != nil { - return fmt.Errorf("Error setting permissions for container %s in storage account %s: %+v", name, storageAccountName, err) + if _, err := client.Create(ctx, accountName, containerName, input); err != nil { + return fmt.Errorf("Error creating Container %q (Account %q / Resource Group %q): %s", containerName, accountName, *resourceGroup, err) } d.SetId(id) return resourceArmStorageContainerRead(d, meta) } -// resourceAzureStorageContainerRead does all the necessary API calls to -// read the status of the storage container off Azure. -func resourceArmStorageContainerRead(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext +func resourceArmStorageContainerUpdate(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage - id, err := parseStorageContainerID(d.Id(), armClient.environment) + id, err := containers.ParseResourceID(d.Id()) if err != nil { return err } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Container %q (Account %s): %s", id.ContainerName, id.AccountName, err) } if resourceGroup == nil { - log.Printf("Cannot locate Resource Group for Storage Account %q (presuming it's gone) - removing from state", id.storageAccountName) + log.Printf("[DEBUG] Unable to locate Resource Group for Storage Container %q (Account %s) - assuming removed & removing from state", id.ContainerName, id.AccountName) d.SetId("") return nil } - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) + client, err := storageClient.ContainersClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return err - } - if !accountExists { - log.Printf("[DEBUG] Storage account %q not found, removing container %q from state", id.storageAccountName, d.Id()) - d.SetId("") - return nil + return fmt.Errorf("Error building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) } - var container *storage.Container - listParams := storage.ListContainersParameters{ - Prefix: id.containerName, - Timeout: 90, - } + if d.HasChange("container_access_type") { + log.Printf("[DEBUG] Updating the Access Control for Container %q (Storage Account %q / Resource Group %q)..", id.ContainerName, id.AccountName, *resourceGroup) + accessLevelRaw := d.Get("container_access_type").(string) + accessLevel := expandStorageContainerAccessLevel(accessLevelRaw) - for { - resp, err := blobClient.ListContainers(listParams) - if err != nil { - return fmt.Errorf("Failed to retrieve storage resp in account %q: %s", id.containerName, err) + if _, err := client.SetAccessControl(ctx, id.AccountName, id.ContainerName, accessLevel); err != nil { + return fmt.Errorf("Error updating the Access Control for Container %q (Storage Account %q / Resource Group %q): %s", id.ContainerName, id.AccountName, *resourceGroup, err) } + log.Printf("[DEBUG] Updated the Access Control for Container %q (Storage Account %q / Resource Group %q)", id.ContainerName, id.AccountName, *resourceGroup) + } - for _, c := range resp.Containers { - if c.Name == id.containerName { - container = &c - break - } - } + if d.HasChange("metadata") { + log.Printf("[DEBUG] Updating the MetaData for Container %q (Storage Account %q / Resource Group %q)..", id.ContainerName, id.AccountName, *resourceGroup) + metaDataRaw := d.Get("metadata").(map[string]interface{}) + metaData := storage.ExpandMetaData(metaDataRaw) - if resp.NextMarker == "" { - break + if _, err := client.SetMetaData(ctx, id.AccountName, id.ContainerName, metaData); err != nil { + return fmt.Errorf("Error updating the MetaData for Container %q (Storage Account %q / Resource Group %q): %s", id.ContainerName, id.AccountName, *resourceGroup, err) } + log.Printf("[DEBUG] Updated the MetaData for Container %q (Storage Account %q / Resource Group %q)", id.ContainerName, id.AccountName, *resourceGroup) + } + + return resourceArmStorageContainerRead(d, meta) +} + +func resourceArmStorageContainerRead(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage - listParams.Marker = resp.NextMarker + id, err := containers.ParseResourceID(d.Id()) + if err != nil { + return err } - if container == nil { - log.Printf("[INFO] Storage container %q does not exist in account %q, removing from state...", id.containerName, id.storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Container %q (Account %s): %s", id.ContainerName, id.AccountName, err) + } + if resourceGroup == nil { + log.Printf("[DEBUG] Unable to locate Resource Group for Storage Container %q (Account %s) - assuming removed & removing from state", id.ContainerName, id.AccountName) d.SetId("") return nil } - d.Set("name", id.containerName) - d.Set("storage_account_name", id.storageAccountName) - d.Set("resource_group_name", resourceGroup) + client, err := storageClient.ContainersClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) + } - // for historical reasons, "private" above is an empty string in the API - if container.Properties.PublicAccess == storage.ContainerAccessTypePrivate { - d.Set("container_access_type", "private") - } else { - d.Set("container_access_type", string(container.Properties.PublicAccess)) + props, err := client.GetProperties(ctx, id.AccountName, id.ContainerName) + if err != nil { + if utils.ResponseWasNotFound(props.Response) { + log.Printf("[DEBUG] Container %q was not found in Account %q / Resource Group %q - assuming removed & removing from state", id.ContainerName, id.AccountName, *resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Container %q (Account %q / Resource Group %q): %s", id.ContainerName, id.AccountName, *resourceGroup, err) } - output := make(map[string]interface{}) + d.Set("name", id.ContainerName) + d.Set("storage_account_name", id.AccountName) + d.Set("resource_group_name", resourceGroup) + + d.Set("container_access_type", flattenStorageContainerAccessLevel(props.AccessLevel)) - output["last_modified"] = container.Properties.LastModified - output["lease_status"] = container.Properties.LeaseStatus - output["lease_state"] = container.Properties.LeaseState - output["lease_duration"] = container.Properties.LeaseDuration + if err := d.Set("metadata", storage.FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("Error setting `metadata`: %+v", err) + } - if err := d.Set("properties", output); err != nil { + if err := d.Set("properties", flattenStorageContainerProperties(props)); err != nil { return fmt.Errorf("Error setting `properties`: %+v", err) } + d.Set("has_immutability_policy", props.HasImmutabilityPolicy) + d.Set("has_legal_hold", props.HasLegalHold) + return nil } -// resourceAzureStorageContainerDelete does all the necessary API calls to -// delete a storage container off Azure. func resourceArmStorageContainerDelete(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage - id, err := parseStorageContainerID(d.Id(), armClient.environment) + id, err := containers.ParseResourceID(d.Id()) if err != nil { return err } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Container %q (Account %s): %s", id.ContainerName, id.AccountName, err) } if resourceGroup == nil { - log.Printf("Cannot locate Resource Group for Storage Account %q (presuming it's gone) - removing from state", id.storageAccountName) + log.Printf("[DEBUG] Unable to locate Resource Group for Storage Container %q (Account %s) - assuming removed & removing from state", id.ContainerName, id.AccountName) + d.SetId("") return nil } - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) + client, err := storageClient.ContainersClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return err - } - if !accountExists { - log.Printf("[INFO] Storage Account %q doesn't exist so the container won't exist", id.storageAccountName) - return nil + return fmt.Errorf("Error building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) } - log.Printf("[INFO] Deleting storage container %q in account %q", id.containerName, id.storageAccountName) - reference := blobClient.GetContainerReference(id.containerName) - deleteOptions := &storage.DeleteContainerOptions{} - if _, err := reference.DeleteIfExists(deleteOptions); err != nil { - return fmt.Errorf("Error deleting storage container %q from storage account %q: %s", id.containerName, id.storageAccountName, err) + if _, err := client.Delete(ctx, id.AccountName, id.ContainerName); err != nil { + return fmt.Errorf("Error deleting Container %q (Storage Account %q / Resource Group %q): %s", id.ContainerName, id.AccountName, *resourceGroup, err) } return nil } -func checkContainerIsCreated(reference *storage.Container) func() *resource.RetryError { - return func() *resource.RetryError { - createOptions := &storage.CreateContainerOptions{} - - if _, err := reference.CreateIfNotExists(createOptions); err != nil { - return resource.RetryableError(err) - } +func flattenStorageContainerProperties(input containers.ContainerProperties) map[string]interface{} { + output := map[string]interface{}{ + "last_modified": input.Header.Get("Last-Modified"), + "lease_duration": "", + "lease_state": string(input.LeaseState), + "lease_status": string(input.LeaseStatus), + } - return nil + if input.LeaseDuration != nil { + output["lease_duration"] = string(*input.LeaseDuration) } -} -type storageContainerId struct { - storageAccountName string - containerName string + return output } -func parseStorageContainerID(input string, environment azure.Environment) (*storageContainerId, error) { - uri, err := url.Parse(input) - if err != nil { - return nil, fmt.Errorf("Error parsing %q as URI: %+v", input, err) +func expandStorageContainerAccessLevel(input string) containers.AccessLevel { + // for historical reasons, "private" above is an empty string in the API + // so the enum doesn't 1:1 match. You could argue the SDK should handle this + // but this is suitable for now + if input == "private" { + return containers.Private } - // remove the leading `/` - segments := strings.Split(strings.TrimPrefix(uri.Path, "/"), "/") - if len(segments) < 1 { - return nil, fmt.Errorf("Expected number of segments in the path to be < 1 but got %d", len(segments)) + return containers.AccessLevel(input) +} + +func flattenStorageContainerAccessLevel(input containers.AccessLevel) string { + // for historical reasons, "private" above is an empty string in the API + if input == containers.Private { + return "private" } - storageAccountName := strings.Replace(uri.Host, fmt.Sprintf(".blob.%s", environment.StorageEndpointSuffix), "", 1) - containerName := segments[0] + return string(input) +} - id := storageContainerId{ - storageAccountName: storageAccountName, - containerName: containerName, +func validateArmStorageContainerName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if !regexp.MustCompile(`^\$root$|^\$web$|^[0-9a-z-]+$`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "only lowercase alphanumeric characters and hyphens allowed in %q: %q", + k, value)) } - return &id, nil + if len(value) < 3 || len(value) > 63 { + errors = append(errors, fmt.Errorf( + "%q must be between 3 and 63 characters: %q", k, value)) + } + if regexp.MustCompile(`^-`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q cannot begin with a hyphen: %q", k, value)) + } + return warnings, errors } diff --git a/azurerm/resource_arm_storage_container_migration_test.go b/azurerm/resource_arm_storage_container_migration_test.go index a638f4e6c907..b772aa6bf9a1 100644 --- a/azurerm/resource_arm_storage_container_migration_test.go +++ b/azurerm/resource_arm_storage_container_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMStorageContainerMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false, "") + client, err := getArmClient(config, false, "", true) if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/azurerm/resource_arm_storage_container_test.go b/azurerm/resource_arm_storage_container_test.go index 3de0224b4e8a..b49fbd22b968 100644 --- a/azurerm/resource_arm_storage_container_test.go +++ b/azurerm/resource_arm_storage_container_test.go @@ -2,24 +2,23 @@ package azurerm import ( "fmt" - "log" "strings" "testing" - "github.com/Azure/azure-sdk-for-go/storage" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func TestAccAzureRMStorageContainer_basic(t *testing.T) { resourceName := "azurerm_storage_container.test" - var c storage.Container ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - config := testAccAzureRMStorageContainer_basic(ri, rs, testLocation()) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -27,9 +26,9 @@ func TestAccAzureRMStorageContainer_basic(t *testing.T) { CheckDestroy: testCheckAzureRMStorageContainerDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageContainer_basic(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageContainerExists(resourceName, &c), + testCheckAzureRMStorageContainerExists(resourceName), ), }, { @@ -42,13 +41,12 @@ func TestAccAzureRMStorageContainer_basic(t *testing.T) { } func TestAccAzureRMStorageContainer_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } resourceName := "azurerm_storage_container.test" - var c storage.Container ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) @@ -62,7 +60,7 @@ func TestAccAzureRMStorageContainer_requiresImport(t *testing.T) { { Config: testAccAzureRMStorageContainer_basic(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageContainerExists(resourceName, &c), + testCheckAzureRMStorageContainerExists(resourceName), ), }, { @@ -75,14 +73,10 @@ func TestAccAzureRMStorageContainer_requiresImport(t *testing.T) { func TestAccAzureRMStorageContainer_update(t *testing.T) { resourceName := "azurerm_storage_container.test" - var c storage.Container ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - at1 := "private" - at2 := "container" - initconfig := testAccAzureRMStorageContainer_update(ri, rs, testLocation(), at1) - updateconfig := testAccAzureRMStorageContainer_update(ri, rs, testLocation(), at2) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -90,17 +84,17 @@ func TestAccAzureRMStorageContainer_update(t *testing.T) { CheckDestroy: testCheckAzureRMStorageContainerDestroy, Steps: []resource.TestStep{ { - Config: initconfig, + Config: testAccAzureRMStorageContainer_update(ri, rs, location, "private"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageContainerExists(resourceName, &c), - resource.TestCheckResourceAttr(resourceName, "container_access_type", at1), + testCheckAzureRMStorageContainerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "container_access_type", "private"), ), }, { - Config: updateconfig, + Config: testAccAzureRMStorageContainer_update(ri, rs, location, "container"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageContainerExists(resourceName, &c), - resource.TestCheckResourceAttr(resourceName, "container_access_type", at2), + testCheckAzureRMStorageContainerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "container_access_type", "container"), ), }, { @@ -112,12 +106,60 @@ func TestAccAzureRMStorageContainer_update(t *testing.T) { }) } -func TestAccAzureRMStorageContainer_disappears(t *testing.T) { - var c storage.Container +func TestAccAzureRMStorageContainer_metaData(t *testing.T) { + resourceName := "azurerm_storage_container.test" + + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageContainerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageContainer_metaData(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageContainerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMStorageContainer_metaDataUpdated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageContainerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMStorageContainer_metaDataEmpty(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageContainerExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccAzureRMStorageContainer_disappears(t *testing.T) { + resourceName := "azurerm_storage_container.test" ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - config := testAccAzureRMStorageContainer_basic(ri, rs, testLocation()) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -125,10 +167,10 @@ func TestAccAzureRMStorageContainer_disappears(t *testing.T) { CheckDestroy: testCheckAzureRMStorageContainerDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageContainer_basic(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageContainerExists("azurerm_storage_container.test", &c), - testAccARMStorageContainerDisappears("azurerm_storage_container.test", &c), + testCheckAzureRMStorageContainerExists(resourceName), + testAccARMStorageContainerDisappears(resourceName), ), ExpectNonEmptyPlan: true, }, @@ -138,11 +180,10 @@ func TestAccAzureRMStorageContainer_disappears(t *testing.T) { func TestAccAzureRMStorageContainer_root(t *testing.T) { resourceName := "azurerm_storage_container.test" - var c storage.Container ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - config := testAccAzureRMStorageContainer_root(ri, rs, testLocation()) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -150,9 +191,9 @@ func TestAccAzureRMStorageContainer_root(t *testing.T) { CheckDestroy: testCheckAzureRMStorageContainerDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageContainer_root(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageContainerExists(resourceName, &c), + testCheckAzureRMStorageContainerExists(resourceName), resource.TestCheckResourceAttr(resourceName, "name", "$root"), ), }, @@ -165,7 +206,35 @@ func TestAccAzureRMStorageContainer_root(t *testing.T) { }) } -func testCheckAzureRMStorageContainerExists(resourceName string, c *storage.Container) resource.TestCheckFunc { +func TestAccAzureRMStorageContainer_web(t *testing.T) { + resourceName := "azurerm_storage_container.test" + + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageContainerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageContainer_web(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageContainerExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "name", "$web"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMStorageContainerExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] @@ -173,80 +242,69 @@ func testCheckAzureRMStorageContainerExists(resourceName string, c *storage.Cont return fmt.Errorf("Not found: %s", resourceName) } - name := rs.Primary.Attributes["name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage container: %s", name) - } + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + containerName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroup, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Container %q (Account %s): %s", containerName, accountName, err) } - if !accountExists { - return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Container %q (Account %s) - assuming removed & removing from state", containerName, accountName) } - containers, err := blobClient.ListContainers(storage.ListContainersParameters{ - Prefix: name, - Timeout: 90, - }) + client, err := storageClient.ContainersClient(ctx, *resourceGroup, accountName) if err != nil { - return fmt.Errorf("Error listing Storage Container %q containers (storage account: %q) : %+v", name, storageAccountName, err) + return fmt.Errorf("Error building Containers Client: %s", err) } - if len(containers.Containers) == 0 { - return fmt.Errorf("Bad: Storage Container %q (storage account: %q) does not exist", name, storageAccountName) - } - - var found bool - for _, container := range containers.Containers { - if container.Name == name { - found = true - *c = container + resp, err := client.GetProperties(ctx, accountName, containerName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Container %q (Account %q / Resource Group %q) does not exist", containerName, accountName, *resourceGroup) } - } - if !found { - return fmt.Errorf("Bad: Storage Container %q (storage account: %q) does not exist", name, storageAccountName) + return fmt.Errorf("Bad: Get on ContainersClient: %+v", err) } return nil } } -func testAccARMStorageContainerDisappears(resourceName string, c *storage.Container) resource.TestCheckFunc { +func testAccARMStorageContainerDisappears(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] if !ok { return fmt.Errorf("Not found: %s", resourceName) } - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage container: %s", c.Name) + containerName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Container %q (Account %s): %s", containerName, accountName, err) + } + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Container %q (Account %s) - assuming removed & removing from state", containerName, accountName) } - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroup, storageAccountName) + client, err := storageClient.ContainersClient(ctx, *resourceGroup, accountName) if err != nil { - return err + return fmt.Errorf("Error building Containers Client: %s", err) } - if !accountExists { - log.Printf("[INFO]Storage Account %q doesn't exist so the container won't exist", storageAccountName) - return nil + + if _, err := client.Delete(ctx, accountName, containerName); err != nil { + return fmt.Errorf("Error deleting Container %q (Account %q): %s", containerName, accountName, err) } - reference := blobClient.GetContainerReference(c.Name) - options := &storage.DeleteContainerOptions{} - _, err = reference.DeleteIfExists(options) - return err + return nil } } @@ -256,96 +314,43 @@ func testCheckAzureRMStorageContainerDestroy(s *terraform.State) error { continue } - name := rs.Primary.Attributes["name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage container: %s", name) - } + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + containerName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext - blobClient, accountExists, err := armClient.getBlobStorageClientForStorageAccount(ctx, resourceGroup, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - //If we can't get keys then the blob can't exist - return nil + return fmt.Errorf("Error locating Resource Group for Storage Container %q (Account %s): %s", containerName, accountName, err) } - if !accountExists { + + if resourceGroup == nil { return nil } - containers, err := blobClient.ListContainers(storage.ListContainersParameters{ - Prefix: name, - Timeout: 90, - }) - + client, err := storageClient.ContainersClient(ctx, *resourceGroup, accountName) if err != nil { - return nil + return fmt.Errorf("Error building Containers Client: %s", err) } - var found bool - for _, container := range containers.Containers { - if container.Name == name { - found = true + props, err := client.GetProperties(ctx, accountName, containerName) + if err != nil { + if utils.ResponseWasNotFound(props.Response) { + return nil } - } - if found { - return fmt.Errorf("Bad: Storage Container %q (storage account: %q) still exist", name, storageAccountName) + return fmt.Errorf("Error retrieving Container %q in Storage Account %q: %s", containerName, accountName, err) } } return nil } -func TestValidateArmStorageContainerName(t *testing.T) { - validNames := []string{ - "valid-name", - "valid02-name", - "$root", - } - for _, v := range validNames { - _, errors := validateArmStorageContainerName(v, "name") - if len(errors) != 0 { - t.Fatalf("%q should be a valid Storage Container Name: %q", v, errors) - } - } - - invalidNames := []string{ - "InvalidName1", - "-invalidname1", - "invalid_name", - "invalid!", - "ww", - "$notroot", - strings.Repeat("w", 65), - } - for _, v := range invalidNames { - _, errors := validateArmStorageContainerName(v, "name") - if len(errors) == 0 { - t.Fatalf("%q should be an invalid Storage Container Name", v) - } - } -} - func testAccAzureRMStorageContainer_basic(rInt int, rString string, location string) string { + template := testAccAzureRMStorageContainer_template(rInt, rString, location) return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_storage_account" "test" { - name = "acctestacc%s" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "LRS" - - tags = { - environment = "staging" - } -} +%s resource "azurerm_storage_container" "test" { name = "vhds" @@ -353,7 +358,7 @@ resource "azurerm_storage_container" "test" { storage_account_name = "${azurerm_storage_account.test.name}" container_access_type = "private" } -`, rInt, location, rString) +`, template) } func testAccAzureRMStorageContainer_requiresImport(rInt int, rString string, location string) string { @@ -371,34 +376,102 @@ resource "azurerm_storage_container" "import" { } func testAccAzureRMStorageContainer_update(rInt int, rString string, location string, accessType string) string { + template := testAccAzureRMStorageContainer_template(rInt, rString, location) return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" +%s + +resource "azurerm_storage_container" "test" { + name = "vhds" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "%s" +} +`, template, accessType) } -resource "azurerm_storage_account" "test" { - name = "acctestacc%s" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "LRS" +func testAccAzureRMStorageContainer_metaData(rInt int, rString string, location string) string { + template := testAccAzureRMStorageContainer_template(rInt, rString, location) + return fmt.Sprintf(` +%s - tags = { - environment = "staging" +resource "azurerm_storage_container" "test" { + name = "vhds" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" + + metadata = { + hello = "world" } } +`, template) +} + +func testAccAzureRMStorageContainer_metaDataUpdated(rInt int, rString string, location string) string { + template := testAccAzureRMStorageContainer_template(rInt, rString, location) + return fmt.Sprintf(` +%s resource "azurerm_storage_container" "test" { name = "vhds" resource_group_name = "${azurerm_resource_group.test.name}" storage_account_name = "${azurerm_storage_account.test.name}" - container_access_type = "%s" + container_access_type = "private" + + metadata = { + hello = "world" + panda = "pops" + } } -`, rInt, location, rString, accessType) +`, template) +} + +func testAccAzureRMStorageContainer_metaDataEmpty(rInt int, rString string, location string) string { + template := testAccAzureRMStorageContainer_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_container" "test" { + name = "vhds" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" + + metadata = { + } +} +`, template) } func testAccAzureRMStorageContainer_root(rInt int, rString string, location string) string { + template := testAccAzureRMStorageContainer_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_container" "test" { + name = "$root" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, template) +} + +func testAccAzureRMStorageContainer_web(rInt int, rString string, location string) string { + template := testAccAzureRMStorageContainer_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_container" "test" { + name = "$web" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" +} +`, template) +} + +func testAccAzureRMStorageContainer_template(rInt int, rString, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -416,12 +489,37 @@ resource "azurerm_storage_account" "test" { environment = "staging" } } - -resource "azurerm_storage_container" "test" { - name = "$root" - resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.test.name}" - container_access_type = "private" -} `, rInt, location, rString) } + +func TestValidateArmStorageContainerName(t *testing.T) { + validNames := []string{ + "valid-name", + "valid02-name", + "$root", + "$web", + } + for _, v := range validNames { + _, errors := validateArmStorageContainerName(v, "name") + if len(errors) != 0 { + t.Fatalf("%q should be a valid Storage Container Name: %q", v, errors) + } + } + + invalidNames := []string{ + "InvalidName1", + "-invalidname1", + "invalid_name", + "invalid!", + "ww", + "$notroot", + "$notweb", + strings.Repeat("w", 65), + } + for _, v := range invalidNames { + _, errors := validateArmStorageContainerName(v, "name") + if len(errors) == 0 { + t.Fatalf("%q should be an invalid Storage Container Name", v) + } + } +} diff --git a/azurerm/resource_arm_storage_queue.go b/azurerm/resource_arm_storage_queue.go index bb7125955452..1d9e98cae361 100644 --- a/azurerm/resource_arm_storage_queue.go +++ b/azurerm/resource_arm_storage_queue.go @@ -3,19 +3,22 @@ package azurerm import ( "fmt" "log" - "net/url" "regexp" - "strings" - "github.com/Azure/azure-sdk-for-go/storage" "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/queue/queues" ) func resourceArmStorageQueue() *schema.Resource { return &schema.Resource{ Create: resourceArmStorageQueueCreate, Read: resourceArmStorageQueueRead, + Update: resourceArmStorageQueueUpdate, Delete: resourceArmStorageQueueDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -30,12 +33,17 @@ func resourceArmStorageQueue() *schema.Resource { ForceNew: true, ValidateFunc: validateArmStorageQueueName, }, - "resource_group_name": resourceGroupNameSchema(), + "storage_account_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageAccountName, }, + + "resource_group_name": azure.SchemaResourceGroupNameDeprecated(), + + "metadata": storage.MetaDataSchema(), }, } } @@ -70,157 +78,156 @@ func validateArmStorageQueueName(v interface{}, k string) (warnings []string, er } func resourceArmStorageQueueCreate(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext - environment := armClient.environment + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext + + queueName := d.Get("name").(string) + accountName := d.Get("storage_account_name").(string) - name := d.Get("name").(string) - resourceGroupName := d.Get("resource_group_name").(string) - storageAccountName := d.Get("storage_account_name").(string) + metaDataRaw := d.Get("metadata").(map[string]interface{}) + metaData := storage.ExpandMetaData(metaDataRaw) - queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Queue %q (Account %s): %s", queueName, accountName, err) } - if !accountExists { - return fmt.Errorf("Storage Account %q Not Found", storageAccountName) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Queue %q (Account %s)", queueName, accountName) } - queueReference := queueClient.GetQueueReference(name) - id := fmt.Sprintf("https://%s.queue.%s/%s", storageAccountName, environment.StorageEndpointSuffix, name) - if requireResourcesToBeImported { - exists, e := queueReference.Exists() - if e != nil { - return fmt.Errorf("Error checking if Queue %q exists (Account %q / Resource Group %q): %s", name, storageAccountName, resourceGroupName, e) + queueClient, err := storageClient.QueuesClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building Queues Client: %s", err) + } + + resourceID := queueClient.GetResourceID(accountName, queueName) + if features.ShouldResourcesBeImported() { + existing, err := queueClient.GetMetaData(ctx, accountName, queueName) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Queue %q (Storage Account %q): %s", queueName, accountName, err) + } } - if exists { - return tf.ImportAsExistsError("azurerm_storage_queue", id) + if !utils.ResponseWasNotFound(existing.Response) { + return tf.ImportAsExistsError("azurerm_storage_queue", resourceID) } } - log.Printf("[INFO] Creating queue %q in storage account %q", name, storageAccountName) - options := &storage.QueueServiceOptions{} - err = queueReference.Create(options) - if err != nil { - return fmt.Errorf("Error creating storage queue on Azure: %s", err) + if _, err := queueClient.Create(ctx, accountName, queueName, metaData); err != nil { + return fmt.Errorf("Error creating Queue %q (Account %q): %+v", queueName, accountName, err) } - d.SetId(id) + d.SetId(resourceID) + return resourceArmStorageQueueRead(d, meta) } -func resourceArmStorageQueueRead(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext +func resourceArmStorageQueueUpdate(d *schema.ResourceData, meta interface{}) error { + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext - id, err := parseStorageQueueID(d.Id()) + id, err := queues.ParseResourceID(d.Id()) if err != nil { return err } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + metaDataRaw := d.Get("metadata").(map[string]interface{}) + metaData := storage.ExpandMetaData(metaDataRaw) + + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Queue %q (Account %s): %s", id.QueueName, id.AccountName, err) } - if resourceGroup == nil { - log.Printf("[WARN] Unable to determine Resource Group for Storage Account %q (assuming removed) - removing from state", id.storageAccountName) - d.SetId("") - return nil + return fmt.Errorf("Unable to locate Resource Group for Storage Queue %q (Account %s)", id.QueueName, id.AccountName) + } + + queuesClient, err := storageClient.QueuesClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building Queues Client: %s", err) + } + + if _, err := queuesClient.SetMetaData(ctx, id.AccountName, id.QueueName, metaData); err != nil { + return fmt.Errorf("Error setting MetaData for Queue %q (Storage Account %q): %s", id.QueueName, id.AccountName, err) } - queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) + return resourceArmStorageQueueRead(d, meta) +} + +func resourceArmStorageQueueRead(d *schema.ResourceData, meta interface{}) error { + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext + + id, err := queues.ParseResourceID(d.Id()) if err != nil { return err } - if !accountExists { - log.Printf("[DEBUG] Storage account %q not found, removing queue %q from state", id.storageAccountName, id.queueName) + + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Queue Container %q (Account %s): %s", id.QueueName, id.AccountName, err) + } + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Queue %q (Account %s) - assuming removed & removing from state", id.QueueName, id.AccountName) d.SetId("") return nil } - log.Printf("[INFO] Checking for existence of storage queue %q.", id.queueName) - queueReference := queueClient.GetQueueReference(id.queueName) - exists, err := queueReference.Exists() + queuesClient, err := storageClient.QueuesClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return fmt.Errorf("error checking if storage queue %q exists: %s", id.queueName, err) + return fmt.Errorf("Error building Queues Client: %s", err) } - if !exists { - log.Printf("[INFO] Storage queue %q no longer exists, removing from state...", id.queueName) - d.SetId("") + metaData, err := queuesClient.GetMetaData(ctx, id.AccountName, id.QueueName) + if err != nil { + if utils.ResponseWasNotFound(metaData.Response) { + log.Printf("[INFO] Storage Queue %q no longer exists, removing from state...", id.QueueName) + d.SetId("") + return nil + } + return nil } - d.Set("name", id.queueName) - d.Set("storage_account_name", id.storageAccountName) + d.Set("name", id.QueueName) + d.Set("storage_account_name", id.AccountName) d.Set("resource_group_name", *resourceGroup) + if err := d.Set("metadata", storage.FlattenMetaData(metaData.MetaData)); err != nil { + return fmt.Errorf("Error setting `metadata`: %s", err) + } + return nil } func resourceArmStorageQueueDelete(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext - id, err := parseStorageQueueID(d.Id()) + id, err := queues.ParseResourceID(d.Id()) if err != nil { return err } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Queue %q (Account %s): %s", id.QueueName, id.AccountName, err) } - if resourceGroup == nil { - log.Printf("[WARN] Unable to determine Resource Group for Storage Account %q (assuming removed) - removing from state", id.storageAccountName) + log.Printf("[WARN] Unable to determine Resource Group for Storage Queue %q (Account %s) - assuming removed & removing from state", id.QueueName, id.AccountName) + d.SetId("") return nil } - queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) + queuesClient, err := storageClient.QueuesClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return err - } - if !accountExists { - log.Printf("[INFO]Storage Account %q doesn't exist so the blob won't exist", id.storageAccountName) - return nil + return fmt.Errorf("Error building Queues Client: %s", err) } - log.Printf("[INFO] Deleting storage queue %q", id.queueName) - queueReference := queueClient.GetQueueReference(id.queueName) - options := &storage.QueueServiceOptions{} - if err = queueReference.Delete(options); err != nil { - return fmt.Errorf("Error deleting storage queue %q: %s", id.queueName, err) + if _, err := queuesClient.Delete(ctx, id.AccountName, id.QueueName); err != nil { + return fmt.Errorf("Error deleting Storage Queue %q: %s", id.QueueName, err) } return nil } - -type storageQueueId struct { - storageAccountName string - queueName string -} - -func parseStorageQueueID(input string) (*storageQueueId, error) { - // https://myaccount.queue.core.windows.net/myqueue - uri, err := url.Parse(input) - if err != nil { - return nil, fmt.Errorf("Error parsing %q as a URI: %+v", input, err) - } - - segments := strings.Split(uri.Host, ".") - if len(segments) > 0 { - storageAccountName := segments[0] - // remove the leading `/` - queue := strings.TrimPrefix(uri.Path, "/") - id := storageQueueId{ - storageAccountName: storageAccountName, - queueName: queue, - } - return &id, nil - } - - return nil, nil -} diff --git a/azurerm/resource_arm_storage_queue_migration_test.go b/azurerm/resource_arm_storage_queue_migration_test.go index 8c9c32ccaef0..d82856e662ea 100644 --- a/azurerm/resource_arm_storage_queue_migration_test.go +++ b/azurerm/resource_arm_storage_queue_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMStorageQueueMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false, "") + client, err := getArmClient(config, false, "", true) if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/azurerm/resource_arm_storage_queue_test.go b/azurerm/resource_arm_storage_queue_test.go index 66ef960de07c..5bfaa640c4c3 100644 --- a/azurerm/resource_arm_storage_queue_test.go +++ b/azurerm/resource_arm_storage_queue_test.go @@ -9,6 +9,8 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func TestResourceAzureRMStorageQueueName_Validation(t *testing.T) { @@ -55,7 +57,7 @@ func TestAccAzureRMStorageQueue_basic(t *testing.T) { resourceName := "azurerm_storage_queue.test" ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - config := testAccAzureRMStorageQueue_basic(ri, rs, testLocation()) + location := testLocation() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -63,7 +65,7 @@ func TestAccAzureRMStorageQueue_basic(t *testing.T) { CheckDestroy: testCheckAzureRMStorageQueueDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageQueue_basic(ri, rs, location), Check: resource.ComposeTestCheckFunc( testCheckAzureRMStorageQueueExists(resourceName), ), @@ -78,7 +80,7 @@ func TestAccAzureRMStorageQueue_basic(t *testing.T) { } func TestAccAzureRMStorageQueue_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } @@ -107,6 +109,43 @@ func TestAccAzureRMStorageQueue_requiresImport(t *testing.T) { }) } +func TestAccAzureRMStorageQueue_metaData(t *testing.T) { + resourceName := "azurerm_storage_queue.test" + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageQueueDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageQueue_metaData(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageQueueExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMStorageQueue_metaDataUpdated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageQueueExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMStorageQueueExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -116,30 +155,31 @@ func testCheckAzureRMStorageQueueExists(resourceName string) resource.TestCheckF } name := rs.Primary.Attributes["name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage queue: %s", name) - } + accountName := rs.Primary.Attributes["storage_account_name"] + + ctx := testAccProvider.Meta().(*ArmClient).StopContext + storageClient := testAccProvider.Meta().(*ArmClient).storage - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext - queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(ctx, resourceGroup, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Queue %q (Account %s): %s", name, accountName, err) } - if !accountExists { - return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Queue %q (Account %s) - assuming removed", name, accountName) } - queueReference := queueClient.GetQueueReference(name) - exists, err := queueReference.Exists() + queueClient, err := storageClient.QueuesClient(ctx, *resourceGroup, accountName) if err != nil { - return err + return fmt.Errorf("Error building Queues Client: %s", err) } - if !exists { - return fmt.Errorf("Bad: Storage Queue %q (storage account: %q) does not exist", name, storageAccountName) + metaData, err := queueClient.GetMetaData(ctx, accountName, name) + if err != nil { + if utils.ResponseWasNotFound(metaData.Response) { + return fmt.Errorf("Bad: Storage Queue %q (storage account: %q) does not exist", name, accountName) + } + + return fmt.Errorf("Bad: error retrieving Storage Queue %q (storage account: %q): %s", name, accountName, err) } return nil @@ -153,61 +193,51 @@ func testCheckAzureRMStorageQueueDestroy(s *terraform.State) error { } name := rs.Primary.Attributes["name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage queue: %s", name) - } + accountName := rs.Primary.Attributes["storage_account_name"] - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext - queueClient, accountExists, err := armClient.getQueueServiceClientForStorageAccount(ctx, resourceGroup, storageAccountName) + ctx := testAccProvider.Meta().(*ArmClient).StopContext + storageClient := testAccProvider.Meta().(*ArmClient).storage + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return nil + return fmt.Errorf("Error locating Resource Group for Storage Queue %q (Account %s): %s", name, accountName, err) } - if !accountExists { + + // expected if this has been deleted + if resourceGroup == nil { return nil } - queueReference := queueClient.GetQueueReference(name) - exists, err := queueReference.Exists() + queueClient, err := storageClient.QueuesClient(ctx, *resourceGroup, accountName) if err != nil { - return nil + return fmt.Errorf("Error building Queues Client: %s", err) } - if exists { - return fmt.Errorf("Bad: Storage Queue %q (storage account: %q) still exists", name, storageAccountName) + metaData, err := queueClient.GetMetaData(ctx, accountName, name) + if err != nil { + if utils.ResponseWasNotFound(metaData.Response) { + return nil + } + + return fmt.Errorf("Unexpected error getting MetaData for Queue %q: %s", name, err) } + + return fmt.Errorf("Bad: Storage Queue %q (storage account: %q) still exists", name, accountName) } return nil } func testAccAzureRMStorageQueue_basic(rInt int, rString string, location string) string { + template := testAccAzureRMStorageQueue_template(rInt, rString, location) return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" -} - -resource "azurerm_storage_account" "test" { - name = "acctestacc%s" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "LRS" - - tags = { - environment = "staging" - } -} +%s resource "azurerm_storage_queue" "test" { name = "mysamplequeue-%d" - resource_group_name = "${azurerm_resource_group.test.name}" storage_account_name = "${azurerm_storage_account.test.name}" } -`, rInt, location, rString, rInt) +`, template, rInt) } func testAccAzureRMStorageQueue_requiresImport(rInt int, rString string, location string) string { @@ -217,8 +247,62 @@ func testAccAzureRMStorageQueue_requiresImport(rInt int, rString string, locatio resource "azurerm_storage_queue" "import" { name = "${azurerm_storage_queue.test.name}" - resource_group_name = "${azurerm_storage_queue.test.resource_group_name}" storage_account_name = "${azurerm_storage_queue.test.storage_account_name}" } `, template) } + +func testAccAzureRMStorageQueue_metaData(rInt int, rString string, location string) string { + template := testAccAzureRMStorageQueue_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_queue" "test" { + name = "mysamplequeue-%d" + storage_account_name = "${azurerm_storage_account.test.name}" + + metadata = { + hello = "world" + } +} +`, template, rInt) +} + +func testAccAzureRMStorageQueue_metaDataUpdated(rInt int, rString string, location string) string { + template := testAccAzureRMStorageQueue_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_queue" "test" { + name = "mysamplequeue-%d" + storage_account_name = "${azurerm_storage_account.test.name}" + + metadata = { + hello = "world" + rick = "M0rty" + } +} +`, template, rInt) +} + +func testAccAzureRMStorageQueue_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestacc%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + tags = { + environment = "staging" + } +} + +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_storage_share.go b/azurerm/resource_arm_storage_share.go index 7a7aab8c08b5..1dce8cc3a80c 100644 --- a/azurerm/resource_arm_storage_share.go +++ b/azurerm/resource_arm_storage_share.go @@ -4,13 +4,16 @@ import ( "fmt" "log" "regexp" - "strings" + "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" - - "github.com/Azure/azure-sdk-for-go/storage" - "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/file/shares" ) func resourceArmStorageShare() *schema.Resource { @@ -22,8 +25,20 @@ func resourceArmStorageShare() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - SchemaVersion: 1, - MigrateState: resourceStorageShareMigrateState, + SchemaVersion: 2, + StateUpgraders: []schema.StateUpgrader{ + { + // this should have been applied from pre-0.12 migration system; backporting just in-case + Type: resourceStorageShareStateResourceV0V1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceStorageShareStateUpgradeV0ToV1, + Version: 0, + }, + { + Type: resourceStorageShareStateResourceV0V1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceStorageShareStateUpgradeV1ToV2, + Version: 1, + }, + }, Schema: map[string]*schema.Schema{ "name": { @@ -32,18 +47,61 @@ func resourceArmStorageShare() *schema.Resource { ForceNew: true, ValidateFunc: validateArmStorageShareName, }, - "resource_group_name": resourceGroupNameSchema(), + + "resource_group_name": azure.SchemaResourceGroupNameDeprecated(), + "storage_account_name": { Type: schema.TypeString, Required: true, ForceNew: true, }, + "quota": { Type: schema.TypeInt, Optional: true, Default: 5120, - ValidateFunc: validation.IntBetween(1, 5120), + ValidateFunc: validation.IntBetween(1, 102400), }, + + "metadata": storage.MetaDataSchema(), + + "acl": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 64), + }, + "access_policy": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "expiry": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "permissions": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + }, + }, + "url": { Type: schema.TypeString, Computed: true, @@ -52,56 +110,58 @@ func resourceArmStorageShare() *schema.Resource { } } func resourceArmStorageShareCreate(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage + + accountName := d.Get("storage_account_name").(string) + shareName := d.Get("name").(string) + quota := d.Get("quota").(int) - resourceGroupName := d.Get("resource_group_name").(string) - storageAccountName := d.Get("storage_account_name").(string) + metaDataRaw := d.Get("metadata").(map[string]interface{}) + metaData := storage.ExpandMetaData(metaDataRaw) - fileClient, accountExists, err := armClient.getFileServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + aclsRaw := d.Get("acl").(*schema.Set).List() + acls := expandStorageShareACLs(aclsRaw) + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Share %q (Account %s): %s", shareName, accountName, err) } - if !accountExists { - return fmt.Errorf("Storage Account %q Not Found", storageAccountName) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Share %q (Account %s) - assuming removed & removing from state", shareName, accountName) } - name := d.Get("name").(string) - metaData := make(map[string]string) // TODO: support MetaData - options := &storage.FileRequestOptions{} + client, err := storageClient.FileSharesClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building File Share Client: %s", err) + } - log.Printf("[INFO] Creating share %q in storage account %q", name, storageAccountName) - reference := fileClient.GetShareReference(name) + id := client.GetResourceID(accountName, shareName) - id := fmt.Sprintf("%s/%s/%s", name, resourceGroupName, storageAccountName) - if requireResourcesToBeImported { - exists, e := reference.Exists() - if e != nil { - return fmt.Errorf("Error checking if Share %q exists (Account %q / Resource Group %q): %s", name, storageAccountName, resourceGroupName, e) + if features.ShouldResourcesBeImported() { + existing, err := client.GetProperties(ctx, accountName, shareName) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for existence of existing Storage Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, *resourceGroup, err) + } } - if exists { + if !utils.ResponseWasNotFound(existing.Response) { return tf.ImportAsExistsError("azurerm_storage_share", id) } } - err = reference.Create(options) - if err != nil { - return fmt.Errorf("Error creating Storage Share %q reference (storage account: %q) : %+v", name, storageAccountName, err) + log.Printf("[INFO] Creating Share %q in Storage Account %q", shareName, accountName) + input := shares.CreateInput{ + QuotaInGB: quota, + MetaData: metaData, } - - log.Printf("[INFO] Setting share %q metadata in storage account %q", name, storageAccountName) - reference.Metadata = metaData - if err := reference.SetMetadata(options); err != nil { - return fmt.Errorf("Error setting metadata on Storage Share %q: %+v", name, err) + if _, err := client.Create(ctx, accountName, shareName, input); err != nil { + return fmt.Errorf("Error creating Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, *resourceGroup, err) } - log.Printf("[INFO] Setting share %q properties in storage account %q", name, storageAccountName) - reference.Properties = storage.ShareProperties{ - Quota: d.Get("quota").(int), - } - if err := reference.SetProperties(options); err != nil { - return fmt.Errorf("Error setting properties on Storage Share %q: %+v", name, err) + if _, err := client.SetACL(ctx, accountName, shareName, acls); err != nil { + return fmt.Errorf("Error setting ACL's for Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, *resourceGroup, err) } d.SetId(id) @@ -109,124 +169,204 @@ func resourceArmStorageShareCreate(d *schema.ResourceData, meta interface{}) err } func resourceArmStorageShareRead(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage - id := strings.Split(d.Id(), "/") - if len(id) != 3 { - return fmt.Errorf("ID was not in the expected format - expected `{name}/{resourceGroup}/{storageAccountName}` got %q", id) + id, err := shares.ParseResourceID(d.Id()) + if err != nil { + return err } - name := id[0] - resourceGroupName := id[1] - storageAccountName := id[2] - fileClient, accountExists, err := armClient.getFileServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Share %q (Account %s): %s", id.ShareName, id.AccountName, err) } - if !accountExists { - log.Printf("[DEBUG] Storage account %q not found, removing file %q from state", storageAccountName, d.Id()) + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Share %q (Account %s) - assuming removed & removing from state", id.ShareName, id.AccountName) d.SetId("") return nil } - reference := fileClient.GetShareReference(name) - exists, err := reference.Exists() + client, err := storageClient.FileSharesClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return fmt.Errorf("Error testing existence of share %q: %s", name, err) + return fmt.Errorf("Error building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) } - if !exists { - log.Printf("[INFO] Share %q no longer exists, removing from state...", name) - d.SetId("") - return nil + props, err := client.GetProperties(ctx, id.AccountName, id.ShareName) + if err != nil { + if utils.ResponseWasNotFound(props.Response) { + log.Printf("[DEBUG] File Share %q was not found in Account %q / Resource Group %q - assuming removed & removing from state", id.ShareName, id.AccountName, *resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving File Share %q (Account %q / Resource Group %q): %s", id.ShareName, id.AccountName, *resourceGroup, err) } - url := reference.URL() - if url == "" { - log.Printf("[INFO] URL for %q is empty", name) + acls, err := client.GetACL(ctx, id.AccountName, id.ShareName) + if err != nil { + return fmt.Errorf("Error retrieving ACL's for File Share %q (Account %q / Resource Group %q): %s", id.ShareName, id.AccountName, *resourceGroup, err) } - d.Set("name", name) - d.Set("resource_group_name", resourceGroupName) - d.Set("storage_account_name", storageAccountName) - d.Set("url", url) - if err := reference.FetchAttributes(nil); err != nil { - return fmt.Errorf("Error fetching properties on Storage Share %q: %+v", name, err) + d.Set("name", id.ShareName) + d.Set("storage_account_name", id.AccountName) + d.Set("url", client.GetResourceID(id.AccountName, id.ShareName)) + d.Set("quota", props.ShareQuota) + + if err := d.Set("metadata", storage.FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("Error flattening `metadata`: %+v", err) } - d.Set("quota", reference.Properties.Quota) + + if err := d.Set("acl", flattenStorageShareACLs(acls)); err != nil { + return fmt.Errorf("Error flattening `acl`: %+v", err) + } + + // Deprecated: remove in 2.0 + d.Set("resource_group_name", resourceGroup) return nil } func resourceArmStorageShareUpdate(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage - id := strings.Split(d.Id(), "/") - if len(id) != 3 { - return fmt.Errorf("ID was not in the expected format - expected `{name}/{resourceGroup}/{storageAccountName}` got %q", id) + id, err := shares.ParseResourceID(d.Id()) + if err != nil { + return err } - name := id[0] - resourceGroupName := id[1] - storageAccountName := id[2] - fileClient, accountExists, err := armClient.getFileServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Share %q (Account %s): %s", id.ShareName, id.AccountName, err) + } + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Share %q (Account %s) - assuming removed & removing from state", id.ShareName, id.AccountName) + d.SetId("") + return nil + } + + client, err := storageClient.FileSharesClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) } - if !accountExists { - return fmt.Errorf("Storage Account %q Not Found", storageAccountName) + + if d.HasChange("quota") { + log.Printf("[DEBUG] Updating the Quota for File Share %q (Storage Account %q)", id.ShareName, id.AccountName) + quota := d.Get("quota").(int) + if _, err := client.SetProperties(ctx, id.AccountName, id.ShareName, quota); err != nil { + return fmt.Errorf("Error updating Quota for File Share %q (Storage Account %q): %s", id.ShareName, id.AccountName, err) + } + + log.Printf("[DEBUG] Updated the Quota for File Share %q (Storage Account %q)", id.ShareName, id.AccountName) } - options := &storage.FileRequestOptions{} + if d.HasChange("metadata") { + log.Printf("[DEBUG] Updating the MetaData for File Share %q (Storage Account %q)", id.ShareName, id.AccountName) - reference := fileClient.GetShareReference(name) + metaDataRaw := d.Get("metadata").(map[string]interface{}) + metaData := storage.ExpandMetaData(metaDataRaw) + + if _, err := client.SetMetaData(ctx, id.AccountName, id.ShareName, metaData); err != nil { + return fmt.Errorf("Error updating MetaData for File Share %q (Storage Account %q): %s", id.ShareName, id.AccountName, err) + } - log.Printf("[INFO] Setting share %q properties in storage account %q", name, storageAccountName) - reference.Properties = storage.ShareProperties{ - Quota: d.Get("quota").(int), + log.Printf("[DEBUG] Updated the MetaData for File Share %q (Storage Account %q)", id.ShareName, id.AccountName) } - if err := reference.SetProperties(options); err != nil { - return fmt.Errorf("Error setting properties on Storage Share %q: %+v", name, err) + + if d.HasChange("acl") { + log.Printf("[DEBUG] Updating the ACL's for File Share %q (Storage Account %q)", id.ShareName, id.AccountName) + + aclsRaw := d.Get("acl").(*schema.Set).List() + acls := expandStorageShareACLs(aclsRaw) + + if _, err := client.SetACL(ctx, id.AccountName, id.ShareName, acls); err != nil { + return fmt.Errorf("Error updating ACL's for File Share %q (Storage Account %q): %s", id.ShareName, id.AccountName, err) + } + + log.Printf("[DEBUG] Updated the ACL's for File Share %q (Storage Account %q)", id.ShareName, id.AccountName) } return resourceArmStorageShareRead(d, meta) } func resourceArmStorageShareDelete(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage - id := strings.Split(d.Id(), "/") - if len(id) != 3 { - return fmt.Errorf("ID was not in the expected format - expected `{name}/{resourceGroup}/{storageAccountName}` got %q", id) + id, err := shares.ParseResourceID(d.Id()) + if err != nil { + return err } - name := id[0] - resourceGroupName := id[1] - storageAccountName := id[2] - fileClient, accountExists, err := armClient.getFileServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Share %q (Account %s): %s", id.ShareName, id.AccountName, err) } - if !accountExists { - log.Printf("[INFO]Storage Account %q doesn't exist so the file won't exist", storageAccountName) + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Share %q (Account %s) - assuming removed & removing from state", id.ShareName, id.AccountName) + d.SetId("") return nil } - reference := fileClient.GetShareReference(name) - options := &storage.FileRequestOptions{} + client, err := storageClient.FileSharesClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) + } - if _, err = reference.DeleteIfExists(options); err != nil { - return fmt.Errorf("Error deleting storage file %q: %s", name, err) + deleteSnapshots := true + if _, err := client.Delete(ctx, id.AccountName, id.ShareName, deleteSnapshots); err != nil { + return fmt.Errorf("Error deleting File Share %q (Storage Account %q / Resource Group %q): %s", id.ShareName, id.AccountName, *resourceGroup, err) } - d.SetId("") return nil } -//Following the naming convention as laid out in the docs https://msdn.microsoft.com/library/azure/dn167011.aspx +func expandStorageShareACLs(input []interface{}) []shares.SignedIdentifier { + results := make([]shares.SignedIdentifier, 0) + + for _, v := range input { + vals := v.(map[string]interface{}) + + policies := vals["access_policy"].([]interface{}) + policy := policies[0].(map[string]interface{}) + + identifier := shares.SignedIdentifier{ + Id: vals["id"].(string), + AccessPolicy: shares.AccessPolicy{ + Start: policy["start"].(string), + Expiry: policy["expiry"].(string), + Permission: policy["permissions"].(string), + }, + } + results = append(results, identifier) + } + + return results +} + +func flattenStorageShareACLs(input shares.GetACLResult) []interface{} { + result := make([]interface{}, 0) + + for _, v := range input.SignedIdentifiers { + output := map[string]interface{}{ + "id": v.Id, + "access_policy": []interface{}{ + map[string]interface{}{ + "start": v.AccessPolicy.Start, + "expiry": v.AccessPolicy.Expiry, + "permissions": v.AccessPolicy.Permission, + }, + }, + } + + result = append(result, output) + } + + return result +} + +// Following the naming convention as laid out in the docs https://msdn.microsoft.com/library/azure/dn167011.aspx func validateArmStorageShareName(v interface{}, k string) (warnings []string, errors []error) { value := v.(string) if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) { diff --git a/azurerm/resource_arm_storage_share_directory.go b/azurerm/resource_arm_storage_share_directory.go new file mode 100644 index 000000000000..d49d95fa676f --- /dev/null +++ b/azurerm/resource_arm_storage_share_directory.go @@ -0,0 +1,232 @@ +package azurerm + +import ( + "context" + "fmt" + "log" + "strconv" + "time" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/file/directories" +) + +func resourceArmStorageShareDirectory() *schema.Resource { + return &schema.Resource{ + Create: resourceArmStorageShareDirectoryCreate, + Read: resourceArmStorageShareDirectoryRead, + Update: resourceArmStorageShareDirectoryUpdate, + Delete: resourceArmStorageShareDirectoryDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.StorageShareDirectoryName, + }, + "share_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "storage_account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "metadata": storage.MetaDataSchema(), + }, + } +} + +func resourceArmStorageShareDirectoryCreate(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage + + accountName := d.Get("storage_account_name").(string) + shareName := d.Get("share_name").(string) + directoryName := d.Get("name").(string) + + metaDataRaw := d.Get("metadata").(map[string]interface{}) + metaData := storage.ExpandMetaData(metaDataRaw) + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Share Directory %q (Share %s, Account %s): %s", directoryName, shareName, accountName, err) + } + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Share Directory %q (Share %s, Account %s) ", directoryName, shareName, accountName) + } + + client, err := storageClient.FileShareDirectoriesClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building File Share Client: %s", err) + } + + if features.ShouldResourcesBeImported() { + existing, err := client.Get(ctx, accountName, shareName, directoryName) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Directory %q (File Share %q / Storage Account %q / Resource Group %q): %s", directoryName, shareName, accountName, *resourceGroup, err) + } + } + + if !utils.ResponseWasNotFound(existing.Response) { + id := client.GetResourceID(accountName, shareName, directoryName) + return tf.ImportAsExistsError("azurerm_storage_share_directory", id) + } + } + + if _, err := client.Create(ctx, accountName, shareName, directoryName, metaData); err != nil { + return fmt.Errorf("Error creating Directory %q (File Share %q / Account %q): %+v", directoryName, shareName, accountName, err) + } + + // Storage Share Directories are eventually consistent + log.Printf("[DEBUG] Waiting for Directory %q (File Share %q / Account %q) to become available", directoryName, shareName, accountName) + stateConf := &resource.StateChangeConf{ + Pending: []string{"404"}, + Target: []string{"200"}, + Refresh: storageShareDirectoryRefreshFunc(ctx, client, accountName, shareName, directoryName), + Timeout: 5 * time.Minute, + MinTimeout: 10 * time.Second, + ContinuousTargetOccurence: 5, + } + + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for Directory %q (File Share %q / Account %q) to become available: %s", directoryName, shareName, accountName, err) + } + + resourceID := client.GetResourceID(accountName, shareName, directoryName) + d.SetId(resourceID) + + return resourceArmStorageShareDirectoryRead(d, meta) +} + +func resourceArmStorageShareDirectoryUpdate(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage + + id, err := directories.ParseResourceID(d.Id()) + if err != nil { + return err + } + + metaDataRaw := d.Get("metadata").(map[string]interface{}) + metaData := storage.ExpandMetaData(metaDataRaw) + + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Share Directory %q (Share %s, Account %s): %s", id.DirectoryName, id.ShareName, id.AccountName, err) + } + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Share Directory %q (Share %s, Account %s) - assuming removed & removing from state", id.DirectoryName, id.ShareName, id.AccountName) + d.SetId("") + return nil + } + + client, err := storageClient.FileShareDirectoriesClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building File Share Client: %s", err) + } + + if _, err := client.SetMetaData(ctx, id.AccountName, id.ShareName, id.DirectoryName, metaData); err != nil { + return fmt.Errorf("Error updating MetaData for Directory %q (File Share %q / Account %q): %+v", id.DirectoryName, id.ShareName, id.AccountName, err) + } + + return resourceArmStorageShareDirectoryRead(d, meta) +} + +func resourceArmStorageShareDirectoryRead(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage + + id, err := directories.ParseResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Share Directory %q (Share %s, Account %s): %s", id.DirectoryName, id.ShareName, id.AccountName, err) + } + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Share Directory %q (Share %s, Account %s) - assuming removed & removing from state", id.DirectoryName, id.ShareName, id.AccountName) + d.SetId("") + return nil + } + + client, err := storageClient.FileShareDirectoriesClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) + } + + props, err := client.Get(ctx, id.AccountName, id.ShareName, id.DirectoryName) + if err != nil { + return fmt.Errorf("Error retrieving Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryName, id.ShareName, id.AccountName, *resourceGroup, err) + } + + d.Set("name", id.DirectoryName) + d.Set("share_name", id.ShareName) + d.Set("storage_account_name", id.AccountName) + + if err := d.Set("metadata", storage.FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("Error setting `metadata`: %s", err) + } + + return nil +} + +func resourceArmStorageShareDirectoryDelete(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage + + id, err := directories.ParseResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Share Directory %q (Share %s, Account %s): %s", id.DirectoryName, id.ShareName, id.AccountName, err) + } + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Share Directory %q (Share %s, Account %s) - assuming removed already", id.DirectoryName, id.ShareName, id.AccountName) + d.SetId("") + return nil + } + + client, err := storageClient.FileShareDirectoriesClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) + } + + if _, err := client.Delete(ctx, id.AccountName, id.ShareName, id.DirectoryName); err != nil { + return fmt.Errorf("Error deleting Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryName, id.ShareName, id.AccountName, *resourceGroup, err) + } + + return nil +} + +func storageShareDirectoryRefreshFunc(ctx context.Context, client *directories.Client, accountName, shareName, directoryName string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + res, err := client.Get(ctx, accountName, shareName, directoryName) + if err != nil { + return nil, strconv.Itoa(res.StatusCode), fmt.Errorf("Error retrieving Directory %q (File Share %q / Account %q): %s", directoryName, shareName, accountName, err) + } + + return res, strconv.Itoa(res.StatusCode), nil + } +} diff --git a/azurerm/resource_arm_storage_share_directory_test.go b/azurerm/resource_arm_storage_share_directory_test.go new file mode 100644 index 000000000000..32e37bd52e5b --- /dev/null +++ b/azurerm/resource_arm_storage_share_directory_test.go @@ -0,0 +1,377 @@ +package azurerm + +import ( + "fmt" + "net/http" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMStorageShareDirectory_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + resourceName := "azurerm_storage_share_directory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageShareDirectoryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageShareDirectory_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareDirectoryExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMStorageShareDirectory_uppercase(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + resourceName := "azurerm_storage_share_directory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageShareDirectoryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageShareDirectory_uppercase(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareDirectoryExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMStorageShareDirectory_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + resourceName := "azurerm_storage_share_directory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageShareDirectoryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageShareDirectory_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareDirectoryExists(resourceName), + ), + }, + { + Config: testAccAzureRMStorageShareDirectory_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_storage_share_directory"), + }, + }, + }) +} + +func TestAccAzureRMStorageShareDirectory_complete(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + resourceName := "azurerm_storage_share_directory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageShareDirectoryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageShareDirectory_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareDirectoryExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMStorageShareDirectory_update(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + resourceName := "azurerm_storage_share_directory.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageShareDirectoryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageShareDirectory_complete(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareDirectoryExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMStorageShareDirectory_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareDirectoryExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccAzureRMStorageShareDirectory_nested(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageShareDirectoryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageShareDirectory_nested(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareDirectoryExists("azurerm_storage_share_directory.parent"), + testCheckAzureRMStorageShareDirectoryExists("azurerm_storage_share_directory.child"), + ), + }, + }, + }) +} + +func testCheckAzureRMStorageShareDirectoryExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + shareName := rs.Primary.Attributes["share_name"] + accountName := rs.Primary.Attributes["storage_account_name"] + + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Share Directory %q (Share %s, Account %s): %s", name, shareName, accountName, err) + } + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Share Directory %q (Share %s, Account %s) ", name, shareName, accountName) + } + + client, err := storageClient.FileShareDirectoriesClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building FileShare Client: %s", err) + } + + resp, err := client.Get(ctx, accountName, shareName, name) + if err != nil { + return fmt.Errorf("Bad: Get on FileShareDirectoriesClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Directory %q (File Share %q / Account %q / Resource Group %q) does not exist", name, shareName, accountName, *resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMStorageShareDirectoryDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_storage_share_directory" { + continue + } + + name := rs.Primary.Attributes["name"] + shareName := rs.Primary.Attributes["share_name"] + accountName := rs.Primary.Attributes["storage_account_name"] + + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Share Directory %q (Share %s, Account %s): %s", name, shareName, accountName, err) + } + + // not found, the account's gone + if resourceGroup == nil { + return nil + } + + client, err := storageClient.FileShareDirectoriesClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building FileShare Client: %s", err) + } + + resp, err := client.Get(ctx, accountName, shareName, name) + if err != nil { + return fmt.Errorf("Bad: Get on FileShareDirectoriesClient: %+v", err) + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("File Share still exists:\n%#v", resp) + } + } + + return nil +} + +func testAccAzureRMStorageShareDirectory_basic(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShareDirectory_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share_directory" "test" { + name = "dir" + share_name = "${azurerm_storage_share.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} +`, template) +} + +func testAccAzureRMStorageShareDirectory_uppercase(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShareDirectory_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share_directory" "test" { + name = "UpperCaseCharacterS" + share_name = "${azurerm_storage_share.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} +`, template) +} + +func testAccAzureRMStorageShareDirectory_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShareDirectory_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share_directory" "import" { + name = "${azurerm_storage_share_directory.test.name}" + share_name = "${azurerm_storage_share_directory.test.share_name}" + storage_account_name = "${azurerm_storage_share_directory.test.storage_account_name}" +} +`, template) +} + +func testAccAzureRMStorageShareDirectory_complete(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShareDirectory_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share_directory" "test" { + name = "dir" + share_name = "${azurerm_storage_share.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + + metadata = { + hello = "world" + } +} +`, template) +} + +func testAccAzureRMStorageShareDirectory_updated(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShareDirectory_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share_directory" "test" { + name = "dir" + share_name = "${azurerm_storage_share.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + + metadata = { + hello = "world" + sunshine = "at dawn" + } +} +`, template) +} + +func testAccAzureRMStorageShareDirectory_nested(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShareDirectory_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share_directory" "parent" { + name = "parent" + share_name = "${azurerm_storage_share.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} + +resource "azurerm_storage_share_directory" "child" { + name = "${azurerm_storage_share_directory.parent.name}/child" + share_name = "${azurerm_storage_share.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} +`, template) +} + +func testAccAzureRMStorageShareDirectory_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_share" "test" { + name = "fileshare" + storage_account_name = "${azurerm_storage_account.test.name}" + quota = 50 +} +`, rInt, location, rString) +} diff --git a/azurerm/resource_arm_storage_share_migration.go b/azurerm/resource_arm_storage_share_migration.go index f2bd6deccc46..d4355c495133 100644 --- a/azurerm/resource_arm_storage_share_migration.go +++ b/azurerm/resource_arm_storage_share_migration.go @@ -3,37 +3,76 @@ package azurerm import ( "fmt" "log" + "strings" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/file/shares" ) -func resourceStorageShareMigrateState( - v int, is *terraform.InstanceState, _ interface{}) (*terraform.InstanceState, error) { - switch v { - case 0: - log.Println("[INFO] Found AzureRM Storage Share State v0; migrating to v1") - return migrateStorageShareStateV0toV1(is) - default: - return is, fmt.Errorf("Unexpected schema version: %d", v) +// the schema schema was used for both V0 and V1 +func resourceStorageShareStateResourceV0V1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageShareName, + }, + "resource_group_name": azure.SchemaResourceGroupName(), + "storage_account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "quota": { + Type: schema.TypeInt, + Optional: true, + Default: 5120, + ValidateFunc: validation.IntBetween(1, 5120), + }, + "url": { + Type: schema.TypeString, + Computed: true, + }, + }, } } -func migrateStorageShareStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) { - if is.Empty() { - log.Println("[DEBUG] Empty InstanceState; nothing to migrate.") - return is, nil +func resourceStorageShareStateUpgradeV0ToV1(rawState map[string]interface{}, _ interface{}) (map[string]interface{}, error) { + shareName := rawState["name"].(string) + resourceGroup := rawState["resource_group_name"].(string) + accountName := rawState["storage_account_name"].(string) + + id := rawState["id"].(string) + newResourceID := fmt.Sprintf("%s/%s/%s", shareName, resourceGroup, accountName) + log.Printf("[DEBUG] Updating ID from %q to %q", id, newResourceID) + + rawState["id"] = newResourceID + return rawState, nil +} + +func resourceStorageShareStateUpgradeV1ToV2(rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + id := rawState["id"].(string) + + // name/resourceGroup/accountName + parsedId := strings.Split(id, "/") + if len(parsedId) != 3 { + return rawState, fmt.Errorf("Expected 3 segments in the ID but got %d", len(parsedId)) } - log.Printf("[DEBUG] ARM Storage Share Attributes before Migration: %#v", is.Attributes) + shareName := parsedId[0] + accountName := parsedId[2] + + environment := meta.(*ArmClient).environment + client := shares.NewWithEnvironment(environment) - name := is.Attributes["name"] - resourceGroupName := is.Attributes["resource_group_name"] - storageAccountName := is.Attributes["storage_account_name"] - newID := fmt.Sprintf("%s/%s/%s", name, resourceGroupName, storageAccountName) - is.Attributes["id"] = newID - is.ID = newID + newResourceId := client.GetResourceID(accountName, shareName) + log.Printf("[DEBUG] Updating Resource ID from %q to %q", id, newResourceId) - log.Printf("[DEBUG] ARM Storage Share Attributes after State Migration: %#v", is.Attributes) + rawState["id"] = newResourceId - return is, nil + return rawState, nil } diff --git a/azurerm/resource_arm_storage_share_migration_test.go b/azurerm/resource_arm_storage_share_migration_test.go index 378ba12030b4..b97526eb1322 100644 --- a/azurerm/resource_arm_storage_share_migration_test.go +++ b/azurerm/resource_arm_storage_share_migration_test.go @@ -1,49 +1,93 @@ package azurerm import ( + "fmt" + "reflect" "testing" - "github.com/hashicorp/terraform/terraform" + "github.com/Azure/go-autorest/autorest/azure" ) -func TestAzureRMStorageShareMigrateState(t *testing.T) { - cases := map[string]struct { - StateVersion int - ID string - InputAttributes map[string]string - ExpectedAttributes map[string]string - Meta interface{} - }{ - "v0_1": { - StateVersion: 0, - ID: "some_id", - InputAttributes: map[string]string{ - "name": "some_id", - "resource_group_name": "some_rgn", - "storage_account_name": "some_sgn", - }, - ExpectedAttributes: map[string]string{ - "id": "some_id/some_rgn/some_sgn", - }, - }, +func TestAzureRMStorageShareMigrateStateV0ToV1(t *testing.T) { + clouds := []azure.Environment{ + azure.ChinaCloud, + azure.GermanCloud, + azure.PublicCloud, + azure.USGovernmentCloud, } - for tn, tc := range cases { - is := &terraform.InstanceState{ - ID: tc.ID, - Attributes: tc.InputAttributes, + for _, cloud := range clouds { + t.Logf("[DEBUG] Testing with Cloud %q", cloud.Name) + + input := map[string]interface{}{ + "id": "share1", + "name": "share1", + "resource_group_name": "group1", + "storage_account_name": "account1", + "quota": 5120, + } + meta := &ArmClient{ + environment: cloud, + } + expected := map[string]interface{}{ + "id": "share1/group1/account1", + "name": "share1", + "resource_group_name": "group1", + "storage_account_name": "account1", + "quota": 5120, } - is, err := resourceStorageShareMigrateState(tc.StateVersion, is, tc.Meta) + actual, err := resourceStorageShareStateUpgradeV0ToV1(input, meta) if err != nil { - t.Fatalf("bad: %s, err: %#v", tn, err) + t.Fatalf("Expected no error but got: %s", err) } - for k, v := range tc.ExpectedAttributes { - actual := is.Attributes[k] - if actual != v { - t.Fatalf("Bad Storage Share Migrate for %q: %q\n\n expected: %q", k, actual, v) - } + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("Expected %+v. Got %+v. But expected them to be the same", expected, actual) } + + t.Logf("[DEBUG] Ok!") + } +} + +func TestAzureRMStorageShareMigrateStateV1ToV2(t *testing.T) { + clouds := []azure.Environment{ + azure.ChinaCloud, + azure.GermanCloud, + azure.PublicCloud, + azure.USGovernmentCloud, + } + + for _, cloud := range clouds { + t.Logf("[DEBUG] Testing with Cloud %q", cloud.Name) + + input := map[string]interface{}{ + "id": "share1/group1/account1", + "name": "share1", + "resource_group_name": "group1", + "storage_account_name": "account1", + "quota": 5120, + } + meta := &ArmClient{ + environment: cloud, + } + expected := map[string]interface{}{ + "id": fmt.Sprintf("https://account1.file.%s/share1", cloud.StorageEndpointSuffix), + "name": "share1", + "resource_group_name": "group1", + "storage_account_name": "account1", + "quota": 5120, + } + + actual, err := resourceStorageShareStateUpgradeV1ToV2(input, meta) + if err != nil { + t.Fatalf("Expected no error but got: %s", err) + } + + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("Expected %+v. Got %+v. But expected them to be the same", expected, actual) + } + + t.Logf("[DEBUG] Ok!") } } diff --git a/azurerm/resource_arm_storage_share_test.go b/azurerm/resource_arm_storage_share_test.go index a5d89cc9a990..7def22abdf9f 100644 --- a/azurerm/resource_arm_storage_share_test.go +++ b/azurerm/resource_arm_storage_share_test.go @@ -2,23 +2,21 @@ package azurerm import ( "fmt" - "log" "strings" "testing" - "github.com/Azure/azure-sdk-for-go/storage" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func TestAccAzureRMStorageShare_basic(t *testing.T) { - var sS storage.Share - ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - config := testAccAzureRMStorageShare_basic(ri, rs, testLocation()) + location := testLocation() resourceName := "azurerm_storage_share.test" resource.ParallelTest(t, resource.TestCase{ @@ -27,9 +25,9 @@ func TestAccAzureRMStorageShare_basic(t *testing.T) { CheckDestroy: testCheckAzureRMStorageShareDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageShare_basic(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageShareExists(resourceName, &sS), + testCheckAzureRMStorageShareExists(resourceName), ), }, { @@ -42,13 +40,11 @@ func TestAccAzureRMStorageShare_basic(t *testing.T) { } func TestAccAzureRMStorageShare_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } - var sS storage.Share - ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) location := testLocation() @@ -62,7 +58,7 @@ func TestAccAzureRMStorageShare_requiresImport(t *testing.T) { { Config: testAccAzureRMStorageShare_basic(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageShareExists(resourceName, &sS), + testCheckAzureRMStorageShareExists(resourceName), ), }, { @@ -74,11 +70,9 @@ func TestAccAzureRMStorageShare_requiresImport(t *testing.T) { } func TestAccAzureRMStorageShare_disappears(t *testing.T) { - var sS storage.Share - ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - config := testAccAzureRMStorageShare_basic(ri, rs, testLocation()) + location := testLocation() resourceName := "azurerm_storage_share.test" resource.ParallelTest(t, resource.TestCase{ @@ -87,10 +81,10 @@ func TestAccAzureRMStorageShare_disappears(t *testing.T) { CheckDestroy: testCheckAzureRMStorageShareDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageShare_basic(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageShareExists(resourceName, &sS), - testAccARMStorageShareDisappears(resourceName, &sS), + testCheckAzureRMStorageShareExists(resourceName), + testCheckAzureRMStorageShareDisappears(resourceName), ), ExpectNonEmptyPlan: true, }, @@ -98,13 +92,47 @@ func TestAccAzureRMStorageShare_disappears(t *testing.T) { }) } -func TestAccAzureRMStorageShare_updateQuota(t *testing.T) { - var sS storage.Share +func TestAccAzureRMStorageShare_metaData(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + resourceName := "azurerm_storage_share.test" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageShareDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageShare_metaData(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMStorageShare_metaDataUpdated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMStorageShare_acl(t *testing.T) { ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) - config := testAccAzureRMStorageShare_basic(ri, rs, testLocation()) - config2 := testAccAzureRMStorageShare_updateQuota(ri, rs, testLocation()) + location := testLocation() resourceName := "azurerm_storage_share.test" resource.ParallelTest(t, resource.TestCase{ @@ -113,15 +141,52 @@ func TestAccAzureRMStorageShare_updateQuota(t *testing.T) { CheckDestroy: testCheckAzureRMStorageShareDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccAzureRMStorageShare_acl(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageShareExists(resourceName, &sS), + testCheckAzureRMStorageShareExists(resourceName), ), }, { - Config: config2, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMStorageShare_aclUpdated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMStorageShare_updateQuota(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + resourceName := "azurerm_storage_share.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageShareDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageShare_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageShareExists(resourceName), + ), + }, + { + Config: testAccAzureRMStorageShare_updateQuota(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageShareExists(resourceName, &sS), + testCheckAzureRMStorageShareExists(resourceName), resource.TestCheckResourceAttr(resourceName, "quota", "5"), ), }, @@ -129,93 +194,68 @@ func TestAccAzureRMStorageShare_updateQuota(t *testing.T) { }) } -func testCheckAzureRMStorageShareExists(resourceName string, sS *storage.Share) resource.TestCheckFunc { +func testCheckAzureRMStorageShareExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[resourceName] if !ok { return fmt.Errorf("Not found: %s", resourceName) } - name := rs.Primary.Attributes["name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroupName, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for share: %s", name) - } + shareName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext - fileClient, accountExists, err := armClient.getFileServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) - if err != nil { - return err - } - if !accountExists { - return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName) - } + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext - shares, err := fileClient.ListShares(storage.ListSharesParameters{ - Prefix: name, - Timeout: 90, - }) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return fmt.Errorf("Error listing Storage Share %q shares (storage account: %q) : %+v", name, storageAccountName, err) + return fmt.Errorf("Error locating Resource Group for Storage Share %q (Account %s): %s", shareName, accountName, err) } - - if len(shares.Shares) == 0 { - return fmt.Errorf("Bad: Share %q (storage account: %q) does not exist", name, storageAccountName) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Share %q (Account %s) - assuming removed & removing from state", shareName, accountName) } - var found bool - for _, share := range shares.Shares { - if share.Name == name { - found = true - *sS = share - } + client, err := storageClient.FileSharesClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building FileShare Client: %s", err) } - if !found { - return fmt.Errorf("Bad: Share %q (storage account: %q) does not exist", name, storageAccountName) + if _, err = client.GetProperties(ctx, accountName, shareName); err != nil { + return fmt.Errorf("Bad: Share %q (Storage Account: %q) does not exist", shareName, accountName) } return nil } } -func testAccARMStorageShareDisappears(resourceName string, sS *storage.Share) resource.TestCheckFunc { +func testCheckAzureRMStorageShareDisappears(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] if !ok { return fmt.Errorf("Not found: %s", resourceName) } - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext + shareName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroupName, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage share: %s", sS.Name) - } + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext - fileClient, accountExists, err := armClient.getFileServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Share %q (Account %s): %s", shareName, accountName, err) } - if !accountExists { - log.Printf("[INFO]Storage Account %q doesn't exist so the share won't exist", storageAccountName) - return nil + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Share %q (Account %s) - assuming removed & removing from state", shareName, accountName) } - reference := fileClient.GetShareReference(sS.Name) - options := &storage.FileRequestOptions{} - err = reference.Create(options) + client, err := storageClient.FileSharesClient(ctx, *resourceGroup, accountName) if err != nil { - return fmt.Errorf("Error creating Storage Share %q reference (storage account: %q) : %+v", sS.Name, storageAccountName, err) + return fmt.Errorf("Error building FileShare Client: %s", err) } - if _, err = reference.DeleteIfExists(options); err != nil { - return fmt.Errorf("Error deleting storage Share %q: %s", sS.Name, err) + if _, err := client.Delete(ctx, accountName, shareName, true); err != nil { + return fmt.Errorf("Error deleting Share %q (Account %q): %v", shareName, accountName, err) } return nil @@ -228,75 +268,142 @@ func testCheckAzureRMStorageShareDestroy(s *terraform.State) error { continue } - name := rs.Primary.Attributes["name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroupName, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for share: %s", name) - } + shareName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] + + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext - fileClient, accountExists, err := armClient.getFileServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - //If we can't get keys then the blob can't exist - return nil + return fmt.Errorf("Error locating Resource Group for Storage Share %q (Account %s): %s", shareName, accountName, err) } - if !accountExists { + if resourceGroup == nil { return nil } - shares, err := fileClient.ListShares(storage.ListSharesParameters{ - Prefix: name, - Timeout: 90, - }) - + client, err := storageClient.FileSharesClient(ctx, *resourceGroup, accountName) if err != nil { - return nil + return fmt.Errorf("Error building FileShare Client: %s", err) } - var found bool - for _, share := range shares.Shares { - if share.Name == name { - found = true + props, err := client.GetProperties(ctx, accountName, shareName) + if err != nil { + if utils.ResponseWasNotFound(props.Response) { + return nil } - } - if found { - return fmt.Errorf("Bad: Share %q (storage account: %q) still exists", name, storageAccountName) + return fmt.Errorf("Error retrieving Share %q: %s", shareName, accountName) } + + return fmt.Errorf("Bad: Share %q (storage account: %q) still exists", shareName, accountName) } return nil } func testAccAzureRMStorageShare_basic(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShare_template(rInt, rString, location) return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-%d" - location = "%s" +%s + +resource "azurerm_storage_share" "test" { + name = "testshare%s" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} +`, template, rString) } -resource "azurerm_storage_account" "test" { - name = "acctestacc%s" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "LRS" +func testAccAzureRMStorageShare_metaData(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShare_template(rInt, rString, location) + return fmt.Sprintf(` +%s - tags = { - environment = "staging" +resource "azurerm_storage_share" "test" { + name = "testshare%s" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + + metadata = { + hello = "world" } } +`, template, rString) +} + +func testAccAzureRMStorageShare_metaDataUpdated(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShare_template(rInt, rString, location) + return fmt.Sprintf(` +%s resource "azurerm_storage_share" "test" { - name = "testshare" + name = "testshare%s" resource_group_name = "${azurerm_resource_group.test.name}" storage_account_name = "${azurerm_storage_account.test.name}" + + metadata = { + hello = "world" + happy = "birthday" + } } -`, rInt, location, rString) +`, template, rString) } +func testAccAzureRMStorageShare_acl(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShare_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share" "test" { + name = "testshare%s" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + + acl { + id = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI" + + access_policy { + permissions = "rwd" + start = "2019-07-02T09:38:21.0000000Z" + expiry = "2019-07-02T10:38:21.0000000Z" + } + } +} +`, template, rString) +} + +func testAccAzureRMStorageShare_aclUpdated(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShare_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share" "test" { + name = "testshare%s" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + + acl { + id = "AAAANDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI" + + access_policy { + permissions = "rwd" + start = "2019-07-02T09:38:21.0000000Z" + expiry = "2019-07-02T10:38:21.0000000Z" + } + } + acl { + id = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI" + + access_policy { + permissions = "rwd" + start = "2019-07-02T09:38:21.0000000Z" + expiry = "2019-07-02T10:38:21.0000000Z" + } + } +} +`, template, rString) +} func testAccAzureRMStorageShare_requiresImport(rInt int, rString string, location string) string { template := testAccAzureRMStorageShare_basic(rInt, rString, location) return fmt.Sprintf(` @@ -311,6 +418,20 @@ resource "azurerm_storage_share" "import" { } func testAccAzureRMStorageShare_updateQuota(rInt int, rString string, location string) string { + template := testAccAzureRMStorageShare_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_share" "test" { + name = "testshare%s" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + quota = 5 +} +`, template, rString) +} + +func testAccAzureRMStorageShare_template(rInt int, rString string, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -328,13 +449,6 @@ resource "azurerm_storage_account" "test" { environment = "staging" } } - -resource "azurerm_storage_share" "test" { - name = "testshare" - resource_group_name = "${azurerm_resource_group.test.name}" - storage_account_name = "${azurerm_storage_account.test.name}" - quota = 5 -} `, rInt, location, rString) } diff --git a/azurerm/resource_arm_storage_table.go b/azurerm/resource_arm_storage_table.go index 20d4e9fc557b..7119f2d8b663 100644 --- a/azurerm/resource_arm_storage_table.go +++ b/azurerm/resource_arm_storage_table.go @@ -3,13 +3,16 @@ package azurerm import ( "fmt" "log" - "net/url" "regexp" - "strings" - "github.com/Azure/azure-sdk-for-go/storage" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/table/tables" ) func resourceArmStorageTable() *schema.Resource { @@ -17,11 +20,24 @@ func resourceArmStorageTable() *schema.Resource { Create: resourceArmStorageTableCreate, Read: resourceArmStorageTableRead, Delete: resourceArmStorageTableDelete, + Update: resourceArmStorageTableUpdate, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - SchemaVersion: 1, - MigrateState: resourceStorageTableMigrateState, + SchemaVersion: 2, + StateUpgraders: []schema.StateUpgrader{ + { + // this should have been applied from pre-0.12 migration system; backporting just in-case + Type: resourceStorageTableStateResourceV0V1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceStorageTableStateUpgradeV0ToV1, + Version: 0, + }, + { + Type: resourceStorageTableStateResourceV0V1().CoreConfigSchema().ImpliedType(), + Upgrade: resourceStorageTableStateUpgradeV1ToV2, + Version: 1, + }, + }, Schema: map[string]*schema.Schema{ "name": { @@ -30,73 +46,100 @@ func resourceArmStorageTable() *schema.Resource { ForceNew: true, ValidateFunc: validateArmStorageTableName, }, - "resource_group_name": resourceGroupNameSchema(), + "storage_account_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageAccountName, }, - }, - } -} -func validateArmStorageTableName(v interface{}, k string) (warnings []string, errors []error) { - value := v.(string) - if value == "table" { - errors = append(errors, fmt.Errorf( - "Table Storage %q cannot use the word `table`: %q", - k, value)) - } - if !regexp.MustCompile(`^[A-Za-z][A-Za-z0-9]{2,62}$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "Table Storage %q cannot begin with a numeric character, only alphanumeric characters are allowed and must be between 3 and 63 characters long: %q", - k, value)) + // TODO: deprecate this in the docs + "resource_group_name": azure.SchemaResourceGroupNameDeprecated(), + + "acl": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 64), + }, + "access_policy": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "expiry": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "permissions": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + }, + }, + }, } - - return warnings, errors } func resourceArmStorageTableCreate(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext - environment := armClient.environment + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage - name := d.Get("name").(string) - resourceGroupName := d.Get("resource_group_name").(string) - storageAccountName := d.Get("storage_account_name").(string) + tableName := d.Get("name").(string) + accountName := d.Get("storage_account_name").(string) + aclsRaw := d.Get("acl").(*schema.Set).List() + acls := expandStorageTableACLs(aclsRaw) - tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(ctx, resourceGroupName, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", tableName, accountName, err) } - if !accountExists { - return fmt.Errorf("Storage Account %q Not Found", storageAccountName) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Share %q (Account %s) - assuming removed & removing from state", tableName, accountName) } - table := tableClient.GetTableReference(name) - id := fmt.Sprintf("https://%s.table.%s/%s", storageAccountName, environment.StorageEndpointSuffix, name) + client, err := storageClient.TablesClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building Table Client: %s", err) + } - if requireResourcesToBeImported { - metaDataLevel := storage.MinimalMetadata - options := &storage.QueryTablesOptions{} - tables, e := tableClient.QueryTables(metaDataLevel, options) - if e != nil { - return fmt.Errorf("Error checking if Table %q exists (Account %q / Resource Group %q): %s", name, storageAccountName, resourceGroupName, e) + id := client.GetResourceID(accountName, tableName) + if features.ShouldResourcesBeImported() { + existing, err := client.Exists(ctx, *resourceGroup, tableName) + if err != nil { + if !utils.ResponseWasNotFound(existing) { + return fmt.Errorf("Error checking for existence of existing Storage Table %q (Account %q / Resource Group %q): %+v", tableName, accountName, *resourceGroup, err) + } } - for _, table := range tables.Tables { - if table.Name == name { - return tf.ImportAsExistsError("azurerm_storage_table", id) - } + if !utils.ResponseWasNotFound(existing) { + return tf.ImportAsExistsError("azurerm_storage_table", id) } } - log.Printf("[INFO] Creating table %q in storage account %q.", name, storageAccountName) - timeout := uint(60) - options := &storage.TableOptions{} - err = table.Create(timeout, storage.NoMetadata, options) - if err != nil { - return fmt.Errorf("Error creating table %q in storage account %q: %s", name, storageAccountName, err) + log.Printf("[DEBUG] Creating Table %q in Storage Account %q.", tableName, accountName) + if _, err := client.Create(ctx, accountName, tableName); err != nil { + return fmt.Errorf("Error creating Table %q within Storage Account %q: %s", tableName, accountName, err) + } + + if _, err := client.SetACL(ctx, accountName, tableName, acls); err != nil { + return fmt.Errorf("Error setting ACL's for Storage Table %q (Account %q / Resource Group %q): %+v", tableName, accountName, *resourceGroup, err) } d.SetId(id) @@ -104,126 +147,186 @@ func resourceArmStorageTableCreate(d *schema.ResourceData, meta interface{}) err } func resourceArmStorageTableRead(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext - id, err := parseStorageTableID(d.Id()) + id, err := tables.ParseResourceID(d.Id()) if err != nil { return err } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", id.TableName, id.AccountName, err) } if resourceGroup == nil { - log.Printf("Unable to determine Resource Group for Storage Account %q (assuming removed)", id.storageAccountName) + log.Printf("Unable to determine Resource Group for Storage Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountName) d.SetId("") return nil } - tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) + client, err := storageClient.TablesClient(ctx, *resourceGroup, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error building Table Client: %s", err) } - if !accountExists { - log.Printf("[DEBUG] Storage account %q not found, removing table %q from state", id.storageAccountName, id.tableName) - d.SetId("") - return nil - } - - metaDataLevel := storage.MinimalMetadata - options := &storage.QueryTablesOptions{} - tables, err := tableClient.QueryTables(metaDataLevel, options) + exists, err := client.Exists(ctx, id.AccountName, id.TableName) if err != nil { - return fmt.Errorf("Failed to retrieve Tables in Storage Account %q: %s", id.tableName, err) - } - - var storageTable *storage.Table - for _, table := range tables.Tables { - if table.Name == id.tableName { - storageTable = &table - break + if utils.ResponseWasNotFound(exists) { + log.Printf("[DEBUG] Storage Account %q not found, removing table %q from state", id.AccountName, id.TableName) + d.SetId("") + return nil } + + return fmt.Errorf("Error retrieving Table %q in Storage Account %q: %s", id.TableName, id.AccountName, err) } - if storageTable == nil { - log.Printf("[INFO] Table %q does not exist in Storage Account %q, removing from state...", id.tableName, id.storageAccountName) - d.SetId("") - return nil + acls, err := client.GetACL(ctx, id.AccountName, id.TableName) + if err != nil { + return fmt.Errorf("Error retrieving ACL's %q in Storage Account %q: %s", id.TableName, id.AccountName, err) } - d.Set("name", id.tableName) - d.Set("storage_account_name", id.storageAccountName) + d.Set("name", id.TableName) + d.Set("storage_account_name", id.AccountName) d.Set("resource_group_name", resourceGroup) + if err := d.Set("acl", flattenStorageTableACLs(acls)); err != nil { + return fmt.Errorf("Error flattening `acl`: %+v", err) + } + return nil } func resourceArmStorageTableDelete(d *schema.ResourceData, meta interface{}) error { - armClient := meta.(*ArmClient) - ctx := armClient.StopContext + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext - id, err := parseStorageTableID(d.Id()) + id, err := tables.ParseResourceID(d.Id()) if err != nil { return err } - resourceGroup, err := determineResourceGroupForStorageAccount(id.storageAccountName, armClient) + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", id.TableName, id.AccountName, err) } if resourceGroup == nil { - log.Printf("Unable to determine Resource Group for Storage Account %q (assuming removed)", id.storageAccountName) + log.Printf("Unable to determine Resource Group for Storage Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountName) return nil } - tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(ctx, *resourceGroup, id.storageAccountName) + client, err := storageClient.TablesClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building Table Client: %s", err) + } + + log.Printf("[INFO] Deleting Table %q in Storage Account %q", id.TableName, id.AccountName) + if _, err := client.Delete(ctx, id.AccountName, id.TableName); err != nil { + return fmt.Errorf("Error deleting Table %q from Storage Account %q: %s", id.TableName, id.AccountName, err) + } + + return nil +} + +func resourceArmStorageTableUpdate(d *schema.ResourceData, meta interface{}) error { + storageClient := meta.(*ArmClient).storage + ctx := meta.(*ArmClient).StopContext + + id, err := tables.ParseResourceID(d.Id()) if err != nil { return err } - if !accountExists { - log.Printf("[INFO] Storage Account %q doesn't exist so the table won't exist", id.storageAccountName) + + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", id.TableName, id.AccountName, err) + } + + if resourceGroup == nil { + log.Printf("Unable to determine Resource Group for Storage Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountName) + d.SetId("") return nil } - table := tableClient.GetTableReference(id.tableName) - timeout := uint(60) - options := &storage.TableOptions{} + client, err := storageClient.TablesClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building Table Client: %s", err) + } + + if d.HasChange("acl") { + log.Printf("[DEBUG] Updating the ACL's for Storage Table %q (Storage Account %q)", id.TableName, id.AccountName) + + aclsRaw := d.Get("acl").(*schema.Set).List() + acls := expandStorageTableACLs(aclsRaw) + + if _, err := client.SetACL(ctx, id.AccountName, id.TableName, acls); err != nil { + return fmt.Errorf("Error updating ACL's for Storage Table %q (Storage Account %q): %s", id.TableName, id.AccountName, err) + } - log.Printf("[INFO] Deleting Table %q in Storage Account %q", id.tableName, id.storageAccountName) - if err := table.Delete(timeout, options); err != nil { - return fmt.Errorf("Error deleting table %q from Storage Account %q: %s", id.tableName, id.storageAccountName, err) + log.Printf("[DEBUG] Updated the ACL's for Storage Table %q (Storage Account %q)", id.TableName, id.AccountName) } - return nil + return resourceArmStorageTableRead(d, meta) } -type storageTableId struct { - storageAccountName string - tableName string +func validateArmStorageTableName(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + if value == "table" { + errors = append(errors, fmt.Errorf( + "Table Storage %q cannot use the word `table`: %q", + k, value)) + } + if !regexp.MustCompile(`^[A-Za-z][A-Za-z0-9]{2,62}$`).MatchString(value) { + errors = append(errors, fmt.Errorf( + "Table Storage %q cannot begin with a numeric character, only alphanumeric characters are allowed and must be between 3 and 63 characters long: %q", + k, value)) + } + + return warnings, errors } -func parseStorageTableID(input string) (*storageTableId, error) { - // https://myaccount.table.core.windows.net/table1 - uri, err := url.Parse(input) - if err != nil { - return nil, fmt.Errorf("Error parsing %q as a URI: %+v", input, err) +func expandStorageTableACLs(input []interface{}) []tables.SignedIdentifier { + results := make([]tables.SignedIdentifier, 0) + + for _, v := range input { + vals := v.(map[string]interface{}) + + policies := vals["access_policy"].([]interface{}) + policy := policies[0].(map[string]interface{}) + + identifier := tables.SignedIdentifier{ + Id: vals["id"].(string), + AccessPolicy: tables.AccessPolicy{ + Start: policy["start"].(string), + Expiry: policy["expiry"].(string), + Permission: policy["permissions"].(string), + }, + } + results = append(results, identifier) } - segments := strings.Split(uri.Host, ".") - if len(segments) > 0 { - storageAccountName := segments[0] - table := strings.Replace(uri.Path, "/", "", 1) - id := storageTableId{ - storageAccountName: storageAccountName, - tableName: table, + return results +} + +func flattenStorageTableACLs(input tables.GetACLResult) []interface{} { + result := make([]interface{}, 0) + + for _, v := range input.SignedIdentifiers { + output := map[string]interface{}{ + "id": v.Id, + "access_policy": []interface{}{ + map[string]interface{}{ + "start": v.AccessPolicy.Start, + "expiry": v.AccessPolicy.Expiry, + "permissions": v.AccessPolicy.Permission, + }, + }, } - return &id, nil + + result = append(result, output) } - return nil, nil + return result } diff --git a/azurerm/resource_arm_storage_table_entity.go b/azurerm/resource_arm_storage_table_entity.go new file mode 100644 index 000000000000..cd4531b727cf --- /dev/null +++ b/azurerm/resource_arm_storage_table_entity.go @@ -0,0 +1,213 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/table/entities" +) + +func resourceArmStorageTableEntity() *schema.Resource { + return &schema.Resource{ + Create: resourceArmStorageTableEntityCreateUpdate, + Read: resourceArmStorageTableEntityRead, + Update: resourceArmStorageTableEntityCreateUpdate, + Delete: resourceArmStorageTableEntityDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "table_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageTableName, + }, + "storage_account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageAccountName, + }, + "partition_key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "row_key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "entity": { + Type: schema.TypeMap, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +func resourceArmStorageTableEntityCreateUpdate(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage + + accountName := d.Get("storage_account_name").(string) + tableName := d.Get("table_name").(string) + partitionKey := d.Get("partition_key").(string) + rowKey := d.Get("row_key").(string) + entity := d.Get("entity").(map[string]interface{}) + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Stable %q (Account %s): %s", tableName, accountName, err) + } + if resourceGroup == nil { + if d.IsNewResource() { + return fmt.Errorf("Unable to locate Resource Group for Storage Table %q (Account %s)", tableName, accountName) + } else { + log.Printf("[DEBUG] Unable to locate Resource Group for Storage Table %q (Account %s) - assuming removed & removing from state", tableName, accountName) + d.SetId("") + return nil + } + } + + client, err := storageClient.TableEntityClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building Entity Client: %s", err) + } + + if features.ShouldResourcesBeImported() { + input := entities.GetEntityInput{ + PartitionKey: partitionKey, + RowKey: rowKey, + MetaDataLevel: entities.NoMetaData, + } + existing, err := client.Get(ctx, accountName, tableName, input) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", partitionKey, rowKey, tableName, accountName, *resourceGroup, err) + } + } + + if !utils.ResponseWasNotFound(existing.Response) { + id := client.GetResourceID(accountName, tableName, partitionKey, rowKey) + return tf.ImportAsExistsError("azurerm_storage_table_entity", id) + } + } + + input := entities.InsertOrMergeEntityInput{ + PartitionKey: partitionKey, + RowKey: rowKey, + Entity: entity, + } + + if _, err := client.InsertOrMerge(ctx, accountName, tableName, input); err != nil { + return fmt.Errorf("Error creating Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %+v", partitionKey, rowKey, tableName, accountName, *resourceGroup, err) + } + + resourceID := client.GetResourceID(accountName, tableName, partitionKey, rowKey) + d.SetId(resourceID) + + return resourceArmStorageTableEntityRead(d, meta) +} + +func resourceArmStorageTableEntityRead(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage + + id, err := entities.ParseResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", id.TableName, id.AccountName, err) + } + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountName) + d.SetId("") + return nil + } + + client, err := storageClient.TableEntityClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building Table Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) + } + + input := entities.GetEntityInput{ + PartitionKey: id.PartitionKey, + RowKey: id.RowKey, + MetaDataLevel: entities.NoMetaData, + } + + result, err := client.Get(ctx, id.AccountName, id.TableName, input) + if err != nil { + return fmt.Errorf("Error retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, *resourceGroup, err) + } + + d.Set("storage_account_name", id.AccountName) + d.Set("table_name", id.TableName) + d.Set("partition_key", id.PartitionKey) + d.Set("row_key", id.RowKey) + if err := d.Set("entity", flattenEntity(result.Entity)); err != nil { + return fmt.Errorf("Error setting `entity` for Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, *resourceGroup, err) + } + + return nil +} + +func resourceArmStorageTableEntityDelete(d *schema.ResourceData, meta interface{}) error { + ctx := meta.(*ArmClient).StopContext + storageClient := meta.(*ArmClient).storage + + id, err := entities.ParseResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup, err := storageClient.FindResourceGroup(ctx, id.AccountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", id.TableName, id.AccountName, err) + } + if resourceGroup == nil { + log.Printf("[WARN] Unable to determine Resource Group for Storage Table %q (Account %s) - assuming removed already", id.TableName, id.AccountName) + return nil + } + + client, err := storageClient.TableEntityClient(ctx, *resourceGroup, id.AccountName) + if err != nil { + return fmt.Errorf("Error building Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountName, *resourceGroup, err) + } + + input := entities.DeleteEntityInput{ + PartitionKey: id.PartitionKey, + RowKey: id.RowKey, + } + + if _, err := client.Delete(ctx, id.AccountName, id.TableName, input); err != nil { + return fmt.Errorf("Error deleting Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, *resourceGroup, err) + } + + return nil +} + +// The api returns extra information that we already have. We'll remove it here before setting it in state. +func flattenEntity(entity map[string]interface{}) map[string]interface{} { + delete(entity, "PartitionKey") + delete(entity, "RowKey") + delete(entity, "Timestamp") + + return entity +} diff --git a/azurerm/resource_arm_storage_table_entity_test.go b/azurerm/resource_arm_storage_table_entity_test.go new file mode 100644 index 000000000000..ca60417a8d9f --- /dev/null +++ b/azurerm/resource_arm_storage_table_entity_test.go @@ -0,0 +1,279 @@ +package azurerm + +import ( + "fmt" + "net/http" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/table/entities" +) + +func TestAccAzureRMTableEntity_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + resourceName := "azurerm_storage_table_entity.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMTableEntityDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMTableEntity_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMTableEntityExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMTableEntity_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + resourceName := "azurerm_storage_table_entity.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMTableEntityDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMTableEntity_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMTableEntityExists(resourceName), + ), + }, + { + Config: testAccAzureRMTableEntity_requiresImport(ri, rs, location), + ExpectError: testRequiresImportError("azurerm_storage_table_entity"), + }, + }, + }) +} + +func TestAccAzureRMTableEntity_update(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(5)) + location := testLocation() + resourceName := "azurerm_storage_table_entity.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMTableEntityDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMTableEntity_basic(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMTableEntityExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMTableEntity_updated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMTableEntityExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMTableEntityExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + tableName := rs.Primary.Attributes["table_name"] + accountName := rs.Primary.Attributes["storage_account_name"] + partitionKey := rs.Primary.Attributes["partition_key"] + rowKey := rs.Primary.Attributes["row_key"] + + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Table Entity (Partition Key %q / Row Key %q) (Table %q / Account %q): %v", partitionKey, rowKey, tableName, accountName, err) + } + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Table Entity (Partition Key %q / Row Key %q) (Table %q / Account %q)", partitionKey, rowKey, tableName, accountName) + } + + client, err := storageClient.TableEntityClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building Table Entity Client: %s", err) + } + + input := entities.GetEntityInput{ + PartitionKey: partitionKey, + RowKey: rowKey, + MetaDataLevel: entities.NoMetaData, + } + resp, err := client.Get(ctx, accountName, tableName, input) + if err != nil { + return fmt.Errorf("Bad: Get on Table EntityClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Entity (Partition Key %q / Row Key %q) (Table %q / Account %q / Resource Group %q) does not exist", partitionKey, rowKey, tableName, accountName, *resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMTableEntityDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_storage_table_entity" { + continue + } + + tableName := rs.Primary.Attributes["table_name"] + accountName := rs.Primary.Attributes["storage_account_name"] + partitionKey := rs.Primary.Attributes["parititon_key"] + rowKey := rs.Primary.Attributes["row_key"] + + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Table Entity (Partition Key %q / Row Key %q) (Table %q / Account %q / Resource Group %q): %v", partitionKey, rowKey, tableName, accountName, *resourceGroup, err) + } + + // not found, the account's gone + if resourceGroup == nil { + return nil + } + + client, err := storageClient.TableEntityClient(ctx, *resourceGroup, accountName) + if err != nil { + return fmt.Errorf("Error building TableEntity Client: %s", err) + } + + input := entities.GetEntityInput{ + PartitionKey: partitionKey, + RowKey: rowKey, + } + resp, err := client.Get(ctx, accountName, tableName, input) + if err != nil { + return fmt.Errorf("Bad: Get on Table Entity: %+v", err) + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Table Entity still exists:\n%#v", resp) + } + } + + return nil +} + +func testAccAzureRMTableEntity_basic(rInt int, rString string, location string) string { + template := testAccAzureRMTableEntity_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_table_entity" "test" { + storage_account_name = "${azurerm_storage_account.test.name}" + table_name = "${azurerm_storage_table.test.name}" + + partition_key = "test_partition%d" + row_key = "test_row%d" + entity = { + Foo = "Bar" + } +} +`, template, rInt, rInt) +} + +func testAccAzureRMTableEntity_requiresImport(rInt int, rString string, location string) string { + template := testAccAzureRMTableEntity_basic(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_table_entity" "test" { + storage_account_name = "${azurerm_storage_account.test.name}" + table_name = "${azurerm_storage_table.test.name}" + + partition_key = "test_partition%d" + row_key = "test_row%d" + entity = { + Foo = "Bar" + } +} +`, template, rInt, rInt) +} + +func testAccAzureRMTableEntity_updated(rInt int, rString string, location string) string { + template := testAccAzureRMTableEntity_template(rInt, rString, location) + return fmt.Sprintf(` +%s + +resource "azurerm_storage_table_entity" "test" { + storage_account_name = "${azurerm_storage_account.test.name}" + table_name = "${azurerm_storage_table.test.name}" + + partition_key = "test_partition%d" + row_key = "test_row%d" + entity = { + Foo = "Bar" + Test = "Updated" + } +} +`, template, rInt, rInt) +} + +func testAccAzureRMTableEntity_template(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_table" "test" { + name = "acctestst%d" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} +`, rInt, location, rString, rInt) +} diff --git a/azurerm/resource_arm_storage_table_migration.go b/azurerm/resource_arm_storage_table_migration.go index e2da0116cca7..d6320ea910df 100644 --- a/azurerm/resource_arm_storage_table_migration.go +++ b/azurerm/resource_arm_storage_table_migration.go @@ -4,37 +4,91 @@ import ( "fmt" "log" - "github.com/hashicorp/terraform/terraform" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" ) -func resourceStorageTableMigrateState( - v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) { - switch v { - case 0: - log.Println("[INFO] Found AzureRM Storage Table State v0; migrating to v1") - return migrateStorageTableStateV0toV1(is, meta) - default: - return is, fmt.Errorf("Unexpected schema version: %d", v) +// the schema schema was used for both V0 and V1 +func resourceStorageTableStateResourceV0V1() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageTableName, + }, + "storage_account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArmStorageAccountName, + }, + "resource_group_name": azure.SchemaResourceGroupNameDeprecated(), + "acl": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 64), + }, + "access_policy": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "expiry": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + "permissions": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + }, + }, + }, } } -func migrateStorageTableStateV0toV1(is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) { - if is.Empty() { - log.Println("[DEBUG] Empty InstanceState; nothing to migrate.") - return is, nil - } +func resourceStorageTableStateUpgradeV0ToV1(rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + tableName := rawState["name"].(string) + accountName := rawState["storage_account_name"].(string) + environment := meta.(*ArmClient).environment - log.Printf("[DEBUG] ARM Storage Table Attributes before Migration: %#v", is.Attributes) + id := rawState["id"].(string) + newResourceID := fmt.Sprintf("https://%s.table.%s/%s", accountName, environment.StorageEndpointSuffix, tableName) + log.Printf("[DEBUG] Updating ID from %q to %q", id, newResourceID) - environment := meta.(*ArmClient).environment + rawState["id"] = newResourceID + return rawState, nil +} - tableName := is.Attributes["name"] - storageAccountName := is.Attributes["storage_account_name"] - newID := fmt.Sprintf("https://%s.table.%s/%s", storageAccountName, environment.StorageEndpointSuffix, tableName) - is.Attributes["id"] = newID - is.ID = newID +func resourceStorageTableStateUpgradeV1ToV2(rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + tableName := rawState["name"].(string) + accountName := rawState["storage_account_name"].(string) + environment := meta.(*ArmClient).environment - log.Printf("[DEBUG] ARM Storage Table Attributes after State Migration: %#v", is.Attributes) + id := rawState["id"].(string) + newResourceID := fmt.Sprintf("https://%s.table.%s/Tables('%s')", accountName, environment.StorageEndpointSuffix, tableName) + log.Printf("[DEBUG] Updating ID from %q to %q", id, newResourceID) - return is, nil + rawState["id"] = newResourceID + return rawState, nil } diff --git a/azurerm/resource_arm_storage_table_migration_test.go b/azurerm/resource_arm_storage_table_migration_test.go index 9122cb3b5643..5775cef3e7fc 100644 --- a/azurerm/resource_arm_storage_table_migration_test.go +++ b/azurerm/resource_arm_storage_table_migration_test.go @@ -2,65 +2,88 @@ package azurerm import ( "fmt" + "reflect" "testing" - "github.com/hashicorp/terraform/terraform" + "github.com/Azure/go-autorest/autorest/azure" ) -// NOTE: this is intentionally an acceptance test (and we're not explicitly setting the env) -// as we want to run this depending on the cloud we're in. -func TestAccAzureRMStorageTableMigrateState(t *testing.T) { - config := testGetAzureConfig(t) - if config == nil { - t.SkipNow() - return +func TestAzureRMStorageTableMigrateStateV0ToV1(t *testing.T) { + clouds := []azure.Environment{ + azure.ChinaCloud, + azure.GermanCloud, + azure.PublicCloud, + azure.USGovernmentCloud, } - client, err := getArmClient(config, false, "") - if err != nil { - t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) - return + for _, cloud := range clouds { + t.Logf("[DEBUG] Testing with Cloud %q", cloud.Name) + + input := map[string]interface{}{ + "id": "table1", + "name": "table1", + "storage_account_name": "account1", + } + meta := &ArmClient{ + environment: cloud, + } + suffix := meta.environment.StorageEndpointSuffix + + expected := map[string]interface{}{ + "id": fmt.Sprintf("https://account1.table.%s/table1", suffix), + "name": "table1", + "storage_account_name": "account1", + } + + actual, err := resourceStorageTableStateUpgradeV0ToV1(input, meta) + if err != nil { + t.Fatalf("Expected no error but got: %s", err) + } + + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("Expected %+v. Got %+v. But expected them to be the same", expected, actual) + } + + t.Logf("[DEBUG] Ok!") } +} - client.StopContext = testAccProvider.StopContext() - - suffix := client.environment.StorageEndpointSuffix - - cases := map[string]struct { - StateVersion int - ID string - InputAttributes map[string]string - ExpectedAttributes map[string]string - }{ - "v0_1_without_value": { - StateVersion: 0, - ID: "some_id", - InputAttributes: map[string]string{ - "name": "table1", - "storage_account_name": "example", - }, - ExpectedAttributes: map[string]string{ - "id": fmt.Sprintf("https://example.table.%s/table1", suffix), - }, - }, +func TestAzureRMStorageTableMigrateStateV1ToV2(t *testing.T) { + clouds := []azure.Environment{ + azure.ChinaCloud, + azure.GermanCloud, + azure.PublicCloud, + azure.USGovernmentCloud, } - for tn, tc := range cases { - is := &terraform.InstanceState{ - ID: tc.ID, - Attributes: tc.InputAttributes, + for _, cloud := range clouds { + t.Logf("[DEBUG] Testing with Cloud %q", cloud.Name) + + meta := &ArmClient{ + environment: cloud, } - is, err := resourceStorageTableMigrateState(tc.StateVersion, is, client) + suffix := meta.environment.StorageEndpointSuffix + input := map[string]interface{}{ + "id": fmt.Sprintf("https://account1.table.%s/table1", suffix), + "name": "table1", + "storage_account_name": "account1", + } + expected := map[string]interface{}{ + "id": fmt.Sprintf("https://account1.table.%s/Tables('table1')", suffix), + "name": "table1", + "storage_account_name": "account1", + } + + actual, err := resourceStorageTableStateUpgradeV1ToV2(input, meta) if err != nil { - t.Fatalf("bad: %s, err: %#v", tn, err) + t.Fatalf("Expected no error but got: %s", err) } - for k, v := range tc.ExpectedAttributes { - actual := is.Attributes[k] - if actual != v { - t.Fatalf("Bad Storage Table Migrate for %q: %q\n\n expected: %q", k, actual, v) - } + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("Expected %+v. Got %+v. But expected them to be the same", expected, actual) } + + t.Logf("[DEBUG] Ok!") } } diff --git a/azurerm/resource_arm_storage_table_test.go b/azurerm/resource_arm_storage_table_test.go index 547242678a6b..b1e44a0fa842 100644 --- a/azurerm/resource_arm_storage_table_test.go +++ b/azurerm/resource_arm_storage_table_test.go @@ -2,20 +2,19 @@ package azurerm import ( "fmt" - "log" "strings" "testing" - "github.com/Azure/azure-sdk-for-go/storage" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) func TestAccAzureRMStorageTable_basic(t *testing.T) { resourceName := "azurerm_storage_table.test" - var table storage.Table ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) @@ -29,7 +28,7 @@ func TestAccAzureRMStorageTable_basic(t *testing.T) { { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageTableExists(resourceName, &table), + testCheckAzureRMStorageTableExists(resourceName), ), }, { @@ -42,13 +41,12 @@ func TestAccAzureRMStorageTable_basic(t *testing.T) { } func TestAccAzureRMStorageTable_requiresImport(t *testing.T) { - if !requireResourcesToBeImported { + if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") return } resourceName := "azurerm_storage_table.test" - var table storage.Table ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) @@ -62,7 +60,7 @@ func TestAccAzureRMStorageTable_requiresImport(t *testing.T) { { Config: testAccAzureRMStorageTable_basic(ri, rs, location), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageTableExists(resourceName, &table), + testCheckAzureRMStorageTableExists(resourceName), ), }, { @@ -74,8 +72,6 @@ func TestAccAzureRMStorageTable_requiresImport(t *testing.T) { } func TestAccAzureRMStorageTable_disappears(t *testing.T) { - var table storage.Table - ri := tf.AccRandTimeInt() rs := strings.ToLower(acctest.RandString(11)) config := testAccAzureRMStorageTable_basic(ri, rs, testLocation()) @@ -88,8 +84,8 @@ func TestAccAzureRMStorageTable_disappears(t *testing.T) { { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMStorageTableExists("azurerm_storage_table.test", &table), - testAccARMStorageTableDisappears("azurerm_storage_table.test", &table), + testCheckAzureRMStorageTableExists("azurerm_storage_table.test"), + testAccARMStorageTableDisappears("azurerm_storage_table.test"), ), ExpectNonEmptyPlan: true, }, @@ -97,7 +93,44 @@ func TestAccAzureRMStorageTable_disappears(t *testing.T) { }) } -func testCheckAzureRMStorageTableExists(resourceName string, t *storage.Table) resource.TestCheckFunc { +func TestAccAzureRMStorageTable_acl(t *testing.T) { + ri := tf.AccRandTimeInt() + rs := strings.ToLower(acctest.RandString(11)) + location := testLocation() + resourceName := "azurerm_storage_table.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStorageTableDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStorageTable_acl(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageTableExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMStorageTable_aclUpdated(ri, rs, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStorageTableExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMStorageTableExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] @@ -105,77 +138,78 @@ func testCheckAzureRMStorageTableExists(resourceName string, t *storage.Table) r return fmt.Errorf("Not found: %s", resourceName) } - name := rs.Primary.Attributes["name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage table: %s", name) - } + tableName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] + + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext - tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(ctx, resourceGroup, storageAccountName) + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - return err + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", tableName, accountName, err) } - if !accountExists { - return fmt.Errorf("Bad: Storage Account %q does not exist", storageAccountName) + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Table %q (Account %s)", tableName, accountName) } - options := &storage.QueryTablesOptions{} - tables, err := tableClient.QueryTables(storage.MinimalMetadata, options) + client, err := storageClient.TablesClient(ctx, *resourceGroup, accountName) if err != nil { - return fmt.Errorf("Error querying Storage Table %q (storage account: %q) : %+v", name, storageAccountName, err) - } - if len(tables.Tables) == 0 { - return fmt.Errorf("Bad: Storage Table %q (storage account: %q) does not exist", name, storageAccountName) + return fmt.Errorf("Error building Table Client: %s", err) } - var found bool - for _, table := range tables.Tables { - if table.Name == name { - found = true - *t = table + props, err := client.Exists(ctx, accountName, tableName) + if err != nil { + if utils.ResponseWasNotFound(props) { + return fmt.Errorf("Table %q doesn't exist in Account %q!", tableName, accountName) } - } - if !found { - return fmt.Errorf("Bad: Storage Table %q (storage account: %q) does not exist", name, storageAccountName) + return fmt.Errorf("Error retrieving Table %q: %s", tableName, accountName) } return nil } } -func testAccARMStorageTableDisappears(resourceName string, t *storage.Table) resource.TestCheckFunc { +func testAccARMStorageTableDisappears(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] if !ok { return fmt.Errorf("Not found: %s", resourceName) } - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext + tableName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage table: %s", t.Name) + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) + if err != nil { + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", tableName, accountName, err) + } + if resourceGroup == nil { + return fmt.Errorf("Unable to locate Resource Group for Storage Table %q (Account %s)", tableName, accountName) } - tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(ctx, resourceGroup, storageAccountName) + client, err := storageClient.TablesClient(ctx, *resourceGroup, accountName) if err != nil { - return err + return fmt.Errorf("Error building Table Client: %s", err) } - if !accountExists { - log.Printf("[INFO]Storage Account %q doesn't exist so the table won't exist", storageAccountName) - return nil + + props, err := client.Exists(ctx, accountName, tableName) + if err != nil { + if utils.ResponseWasNotFound(props) { + return fmt.Errorf("Table %q doesn't exist in Account %q so it can't be deleted!", tableName, accountName) + } + + return fmt.Errorf("Error retrieving Table %q: %s", tableName, accountName) } - table := tableClient.GetTableReference(t.Name) - timeout := uint(60) - options := &storage.TableOptions{} - return table.Delete(timeout, options) + if _, err := client.Delete(ctx, accountName, tableName); err != nil { + return fmt.Errorf("Error deleting Table %q: %s", tableName, err) + } + + return nil } } @@ -185,40 +219,35 @@ func testCheckAzureRMStorageTableDestroy(s *terraform.State) error { continue } - name := rs.Primary.Attributes["name"] - storageAccountName := rs.Primary.Attributes["storage_account_name"] - resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] - if !hasResourceGroup { - return fmt.Errorf("Bad: no resource group found in state for storage table: %s", name) - } + tableName := rs.Primary.Attributes["name"] + accountName := rs.Primary.Attributes["storage_account_name"] - armClient := testAccProvider.Meta().(*ArmClient) - ctx := armClient.StopContext - tableClient, accountExists, err := armClient.getTableServiceClientForStorageAccount(ctx, resourceGroup, storageAccountName) + storageClient := testAccProvider.Meta().(*ArmClient).storage + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resourceGroup, err := storageClient.FindResourceGroup(ctx, accountName) if err != nil { - //If we can't get keys then the table can't exist - return nil + return fmt.Errorf("Error locating Resource Group for Storage Table %q (Account %s): %s", tableName, accountName, err) } - if !accountExists { + if resourceGroup == nil { return nil } - options := &storage.QueryTablesOptions{} - tables, err := tableClient.QueryTables(storage.NoMetadata, options) + client, err := storageClient.TablesClient(ctx, *resourceGroup, accountName) if err != nil { - return nil + return fmt.Errorf("Error building Table Client: %s", err) } - var found bool - for _, table := range tables.Tables { - if table.Name == name { - found = true + props, err := client.Exists(ctx, accountName, tableName) + if err != nil { + if utils.ResponseWasNotFound(props) { + return nil } - } - if found { - return fmt.Errorf("Bad: Storage Table %q (storage account: %q) still exist", name, storageAccountName) + return fmt.Errorf("Error retrieving Table %q: %s", tableName, accountName) } + + return fmt.Errorf("Bad: Table %q (storage account: %q) still exists", tableName, accountName) } return nil @@ -295,3 +324,85 @@ resource "azurerm_storage_table" "import" { } `, template) } + +func testAccAzureRMStorageTable_acl(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestacc%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + tags = { + environment = "staging" + } +} + +resource "azurerm_storage_table" "test" { + name = "acctestst%d" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + acl { + id = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI" + + access_policy { + permissions = "raud" + start = "2020-11-26T08:49:37.0000000Z" + expiry = "2020-11-27T08:49:37.0000000Z" + } + } +} +`, rInt, location, rString, rInt) +} + +func testAccAzureRMStorageTable_aclUpdated(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_storage_account" "test" { + name = "acctestacc%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + tags = { + environment = "staging" + } +} + +resource "azurerm_storage_table" "test" { + name = "acctestst%d" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + + acl { + id = "AAAANDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI" + + access_policy { + permissions = "raud" + start = "2020-11-26T08:49:37.0000000Z" + expiry = "2020-11-27T08:49:37.0000000Z" + } + } + acl { + id = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI" + + access_policy { + permissions = "raud" + start = "2019-07-02T09:38:21.0000000Z" + expiry = "2019-07-02T10:38:21.0000000Z" + } + } +} +`, rInt, location, rString, rInt) +} diff --git a/azurerm/resource_arm_stream_analytics_function_javascript_udf.go b/azurerm/resource_arm_stream_analytics_function_javascript_udf.go new file mode 100644 index 000000000000..572de1830e2f --- /dev/null +++ b/azurerm/resource_arm_stream_analytics_function_javascript_udf.go @@ -0,0 +1,305 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/validation" + + "github.com/Azure/azure-sdk-for-go/services/streamanalytics/mgmt/2016-03-01/streamanalytics" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmStreamAnalyticsFunctionUDF() *schema.Resource { + return &schema.Resource{ + Create: resourceArmStreamAnalyticsFunctionUDFCreateUpdate, + Read: resourceArmStreamAnalyticsFunctionUDFRead, + Update: resourceArmStreamAnalyticsFunctionUDFCreateUpdate, + Delete: resourceArmStreamAnalyticsFunctionUDFDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "stream_analytics_job_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "input": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "any", + "datetime", + "array", + "bigint", + "float", + "nvarchar(max)", + "record", + }, false), + }, + }, + }, + }, + + "output": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "any", + "datetime", + "array", + "bigint", + "float", + "nvarchar(max)", + "record", + }, false), + }, + }, + }, + }, + + "script": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + // TODO: JS diff suppress func?! + }, + }, + } +} + +func resourceArmStreamAnalyticsFunctionUDFCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).streamanalytics.FunctionsClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Azure Stream Analytics Function Javascript UDF creation.") + name := d.Get("name").(string) + jobName := d.Get("stream_analytics_job_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, jobName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Stream Analytics Function Javascript UDF %q (Job %q / Resource Group %q): %s", name, jobName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_stream_analytics_function_javascript_udf", *existing.ID) + } + } + + script := d.Get("script").(string) + inputsRaw := d.Get("input").([]interface{}) + inputs := expandStreamAnalyticsFunctionInputs(inputsRaw) + + outputRaw := d.Get("output").([]interface{}) + output := expandStreamAnalyticsFunctionOutput(outputRaw) + + function := streamanalytics.Function{ + Properties: &streamanalytics.ScalarFunctionProperties{ + Type: streamanalytics.TypeScalar, + ScalarFunctionConfiguration: &streamanalytics.ScalarFunctionConfiguration{ + Binding: &streamanalytics.JavaScriptFunctionBinding{ + Type: streamanalytics.TypeMicrosoftStreamAnalyticsJavascriptUdf, + JavaScriptFunctionBindingProperties: &streamanalytics.JavaScriptFunctionBindingProperties{ + Script: utils.String(script), + }, + }, + Inputs: inputs, + Output: output, + }, + }, + } + + if d.IsNewResource() { + if _, err := client.CreateOrReplace(ctx, function, resourceGroup, jobName, name, "", ""); err != nil { + return fmt.Errorf("Error Creating Stream Analytics Function Javascript UDF %q (Job %q / Resource Group %q): %+v", name, jobName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, jobName, name) + if err != nil { + return fmt.Errorf("Error retrieving Stream Analytics Function Javascript UDF %q (Job %q / Resource Group %q): %+v", name, jobName, resourceGroup, err) + } + if read.ID == nil { + return fmt.Errorf("Cannot read ID of Stream Analytics Function Javascript UDF %q (Job %q / Resource Group %q)", name, jobName, resourceGroup) + } + + d.SetId(*read.ID) + } else { + if _, err := client.Update(ctx, function, resourceGroup, jobName, name, ""); err != nil { + return fmt.Errorf("Error Updating Stream Analytics Function Javascript UDF %q (Job %q / Resource Group %q): %+v", name, jobName, resourceGroup, err) + } + } + + return resourceArmStreamAnalyticsFunctionUDFRead(d, meta) +} + +func resourceArmStreamAnalyticsFunctionUDFRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).streamanalytics.FunctionsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + jobName := id.Path["streamingjobs"] + name := id.Path["functions"] + + resp, err := client.Get(ctx, resourceGroup, jobName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Function Javascript UDF %q was not found in Stream Analytics Job %q / Resource Group %q - removing from state!", name, jobName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Stream Function Javascript UDF %q (Stream Analytics Job %q / Resource Group %q): %+v", name, jobName, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + d.Set("stream_analytics_job_name", jobName) + + if props := resp.Properties; props != nil { + scalarProps, ok := props.AsScalarFunctionProperties() + if !ok { + return fmt.Errorf("Error converting Props to a Scalar Function") + } + + binding, ok := scalarProps.Binding.AsJavaScriptFunctionBinding() + if !ok { + return fmt.Errorf("Error converting Binding to a JavaScript Function Binding") + } + + if bindingProps := binding.JavaScriptFunctionBindingProperties; bindingProps != nil { + d.Set("script", bindingProps.Script) + } + + if err := d.Set("input", flattenStreamAnalyticsFunctionInputs(scalarProps.Inputs)); err != nil { + return fmt.Errorf("Error flattening `input`: %+v", err) + } + + if err := d.Set("output", flattenStreamAnalyticsFunctionOutput(scalarProps.Output)); err != nil { + return fmt.Errorf("Error flattening `output`: %+v", err) + } + } + + return nil +} + +func resourceArmStreamAnalyticsFunctionUDFDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).streamanalytics.FunctionsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + jobName := id.Path["streamingjobs"] + name := id.Path["functions"] + + if resp, err := client.Delete(ctx, resourceGroup, jobName, name); err != nil { + if !response.WasNotFound(resp.Response) { + return fmt.Errorf("Error deleting Function Javascript UDF %q (Stream Analytics Job %q / Resource Group %q) %+v", name, jobName, resourceGroup, err) + } + } + + return nil +} + +func expandStreamAnalyticsFunctionInputs(input []interface{}) *[]streamanalytics.FunctionInput { + outputs := make([]streamanalytics.FunctionInput, 0) + + for _, raw := range input { + v := raw.(map[string]interface{}) + variableType := v["type"].(string) + outputs = append(outputs, streamanalytics.FunctionInput{ + DataType: utils.String(variableType), + }) + } + + return &outputs +} + +func flattenStreamAnalyticsFunctionInputs(input *[]streamanalytics.FunctionInput) []interface{} { + if input == nil { + return []interface{}{} + } + + outputs := make([]interface{}, 0) + + for _, v := range *input { + var variableType string + if v.DataType != nil { + variableType = *v.DataType + } + + outputs = append(outputs, map[string]interface{}{ + "type": variableType, + }) + } + + return outputs +} + +func expandStreamAnalyticsFunctionOutput(input []interface{}) *streamanalytics.FunctionOutput { + output := input[0].(map[string]interface{}) + + dataType := output["type"].(string) + return &streamanalytics.FunctionOutput{ + DataType: utils.String(dataType), + } +} + +func flattenStreamAnalyticsFunctionOutput(input *streamanalytics.FunctionOutput) []interface{} { + if input == nil { + return []interface{}{} + } + + var variableType string + if input.DataType != nil { + variableType = *input.DataType + } + + return []interface{}{ + map[string]interface{}{ + "type": variableType, + }, + } +} diff --git a/azurerm/resource_arm_stream_analytics_function_javascript_udf_test.go b/azurerm/resource_arm_stream_analytics_function_javascript_udf_test.go new file mode 100644 index 000000000000..da3837a95605 --- /dev/null +++ b/azurerm/resource_arm_stream_analytics_function_javascript_udf_test.go @@ -0,0 +1,256 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_basic(t *testing.T) { + resourceName := "azurerm_stream_analytics_function_javascript_udf.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_stream_analytics_function_javascript_udf.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFExists(resourceName), + ), + }, + { + Config: testAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_stream_analytics_function_javascript_udf"), + }, + }, + }) +} + +func TestAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_inputs(t *testing.T) { + resourceName := "azurerm_stream_analytics_function_javascript_udf.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_inputs(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + jobName := rs.Primary.Attributes["stream_analytics_job_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).streamanalytics.FunctionsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, jobName, name) + if err != nil { + return fmt.Errorf("Bad: Get on streamAnalyticsFunctionsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Function JavaScript UDF %q (Stream Analytics Job %q / Resource Group %q) does not exist", name, jobName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMStreamAnalyticsFunctionJavaScriptUDFDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).streamanalytics.OutputsClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_stream_analytics_function_javascript_udf" { + continue + } + + name := rs.Primary.Attributes["name"] + jobName := rs.Primary.Attributes["stream_analytics_job_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, jobName, name) + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Stream Analytics Function JavaScript UDF still exists:\n%#v", resp.OutputProperties) + } + } + + return nil +} + +func testAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_basic(rInt int, location string) string { + template := testAccAzureRMStreamAnalyticsFunctionJavaScriptUDF_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_stream_analytics_function_javascript_udf" "test" { + name = "acctestinput-%d" + stream_analytics_job_name = "${azurerm_stream_analytics_job.test.name}" + resource_group_name = "${azurerm_stream_analytics_job.test.resource_group_name}" + + script = <" that closes the next token. If - // non-empty, the subsequent call to Next will return a raw or RCDATA text - // token: one that treats "

" as text instead of an element. - // rawTag's contents are lower-cased. - rawTag string - // textIsRaw is whether the current text token's data is not escaped. - textIsRaw bool - // convertNUL is whether NUL bytes in the current token's data should - // be converted into \ufffd replacement characters. - convertNUL bool - // allowCDATA is whether CDATA sections are allowed in the current context. - allowCDATA bool -} - -// AllowCDATA sets whether or not the tokenizer recognizes as -// the text "foo". The default value is false, which means to recognize it as -// a bogus comment "" instead. -// -// Strictly speaking, an HTML5 compliant tokenizer should allow CDATA if and -// only if tokenizing foreign content, such as MathML and SVG. However, -// tracking foreign-contentness is difficult to do purely in the tokenizer, -// as opposed to the parser, due to HTML integration points: an element -// can contain a that is foreign-to-SVG but not foreign-to- -// HTML. For strict compliance with the HTML5 tokenization algorithm, it is the -// responsibility of the user of a tokenizer to call AllowCDATA as appropriate. -// In practice, if using the tokenizer without caring whether MathML or SVG -// CDATA is text or comments, such as tokenizing HTML to find all the anchor -// text, it is acceptable to ignore this responsibility. -func (z *Tokenizer) AllowCDATA(allowCDATA bool) { - z.allowCDATA = allowCDATA -} - -// NextIsNotRawText instructs the tokenizer that the next token should not be -// considered as 'raw text'. Some elements, such as script and title elements, -// normally require the next token after the opening tag to be 'raw text' that -// has no child elements. For example, tokenizing "a<b>c</b>d" -// yields a start tag token for "", a text token for "a<b>c</b>d", and -// an end tag token for "". There are no distinct start tag or end tag -// tokens for the "" and "". -// -// This tokenizer implementation will generally look for raw text at the right -// times. Strictly speaking, an HTML5 compliant tokenizer should not look for -// raw text if in foreign content: generally needs raw text, but a -// <title> inside an <svg> does not. Another example is that a <textarea> -// generally needs raw text, but a <textarea> is not allowed as an immediate -// child of a <select>; in normal parsing, a <textarea> implies </select>, but -// one cannot close the implicit element when parsing a <select>'s InnerHTML. -// Similarly to AllowCDATA, tracking the correct moment to override raw-text- -// ness is difficult to do purely in the tokenizer, as opposed to the parser. -// For strict compliance with the HTML5 tokenization algorithm, it is the -// responsibility of the user of a tokenizer to call NextIsNotRawText as -// appropriate. In practice, like AllowCDATA, it is acceptable to ignore this -// responsibility for basic usage. -// -// Note that this 'raw text' concept is different from the one offered by the -// Tokenizer.Raw method. -func (z *Tokenizer) NextIsNotRawText() { - z.rawTag = "" -} - -// Err returns the error associated with the most recent ErrorToken token. -// This is typically io.EOF, meaning the end of tokenization. -func (z *Tokenizer) Err() error { - if z.tt != ErrorToken { - return nil - } - return z.err -} - -// readByte returns the next byte from the input stream, doing a buffered read -// from z.r into z.buf if necessary. z.buf[z.raw.start:z.raw.end] remains a contiguous byte -// slice that holds all the bytes read so far for the current token. -// It sets z.err if the underlying reader returns an error. -// Pre-condition: z.err == nil. -func (z *Tokenizer) readByte() byte { - if z.raw.end >= len(z.buf) { - // Our buffer is exhausted and we have to read from z.r. Check if the - // previous read resulted in an error. - if z.readErr != nil { - z.err = z.readErr - return 0 - } - // We copy z.buf[z.raw.start:z.raw.end] to the beginning of z.buf. If the length - // z.raw.end - z.raw.start is more than half the capacity of z.buf, then we - // allocate a new buffer before the copy. - c := cap(z.buf) - d := z.raw.end - z.raw.start - var buf1 []byte - if 2*d > c { - buf1 = make([]byte, d, 2*c) - } else { - buf1 = z.buf[:d] - } - copy(buf1, z.buf[z.raw.start:z.raw.end]) - if x := z.raw.start; x != 0 { - // Adjust the data/attr spans to refer to the same contents after the copy. - z.data.start -= x - z.data.end -= x - z.pendingAttr[0].start -= x - z.pendingAttr[0].end -= x - z.pendingAttr[1].start -= x - z.pendingAttr[1].end -= x - for i := range z.attr { - z.attr[i][0].start -= x - z.attr[i][0].end -= x - z.attr[i][1].start -= x - z.attr[i][1].end -= x - } - } - z.raw.start, z.raw.end, z.buf = 0, d, buf1[:d] - // Now that we have copied the live bytes to the start of the buffer, - // we read from z.r into the remainder. - var n int - n, z.readErr = readAtLeastOneByte(z.r, buf1[d:cap(buf1)]) - if n == 0 { - z.err = z.readErr - return 0 - } - z.buf = buf1[:d+n] - } - x := z.buf[z.raw.end] - z.raw.end++ - if z.maxBuf > 0 && z.raw.end-z.raw.start >= z.maxBuf { - z.err = ErrBufferExceeded - return 0 - } - return x -} - -// Buffered returns a slice containing data buffered but not yet tokenized. -func (z *Tokenizer) Buffered() []byte { - return z.buf[z.raw.end:] -} - -// readAtLeastOneByte wraps an io.Reader so that reading cannot return (0, nil). -// It returns io.ErrNoProgress if the underlying r.Read method returns (0, nil) -// too many times in succession. -func readAtLeastOneByte(r io.Reader, b []byte) (int, error) { - for i := 0; i < 100; i++ { - n, err := r.Read(b) - if n != 0 || err != nil { - return n, err - } - } - return 0, io.ErrNoProgress -} - -// skipWhiteSpace skips past any white space. -func (z *Tokenizer) skipWhiteSpace() { - if z.err != nil { - return - } - for { - c := z.readByte() - if z.err != nil { - return - } - switch c { - case ' ', '\n', '\r', '\t', '\f': - // No-op. - default: - z.raw.end-- - return - } - } -} - -// readRawOrRCDATA reads until the next "</foo>", where "foo" is z.rawTag and -// is typically something like "script" or "textarea". -func (z *Tokenizer) readRawOrRCDATA() { - if z.rawTag == "script" { - z.readScript() - z.textIsRaw = true - z.rawTag = "" - return - } -loop: - for { - c := z.readByte() - if z.err != nil { - break loop - } - if c != '<' { - continue loop - } - c = z.readByte() - if z.err != nil { - break loop - } - if c != '/' { - continue loop - } - if z.readRawEndTag() || z.err != nil { - break loop - } - } - z.data.end = z.raw.end - // A textarea's or title's RCDATA can contain escaped entities. - z.textIsRaw = z.rawTag != "textarea" && z.rawTag != "title" - z.rawTag = "" -} - -// readRawEndTag attempts to read a tag like "</foo>", where "foo" is z.rawTag. -// If it succeeds, it backs up the input position to reconsume the tag and -// returns true. Otherwise it returns false. The opening "</" has already been -// consumed. -func (z *Tokenizer) readRawEndTag() bool { - for i := 0; i < len(z.rawTag); i++ { - c := z.readByte() - if z.err != nil { - return false - } - if c != z.rawTag[i] && c != z.rawTag[i]-('a'-'A') { - z.raw.end-- - return false - } - } - c := z.readByte() - if z.err != nil { - return false - } - switch c { - case ' ', '\n', '\r', '\t', '\f', '/', '>': - // The 3 is 2 for the leading "</" plus 1 for the trailing character c. - z.raw.end -= 3 + len(z.rawTag) - return true - } - z.raw.end-- - return false -} - -// readScript reads until the next </script> tag, following the byzantine -// rules for escaping/hiding the closing tag. -func (z *Tokenizer) readScript() { - defer func() { - z.data.end = z.raw.end - }() - var c byte - -scriptData: - c = z.readByte() - if z.err != nil { - return - } - if c == '<' { - goto scriptDataLessThanSign - } - goto scriptData - -scriptDataLessThanSign: - c = z.readByte() - if z.err != nil { - return - } - switch c { - case '/': - goto scriptDataEndTagOpen - case '!': - goto scriptDataEscapeStart - } - z.raw.end-- - goto scriptData - -scriptDataEndTagOpen: - if z.readRawEndTag() || z.err != nil { - return - } - goto scriptData - -scriptDataEscapeStart: - c = z.readByte() - if z.err != nil { - return - } - if c == '-' { - goto scriptDataEscapeStartDash - } - z.raw.end-- - goto scriptData - -scriptDataEscapeStartDash: - c = z.readByte() - if z.err != nil { - return - } - if c == '-' { - goto scriptDataEscapedDashDash - } - z.raw.end-- - goto scriptData - -scriptDataEscaped: - c = z.readByte() - if z.err != nil { - return - } - switch c { - case '-': - goto scriptDataEscapedDash - case '<': - goto scriptDataEscapedLessThanSign - } - goto scriptDataEscaped - -scriptDataEscapedDash: - c = z.readByte() - if z.err != nil { - return - } - switch c { - case '-': - goto scriptDataEscapedDashDash - case '<': - goto scriptDataEscapedLessThanSign - } - goto scriptDataEscaped - -scriptDataEscapedDashDash: - c = z.readByte() - if z.err != nil { - return - } - switch c { - case '-': - goto scriptDataEscapedDashDash - case '<': - goto scriptDataEscapedLessThanSign - case '>': - goto scriptData - } - goto scriptDataEscaped - -scriptDataEscapedLessThanSign: - c = z.readByte() - if z.err != nil { - return - } - if c == '/' { - goto scriptDataEscapedEndTagOpen - } - if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' { - goto scriptDataDoubleEscapeStart - } - z.raw.end-- - goto scriptData - -scriptDataEscapedEndTagOpen: - if z.readRawEndTag() || z.err != nil { - return - } - goto scriptDataEscaped - -scriptDataDoubleEscapeStart: - z.raw.end-- - for i := 0; i < len("script"); i++ { - c = z.readByte() - if z.err != nil { - return - } - if c != "script"[i] && c != "SCRIPT"[i] { - z.raw.end-- - goto scriptDataEscaped - } - } - c = z.readByte() - if z.err != nil { - return - } - switch c { - case ' ', '\n', '\r', '\t', '\f', '/', '>': - goto scriptDataDoubleEscaped - } - z.raw.end-- - goto scriptDataEscaped - -scriptDataDoubleEscaped: - c = z.readByte() - if z.err != nil { - return - } - switch c { - case '-': - goto scriptDataDoubleEscapedDash - case '<': - goto scriptDataDoubleEscapedLessThanSign - } - goto scriptDataDoubleEscaped - -scriptDataDoubleEscapedDash: - c = z.readByte() - if z.err != nil { - return - } - switch c { - case '-': - goto scriptDataDoubleEscapedDashDash - case '<': - goto scriptDataDoubleEscapedLessThanSign - } - goto scriptDataDoubleEscaped - -scriptDataDoubleEscapedDashDash: - c = z.readByte() - if z.err != nil { - return - } - switch c { - case '-': - goto scriptDataDoubleEscapedDashDash - case '<': - goto scriptDataDoubleEscapedLessThanSign - case '>': - goto scriptData - } - goto scriptDataDoubleEscaped - -scriptDataDoubleEscapedLessThanSign: - c = z.readByte() - if z.err != nil { - return - } - if c == '/' { - goto scriptDataDoubleEscapeEnd - } - z.raw.end-- - goto scriptDataDoubleEscaped - -scriptDataDoubleEscapeEnd: - if z.readRawEndTag() { - z.raw.end += len("</script>") - goto scriptDataEscaped - } - if z.err != nil { - return - } - goto scriptDataDoubleEscaped -} - -// readComment reads the next comment token starting with "<!--". The opening -// "<!--" has already been consumed. -func (z *Tokenizer) readComment() { - z.data.start = z.raw.end - defer func() { - if z.data.end < z.data.start { - // It's a comment with no data, like <!-->. - z.data.end = z.data.start - } - }() - for dashCount := 2; ; { - c := z.readByte() - if z.err != nil { - // Ignore up to two dashes at EOF. - if dashCount > 2 { - dashCount = 2 - } - z.data.end = z.raw.end - dashCount - return - } - switch c { - case '-': - dashCount++ - continue - case '>': - if dashCount >= 2 { - z.data.end = z.raw.end - len("-->") - return - } - case '!': - if dashCount >= 2 { - c = z.readByte() - if z.err != nil { - z.data.end = z.raw.end - return - } - if c == '>' { - z.data.end = z.raw.end - len("--!>") - return - } - } - } - dashCount = 0 - } -} - -// readUntilCloseAngle reads until the next ">". -func (z *Tokenizer) readUntilCloseAngle() { - z.data.start = z.raw.end - for { - c := z.readByte() - if z.err != nil { - z.data.end = z.raw.end - return - } - if c == '>' { - z.data.end = z.raw.end - len(">") - return - } - } -} - -// readMarkupDeclaration reads the next token starting with "<!". It might be -// a "<!--comment-->", a "<!DOCTYPE foo>", a "<![CDATA[section]]>" or -// "<!a bogus comment". The opening "<!" has already been consumed. -func (z *Tokenizer) readMarkupDeclaration() TokenType { - z.data.start = z.raw.end - var c [2]byte - for i := 0; i < 2; i++ { - c[i] = z.readByte() - if z.err != nil { - z.data.end = z.raw.end - return CommentToken - } - } - if c[0] == '-' && c[1] == '-' { - z.readComment() - return CommentToken - } - z.raw.end -= 2 - if z.readDoctype() { - return DoctypeToken - } - if z.allowCDATA && z.readCDATA() { - z.convertNUL = true - return TextToken - } - // It's a bogus comment. - z.readUntilCloseAngle() - return CommentToken -} - -// readDoctype attempts to read a doctype declaration and returns true if -// successful. The opening "<!" has already been consumed. -func (z *Tokenizer) readDoctype() bool { - const s = "DOCTYPE" - for i := 0; i < len(s); i++ { - c := z.readByte() - if z.err != nil { - z.data.end = z.raw.end - return false - } - if c != s[i] && c != s[i]+('a'-'A') { - // Back up to read the fragment of "DOCTYPE" again. - z.raw.end = z.data.start - return false - } - } - if z.skipWhiteSpace(); z.err != nil { - z.data.start = z.raw.end - z.data.end = z.raw.end - return true - } - z.readUntilCloseAngle() - return true -} - -// readCDATA attempts to read a CDATA section and returns true if -// successful. The opening "<!" has already been consumed. -func (z *Tokenizer) readCDATA() bool { - const s = "[CDATA[" - for i := 0; i < len(s); i++ { - c := z.readByte() - if z.err != nil { - z.data.end = z.raw.end - return false - } - if c != s[i] { - // Back up to read the fragment of "[CDATA[" again. - z.raw.end = z.data.start - return false - } - } - z.data.start = z.raw.end - brackets := 0 - for { - c := z.readByte() - if z.err != nil { - z.data.end = z.raw.end - return true - } - switch c { - case ']': - brackets++ - case '>': - if brackets >= 2 { - z.data.end = z.raw.end - len("]]>") - return true - } - brackets = 0 - default: - brackets = 0 - } - } -} - -// startTagIn returns whether the start tag in z.buf[z.data.start:z.data.end] -// case-insensitively matches any element of ss. -func (z *Tokenizer) startTagIn(ss ...string) bool { -loop: - for _, s := range ss { - if z.data.end-z.data.start != len(s) { - continue loop - } - for i := 0; i < len(s); i++ { - c := z.buf[z.data.start+i] - if 'A' <= c && c <= 'Z' { - c += 'a' - 'A' - } - if c != s[i] { - continue loop - } - } - return true - } - return false -} - -// readStartTag reads the next start tag token. The opening "<a" has already -// been consumed, where 'a' means anything in [A-Za-z]. -func (z *Tokenizer) readStartTag() TokenType { - z.readTag(true) - if z.err != nil { - return ErrorToken - } - // Several tags flag the tokenizer's next token as raw. - c, raw := z.buf[z.data.start], false - if 'A' <= c && c <= 'Z' { - c += 'a' - 'A' - } - switch c { - case 'i': - raw = z.startTagIn("iframe") - case 'n': - raw = z.startTagIn("noembed", "noframes", "noscript") - case 'p': - raw = z.startTagIn("plaintext") - case 's': - raw = z.startTagIn("script", "style") - case 't': - raw = z.startTagIn("textarea", "title") - case 'x': - raw = z.startTagIn("xmp") - } - if raw { - z.rawTag = strings.ToLower(string(z.buf[z.data.start:z.data.end])) - } - // Look for a self-closing token like "<br/>". - if z.err == nil && z.buf[z.raw.end-2] == '/' { - return SelfClosingTagToken - } - return StartTagToken -} - -// readTag reads the next tag token and its attributes. If saveAttr, those -// attributes are saved in z.attr, otherwise z.attr is set to an empty slice. -// The opening "<a" or "</a" has already been consumed, where 'a' means anything -// in [A-Za-z]. -func (z *Tokenizer) readTag(saveAttr bool) { - z.attr = z.attr[:0] - z.nAttrReturned = 0 - // Read the tag name and attribute key/value pairs. - z.readTagName() - if z.skipWhiteSpace(); z.err != nil { - return - } - for { - c := z.readByte() - if z.err != nil || c == '>' { - break - } - z.raw.end-- - z.readTagAttrKey() - z.readTagAttrVal() - // Save pendingAttr if saveAttr and that attribute has a non-empty key. - if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end { - z.attr = append(z.attr, z.pendingAttr) - } - if z.skipWhiteSpace(); z.err != nil { - break - } - } -} - -// readTagName sets z.data to the "div" in "<div k=v>". The reader (z.raw.end) -// is positioned such that the first byte of the tag name (the "d" in "<div") -// has already been consumed. -func (z *Tokenizer) readTagName() { - z.data.start = z.raw.end - 1 - for { - c := z.readByte() - if z.err != nil { - z.data.end = z.raw.end - return - } - switch c { - case ' ', '\n', '\r', '\t', '\f': - z.data.end = z.raw.end - 1 - return - case '/', '>': - z.raw.end-- - z.data.end = z.raw.end - return - } - } -} - -// readTagAttrKey sets z.pendingAttr[0] to the "k" in "<div k=v>". -// Precondition: z.err == nil. -func (z *Tokenizer) readTagAttrKey() { - z.pendingAttr[0].start = z.raw.end - for { - c := z.readByte() - if z.err != nil { - z.pendingAttr[0].end = z.raw.end - return - } - switch c { - case ' ', '\n', '\r', '\t', '\f', '/': - z.pendingAttr[0].end = z.raw.end - 1 - return - case '=', '>': - z.raw.end-- - z.pendingAttr[0].end = z.raw.end - return - } - } -} - -// readTagAttrVal sets z.pendingAttr[1] to the "v" in "<div k=v>". -func (z *Tokenizer) readTagAttrVal() { - z.pendingAttr[1].start = z.raw.end - z.pendingAttr[1].end = z.raw.end - if z.skipWhiteSpace(); z.err != nil { - return - } - c := z.readByte() - if z.err != nil { - return - } - if c != '=' { - z.raw.end-- - return - } - if z.skipWhiteSpace(); z.err != nil { - return - } - quote := z.readByte() - if z.err != nil { - return - } - switch quote { - case '>': - z.raw.end-- - return - - case '\'', '"': - z.pendingAttr[1].start = z.raw.end - for { - c := z.readByte() - if z.err != nil { - z.pendingAttr[1].end = z.raw.end - return - } - if c == quote { - z.pendingAttr[1].end = z.raw.end - 1 - return - } - } - - default: - z.pendingAttr[1].start = z.raw.end - 1 - for { - c := z.readByte() - if z.err != nil { - z.pendingAttr[1].end = z.raw.end - return - } - switch c { - case ' ', '\n', '\r', '\t', '\f': - z.pendingAttr[1].end = z.raw.end - 1 - return - case '>': - z.raw.end-- - z.pendingAttr[1].end = z.raw.end - return - } - } - } -} - -// Next scans the next token and returns its type. -func (z *Tokenizer) Next() TokenType { - z.raw.start = z.raw.end - z.data.start = z.raw.end - z.data.end = z.raw.end - if z.err != nil { - z.tt = ErrorToken - return z.tt - } - if z.rawTag != "" { - if z.rawTag == "plaintext" { - // Read everything up to EOF. - for z.err == nil { - z.readByte() - } - z.data.end = z.raw.end - z.textIsRaw = true - } else { - z.readRawOrRCDATA() - } - if z.data.end > z.data.start { - z.tt = TextToken - z.convertNUL = true - return z.tt - } - } - z.textIsRaw = false - z.convertNUL = false - -loop: - for { - c := z.readByte() - if z.err != nil { - break loop - } - if c != '<' { - continue loop - } - - // Check if the '<' we have just read is part of a tag, comment - // or doctype. If not, it's part of the accumulated text token. - c = z.readByte() - if z.err != nil { - break loop - } - var tokenType TokenType - switch { - case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z': - tokenType = StartTagToken - case c == '/': - tokenType = EndTagToken - case c == '!' || c == '?': - // We use CommentToken to mean any of "<!--actual comments-->", - // "<!DOCTYPE declarations>" and "<?xml processing instructions?>". - tokenType = CommentToken - default: - // Reconsume the current character. - z.raw.end-- - continue - } - - // We have a non-text token, but we might have accumulated some text - // before that. If so, we return the text first, and return the non- - // text token on the subsequent call to Next. - if x := z.raw.end - len("<a"); z.raw.start < x { - z.raw.end = x - z.data.end = x - z.tt = TextToken - return z.tt - } - switch tokenType { - case StartTagToken: - z.tt = z.readStartTag() - return z.tt - case EndTagToken: - c = z.readByte() - if z.err != nil { - break loop - } - if c == '>' { - // "</>" does not generate a token at all. Generate an empty comment - // to allow passthrough clients to pick up the data using Raw. - // Reset the tokenizer state and start again. - z.tt = CommentToken - return z.tt - } - if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' { - z.readTag(false) - if z.err != nil { - z.tt = ErrorToken - } else { - z.tt = EndTagToken - } - return z.tt - } - z.raw.end-- - z.readUntilCloseAngle() - z.tt = CommentToken - return z.tt - case CommentToken: - if c == '!' { - z.tt = z.readMarkupDeclaration() - return z.tt - } - z.raw.end-- - z.readUntilCloseAngle() - z.tt = CommentToken - return z.tt - } - } - if z.raw.start < z.raw.end { - z.data.end = z.raw.end - z.tt = TextToken - return z.tt - } - z.tt = ErrorToken - return z.tt -} - -// Raw returns the unmodified text of the current token. Calling Next, Token, -// Text, TagName or TagAttr may change the contents of the returned slice. -func (z *Tokenizer) Raw() []byte { - return z.buf[z.raw.start:z.raw.end] -} - -// convertNewlines converts "\r" and "\r\n" in s to "\n". -// The conversion happens in place, but the resulting slice may be shorter. -func convertNewlines(s []byte) []byte { - for i, c := range s { - if c != '\r' { - continue - } - - src := i + 1 - if src >= len(s) || s[src] != '\n' { - s[i] = '\n' - continue - } - - dst := i - for src < len(s) { - if s[src] == '\r' { - if src+1 < len(s) && s[src+1] == '\n' { - src++ - } - s[dst] = '\n' - } else { - s[dst] = s[src] - } - src++ - dst++ - } - return s[:dst] - } - return s -} - -var ( - nul = []byte("\x00") - replacement = []byte("\ufffd") -) - -// Text returns the unescaped text of a text, comment or doctype token. The -// contents of the returned slice may change on the next call to Next. -func (z *Tokenizer) Text() []byte { - switch z.tt { - case TextToken, CommentToken, DoctypeToken: - s := z.buf[z.data.start:z.data.end] - z.data.start = z.raw.end - z.data.end = z.raw.end - s = convertNewlines(s) - if (z.convertNUL || z.tt == CommentToken) && bytes.Contains(s, nul) { - s = bytes.Replace(s, nul, replacement, -1) - } - if !z.textIsRaw { - s = unescape(s, false) - } - return s - } - return nil -} - -// TagName returns the lower-cased name of a tag token (the `img` out of -// `<IMG SRC="foo">`) and whether the tag has attributes. -// The contents of the returned slice may change on the next call to Next. -func (z *Tokenizer) TagName() (name []byte, hasAttr bool) { - if z.data.start < z.data.end { - switch z.tt { - case StartTagToken, EndTagToken, SelfClosingTagToken: - s := z.buf[z.data.start:z.data.end] - z.data.start = z.raw.end - z.data.end = z.raw.end - return lower(s), z.nAttrReturned < len(z.attr) - } - } - return nil, false -} - -// TagAttr returns the lower-cased key and unescaped value of the next unparsed -// attribute for the current tag token and whether there are more attributes. -// The contents of the returned slices may change on the next call to Next. -func (z *Tokenizer) TagAttr() (key, val []byte, moreAttr bool) { - if z.nAttrReturned < len(z.attr) { - switch z.tt { - case StartTagToken, SelfClosingTagToken: - x := z.attr[z.nAttrReturned] - z.nAttrReturned++ - key = z.buf[x[0].start:x[0].end] - val = z.buf[x[1].start:x[1].end] - return lower(key), unescape(convertNewlines(val), true), z.nAttrReturned < len(z.attr) - } - } - return nil, nil, false -} - -// Token returns the current Token. The result's Data and Attr values remain -// valid after subsequent Next calls. -func (z *Tokenizer) Token() Token { - t := Token{Type: z.tt} - switch z.tt { - case TextToken, CommentToken, DoctypeToken: - t.Data = string(z.Text()) - case StartTagToken, SelfClosingTagToken, EndTagToken: - name, moreAttr := z.TagName() - for moreAttr { - var key, val []byte - key, val, moreAttr = z.TagAttr() - t.Attr = append(t.Attr, Attribute{"", atom.String(key), string(val)}) - } - if a := atom.Lookup(name); a != 0 { - t.DataAtom, t.Data = a, a.String() - } else { - t.DataAtom, t.Data = 0, string(name) - } - } - return t -} - -// SetMaxBuf sets a limit on the amount of data buffered during tokenization. -// A value of 0 means unlimited. -func (z *Tokenizer) SetMaxBuf(n int) { - z.maxBuf = n -} - -// NewTokenizer returns a new HTML Tokenizer for the given Reader. -// The input is assumed to be UTF-8 encoded. -func NewTokenizer(r io.Reader) *Tokenizer { - return NewTokenizerFragment(r, "") -} - -// NewTokenizerFragment returns a new HTML Tokenizer for the given Reader, for -// tokenizing an existing element's InnerHTML fragment. contextTag is that -// element's tag, such as "div" or "iframe". -// -// For example, how the InnerHTML "a<b" is tokenized depends on whether it is -// for a <p> tag or a <script> tag. -// -// The input is assumed to be UTF-8 encoded. -func NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer { - z := &Tokenizer{ - r: r, - buf: make([]byte, 0, 4096), - } - if contextTag != "" { - switch s := strings.ToLower(contextTag); s { - case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "title", "textarea", "xmp": - z.rawTag = s - } - } - return z -} diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index b46791d1da2c..514c126c5f8f 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -643,7 +643,7 @@ func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { return f.WriteDataPadded(streamID, endStream, data, nil) } -// WriteData writes a DATA frame with optional padding. +// WriteDataPadded writes a DATA frame with optional padding. // // If pad is nil, the padding bit is not sent. // The length of pad must not exceed 255 bytes. diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index b57b6e2d0219..d4abeb2b998c 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -1594,12 +1594,6 @@ func (sc *serverConn) processData(f *DataFrame) error { // type PROTOCOL_ERROR." return ConnectionError(ErrCodeProtocol) } - // RFC 7540, sec 6.1: If a DATA frame is received whose stream is not in - // "open" or "half-closed (local)" state, the recipient MUST respond with a - // stream error (Section 5.4.2) of type STREAM_CLOSED. - if state == stateClosed { - return streamError(id, ErrCodeStreamClosed) - } if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued { // This includes sending a RST_STREAM if the stream is // in stateHalfClosedLocal (which currently means that @@ -2313,7 +2307,16 @@ type chunkWriter struct{ rws *responseWriterState } func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } -func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 } +func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 } + +func (rws *responseWriterState) hasNonemptyTrailers() bool { + for _, trailer := range rws.trailers { + if _, ok := rws.handlerHeader[trailer]; ok { + return true + } + } + return false +} // declareTrailer is called for each Trailer header when the // response header is written. It notes that a header will need to be @@ -2413,7 +2416,10 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { rws.promoteUndeclaredTrailers() } - endStream := rws.handlerDone && !rws.hasTrailers() + // only send trailers if they have actually been defined by the + // server handler. + hasNonemptyTrailers := rws.hasNonemptyTrailers() + endStream := rws.handlerDone && !hasNonemptyTrailers if len(p) > 0 || endStream { // only send a 0 byte DATA frame if we're ending the stream. if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil { @@ -2422,7 +2428,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { } } - if rws.handlerDone && rws.hasTrailers() { + if rws.handlerDone && hasNonemptyTrailers { err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ streamID: rws.stream.id, h: rws.handlerHeader, diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index f272e8f9fac2..4ec0792eb5c3 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -1411,7 +1411,11 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail // followed by the query production (see Sections 3.3 and 3.4 of // [RFC3986]). f(":authority", host) - f(":method", req.Method) + m := req.Method + if m == "" { + m = http.MethodGet + } + f(":method", m) if req.Method != "CONNECT" { f(":path", path) f(":scheme", req.URL.Scheme) diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go deleted file mode 100644 index 346fe4423ed7..000000000000 --- a/vendor/golang.org/x/net/idna/idna.go +++ /dev/null @@ -1,732 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package idna implements IDNA2008 using the compatibility processing -// defined by UTS (Unicode Technical Standard) #46, which defines a standard to -// deal with the transition from IDNA2003. -// -// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC -// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894. -// UTS #46 is defined in http://www.unicode.org/reports/tr46. -// See http://unicode.org/cldr/utility/idna.jsp for a visualization of the -// differences between these two standards. -package idna // import "golang.org/x/net/idna" - -import ( - "fmt" - "strings" - "unicode/utf8" - - "golang.org/x/text/secure/bidirule" - "golang.org/x/text/unicode/bidi" - "golang.org/x/text/unicode/norm" -) - -// NOTE: Unlike common practice in Go APIs, the functions will return a -// sanitized domain name in case of errors. Browsers sometimes use a partially -// evaluated string as lookup. -// TODO: the current error handling is, in my opinion, the least opinionated. -// Other strategies are also viable, though: -// Option 1) Return an empty string in case of error, but allow the user to -// specify explicitly which errors to ignore. -// Option 2) Return the partially evaluated string if it is itself a valid -// string, otherwise return the empty string in case of error. -// Option 3) Option 1 and 2. -// Option 4) Always return an empty string for now and implement Option 1 as -// needed, and document that the return string may not be empty in case of -// error in the future. -// I think Option 1 is best, but it is quite opinionated. - -// ToASCII is a wrapper for Punycode.ToASCII. -func ToASCII(s string) (string, error) { - return Punycode.process(s, true) -} - -// ToUnicode is a wrapper for Punycode.ToUnicode. -func ToUnicode(s string) (string, error) { - return Punycode.process(s, false) -} - -// An Option configures a Profile at creation time. -type Option func(*options) - -// Transitional sets a Profile to use the Transitional mapping as defined in UTS -// #46. This will cause, for example, "ß" to be mapped to "ss". Using the -// transitional mapping provides a compromise between IDNA2003 and IDNA2008 -// compatibility. It is used by most browsers when resolving domain names. This -// option is only meaningful if combined with MapForLookup. -func Transitional(transitional bool) Option { - return func(o *options) { o.transitional = true } -} - -// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts -// are longer than allowed by the RFC. -func VerifyDNSLength(verify bool) Option { - return func(o *options) { o.verifyDNSLength = verify } -} - -// RemoveLeadingDots removes leading label separators. Leading runes that map to -// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well. -// -// This is the behavior suggested by the UTS #46 and is adopted by some -// browsers. -func RemoveLeadingDots(remove bool) Option { - return func(o *options) { o.removeLeadingDots = remove } -} - -// ValidateLabels sets whether to check the mandatory label validation criteria -// as defined in Section 5.4 of RFC 5891. This includes testing for correct use -// of hyphens ('-'), normalization, validity of runes, and the context rules. -func ValidateLabels(enable bool) Option { - return func(o *options) { - // Don't override existing mappings, but set one that at least checks - // normalization if it is not set. - if o.mapping == nil && enable { - o.mapping = normalize - } - o.trie = trie - o.validateLabels = enable - o.fromPuny = validateFromPunycode - } -} - -// StrictDomainName limits the set of permissible ASCII characters to those -// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the -// hyphen). This is set by default for MapForLookup and ValidateForRegistration. -// -// This option is useful, for instance, for browsers that allow characters -// outside this range, for example a '_' (U+005F LOW LINE). See -// http://www.rfc-editor.org/std/std3.txt for more details This option -// corresponds to the UseSTD3ASCIIRules option in UTS #46. -func StrictDomainName(use bool) Option { - return func(o *options) { - o.trie = trie - o.useSTD3Rules = use - o.fromPuny = validateFromPunycode - } -} - -// NOTE: the following options pull in tables. The tables should not be linked -// in as long as the options are not used. - -// BidiRule enables the Bidi rule as defined in RFC 5893. Any application -// that relies on proper validation of labels should include this rule. -func BidiRule() Option { - return func(o *options) { o.bidirule = bidirule.ValidString } -} - -// ValidateForRegistration sets validation options to verify that a given IDN is -// properly formatted for registration as defined by Section 4 of RFC 5891. -func ValidateForRegistration() Option { - return func(o *options) { - o.mapping = validateRegistration - StrictDomainName(true)(o) - ValidateLabels(true)(o) - VerifyDNSLength(true)(o) - BidiRule()(o) - } -} - -// MapForLookup sets validation and mapping options such that a given IDN is -// transformed for domain name lookup according to the requirements set out in -// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894, -// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option -// to add this check. -// -// The mappings include normalization and mapping case, width and other -// compatibility mappings. -func MapForLookup() Option { - return func(o *options) { - o.mapping = validateAndMap - StrictDomainName(true)(o) - ValidateLabels(true)(o) - } -} - -type options struct { - transitional bool - useSTD3Rules bool - validateLabels bool - verifyDNSLength bool - removeLeadingDots bool - - trie *idnaTrie - - // fromPuny calls validation rules when converting A-labels to U-labels. - fromPuny func(p *Profile, s string) error - - // mapping implements a validation and mapping step as defined in RFC 5895 - // or UTS 46, tailored to, for example, domain registration or lookup. - mapping func(p *Profile, s string) (mapped string, isBidi bool, err error) - - // bidirule, if specified, checks whether s conforms to the Bidi Rule - // defined in RFC 5893. - bidirule func(s string) bool -} - -// A Profile defines the configuration of an IDNA mapper. -type Profile struct { - options -} - -func apply(o *options, opts []Option) { - for _, f := range opts { - f(o) - } -} - -// New creates a new Profile. -// -// With no options, the returned Profile is the most permissive and equals the -// Punycode Profile. Options can be passed to further restrict the Profile. The -// MapForLookup and ValidateForRegistration options set a collection of options, -// for lookup and registration purposes respectively, which can be tailored by -// adding more fine-grained options, where later options override earlier -// options. -func New(o ...Option) *Profile { - p := &Profile{} - apply(&p.options, o) - return p -} - -// ToASCII converts a domain or domain label to its ASCII form. For example, -// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and -// ToASCII("golang") is "golang". If an error is encountered it will return -// an error and a (partially) processed result. -func (p *Profile) ToASCII(s string) (string, error) { - return p.process(s, true) -} - -// ToUnicode converts a domain or domain label to its Unicode form. For example, -// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and -// ToUnicode("golang") is "golang". If an error is encountered it will return -// an error and a (partially) processed result. -func (p *Profile) ToUnicode(s string) (string, error) { - pp := *p - pp.transitional = false - return pp.process(s, false) -} - -// String reports a string with a description of the profile for debugging -// purposes. The string format may change with different versions. -func (p *Profile) String() string { - s := "" - if p.transitional { - s = "Transitional" - } else { - s = "NonTransitional" - } - if p.useSTD3Rules { - s += ":UseSTD3Rules" - } - if p.validateLabels { - s += ":ValidateLabels" - } - if p.verifyDNSLength { - s += ":VerifyDNSLength" - } - return s -} - -var ( - // Punycode is a Profile that does raw punycode processing with a minimum - // of validation. - Punycode *Profile = punycode - - // Lookup is the recommended profile for looking up domain names, according - // to Section 5 of RFC 5891. The exact configuration of this profile may - // change over time. - Lookup *Profile = lookup - - // Display is the recommended profile for displaying domain names. - // The configuration of this profile may change over time. - Display *Profile = display - - // Registration is the recommended profile for checking whether a given - // IDN is valid for registration, according to Section 4 of RFC 5891. - Registration *Profile = registration - - punycode = &Profile{} - lookup = &Profile{options{ - transitional: true, - useSTD3Rules: true, - validateLabels: true, - trie: trie, - fromPuny: validateFromPunycode, - mapping: validateAndMap, - bidirule: bidirule.ValidString, - }} - display = &Profile{options{ - useSTD3Rules: true, - validateLabels: true, - trie: trie, - fromPuny: validateFromPunycode, - mapping: validateAndMap, - bidirule: bidirule.ValidString, - }} - registration = &Profile{options{ - useSTD3Rules: true, - validateLabels: true, - verifyDNSLength: true, - trie: trie, - fromPuny: validateFromPunycode, - mapping: validateRegistration, - bidirule: bidirule.ValidString, - }} - - // TODO: profiles - // Register: recommended for approving domain names: don't do any mappings - // but rather reject on invalid input. Bundle or block deviation characters. -) - -type labelError struct{ label, code_ string } - -func (e labelError) code() string { return e.code_ } -func (e labelError) Error() string { - return fmt.Sprintf("idna: invalid label %q", e.label) -} - -type runeError rune - -func (e runeError) code() string { return "P1" } -func (e runeError) Error() string { - return fmt.Sprintf("idna: disallowed rune %U", e) -} - -// process implements the algorithm described in section 4 of UTS #46, -// see http://www.unicode.org/reports/tr46. -func (p *Profile) process(s string, toASCII bool) (string, error) { - var err error - var isBidi bool - if p.mapping != nil { - s, isBidi, err = p.mapping(p, s) - } - // Remove leading empty labels. - if p.removeLeadingDots { - for ; len(s) > 0 && s[0] == '.'; s = s[1:] { - } - } - // TODO: allow for a quick check of the tables data. - // It seems like we should only create this error on ToASCII, but the - // UTS 46 conformance tests suggests we should always check this. - if err == nil && p.verifyDNSLength && s == "" { - err = &labelError{s, "A4"} - } - labels := labelIter{orig: s} - for ; !labels.done(); labels.next() { - label := labels.label() - if label == "" { - // Empty labels are not okay. The label iterator skips the last - // label if it is empty. - if err == nil && p.verifyDNSLength { - err = &labelError{s, "A4"} - } - continue - } - if strings.HasPrefix(label, acePrefix) { - u, err2 := decode(label[len(acePrefix):]) - if err2 != nil { - if err == nil { - err = err2 - } - // Spec says keep the old label. - continue - } - isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight - labels.set(u) - if err == nil && p.validateLabels { - err = p.fromPuny(p, u) - } - if err == nil { - // This should be called on NonTransitional, according to the - // spec, but that currently does not have any effect. Use the - // original profile to preserve options. - err = p.validateLabel(u) - } - } else if err == nil { - err = p.validateLabel(label) - } - } - if isBidi && p.bidirule != nil && err == nil { - for labels.reset(); !labels.done(); labels.next() { - if !p.bidirule(labels.label()) { - err = &labelError{s, "B"} - break - } - } - } - if toASCII { - for labels.reset(); !labels.done(); labels.next() { - label := labels.label() - if !ascii(label) { - a, err2 := encode(acePrefix, label) - if err == nil { - err = err2 - } - label = a - labels.set(a) - } - n := len(label) - if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { - err = &labelError{label, "A4"} - } - } - } - s = labels.result() - if toASCII && p.verifyDNSLength && err == nil { - // Compute the length of the domain name minus the root label and its dot. - n := len(s) - if n > 0 && s[n-1] == '.' { - n-- - } - if len(s) < 1 || n > 253 { - err = &labelError{s, "A4"} - } - } - return s, err -} - -func normalize(p *Profile, s string) (mapped string, isBidi bool, err error) { - // TODO: consider first doing a quick check to see if any of these checks - // need to be done. This will make it slower in the general case, but - // faster in the common case. - mapped = norm.NFC.String(s) - isBidi = bidirule.DirectionString(mapped) == bidi.RightToLeft - return mapped, isBidi, nil -} - -func validateRegistration(p *Profile, s string) (idem string, bidi bool, err error) { - // TODO: filter need for normalization in loop below. - if !norm.NFC.IsNormalString(s) { - return s, false, &labelError{s, "V1"} - } - for i := 0; i < len(s); { - v, sz := trie.lookupString(s[i:]) - if sz == 0 { - return s, bidi, runeError(utf8.RuneError) - } - bidi = bidi || info(v).isBidi(s[i:]) - // Copy bytes not copied so far. - switch p.simplify(info(v).category()) { - // TODO: handle the NV8 defined in the Unicode idna data set to allow - // for strict conformance to IDNA2008. - case valid, deviation: - case disallowed, mapped, unknown, ignored: - r, _ := utf8.DecodeRuneInString(s[i:]) - return s, bidi, runeError(r) - } - i += sz - } - return s, bidi, nil -} - -func (c info) isBidi(s string) bool { - if !c.isMapped() { - return c&attributesMask == rtl - } - // TODO: also store bidi info for mapped data. This is possible, but a bit - // cumbersome and not for the common case. - p, _ := bidi.LookupString(s) - switch p.Class() { - case bidi.R, bidi.AL, bidi.AN: - return true - } - return false -} - -func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) { - var ( - b []byte - k int - ) - // combinedInfoBits contains the or-ed bits of all runes. We use this - // to derive the mayNeedNorm bit later. This may trigger normalization - // overeagerly, but it will not do so in the common case. The end result - // is another 10% saving on BenchmarkProfile for the common case. - var combinedInfoBits info - for i := 0; i < len(s); { - v, sz := trie.lookupString(s[i:]) - if sz == 0 { - b = append(b, s[k:i]...) - b = append(b, "\ufffd"...) - k = len(s) - if err == nil { - err = runeError(utf8.RuneError) - } - break - } - combinedInfoBits |= info(v) - bidi = bidi || info(v).isBidi(s[i:]) - start := i - i += sz - // Copy bytes not copied so far. - switch p.simplify(info(v).category()) { - case valid: - continue - case disallowed: - if err == nil { - r, _ := utf8.DecodeRuneInString(s[start:]) - err = runeError(r) - } - continue - case mapped, deviation: - b = append(b, s[k:start]...) - b = info(v).appendMapping(b, s[start:i]) - case ignored: - b = append(b, s[k:start]...) - // drop the rune - case unknown: - b = append(b, s[k:start]...) - b = append(b, "\ufffd"...) - } - k = i - } - if k == 0 { - // No changes so far. - if combinedInfoBits&mayNeedNorm != 0 { - s = norm.NFC.String(s) - } - } else { - b = append(b, s[k:]...) - if norm.NFC.QuickSpan(b) != len(b) { - b = norm.NFC.Bytes(b) - } - // TODO: the punycode converters require strings as input. - s = string(b) - } - return s, bidi, err -} - -// A labelIter allows iterating over domain name labels. -type labelIter struct { - orig string - slice []string - curStart int - curEnd int - i int -} - -func (l *labelIter) reset() { - l.curStart = 0 - l.curEnd = 0 - l.i = 0 -} - -func (l *labelIter) done() bool { - return l.curStart >= len(l.orig) -} - -func (l *labelIter) result() string { - if l.slice != nil { - return strings.Join(l.slice, ".") - } - return l.orig -} - -func (l *labelIter) label() string { - if l.slice != nil { - return l.slice[l.i] - } - p := strings.IndexByte(l.orig[l.curStart:], '.') - l.curEnd = l.curStart + p - if p == -1 { - l.curEnd = len(l.orig) - } - return l.orig[l.curStart:l.curEnd] -} - -// next sets the value to the next label. It skips the last label if it is empty. -func (l *labelIter) next() { - l.i++ - if l.slice != nil { - if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" { - l.curStart = len(l.orig) - } - } else { - l.curStart = l.curEnd + 1 - if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { - l.curStart = len(l.orig) - } - } -} - -func (l *labelIter) set(s string) { - if l.slice == nil { - l.slice = strings.Split(l.orig, ".") - } - l.slice[l.i] = s -} - -// acePrefix is the ASCII Compatible Encoding prefix. -const acePrefix = "xn--" - -func (p *Profile) simplify(cat category) category { - switch cat { - case disallowedSTD3Mapped: - if p.useSTD3Rules { - cat = disallowed - } else { - cat = mapped - } - case disallowedSTD3Valid: - if p.useSTD3Rules { - cat = disallowed - } else { - cat = valid - } - case deviation: - if !p.transitional { - cat = valid - } - case validNV8, validXV8: - // TODO: handle V2008 - cat = valid - } - return cat -} - -func validateFromPunycode(p *Profile, s string) error { - if !norm.NFC.IsNormalString(s) { - return &labelError{s, "V1"} - } - // TODO: detect whether string may have to be normalized in the following - // loop. - for i := 0; i < len(s); { - v, sz := trie.lookupString(s[i:]) - if sz == 0 { - return runeError(utf8.RuneError) - } - if c := p.simplify(info(v).category()); c != valid && c != deviation { - return &labelError{s, "V6"} - } - i += sz - } - return nil -} - -const ( - zwnj = "\u200c" - zwj = "\u200d" -) - -type joinState int8 - -const ( - stateStart joinState = iota - stateVirama - stateBefore - stateBeforeVirama - stateAfter - stateFAIL -) - -var joinStates = [][numJoinTypes]joinState{ - stateStart: { - joiningL: stateBefore, - joiningD: stateBefore, - joinZWNJ: stateFAIL, - joinZWJ: stateFAIL, - joinVirama: stateVirama, - }, - stateVirama: { - joiningL: stateBefore, - joiningD: stateBefore, - }, - stateBefore: { - joiningL: stateBefore, - joiningD: stateBefore, - joiningT: stateBefore, - joinZWNJ: stateAfter, - joinZWJ: stateFAIL, - joinVirama: stateBeforeVirama, - }, - stateBeforeVirama: { - joiningL: stateBefore, - joiningD: stateBefore, - joiningT: stateBefore, - }, - stateAfter: { - joiningL: stateFAIL, - joiningD: stateBefore, - joiningT: stateAfter, - joiningR: stateStart, - joinZWNJ: stateFAIL, - joinZWJ: stateFAIL, - joinVirama: stateAfter, // no-op as we can't accept joiners here - }, - stateFAIL: { - 0: stateFAIL, - joiningL: stateFAIL, - joiningD: stateFAIL, - joiningT: stateFAIL, - joiningR: stateFAIL, - joinZWNJ: stateFAIL, - joinZWJ: stateFAIL, - joinVirama: stateFAIL, - }, -} - -// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are -// already implicitly satisfied by the overall implementation. -func (p *Profile) validateLabel(s string) (err error) { - if s == "" { - if p.verifyDNSLength { - return &labelError{s, "A4"} - } - return nil - } - if !p.validateLabels { - return nil - } - trie := p.trie // p.validateLabels is only set if trie is set. - if len(s) > 4 && s[2] == '-' && s[3] == '-' { - return &labelError{s, "V2"} - } - if s[0] == '-' || s[len(s)-1] == '-' { - return &labelError{s, "V3"} - } - // TODO: merge the use of this in the trie. - v, sz := trie.lookupString(s) - x := info(v) - if x.isModifier() { - return &labelError{s, "V5"} - } - // Quickly return in the absence of zero-width (non) joiners. - if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { - return nil - } - st := stateStart - for i := 0; ; { - jt := x.joinType() - if s[i:i+sz] == zwj { - jt = joinZWJ - } else if s[i:i+sz] == zwnj { - jt = joinZWNJ - } - st = joinStates[st][jt] - if x.isViramaModifier() { - st = joinStates[st][joinVirama] - } - if i += sz; i == len(s) { - break - } - v, sz = trie.lookupString(s[i:]) - x = info(v) - } - if st == stateFAIL || st == stateAfter { - return &labelError{s, "C"} - } - return nil -} - -func ascii(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] >= utf8.RuneSelf { - return false - } - } - return true -} diff --git a/vendor/golang.org/x/net/idna/idna10.0.0.go b/vendor/golang.org/x/net/idna/idna10.0.0.go new file mode 100644 index 000000000000..a98a31f40388 --- /dev/null +++ b/vendor/golang.org/x/net/idna/idna10.0.0.go @@ -0,0 +1,734 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.10 + +// Package idna implements IDNA2008 using the compatibility processing +// defined by UTS (Unicode Technical Standard) #46, which defines a standard to +// deal with the transition from IDNA2003. +// +// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC +// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894. +// UTS #46 is defined in https://www.unicode.org/reports/tr46. +// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the +// differences between these two standards. +package idna // import "golang.org/x/net/idna" + +import ( + "fmt" + "strings" + "unicode/utf8" + + "golang.org/x/text/secure/bidirule" + "golang.org/x/text/unicode/bidi" + "golang.org/x/text/unicode/norm" +) + +// NOTE: Unlike common practice in Go APIs, the functions will return a +// sanitized domain name in case of errors. Browsers sometimes use a partially +// evaluated string as lookup. +// TODO: the current error handling is, in my opinion, the least opinionated. +// Other strategies are also viable, though: +// Option 1) Return an empty string in case of error, but allow the user to +// specify explicitly which errors to ignore. +// Option 2) Return the partially evaluated string if it is itself a valid +// string, otherwise return the empty string in case of error. +// Option 3) Option 1 and 2. +// Option 4) Always return an empty string for now and implement Option 1 as +// needed, and document that the return string may not be empty in case of +// error in the future. +// I think Option 1 is best, but it is quite opinionated. + +// ToASCII is a wrapper for Punycode.ToASCII. +func ToASCII(s string) (string, error) { + return Punycode.process(s, true) +} + +// ToUnicode is a wrapper for Punycode.ToUnicode. +func ToUnicode(s string) (string, error) { + return Punycode.process(s, false) +} + +// An Option configures a Profile at creation time. +type Option func(*options) + +// Transitional sets a Profile to use the Transitional mapping as defined in UTS +// #46. This will cause, for example, "ß" to be mapped to "ss". Using the +// transitional mapping provides a compromise between IDNA2003 and IDNA2008 +// compatibility. It is used by most browsers when resolving domain names. This +// option is only meaningful if combined with MapForLookup. +func Transitional(transitional bool) Option { + return func(o *options) { o.transitional = true } +} + +// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts +// are longer than allowed by the RFC. +func VerifyDNSLength(verify bool) Option { + return func(o *options) { o.verifyDNSLength = verify } +} + +// RemoveLeadingDots removes leading label separators. Leading runes that map to +// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well. +// +// This is the behavior suggested by the UTS #46 and is adopted by some +// browsers. +func RemoveLeadingDots(remove bool) Option { + return func(o *options) { o.removeLeadingDots = remove } +} + +// ValidateLabels sets whether to check the mandatory label validation criteria +// as defined in Section 5.4 of RFC 5891. This includes testing for correct use +// of hyphens ('-'), normalization, validity of runes, and the context rules. +func ValidateLabels(enable bool) Option { + return func(o *options) { + // Don't override existing mappings, but set one that at least checks + // normalization if it is not set. + if o.mapping == nil && enable { + o.mapping = normalize + } + o.trie = trie + o.validateLabels = enable + o.fromPuny = validateFromPunycode + } +} + +// StrictDomainName limits the set of permissible ASCII characters to those +// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the +// hyphen). This is set by default for MapForLookup and ValidateForRegistration. +// +// This option is useful, for instance, for browsers that allow characters +// outside this range, for example a '_' (U+005F LOW LINE). See +// http://www.rfc-editor.org/std/std3.txt for more details This option +// corresponds to the UseSTD3ASCIIRules option in UTS #46. +func StrictDomainName(use bool) Option { + return func(o *options) { + o.trie = trie + o.useSTD3Rules = use + o.fromPuny = validateFromPunycode + } +} + +// NOTE: the following options pull in tables. The tables should not be linked +// in as long as the options are not used. + +// BidiRule enables the Bidi rule as defined in RFC 5893. Any application +// that relies on proper validation of labels should include this rule. +func BidiRule() Option { + return func(o *options) { o.bidirule = bidirule.ValidString } +} + +// ValidateForRegistration sets validation options to verify that a given IDN is +// properly formatted for registration as defined by Section 4 of RFC 5891. +func ValidateForRegistration() Option { + return func(o *options) { + o.mapping = validateRegistration + StrictDomainName(true)(o) + ValidateLabels(true)(o) + VerifyDNSLength(true)(o) + BidiRule()(o) + } +} + +// MapForLookup sets validation and mapping options such that a given IDN is +// transformed for domain name lookup according to the requirements set out in +// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894, +// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option +// to add this check. +// +// The mappings include normalization and mapping case, width and other +// compatibility mappings. +func MapForLookup() Option { + return func(o *options) { + o.mapping = validateAndMap + StrictDomainName(true)(o) + ValidateLabels(true)(o) + } +} + +type options struct { + transitional bool + useSTD3Rules bool + validateLabels bool + verifyDNSLength bool + removeLeadingDots bool + + trie *idnaTrie + + // fromPuny calls validation rules when converting A-labels to U-labels. + fromPuny func(p *Profile, s string) error + + // mapping implements a validation and mapping step as defined in RFC 5895 + // or UTS 46, tailored to, for example, domain registration or lookup. + mapping func(p *Profile, s string) (mapped string, isBidi bool, err error) + + // bidirule, if specified, checks whether s conforms to the Bidi Rule + // defined in RFC 5893. + bidirule func(s string) bool +} + +// A Profile defines the configuration of an IDNA mapper. +type Profile struct { + options +} + +func apply(o *options, opts []Option) { + for _, f := range opts { + f(o) + } +} + +// New creates a new Profile. +// +// With no options, the returned Profile is the most permissive and equals the +// Punycode Profile. Options can be passed to further restrict the Profile. The +// MapForLookup and ValidateForRegistration options set a collection of options, +// for lookup and registration purposes respectively, which can be tailored by +// adding more fine-grained options, where later options override earlier +// options. +func New(o ...Option) *Profile { + p := &Profile{} + apply(&p.options, o) + return p +} + +// ToASCII converts a domain or domain label to its ASCII form. For example, +// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and +// ToASCII("golang") is "golang". If an error is encountered it will return +// an error and a (partially) processed result. +func (p *Profile) ToASCII(s string) (string, error) { + return p.process(s, true) +} + +// ToUnicode converts a domain or domain label to its Unicode form. For example, +// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and +// ToUnicode("golang") is "golang". If an error is encountered it will return +// an error and a (partially) processed result. +func (p *Profile) ToUnicode(s string) (string, error) { + pp := *p + pp.transitional = false + return pp.process(s, false) +} + +// String reports a string with a description of the profile for debugging +// purposes. The string format may change with different versions. +func (p *Profile) String() string { + s := "" + if p.transitional { + s = "Transitional" + } else { + s = "NonTransitional" + } + if p.useSTD3Rules { + s += ":UseSTD3Rules" + } + if p.validateLabels { + s += ":ValidateLabels" + } + if p.verifyDNSLength { + s += ":VerifyDNSLength" + } + return s +} + +var ( + // Punycode is a Profile that does raw punycode processing with a minimum + // of validation. + Punycode *Profile = punycode + + // Lookup is the recommended profile for looking up domain names, according + // to Section 5 of RFC 5891. The exact configuration of this profile may + // change over time. + Lookup *Profile = lookup + + // Display is the recommended profile for displaying domain names. + // The configuration of this profile may change over time. + Display *Profile = display + + // Registration is the recommended profile for checking whether a given + // IDN is valid for registration, according to Section 4 of RFC 5891. + Registration *Profile = registration + + punycode = &Profile{} + lookup = &Profile{options{ + transitional: true, + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + display = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + registration = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + verifyDNSLength: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateRegistration, + bidirule: bidirule.ValidString, + }} + + // TODO: profiles + // Register: recommended for approving domain names: don't do any mappings + // but rather reject on invalid input. Bundle or block deviation characters. +) + +type labelError struct{ label, code_ string } + +func (e labelError) code() string { return e.code_ } +func (e labelError) Error() string { + return fmt.Sprintf("idna: invalid label %q", e.label) +} + +type runeError rune + +func (e runeError) code() string { return "P1" } +func (e runeError) Error() string { + return fmt.Sprintf("idna: disallowed rune %U", e) +} + +// process implements the algorithm described in section 4 of UTS #46, +// see https://www.unicode.org/reports/tr46. +func (p *Profile) process(s string, toASCII bool) (string, error) { + var err error + var isBidi bool + if p.mapping != nil { + s, isBidi, err = p.mapping(p, s) + } + // Remove leading empty labels. + if p.removeLeadingDots { + for ; len(s) > 0 && s[0] == '.'; s = s[1:] { + } + } + // TODO: allow for a quick check of the tables data. + // It seems like we should only create this error on ToASCII, but the + // UTS 46 conformance tests suggests we should always check this. + if err == nil && p.verifyDNSLength && s == "" { + err = &labelError{s, "A4"} + } + labels := labelIter{orig: s} + for ; !labels.done(); labels.next() { + label := labels.label() + if label == "" { + // Empty labels are not okay. The label iterator skips the last + // label if it is empty. + if err == nil && p.verifyDNSLength { + err = &labelError{s, "A4"} + } + continue + } + if strings.HasPrefix(label, acePrefix) { + u, err2 := decode(label[len(acePrefix):]) + if err2 != nil { + if err == nil { + err = err2 + } + // Spec says keep the old label. + continue + } + isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight + labels.set(u) + if err == nil && p.validateLabels { + err = p.fromPuny(p, u) + } + if err == nil { + // This should be called on NonTransitional, according to the + // spec, but that currently does not have any effect. Use the + // original profile to preserve options. + err = p.validateLabel(u) + } + } else if err == nil { + err = p.validateLabel(label) + } + } + if isBidi && p.bidirule != nil && err == nil { + for labels.reset(); !labels.done(); labels.next() { + if !p.bidirule(labels.label()) { + err = &labelError{s, "B"} + break + } + } + } + if toASCII { + for labels.reset(); !labels.done(); labels.next() { + label := labels.label() + if !ascii(label) { + a, err2 := encode(acePrefix, label) + if err == nil { + err = err2 + } + label = a + labels.set(a) + } + n := len(label) + if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { + err = &labelError{label, "A4"} + } + } + } + s = labels.result() + if toASCII && p.verifyDNSLength && err == nil { + // Compute the length of the domain name minus the root label and its dot. + n := len(s) + if n > 0 && s[n-1] == '.' { + n-- + } + if len(s) < 1 || n > 253 { + err = &labelError{s, "A4"} + } + } + return s, err +} + +func normalize(p *Profile, s string) (mapped string, isBidi bool, err error) { + // TODO: consider first doing a quick check to see if any of these checks + // need to be done. This will make it slower in the general case, but + // faster in the common case. + mapped = norm.NFC.String(s) + isBidi = bidirule.DirectionString(mapped) == bidi.RightToLeft + return mapped, isBidi, nil +} + +func validateRegistration(p *Profile, s string) (idem string, bidi bool, err error) { + // TODO: filter need for normalization in loop below. + if !norm.NFC.IsNormalString(s) { + return s, false, &labelError{s, "V1"} + } + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + if sz == 0 { + return s, bidi, runeError(utf8.RuneError) + } + bidi = bidi || info(v).isBidi(s[i:]) + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + // TODO: handle the NV8 defined in the Unicode idna data set to allow + // for strict conformance to IDNA2008. + case valid, deviation: + case disallowed, mapped, unknown, ignored: + r, _ := utf8.DecodeRuneInString(s[i:]) + return s, bidi, runeError(r) + } + i += sz + } + return s, bidi, nil +} + +func (c info) isBidi(s string) bool { + if !c.isMapped() { + return c&attributesMask == rtl + } + // TODO: also store bidi info for mapped data. This is possible, but a bit + // cumbersome and not for the common case. + p, _ := bidi.LookupString(s) + switch p.Class() { + case bidi.R, bidi.AL, bidi.AN: + return true + } + return false +} + +func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) { + var ( + b []byte + k int + ) + // combinedInfoBits contains the or-ed bits of all runes. We use this + // to derive the mayNeedNorm bit later. This may trigger normalization + // overeagerly, but it will not do so in the common case. The end result + // is another 10% saving on BenchmarkProfile for the common case. + var combinedInfoBits info + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + if sz == 0 { + b = append(b, s[k:i]...) + b = append(b, "\ufffd"...) + k = len(s) + if err == nil { + err = runeError(utf8.RuneError) + } + break + } + combinedInfoBits |= info(v) + bidi = bidi || info(v).isBidi(s[i:]) + start := i + i += sz + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + case valid: + continue + case disallowed: + if err == nil { + r, _ := utf8.DecodeRuneInString(s[start:]) + err = runeError(r) + } + continue + case mapped, deviation: + b = append(b, s[k:start]...) + b = info(v).appendMapping(b, s[start:i]) + case ignored: + b = append(b, s[k:start]...) + // drop the rune + case unknown: + b = append(b, s[k:start]...) + b = append(b, "\ufffd"...) + } + k = i + } + if k == 0 { + // No changes so far. + if combinedInfoBits&mayNeedNorm != 0 { + s = norm.NFC.String(s) + } + } else { + b = append(b, s[k:]...) + if norm.NFC.QuickSpan(b) != len(b) { + b = norm.NFC.Bytes(b) + } + // TODO: the punycode converters require strings as input. + s = string(b) + } + return s, bidi, err +} + +// A labelIter allows iterating over domain name labels. +type labelIter struct { + orig string + slice []string + curStart int + curEnd int + i int +} + +func (l *labelIter) reset() { + l.curStart = 0 + l.curEnd = 0 + l.i = 0 +} + +func (l *labelIter) done() bool { + return l.curStart >= len(l.orig) +} + +func (l *labelIter) result() string { + if l.slice != nil { + return strings.Join(l.slice, ".") + } + return l.orig +} + +func (l *labelIter) label() string { + if l.slice != nil { + return l.slice[l.i] + } + p := strings.IndexByte(l.orig[l.curStart:], '.') + l.curEnd = l.curStart + p + if p == -1 { + l.curEnd = len(l.orig) + } + return l.orig[l.curStart:l.curEnd] +} + +// next sets the value to the next label. It skips the last label if it is empty. +func (l *labelIter) next() { + l.i++ + if l.slice != nil { + if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" { + l.curStart = len(l.orig) + } + } else { + l.curStart = l.curEnd + 1 + if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { + l.curStart = len(l.orig) + } + } +} + +func (l *labelIter) set(s string) { + if l.slice == nil { + l.slice = strings.Split(l.orig, ".") + } + l.slice[l.i] = s +} + +// acePrefix is the ASCII Compatible Encoding prefix. +const acePrefix = "xn--" + +func (p *Profile) simplify(cat category) category { + switch cat { + case disallowedSTD3Mapped: + if p.useSTD3Rules { + cat = disallowed + } else { + cat = mapped + } + case disallowedSTD3Valid: + if p.useSTD3Rules { + cat = disallowed + } else { + cat = valid + } + case deviation: + if !p.transitional { + cat = valid + } + case validNV8, validXV8: + // TODO: handle V2008 + cat = valid + } + return cat +} + +func validateFromPunycode(p *Profile, s string) error { + if !norm.NFC.IsNormalString(s) { + return &labelError{s, "V1"} + } + // TODO: detect whether string may have to be normalized in the following + // loop. + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + if sz == 0 { + return runeError(utf8.RuneError) + } + if c := p.simplify(info(v).category()); c != valid && c != deviation { + return &labelError{s, "V6"} + } + i += sz + } + return nil +} + +const ( + zwnj = "\u200c" + zwj = "\u200d" +) + +type joinState int8 + +const ( + stateStart joinState = iota + stateVirama + stateBefore + stateBeforeVirama + stateAfter + stateFAIL +) + +var joinStates = [][numJoinTypes]joinState{ + stateStart: { + joiningL: stateBefore, + joiningD: stateBefore, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateVirama, + }, + stateVirama: { + joiningL: stateBefore, + joiningD: stateBefore, + }, + stateBefore: { + joiningL: stateBefore, + joiningD: stateBefore, + joiningT: stateBefore, + joinZWNJ: stateAfter, + joinZWJ: stateFAIL, + joinVirama: stateBeforeVirama, + }, + stateBeforeVirama: { + joiningL: stateBefore, + joiningD: stateBefore, + joiningT: stateBefore, + }, + stateAfter: { + joiningL: stateFAIL, + joiningD: stateBefore, + joiningT: stateAfter, + joiningR: stateStart, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateAfter, // no-op as we can't accept joiners here + }, + stateFAIL: { + 0: stateFAIL, + joiningL: stateFAIL, + joiningD: stateFAIL, + joiningT: stateFAIL, + joiningR: stateFAIL, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateFAIL, + }, +} + +// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are +// already implicitly satisfied by the overall implementation. +func (p *Profile) validateLabel(s string) (err error) { + if s == "" { + if p.verifyDNSLength { + return &labelError{s, "A4"} + } + return nil + } + if !p.validateLabels { + return nil + } + trie := p.trie // p.validateLabels is only set if trie is set. + if len(s) > 4 && s[2] == '-' && s[3] == '-' { + return &labelError{s, "V2"} + } + if s[0] == '-' || s[len(s)-1] == '-' { + return &labelError{s, "V3"} + } + // TODO: merge the use of this in the trie. + v, sz := trie.lookupString(s) + x := info(v) + if x.isModifier() { + return &labelError{s, "V5"} + } + // Quickly return in the absence of zero-width (non) joiners. + if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { + return nil + } + st := stateStart + for i := 0; ; { + jt := x.joinType() + if s[i:i+sz] == zwj { + jt = joinZWJ + } else if s[i:i+sz] == zwnj { + jt = joinZWNJ + } + st = joinStates[st][jt] + if x.isViramaModifier() { + st = joinStates[st][joinVirama] + } + if i += sz; i == len(s) { + break + } + v, sz = trie.lookupString(s[i:]) + x = info(v) + } + if st == stateFAIL || st == stateAfter { + return &labelError{s, "C"} + } + return nil +} + +func ascii(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= utf8.RuneSelf { + return false + } + } + return true +} diff --git a/vendor/golang.org/x/net/idna/idna9.0.0.go b/vendor/golang.org/x/net/idna/idna9.0.0.go new file mode 100644 index 000000000000..8842146b5d99 --- /dev/null +++ b/vendor/golang.org/x/net/idna/idna9.0.0.go @@ -0,0 +1,682 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.10 + +// Package idna implements IDNA2008 using the compatibility processing +// defined by UTS (Unicode Technical Standard) #46, which defines a standard to +// deal with the transition from IDNA2003. +// +// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC +// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894. +// UTS #46 is defined in https://www.unicode.org/reports/tr46. +// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the +// differences between these two standards. +package idna // import "golang.org/x/net/idna" + +import ( + "fmt" + "strings" + "unicode/utf8" + + "golang.org/x/text/secure/bidirule" + "golang.org/x/text/unicode/norm" +) + +// NOTE: Unlike common practice in Go APIs, the functions will return a +// sanitized domain name in case of errors. Browsers sometimes use a partially +// evaluated string as lookup. +// TODO: the current error handling is, in my opinion, the least opinionated. +// Other strategies are also viable, though: +// Option 1) Return an empty string in case of error, but allow the user to +// specify explicitly which errors to ignore. +// Option 2) Return the partially evaluated string if it is itself a valid +// string, otherwise return the empty string in case of error. +// Option 3) Option 1 and 2. +// Option 4) Always return an empty string for now and implement Option 1 as +// needed, and document that the return string may not be empty in case of +// error in the future. +// I think Option 1 is best, but it is quite opinionated. + +// ToASCII is a wrapper for Punycode.ToASCII. +func ToASCII(s string) (string, error) { + return Punycode.process(s, true) +} + +// ToUnicode is a wrapper for Punycode.ToUnicode. +func ToUnicode(s string) (string, error) { + return Punycode.process(s, false) +} + +// An Option configures a Profile at creation time. +type Option func(*options) + +// Transitional sets a Profile to use the Transitional mapping as defined in UTS +// #46. This will cause, for example, "ß" to be mapped to "ss". Using the +// transitional mapping provides a compromise between IDNA2003 and IDNA2008 +// compatibility. It is used by most browsers when resolving domain names. This +// option is only meaningful if combined with MapForLookup. +func Transitional(transitional bool) Option { + return func(o *options) { o.transitional = true } +} + +// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts +// are longer than allowed by the RFC. +func VerifyDNSLength(verify bool) Option { + return func(o *options) { o.verifyDNSLength = verify } +} + +// RemoveLeadingDots removes leading label separators. Leading runes that map to +// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well. +// +// This is the behavior suggested by the UTS #46 and is adopted by some +// browsers. +func RemoveLeadingDots(remove bool) Option { + return func(o *options) { o.removeLeadingDots = remove } +} + +// ValidateLabels sets whether to check the mandatory label validation criteria +// as defined in Section 5.4 of RFC 5891. This includes testing for correct use +// of hyphens ('-'), normalization, validity of runes, and the context rules. +func ValidateLabels(enable bool) Option { + return func(o *options) { + // Don't override existing mappings, but set one that at least checks + // normalization if it is not set. + if o.mapping == nil && enable { + o.mapping = normalize + } + o.trie = trie + o.validateLabels = enable + o.fromPuny = validateFromPunycode + } +} + +// StrictDomainName limits the set of permissable ASCII characters to those +// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the +// hyphen). This is set by default for MapForLookup and ValidateForRegistration. +// +// This option is useful, for instance, for browsers that allow characters +// outside this range, for example a '_' (U+005F LOW LINE). See +// http://www.rfc-editor.org/std/std3.txt for more details This option +// corresponds to the UseSTD3ASCIIRules option in UTS #46. +func StrictDomainName(use bool) Option { + return func(o *options) { + o.trie = trie + o.useSTD3Rules = use + o.fromPuny = validateFromPunycode + } +} + +// NOTE: the following options pull in tables. The tables should not be linked +// in as long as the options are not used. + +// BidiRule enables the Bidi rule as defined in RFC 5893. Any application +// that relies on proper validation of labels should include this rule. +func BidiRule() Option { + return func(o *options) { o.bidirule = bidirule.ValidString } +} + +// ValidateForRegistration sets validation options to verify that a given IDN is +// properly formatted for registration as defined by Section 4 of RFC 5891. +func ValidateForRegistration() Option { + return func(o *options) { + o.mapping = validateRegistration + StrictDomainName(true)(o) + ValidateLabels(true)(o) + VerifyDNSLength(true)(o) + BidiRule()(o) + } +} + +// MapForLookup sets validation and mapping options such that a given IDN is +// transformed for domain name lookup according to the requirements set out in +// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894, +// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option +// to add this check. +// +// The mappings include normalization and mapping case, width and other +// compatibility mappings. +func MapForLookup() Option { + return func(o *options) { + o.mapping = validateAndMap + StrictDomainName(true)(o) + ValidateLabels(true)(o) + RemoveLeadingDots(true)(o) + } +} + +type options struct { + transitional bool + useSTD3Rules bool + validateLabels bool + verifyDNSLength bool + removeLeadingDots bool + + trie *idnaTrie + + // fromPuny calls validation rules when converting A-labels to U-labels. + fromPuny func(p *Profile, s string) error + + // mapping implements a validation and mapping step as defined in RFC 5895 + // or UTS 46, tailored to, for example, domain registration or lookup. + mapping func(p *Profile, s string) (string, error) + + // bidirule, if specified, checks whether s conforms to the Bidi Rule + // defined in RFC 5893. + bidirule func(s string) bool +} + +// A Profile defines the configuration of a IDNA mapper. +type Profile struct { + options +} + +func apply(o *options, opts []Option) { + for _, f := range opts { + f(o) + } +} + +// New creates a new Profile. +// +// With no options, the returned Profile is the most permissive and equals the +// Punycode Profile. Options can be passed to further restrict the Profile. The +// MapForLookup and ValidateForRegistration options set a collection of options, +// for lookup and registration purposes respectively, which can be tailored by +// adding more fine-grained options, where later options override earlier +// options. +func New(o ...Option) *Profile { + p := &Profile{} + apply(&p.options, o) + return p +} + +// ToASCII converts a domain or domain label to its ASCII form. For example, +// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and +// ToASCII("golang") is "golang". If an error is encountered it will return +// an error and a (partially) processed result. +func (p *Profile) ToASCII(s string) (string, error) { + return p.process(s, true) +} + +// ToUnicode converts a domain or domain label to its Unicode form. For example, +// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and +// ToUnicode("golang") is "golang". If an error is encountered it will return +// an error and a (partially) processed result. +func (p *Profile) ToUnicode(s string) (string, error) { + pp := *p + pp.transitional = false + return pp.process(s, false) +} + +// String reports a string with a description of the profile for debugging +// purposes. The string format may change with different versions. +func (p *Profile) String() string { + s := "" + if p.transitional { + s = "Transitional" + } else { + s = "NonTransitional" + } + if p.useSTD3Rules { + s += ":UseSTD3Rules" + } + if p.validateLabels { + s += ":ValidateLabels" + } + if p.verifyDNSLength { + s += ":VerifyDNSLength" + } + return s +} + +var ( + // Punycode is a Profile that does raw punycode processing with a minimum + // of validation. + Punycode *Profile = punycode + + // Lookup is the recommended profile for looking up domain names, according + // to Section 5 of RFC 5891. The exact configuration of this profile may + // change over time. + Lookup *Profile = lookup + + // Display is the recommended profile for displaying domain names. + // The configuration of this profile may change over time. + Display *Profile = display + + // Registration is the recommended profile for checking whether a given + // IDN is valid for registration, according to Section 4 of RFC 5891. + Registration *Profile = registration + + punycode = &Profile{} + lookup = &Profile{options{ + transitional: true, + useSTD3Rules: true, + validateLabels: true, + removeLeadingDots: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + display = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + removeLeadingDots: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + registration = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + verifyDNSLength: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateRegistration, + bidirule: bidirule.ValidString, + }} + + // TODO: profiles + // Register: recommended for approving domain names: don't do any mappings + // but rather reject on invalid input. Bundle or block deviation characters. +) + +type labelError struct{ label, code_ string } + +func (e labelError) code() string { return e.code_ } +func (e labelError) Error() string { + return fmt.Sprintf("idna: invalid label %q", e.label) +} + +type runeError rune + +func (e runeError) code() string { return "P1" } +func (e runeError) Error() string { + return fmt.Sprintf("idna: disallowed rune %U", e) +} + +// process implements the algorithm described in section 4 of UTS #46, +// see https://www.unicode.org/reports/tr46. +func (p *Profile) process(s string, toASCII bool) (string, error) { + var err error + if p.mapping != nil { + s, err = p.mapping(p, s) + } + // Remove leading empty labels. + if p.removeLeadingDots { + for ; len(s) > 0 && s[0] == '.'; s = s[1:] { + } + } + // It seems like we should only create this error on ToASCII, but the + // UTS 46 conformance tests suggests we should always check this. + if err == nil && p.verifyDNSLength && s == "" { + err = &labelError{s, "A4"} + } + labels := labelIter{orig: s} + for ; !labels.done(); labels.next() { + label := labels.label() + if label == "" { + // Empty labels are not okay. The label iterator skips the last + // label if it is empty. + if err == nil && p.verifyDNSLength { + err = &labelError{s, "A4"} + } + continue + } + if strings.HasPrefix(label, acePrefix) { + u, err2 := decode(label[len(acePrefix):]) + if err2 != nil { + if err == nil { + err = err2 + } + // Spec says keep the old label. + continue + } + labels.set(u) + if err == nil && p.validateLabels { + err = p.fromPuny(p, u) + } + if err == nil { + // This should be called on NonTransitional, according to the + // spec, but that currently does not have any effect. Use the + // original profile to preserve options. + err = p.validateLabel(u) + } + } else if err == nil { + err = p.validateLabel(label) + } + } + if toASCII { + for labels.reset(); !labels.done(); labels.next() { + label := labels.label() + if !ascii(label) { + a, err2 := encode(acePrefix, label) + if err == nil { + err = err2 + } + label = a + labels.set(a) + } + n := len(label) + if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { + err = &labelError{label, "A4"} + } + } + } + s = labels.result() + if toASCII && p.verifyDNSLength && err == nil { + // Compute the length of the domain name minus the root label and its dot. + n := len(s) + if n > 0 && s[n-1] == '.' { + n-- + } + if len(s) < 1 || n > 253 { + err = &labelError{s, "A4"} + } + } + return s, err +} + +func normalize(p *Profile, s string) (string, error) { + return norm.NFC.String(s), nil +} + +func validateRegistration(p *Profile, s string) (string, error) { + if !norm.NFC.IsNormalString(s) { + return s, &labelError{s, "V1"} + } + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + // TODO: handle the NV8 defined in the Unicode idna data set to allow + // for strict conformance to IDNA2008. + case valid, deviation: + case disallowed, mapped, unknown, ignored: + r, _ := utf8.DecodeRuneInString(s[i:]) + return s, runeError(r) + } + i += sz + } + return s, nil +} + +func validateAndMap(p *Profile, s string) (string, error) { + var ( + err error + b []byte + k int + ) + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + start := i + i += sz + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + case valid: + continue + case disallowed: + if err == nil { + r, _ := utf8.DecodeRuneInString(s[start:]) + err = runeError(r) + } + continue + case mapped, deviation: + b = append(b, s[k:start]...) + b = info(v).appendMapping(b, s[start:i]) + case ignored: + b = append(b, s[k:start]...) + // drop the rune + case unknown: + b = append(b, s[k:start]...) + b = append(b, "\ufffd"...) + } + k = i + } + if k == 0 { + // No changes so far. + s = norm.NFC.String(s) + } else { + b = append(b, s[k:]...) + if norm.NFC.QuickSpan(b) != len(b) { + b = norm.NFC.Bytes(b) + } + // TODO: the punycode converters require strings as input. + s = string(b) + } + return s, err +} + +// A labelIter allows iterating over domain name labels. +type labelIter struct { + orig string + slice []string + curStart int + curEnd int + i int +} + +func (l *labelIter) reset() { + l.curStart = 0 + l.curEnd = 0 + l.i = 0 +} + +func (l *labelIter) done() bool { + return l.curStart >= len(l.orig) +} + +func (l *labelIter) result() string { + if l.slice != nil { + return strings.Join(l.slice, ".") + } + return l.orig +} + +func (l *labelIter) label() string { + if l.slice != nil { + return l.slice[l.i] + } + p := strings.IndexByte(l.orig[l.curStart:], '.') + l.curEnd = l.curStart + p + if p == -1 { + l.curEnd = len(l.orig) + } + return l.orig[l.curStart:l.curEnd] +} + +// next sets the value to the next label. It skips the last label if it is empty. +func (l *labelIter) next() { + l.i++ + if l.slice != nil { + if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" { + l.curStart = len(l.orig) + } + } else { + l.curStart = l.curEnd + 1 + if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { + l.curStart = len(l.orig) + } + } +} + +func (l *labelIter) set(s string) { + if l.slice == nil { + l.slice = strings.Split(l.orig, ".") + } + l.slice[l.i] = s +} + +// acePrefix is the ASCII Compatible Encoding prefix. +const acePrefix = "xn--" + +func (p *Profile) simplify(cat category) category { + switch cat { + case disallowedSTD3Mapped: + if p.useSTD3Rules { + cat = disallowed + } else { + cat = mapped + } + case disallowedSTD3Valid: + if p.useSTD3Rules { + cat = disallowed + } else { + cat = valid + } + case deviation: + if !p.transitional { + cat = valid + } + case validNV8, validXV8: + // TODO: handle V2008 + cat = valid + } + return cat +} + +func validateFromPunycode(p *Profile, s string) error { + if !norm.NFC.IsNormalString(s) { + return &labelError{s, "V1"} + } + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + if c := p.simplify(info(v).category()); c != valid && c != deviation { + return &labelError{s, "V6"} + } + i += sz + } + return nil +} + +const ( + zwnj = "\u200c" + zwj = "\u200d" +) + +type joinState int8 + +const ( + stateStart joinState = iota + stateVirama + stateBefore + stateBeforeVirama + stateAfter + stateFAIL +) + +var joinStates = [][numJoinTypes]joinState{ + stateStart: { + joiningL: stateBefore, + joiningD: stateBefore, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateVirama, + }, + stateVirama: { + joiningL: stateBefore, + joiningD: stateBefore, + }, + stateBefore: { + joiningL: stateBefore, + joiningD: stateBefore, + joiningT: stateBefore, + joinZWNJ: stateAfter, + joinZWJ: stateFAIL, + joinVirama: stateBeforeVirama, + }, + stateBeforeVirama: { + joiningL: stateBefore, + joiningD: stateBefore, + joiningT: stateBefore, + }, + stateAfter: { + joiningL: stateFAIL, + joiningD: stateBefore, + joiningT: stateAfter, + joiningR: stateStart, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateAfter, // no-op as we can't accept joiners here + }, + stateFAIL: { + 0: stateFAIL, + joiningL: stateFAIL, + joiningD: stateFAIL, + joiningT: stateFAIL, + joiningR: stateFAIL, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateFAIL, + }, +} + +// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are +// already implicitly satisfied by the overall implementation. +func (p *Profile) validateLabel(s string) error { + if s == "" { + if p.verifyDNSLength { + return &labelError{s, "A4"} + } + return nil + } + if p.bidirule != nil && !p.bidirule(s) { + return &labelError{s, "B"} + } + if !p.validateLabels { + return nil + } + trie := p.trie // p.validateLabels is only set if trie is set. + if len(s) > 4 && s[2] == '-' && s[3] == '-' { + return &labelError{s, "V2"} + } + if s[0] == '-' || s[len(s)-1] == '-' { + return &labelError{s, "V3"} + } + // TODO: merge the use of this in the trie. + v, sz := trie.lookupString(s) + x := info(v) + if x.isModifier() { + return &labelError{s, "V5"} + } + // Quickly return in the absence of zero-width (non) joiners. + if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { + return nil + } + st := stateStart + for i := 0; ; { + jt := x.joinType() + if s[i:i+sz] == zwj { + jt = joinZWJ + } else if s[i:i+sz] == zwnj { + jt = joinZWNJ + } + st = joinStates[st][jt] + if x.isViramaModifier() { + st = joinStates[st][joinVirama] + } + if i += sz; i == len(s) { + break + } + v, sz = trie.lookupString(s[i:]) + x = info(v) + } + if st == stateFAIL || st == stateAfter { + return &labelError{s, "C"} + } + return nil +} + +func ascii(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= utf8.RuneSelf { + return false + } + } + return true +} diff --git a/vendor/golang.org/x/net/idna/tables.go b/vendor/golang.org/x/net/idna/tables.go deleted file mode 100644 index f910b2691443..000000000000 --- a/vendor/golang.org/x/net/idna/tables.go +++ /dev/null @@ -1,4557 +0,0 @@ -// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. - -package idna - -// UnicodeVersion is the Unicode version from which the tables in this package are derived. -const UnicodeVersion = "10.0.0" - -var mappings string = "" + // Size: 8176 bytes - "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + - "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + - "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + - "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" + - "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" + - "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" + - "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" + - "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" + - "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" + - "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" + - "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" + - "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" + - "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" + - "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" + - "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" + - "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" + - "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" + - "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" + - "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" + - "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" + - "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" + - "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" + - "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" + - "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" + - "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" + - "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" + - ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" + - "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" + - "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" + - "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" + - "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" + - "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" + - "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" + - "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" + - "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" + - "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" + - "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" + - "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" + - "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" + - "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" + - "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" + - "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" + - "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" + - "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" + - "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" + - "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" + - "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" + - "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" + - "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" + - "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" + - "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" + - "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" + - "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" + - "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" + - "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" + - "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" + - "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" + - "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" + - "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" + - "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" + - "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" + - "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" + - "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" + - "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" + - "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" + - "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" + - "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" + - "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" + - "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" + - "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" + - "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" + - "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" + - "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" + - " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" + - "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" + - "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" + - "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" + - "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" + - "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" + - "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" + - "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" + - "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" + - "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" + - "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" + - "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" + - "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" + - "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" + - "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" + - "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" + - "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" + - "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" + - "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" + - "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" + - "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" + - "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" + - "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" + - "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" + - "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" + - "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" + - "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" + - "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" + - "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" + - "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" + - "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" + - "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" + - "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" + - "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" + - "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" + - "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" + - "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" + - "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" + - "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" + - "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" + - "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" + - "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" + - "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" + - "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" + - "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" + - "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" + - "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" + - "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" + - "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" + - "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" + - "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" + - "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" + - "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" + - "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" + - "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" + - "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" + - "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" + - "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" + - "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" + - "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" + - "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" + - "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" + - "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" + - "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻" - -var xorData string = "" + // Size: 4855 bytes - "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" + - "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" + - "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" + - "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" + - "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" + - "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" + - "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" + - "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" + - "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" + - "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" + - "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" + - "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" + - "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" + - "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" + - "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" + - "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" + - "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" + - "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" + - "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" + - "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" + - "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" + - "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" + - "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" + - "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" + - "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" + - "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" + - "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" + - "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" + - "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" + - "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" + - "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" + - "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" + - "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" + - "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" + - "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" + - "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" + - "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " + - "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" + - "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" + - "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" + - "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" + - "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" + - ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" + - "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" + - "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" + - "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" + - "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" + - "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" + - "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" + - "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" + - "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" + - "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" + - "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" + - "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" + - "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" + - "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" + - "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" + - "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" + - "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" + - "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" + - "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" + - "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" + - "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" + - "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" + - "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" + - "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" + - "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" + - "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" + - "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" + - "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" + - "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" + - "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" + - "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" + - "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" + - "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" + - "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" + - "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" + - "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" + - "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" + - "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" + - "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" + - "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" + - "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" + - "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" + - "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" + - "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" + - "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" + - "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" + - "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," + - "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" + - "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" + - "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" + - "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" + - ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" + - "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" + - "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" + - "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" + - "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" + - "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" + - "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" + - "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" + - "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" + - "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" + - "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" + - "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" + - "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" + - "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" + - "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" + - "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" + - "\x08\x1a\x0a\x03\x07</\x03\x07:+\x03\x07\x07*\x03\x06&\x1c\x03\x09\x0c" + - "\x16\x03\x09\x10\x0e\x03\x08'\x0f\x03\x08+\x09\x03\x074%\x03\x06!3\x03" + - "\x06\x03+\x03\x0b\x1e\x19\x03\x0a))\x03\x09\x08\x19\x03\x08,\x05\x03\x07" + - "<2\x03\x06\x1c>\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" + - "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" + - "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" + - "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" + - "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" + - "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" + - "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" + - "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" + - "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" + - "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" + - "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" + - "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" + - "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" + - "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" + - "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" + - "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" + - "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" + - "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." + - "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" + - "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" + - "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " + - "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" + - "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" + - "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" + - "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" + - "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" + - "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" + - "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," + - "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" + - "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" + - "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" + - "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" + - "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" + - "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" + - "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" + - "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" + - "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" + - "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" + - "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" + - "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" + - "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" + - "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" + - "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" + - "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" + - "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" + - "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" + - "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" + - "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" + - "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" + - "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" + - "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" + - "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" + - "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" + - "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" + - "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" + - "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" + - "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" + - "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" + - "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" + - "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" + - "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" + - "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" + - "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" + - "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" + - "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" + - "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" + - "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," + - "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" + - "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" + - "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" + - "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" + - "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" + - "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" + - "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" + - "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" + - "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" + - "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" + - "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" + - "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" + - "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" + - "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" + - "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" + - "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" + - "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" + - "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" + - "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" + - "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" + - "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" + - "\x04\x03\x0c?\x05\x03\x0c<?\x03\x0c=\x00\x03\x0c=\x06\x03\x0c=\x05\x03" + - "\x0c=\x0c\x03\x0c=\x0f\x03\x0c=\x0d\x03\x0c=\x0b\x03\x0c=\x07\x03\x0c=" + - "\x19\x03\x0c=\x15\x03\x0c=\x11\x03\x0c=1\x03\x0c=3\x03\x0c=0\x03\x0c=>" + - "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" + - "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" + - "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" + - "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" + - "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" + - "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" + - "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" + - "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" + - "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" + - "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" + - "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" + - "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" + - "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" + - "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" + - "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" + - "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" + - "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" + - "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" + - "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" + - "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" + - "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" + - "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" + - "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" + - "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" + - "\x05\x22\x05\x03\x050\x1d" - -// lookup returns the trie value for the first UTF-8 encoding in s and -// the width in bytes of this encoding. The size will be 0 if s does not -// hold enough bytes to complete the encoding. len(s) must be greater than 0. -func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) { - c0 := s[0] - switch { - case c0 < 0x80: // is ASCII - return idnaValues[c0], 1 - case c0 < 0xC2: - return 0, 1 // Illegal UTF-8: not a starter, not ASCII. - case c0 < 0xE0: // 2-byte UTF-8 - if len(s) < 2 { - return 0, 0 - } - i := idnaIndex[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c1), 2 - case c0 < 0xF0: // 3-byte UTF-8 - if len(s) < 3 { - return 0, 0 - } - i := idnaIndex[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - o := uint32(i)<<6 + uint32(c1) - i = idnaIndex[o] - c2 := s[2] - if c2 < 0x80 || 0xC0 <= c2 { - return 0, 2 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c2), 3 - case c0 < 0xF8: // 4-byte UTF-8 - if len(s) < 4 { - return 0, 0 - } - i := idnaIndex[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - o := uint32(i)<<6 + uint32(c1) - i = idnaIndex[o] - c2 := s[2] - if c2 < 0x80 || 0xC0 <= c2 { - return 0, 2 // Illegal UTF-8: not a continuation byte. - } - o = uint32(i)<<6 + uint32(c2) - i = idnaIndex[o] - c3 := s[3] - if c3 < 0x80 || 0xC0 <= c3 { - return 0, 3 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c3), 4 - } - // Illegal rune - return 0, 1 -} - -// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. -// s must start with a full and valid UTF-8 encoded rune. -func (t *idnaTrie) lookupUnsafe(s []byte) uint16 { - c0 := s[0] - if c0 < 0x80 { // is ASCII - return idnaValues[c0] - } - i := idnaIndex[c0] - if c0 < 0xE0 { // 2-byte UTF-8 - return t.lookupValue(uint32(i), s[1]) - } - i = idnaIndex[uint32(i)<<6+uint32(s[1])] - if c0 < 0xF0 { // 3-byte UTF-8 - return t.lookupValue(uint32(i), s[2]) - } - i = idnaIndex[uint32(i)<<6+uint32(s[2])] - if c0 < 0xF8 { // 4-byte UTF-8 - return t.lookupValue(uint32(i), s[3]) - } - return 0 -} - -// lookupString returns the trie value for the first UTF-8 encoding in s and -// the width in bytes of this encoding. The size will be 0 if s does not -// hold enough bytes to complete the encoding. len(s) must be greater than 0. -func (t *idnaTrie) lookupString(s string) (v uint16, sz int) { - c0 := s[0] - switch { - case c0 < 0x80: // is ASCII - return idnaValues[c0], 1 - case c0 < 0xC2: - return 0, 1 // Illegal UTF-8: not a starter, not ASCII. - case c0 < 0xE0: // 2-byte UTF-8 - if len(s) < 2 { - return 0, 0 - } - i := idnaIndex[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c1), 2 - case c0 < 0xF0: // 3-byte UTF-8 - if len(s) < 3 { - return 0, 0 - } - i := idnaIndex[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - o := uint32(i)<<6 + uint32(c1) - i = idnaIndex[o] - c2 := s[2] - if c2 < 0x80 || 0xC0 <= c2 { - return 0, 2 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c2), 3 - case c0 < 0xF8: // 4-byte UTF-8 - if len(s) < 4 { - return 0, 0 - } - i := idnaIndex[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - o := uint32(i)<<6 + uint32(c1) - i = idnaIndex[o] - c2 := s[2] - if c2 < 0x80 || 0xC0 <= c2 { - return 0, 2 // Illegal UTF-8: not a continuation byte. - } - o = uint32(i)<<6 + uint32(c2) - i = idnaIndex[o] - c3 := s[3] - if c3 < 0x80 || 0xC0 <= c3 { - return 0, 3 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c3), 4 - } - // Illegal rune - return 0, 1 -} - -// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. -// s must start with a full and valid UTF-8 encoded rune. -func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { - c0 := s[0] - if c0 < 0x80 { // is ASCII - return idnaValues[c0] - } - i := idnaIndex[c0] - if c0 < 0xE0 { // 2-byte UTF-8 - return t.lookupValue(uint32(i), s[1]) - } - i = idnaIndex[uint32(i)<<6+uint32(s[1])] - if c0 < 0xF0 { // 3-byte UTF-8 - return t.lookupValue(uint32(i), s[2]) - } - i = idnaIndex[uint32(i)<<6+uint32(s[2])] - if c0 < 0xF8 { // 4-byte UTF-8 - return t.lookupValue(uint32(i), s[3]) - } - return 0 -} - -// idnaTrie. Total size: 29052 bytes (28.37 KiB). Checksum: ef06e7ecc26f36dd. -type idnaTrie struct{} - -func newIdnaTrie(i int) *idnaTrie { - return &idnaTrie{} -} - -// lookupValue determines the type of block n and looks up the value for b. -func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { - switch { - case n < 125: - return uint16(idnaValues[n<<6+uint32(b)]) - default: - n -= 125 - return uint16(idnaSparse.lookup(n, b)) - } -} - -// idnaValues: 127 blocks, 8128 entries, 16256 bytes -// The third block is the zero block. -var idnaValues = [8128]uint16{ - // Block 0x0, offset 0x0 - 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, - 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, - 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080, - 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080, - 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080, - 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080, - 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080, - 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080, - 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008, - 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080, - 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080, - // Block 0x1, offset 0x40 - 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105, - 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105, - 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105, - 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105, - 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080, - 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008, - 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008, - 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008, - 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008, - 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080, - 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080, - // Block 0x2, offset 0x80 - // Block 0x3, offset 0xc0 - 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, - 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, - 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, - 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, - 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, - 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018, - 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018, - 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a, - 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005, - 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018, - 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018, - // Block 0x4, offset 0x100 - 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008, - 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008, - 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008, - 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008, - 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008, - 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008, - 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008, - 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008, - 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008, - 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d, - 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199, - // Block 0x5, offset 0x140 - 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d, - 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008, - 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008, - 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008, - 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008, - 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008, - 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008, - 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008, - 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008, - 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d, - 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9, - // Block 0x6, offset 0x180 - 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008, - 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d, - 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d, - 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d, - 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155, - 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008, - 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d, - 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd, - 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d, - 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008, - 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008, - // Block 0x7, offset 0x1c0 - 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9, - 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d, - 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d, - 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d, - 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008, - 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008, - 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008, - 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008, - 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008, - 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008, - 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008, - // Block 0x8, offset 0x200 - 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008, - 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008, - 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008, - 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008, - 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008, - 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008, - 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008, - 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008, - 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008, - 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d, - 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008, - // Block 0x9, offset 0x240 - 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018, - 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008, - 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008, - 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018, - 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a, - 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369, - 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018, - 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018, - 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018, - 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, - 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, - // Block 0xa, offset 0x280 - 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, - 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, - 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, - 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, - 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, - 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, - 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, - 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, - 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, - 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, - 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, - // Block 0xb, offset 0x2c0 - 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2, - 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040, - 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105, - 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105, - 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105, - 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d, - 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d, - 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008, - 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008, - 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008, - 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008, - // Block 0xc, offset 0x300 - 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008, - 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008, - 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd, - 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008, - 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008, - 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008, - 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008, - 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008, - 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd, - 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008, - 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d, - // Block 0xd, offset 0x340 - 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008, - 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008, - 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008, - 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008, - 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008, - 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008, - 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008, - 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008, - 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008, - 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, - 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, - // Block 0xe, offset 0x380 - 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, - 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, - 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, - 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, - 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, - 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008, - 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008, - 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008, - 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008, - 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008, - 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008, - // Block 0xf, offset 0x3c0 - 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d, - 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d, - 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008, - 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008, - 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008, - 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008, - 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008, - 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008, - 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008, - 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008, - 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008, - // Block 0x10, offset 0x400 - 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008, - 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008, - 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008, - 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008, - 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008, - 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008, - 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008, - 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008, - 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5, - 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, - 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, - // Block 0x11, offset 0x440 - 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, - 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, - 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, - 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, - 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, - 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, - 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, - 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, - 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, - 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, - 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, - // Block 0x12, offset 0x480 - 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, - 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, - 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, - 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, - 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, - 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, - 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, - 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, - 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, - 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, - 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, - // Block 0x13, offset 0x4c0 - 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, - 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, - 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, - 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, - 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, - 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, - 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, - 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, - 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, - 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, - 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, - // Block 0x14, offset 0x500 - 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, - 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, - 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, - 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, - 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, - 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, - 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, - 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, - 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, - 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, - 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, - // Block 0x15, offset 0x540 - 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08, - 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08, - 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08, - 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808, - 0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040, - 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08, - 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08, - 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040, - 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040, - 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040, - 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040, - // Block 0x16, offset 0x580 - 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308, - 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008, - 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308, - 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308, - 0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1, - 0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308, - 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008, - 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, - 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008, - 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008, - 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008, - // Block 0x17, offset 0x5c0 - 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008, - 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008, - 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040, - 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008, - 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008, - 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008, - 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040, - 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, - 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040, - 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040, - 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008, - // Block 0x18, offset 0x600 - 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040, - 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008, - 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040, - 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008, - 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1, - 0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308, - 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008, - 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, - 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018, - 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018, - 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x0040, 0x63f: 0x0040, - // Block 0x19, offset 0x640 - 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008, - 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040, - 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040, - 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008, - 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008, - 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008, - 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040, - 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, - 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008, - 0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040, - 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008, - // Block 0x1a, offset 0x680 - 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040, - 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308, - 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308, - 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040, - 0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040, - 0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040, - 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008, - 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, - 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308, - 0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040, - 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040, - // Block 0x1b, offset 0x6c0 - 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008, - 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008, - 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008, - 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008, - 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008, - 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008, - 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040, - 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, - 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008, - 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, - 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008, - // Block 0x1c, offset 0x700 - 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308, - 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008, - 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040, - 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040, - 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040, - 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308, - 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008, - 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, - 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040, - 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308, - 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308, - // Block 0x1d, offset 0x740 - 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008, - 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008, - 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040, - 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008, - 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008, - 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008, - 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040, - 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, - 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008, - 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040, - 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308, - // Block 0x1e, offset 0x780 - 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040, - 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008, - 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040, - 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008, - 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9, - 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308, - 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008, - 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008, - 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018, - 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040, - 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040, - // Block 0x1f, offset 0x7c0 - 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008, - 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040, - 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040, - 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040, - 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040, - 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008, - 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008, - 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008, - 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008, - 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040, - 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008, - // Block 0x20, offset 0x800 - 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040, - 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308, - 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040, - 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040, - 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040, - 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308, - 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008, - 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, - 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040, - 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018, - 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018, - // Block 0x21, offset 0x840 - 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0040, 0x845: 0x0008, - 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008, - 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040, - 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008, - 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008, - 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008, - 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040, - 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, - 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008, - 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040, - 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308, - // Block 0x22, offset 0x880 - 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040, - 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, - 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040, - 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040, - 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040, - 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, - 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, - 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, - 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040, - 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040, - 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040, - // Block 0x23, offset 0x8c0 - 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040, - 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008, - 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040, - 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008, - 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018, - 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308, - 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008, - 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, - 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018, - 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008, - 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008, - // Block 0x24, offset 0x900 - 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040, - 0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040, - 0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040, - 0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008, - 0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008, - 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, - 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040, - 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008, - 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308, - 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308, - 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040, - // Block 0x25, offset 0x940 - 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008, - 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, - 0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008, - 0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79, - 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008, - 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008, - 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9, - 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040, - 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59, - 0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308, - 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008, - // Block 0x26, offset 0x980 - 0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018, - 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, - 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308, - 0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308, - 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11, - 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308, - 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308, - 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308, - 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308, - 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308, - 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018, - // Block 0x27, offset 0x9c0 - 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008, - 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008, - 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008, - 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008, - 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008, - 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008, - 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008, - 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008, - 0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41, - 0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008, - 0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269, - // Block 0x28, offset 0xa00 - 0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1, - 0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011, - 0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041, - 0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9, - 0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099, - 0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269, - 0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1, - 0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008, - 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008, - 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008, - 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008, - // Block 0x29, offset 0xa40 - 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008, - 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008, - 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008, - 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008, - 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169, - 0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9, - 0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251, - 0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9, - 0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359, - 0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1, - 0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429, - // Block 0x2a, offset 0xa80 - 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, - 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, - 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, - 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008, - 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008, - 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, - 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, - 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, - 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, - 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, - 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, - // Block 0x2b, offset 0xac0 - 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008, - 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008, - 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008, - 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, - 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008, - 0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008, - 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008, - 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008, - 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008, - 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008, - 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008, - // Block 0x2c, offset 0xb00 - 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008, - 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045, - 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008, - 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008, - 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045, - 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008, - 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045, - 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045, - 0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489, - 0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1, - 0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040, - // Block 0x2d, offset 0xb40 - 0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1, - 0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591, - 0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1, - 0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1, - 0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771, - 0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891, - 0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831, - 0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951, - 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040, - 0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459, - 0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686, - // Block 0x2e, offset 0xb80 - 0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040, - 0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489, - 0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008, - 0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008, - 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2, - 0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61, - 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045, - 0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa, - 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040, - 0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9, - 0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040, - // Block 0x2f, offset 0xbc0 - 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a, - 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0, - 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d, - 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e, - 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, - 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018, - 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040, - 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a, - 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018, - 0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018, - 0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018, - // Block 0x30, offset 0xc00 - 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018, - 0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018, - 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018, - 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9, - 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018, - 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340, - 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040, - 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340, - 0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61, - 0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd, - 0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71, - // Block 0x31, offset 0xc40 - 0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61, - 0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5, - 0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09, - 0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359, - 0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040, - 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018, - 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018, - 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018, - 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018, - 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018, - 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018, - // Block 0x32, offset 0xc80 - 0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e, - 0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249, - 0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41, - 0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018, - 0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269, - 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018, - 0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018, - 0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09, - 0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9, - 0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd, - 0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109, - // Block 0x33, offset 0xcc0 - 0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9, - 0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018, - 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151, - 0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279, - 0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399, - 0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439, - 0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369, - 0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61, - 0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451, - 0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5, - 0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61, - // Block 0x34, offset 0xd00 - 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018, - 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040, - 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, - 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, - 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040, - 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51, - 0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601, - 0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691, - 0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26, - 0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6, - 0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a, - // Block 0x35, offset 0xd40 - 0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a, - 0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040, - 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040, - 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040, - 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46, - 0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06, - 0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6, - 0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86, - 0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46, - 0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199, - 0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259, - // Block 0x36, offset 0xd80 - 0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99, - 0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089, - 0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9, - 0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249, - 0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71, - 0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9, - 0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1, - 0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018, - 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018, - 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018, - 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018, - // Block 0x37, offset 0xdc0 - 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008, - 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008, - 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008, - 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008, - 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008, - 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd, - 0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d, - 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9, - 0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d, - 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008, - 0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9, - // Block 0x38, offset 0xe00 - 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008, - 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008, - 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008, - 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008, - 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008, - 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008, - 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018, - 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308, - 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040, - 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018, - 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018, - // Block 0x39, offset 0xe40 - 0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d, - 0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d, - 0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d, - 0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040, - 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040, - 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040, - 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040, - 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040, - 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040, - 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040, - 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040, - // Block 0x3a, offset 0xe80 - 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008, - 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018, - 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018, - 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018, - 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018, - 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018, - 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018, - 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018, - 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018, - 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018, - 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018, - // Block 0x3b, offset 0xec0 - 0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd, - 0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd, - 0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d, - 0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d, - 0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d, - 0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd, - 0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d, - 0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd, - 0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d, - 0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd, - 0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d, - // Block 0x3c, offset 0xf00 - 0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd, - 0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d, - 0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018, - 0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd, - 0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d, - 0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008, - 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008, - 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008, - 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008, - 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040, - 0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040, - // Block 0x3d, offset 0xf40 - 0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd, - 0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018, - 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761, - 0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1, - 0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881, - 0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd, - 0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d, - 0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d, - 0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd, - 0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d, - 0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018, - // Block 0x3e, offset 0xf80 - 0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d, - 0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d, - 0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd, - 0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd, - 0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d, - 0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d, - 0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd, - 0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d, - 0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999, - 0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29, - 0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89, - // Block 0x3f, offset 0xfc0 - 0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69, - 0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69, - 0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15, - 0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75, - 0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded, - 0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d, - 0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5, - 0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d, - 0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d, - 0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd, - 0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040, - // Block 0x40, offset 0x1000 - 0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9, - 0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1, - 0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9, - 0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549, - 0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1, - 0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11, - 0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91, - 0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9, - 0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011, - 0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209, - 0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361, - // Block 0x41, offset 0x1040 - 0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541, - 0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781, - 0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979, - 0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89, - 0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1, - 0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99, - 0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9, - 0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9, - 0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069, - 0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9, - 0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9, - // Block 0x42, offset 0x1080 - 0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271, - 0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9, - 0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed, - 0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371, - 0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9, - 0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d, - 0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211, - 0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1, - 0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599, - 0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9, - 0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611, - // Block 0x43, offset 0x10c0 - 0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671, - 0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709, - 0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781, - 0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1, - 0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811, - 0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901, - 0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1, - 0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11, - 0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31, - 0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51, - 0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d, - // Block 0x44, offset 0x1100 - 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, - 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, - 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, - 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, - 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008, - 0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008, - 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008, - 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308, - 0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308, - 0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308, - 0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008, - // Block 0x45, offset 0x1140 - 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008, - 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008, - 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008, - 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008, - 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11, - 0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008, - 0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008, - 0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008, - 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008, - 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008, - 0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008, - // Block 0x46, offset 0x1180 - 0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018, - 0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018, - 0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018, - 0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008, - 0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008, - 0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008, - 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, - 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, - 0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008, - 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008, - 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008, - // Block 0x47, offset 0x11c0 - 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, - 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008, - 0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, - 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, - 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, - 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, - 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, - 0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008, - 0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008, - 0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d, - 0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008, - // Block 0x48, offset 0x1200 - 0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008, - 0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d, - 0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008, - 0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008, - 0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008, - 0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008, - 0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008, - 0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0040, - 0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008, - 0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040, - 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040, - // Block 0x49, offset 0x1240 - 0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575, - 0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635, - 0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008, - 0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715, - 0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5, - 0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008, - 0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008, - 0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935, - 0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5, - 0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5, - 0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35, - // Block 0x4a, offset 0x1280 - 0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35, - 0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5, - 0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19, - 0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91, - 0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040, - 0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040, - 0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040, - 0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040, - 0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040, - 0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040, - 0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040, - // Block 0x4b, offset 0x12c0 - 0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001, - 0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040, - 0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040, - 0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9, - 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1, - 0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149, - 0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2, - 0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1, - 0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1, - 0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479, - 0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040, - // Block 0x4c, offset 0x1300 - 0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040, - 0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659, - 0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721, - 0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751, - 0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769, - 0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799, - 0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1, - 0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1, - 0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9, - 0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829, - 0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841, - // Block 0x4d, offset 0x1340 - 0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871, - 0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9, - 0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9, - 0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919, - 0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931, - 0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961, - 0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991, - 0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1, - 0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818, - 0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818, - 0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818, - // Block 0x4e, offset 0x1380 - 0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040, - 0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040, - 0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040, - 0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09, - 0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479, - 0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81, - 0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1, - 0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19, - 0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91, - 0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1, - 0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09, - // Block 0x4f, offset 0x13c0 - 0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1, - 0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1, - 0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1, - 0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991, - 0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81, - 0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a, - 0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99, - 0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89, - 0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79, - 0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19, - 0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469, - // Block 0x50, offset 0x1400 - 0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649, - 0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9, - 0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49, - 0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21, - 0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9, - 0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01, - 0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91, - 0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9, - 0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171, - 0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289, - 0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329, - // Block 0x51, offset 0x1440 - 0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1, - 0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621, - 0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739, - 0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1, - 0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9, - 0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29, - 0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079, - 0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1, - 0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171, - 0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261, - 0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301, - // Block 0x52, offset 0x1480 - 0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1, - 0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1, - 0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171, - 0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261, - 0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351, - 0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441, - 0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509, - 0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1, - 0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081, - 0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239, - 0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018, - // Block 0x53, offset 0x14c0 - 0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040, - 0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, - 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609, - 0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721, - 0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839, - 0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919, - 0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9, - 0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9, - 0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9, - 0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1, - 0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79, - // Block 0x54, offset 0x1500 - 0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989, - 0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040, - 0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040, - 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040, - 0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, - 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040, - 0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040, - 0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040, - 0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9, - 0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12, - 0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040, - // Block 0x55, offset 0x1540 - 0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0, - 0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0, - 0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55, - 0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75, - 0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040, - 0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308, - 0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308, - 0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308, - 0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2, - 0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35, - 0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55, - // Block 0x56, offset 0x1580 - 0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018, - 0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56, - 0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95, - 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa, - 0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95, - 0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99, - 0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda, - 0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040, - 0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040, - 0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081, - 0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1, - // Block 0x57, offset 0x15c0 - 0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141, - 0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171, - 0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1, - 0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1, - 0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201, - 0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219, - 0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249, - 0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291, - 0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1, - 0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9, - 0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1, - // Block 0x58, offset 0x1600 - 0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321, - 0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339, - 0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369, - 0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381, - 0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1, - 0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9, - 0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9, - 0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1, - 0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441, - 0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9, - 0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0, - // Block 0x59, offset 0x1640 - 0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea, - 0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2, - 0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9, - 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81, - 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2, - 0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159, - 0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41, - 0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9, - 0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9, - 0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a, - 0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a, - // Block 0x5a, offset 0x1680 - 0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09, - 0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51, - 0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039, - 0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279, - 0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a, - 0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115, - 0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5, - 0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295, - 0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355, - 0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415, - 0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215, - // Block 0x5b, offset 0x16c0 - 0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515, - 0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595, - 0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5, - 0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655, - 0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115, - 0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735, - 0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5, - 0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5, - 0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5, - 0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5, - 0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040, - // Block 0x5c, offset 0x1700 - 0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5, - 0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715, - 0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040, - 0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935, - 0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040, - 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6, - 0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35, - 0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040, - 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040, - 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340, - 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, - // Block 0x5d, offset 0x1740 - 0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08, - 0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808, - 0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08, - 0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908, - 0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08, - 0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808, - 0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040, - 0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18, - 0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818, - 0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, - 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, - // Block 0x5e, offset 0x1780 - 0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08, - 0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08, - 0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08, - 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040, - 0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040, - 0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040, - 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18, - 0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818, - 0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040, - 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040, - 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040, - // Block 0x5f, offset 0x17c0 - 0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008, - 0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008, - 0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040, - 0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008, - 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008, - 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008, - 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040, - 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008, - 0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008, - 0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x0040, - 0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008, - // Block 0x60, offset 0x1800 - 0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040, - 0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008, - 0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040, - 0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008, - 0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008, - 0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008, - 0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308, - 0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040, - 0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040, - 0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040, - 0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040, - // Block 0x61, offset 0x1840 - 0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199, - 0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359, - 0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269, - 0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369, - 0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9, - 0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259, - 0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99, - 0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089, - 0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9, - 0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249, - 0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359, - // Block 0x62, offset 0x1880 - 0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269, - 0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369, - 0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9, - 0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259, - 0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99, - 0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089, - 0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9, - 0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249, - 0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71, - 0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9, - 0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369, - // Block 0x63, offset 0x18c0 - 0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9, - 0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259, - 0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99, - 0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089, - 0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040, - 0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040, - 0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71, - 0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9, - 0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1, - 0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199, - 0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259, - // Block 0x64, offset 0x1900 - 0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99, - 0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089, - 0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9, - 0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249, - 0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71, - 0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9, - 0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1, - 0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199, - 0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359, - 0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269, - 0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089, - // Block 0x65, offset 0x1940 - 0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9, - 0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040, - 0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71, - 0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9, - 0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040, - 0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199, - 0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359, - 0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269, - 0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369, - 0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9, - 0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040, - // Block 0x66, offset 0x1980 - 0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040, - 0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9, - 0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040, - 0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199, - 0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359, - 0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269, - 0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369, - 0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9, - 0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259, - 0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99, - 0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9, - // Block 0x67, offset 0x19c0 - 0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1, - 0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199, - 0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359, - 0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269, - 0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369, - 0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9, - 0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259, - 0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99, - 0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089, - 0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9, - 0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199, - // Block 0x68, offset 0x1a00 - 0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359, - 0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269, - 0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369, - 0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9, - 0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259, - 0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99, - 0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089, - 0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9, - 0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249, - 0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71, - 0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269, - // Block 0x69, offset 0x1a40 - 0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369, - 0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9, - 0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259, - 0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99, - 0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089, - 0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9, - 0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249, - 0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71, - 0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9, - 0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1, - 0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9, - // Block 0x6a, offset 0x1a80 - 0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259, - 0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99, - 0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089, - 0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9, - 0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249, - 0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71, - 0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9, - 0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1, - 0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199, - 0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359, - 0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99, - // Block 0x6b, offset 0x1ac0 - 0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089, - 0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9, - 0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249, - 0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71, - 0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9, - 0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1, - 0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099, - 0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429, - 0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71, - 0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9, - 0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9, - // Block 0x6c, offset 0x1b00 - 0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9, - 0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11, - 0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109, - 0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1, - 0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429, - 0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099, - 0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429, - 0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71, - 0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9, - 0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01, - 0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9, - // Block 0x6d, offset 0x1b40 - 0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11, - 0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109, - 0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1, - 0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429, - 0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099, - 0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429, - 0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71, - 0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9, - 0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01, - 0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1, - 0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11, - // Block 0x6e, offset 0x1b80 - 0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109, - 0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1, - 0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429, - 0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099, - 0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429, - 0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71, - 0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9, - 0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01, - 0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1, - 0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41, - 0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109, - // Block 0x6f, offset 0x1bc0 - 0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1, - 0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429, - 0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099, - 0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429, - 0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71, - 0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9, - 0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01, - 0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1, - 0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41, - 0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1, - 0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1, - // Block 0x70, offset 0x1c00 - 0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429, - 0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41, - 0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079, - 0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1, - 0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61, - 0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9, - 0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81, - 0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079, - 0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1, - 0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61, - 0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1, - // Block 0x71, offset 0x1c40 - 0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115, - 0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135, - 0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115, - 0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175, - 0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115, - 0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08, - 0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08, - 0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08, - 0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08, - 0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08, - 0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08, - // Block 0x72, offset 0x1c80 - 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411, - 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1, - 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9, - 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231, - 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949, - 0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, - 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429, - 0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, - 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, - 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351, - 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040, - // Block 0x73, offset 0x1cc0 - 0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040, - 0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, - 0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9, - 0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231, - 0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949, - 0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040, - 0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, - 0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, - 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, - 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, - 0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040, - // Block 0x74, offset 0x1d00 - 0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411, - 0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1, - 0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9, - 0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231, - 0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040, - 0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249, - 0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429, - 0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339, - 0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1, - 0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351, - 0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040, - // Block 0x75, offset 0x1d40 - 0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02, - 0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018, - 0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2, - 0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72, - 0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32, - 0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2, - 0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2, - 0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0040, - 0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199, - 0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359, - 0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99, - // Block 0x76, offset 0x1d80 - 0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089, - 0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1, - 0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018, - 0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018, - 0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018, - 0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018, - 0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018, - 0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040, - 0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018, - 0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018, - 0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018, - // Block 0x77, offset 0x1dc0 - 0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040, - 0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040, - 0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289, - 0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349, - 0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409, - 0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9, - 0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589, - 0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649, - 0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709, - 0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9, - 0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040, - // Block 0x78, offset 0x1e00 - 0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79, - 0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39, - 0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9, - 0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39, - 0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9, - 0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79, - 0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39, - 0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9, - 0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059, - 0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9, - 0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179, - // Block 0x79, offset 0x1e40 - 0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239, - 0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9, - 0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399, - 0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459, - 0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309, - 0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559, - 0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9, - 0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679, - 0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9, - 0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d, - 0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9, - // Block 0x7a, offset 0x1e80 - 0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9, - 0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959, - 0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d, - 0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d, - 0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9, - 0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99, - 0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9, - 0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9, - 0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99, - 0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39, - 0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99, - // Block 0x7b, offset 0x1ec0 - 0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639, - 0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9, - 0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d, - 0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9, - 0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d, - 0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd, - 0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979, - 0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19, - 0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d, - 0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d, - 0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59, - // Block 0x7c, offset 0x1f00 - 0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99, - 0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39, - 0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9, - 0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39, - 0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd, - 0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19, - 0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9, - 0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59, - 0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd, - 0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d, - 0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079, - // Block 0x7d, offset 0x1f40 - 0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d, - 0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d, - 0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879, - 0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919, - 0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd, - 0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9, - 0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99, - 0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39, - 0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9, - 0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d, - 0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79, - // Block 0x7e, offset 0x1f80 - 0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19, - 0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9, - 0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59, - 0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9, - 0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d, - 0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040, - 0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040, - 0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040, - 0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040, - 0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040, - 0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040, -} - -// idnaIndex: 36 blocks, 2304 entries, 4608 bytes -// Block 0 is the zero block. -var idnaIndex = [2304]uint16{ - // Block 0x0, offset 0x0 - // Block 0x1, offset 0x40 - // Block 0x2, offset 0x80 - // Block 0x3, offset 0xc0 - 0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, - 0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, - 0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84, - 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88, - 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, - 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, - 0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21, - // Block 0x4, offset 0x100 - 0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16, - 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d, - 0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91, - 0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96, - // Block 0x5, offset 0x140 - 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, - 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, - 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, - 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, - 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, - 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, - 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3, - 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c, - // Block 0x6, offset 0x180 - 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b, - 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b, - 0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, - 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, - 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, - 0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0, - 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5, - 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37, - // Block 0x7, offset 0x1c0 - 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1, - 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41, - 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, - 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, - 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, - 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, - 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, - 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, - // Block 0x8, offset 0x200 - 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, - 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, - 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, - 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, - 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, - 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, - 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, - 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, - // Block 0x9, offset 0x240 - 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, - 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, - 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, - 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, - 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, - 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, - 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, - 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, - // Block 0xa, offset 0x280 - 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, - 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, - 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, - 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, - 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, - 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, - 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, - 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3, - // Block 0xb, offset 0x2c0 - 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, - 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, - 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, - 0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8, - 0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0, - 0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8, - 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, - 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, - // Block 0xc, offset 0x300 - 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, - 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, - 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, - 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa, - // Block 0xd, offset 0x340 - 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, - 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, - 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, - 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, - 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, - 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, - 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, - 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, - // Block 0xe, offset 0x380 - 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, - 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, - 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, - 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, - 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe, - 0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c, - 0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52, - 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a, - // Block 0xf, offset 0x3c0 - 0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108, - 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e, - 0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba, - 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba, - 0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c, - 0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba, - 0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, - 0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba, - // Block 0x10, offset 0x400 - 0x400: 0x127, 0x401: 0x128, 0x402: 0x129, 0x403: 0x12a, 0x404: 0x12b, 0x405: 0x12c, 0x406: 0x12d, 0x407: 0x12e, - 0x408: 0x12f, 0x409: 0xba, 0x40a: 0x130, 0x40b: 0x131, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba, - 0x410: 0x132, 0x411: 0x133, 0x412: 0x134, 0x413: 0x135, 0x414: 0xba, 0x415: 0xba, 0x416: 0x136, 0x417: 0x137, - 0x418: 0x138, 0x419: 0x139, 0x41a: 0x13a, 0x41b: 0x13b, 0x41c: 0x13c, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, - 0x420: 0xba, 0x421: 0xba, 0x422: 0x13d, 0x423: 0x13e, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba, - 0x428: 0x13f, 0x429: 0x140, 0x42a: 0x141, 0x42b: 0x142, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, - 0x430: 0x143, 0x431: 0x144, 0x432: 0x145, 0x433: 0xba, 0x434: 0x146, 0x435: 0x147, 0x436: 0xba, 0x437: 0xba, - 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba, - // Block 0x11, offset 0x440 - 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, - 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x148, 0x44f: 0xba, - 0x450: 0x9b, 0x451: 0x149, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x14a, 0x456: 0xba, 0x457: 0xba, - 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, - 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, - 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, - 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, - 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, - // Block 0x12, offset 0x480 - 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, - 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, - 0x490: 0x14b, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, - 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, - 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, - 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, - 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, - 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, - // Block 0x13, offset 0x4c0 - 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, - 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, - 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, - 0x4d8: 0x9f, 0x4d9: 0x14c, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, - 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, - 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, - 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, - 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, - // Block 0x14, offset 0x500 - 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, - 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, - 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, - 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, - 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, - 0x528: 0x142, 0x529: 0x14d, 0x52a: 0xba, 0x52b: 0x14e, 0x52c: 0x14f, 0x52d: 0x150, 0x52e: 0x151, 0x52f: 0xba, - 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, - 0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x152, 0x53e: 0x153, 0x53f: 0x154, - // Block 0x15, offset 0x540 - 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, - 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, - 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, - 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x155, - 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, - 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x156, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, - 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, - 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, - // Block 0x16, offset 0x580 - 0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x157, 0x585: 0x158, 0x586: 0x9f, 0x587: 0x9f, - 0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x159, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, - 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, - 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, - 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, - 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, - 0x5b0: 0x9f, 0x5b1: 0x15a, 0x5b2: 0x15b, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, - 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, - // Block 0x17, offset 0x5c0 - 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x15c, 0x5c4: 0x15d, 0x5c5: 0x15e, 0x5c6: 0x15f, 0x5c7: 0x160, - 0x5c8: 0x9b, 0x5c9: 0x161, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x162, 0x5ce: 0xba, 0x5cf: 0xba, - 0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66, - 0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e, - 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, - 0x5e8: 0x163, 0x5e9: 0x164, 0x5ea: 0x165, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, - 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, - 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, - // Block 0x18, offset 0x600 - 0x600: 0x166, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba, - 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, - 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, - 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, - 0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x167, 0x624: 0x6f, 0x625: 0x168, 0x626: 0xba, 0x627: 0xba, - 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, - 0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, - 0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x169, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, - // Block 0x19, offset 0x640 - 0x640: 0x16a, 0x641: 0x9b, 0x642: 0x16b, 0x643: 0x16c, 0x644: 0x73, 0x645: 0x74, 0x646: 0x16d, 0x647: 0x16e, - 0x648: 0x75, 0x649: 0x16f, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, - 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, - 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x170, 0x65c: 0x9b, 0x65d: 0x171, 0x65e: 0x9b, 0x65f: 0x172, - 0x660: 0x173, 0x661: 0x174, 0x662: 0x175, 0x663: 0xba, 0x664: 0x176, 0x665: 0x177, 0x666: 0x178, 0x667: 0x179, - 0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, - 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, - 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, - // Block 0x1a, offset 0x680 - 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, - 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, - 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, - 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x17a, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, - 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, - 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, - 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, - 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, - // Block 0x1b, offset 0x6c0 - 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, - 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, - 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, - 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x17b, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, - 0x6e0: 0x17c, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, - 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, - 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, - 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, - // Block 0x1c, offset 0x700 - 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, - 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, - 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, - 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, - 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, - 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, - 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, - 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x17d, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f, - // Block 0x1d, offset 0x740 - 0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f, - 0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f, - 0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f, - 0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f, - 0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f, - 0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x17e, - 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, - 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, - // Block 0x1e, offset 0x780 - 0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba, - 0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba, - 0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba, - 0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba, - 0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x17f, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x180, 0x7a7: 0x7b, - 0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba, - 0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba, - 0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba, - // Block 0x1f, offset 0x7c0 - 0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07, - 0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17, - 0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07, - 0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c, - 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, - 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, - // Block 0x20, offset 0x800 - 0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b, - 0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b, - 0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b, - 0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b, - 0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b, - 0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b, - 0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b, - 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b, - // Block 0x21, offset 0x840 - 0x840: 0x181, 0x841: 0x182, 0x842: 0xba, 0x843: 0xba, 0x844: 0x183, 0x845: 0x183, 0x846: 0x183, 0x847: 0x184, - 0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba, - 0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba, - 0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba, - 0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba, - 0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba, - 0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba, - 0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba, - // Block 0x22, offset 0x880 - 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, - 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, - 0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b, - 0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b, - 0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b, - 0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b, - 0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b, - 0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b, - // Block 0x23, offset 0x8c0 - 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b, - 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b, -} - -// idnaSparseOffset: 264 entries, 528 bytes -var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x8a, 0x93, 0xa3, 0xb1, 0xbd, 0xc9, 0xda, 0xe4, 0xeb, 0xf8, 0x109, 0x110, 0x11b, 0x12a, 0x138, 0x142, 0x144, 0x149, 0x14c, 0x14f, 0x151, 0x15d, 0x168, 0x170, 0x176, 0x17c, 0x181, 0x186, 0x189, 0x18d, 0x193, 0x198, 0x1a4, 0x1ae, 0x1b4, 0x1c5, 0x1cf, 0x1d2, 0x1da, 0x1dd, 0x1ea, 0x1f2, 0x1f6, 0x1fd, 0x205, 0x215, 0x221, 0x223, 0x22d, 0x239, 0x245, 0x251, 0x259, 0x25e, 0x268, 0x279, 0x27d, 0x288, 0x28c, 0x295, 0x29d, 0x2a3, 0x2a8, 0x2ab, 0x2af, 0x2b5, 0x2b9, 0x2bd, 0x2c3, 0x2ca, 0x2d0, 0x2d8, 0x2df, 0x2ea, 0x2f4, 0x2f8, 0x2fb, 0x301, 0x305, 0x307, 0x30a, 0x30c, 0x30f, 0x319, 0x31c, 0x32b, 0x32f, 0x334, 0x337, 0x33b, 0x340, 0x345, 0x34b, 0x351, 0x360, 0x366, 0x36a, 0x379, 0x37e, 0x386, 0x390, 0x39b, 0x3a3, 0x3b4, 0x3bd, 0x3cd, 0x3da, 0x3e4, 0x3e9, 0x3f6, 0x3fa, 0x3ff, 0x401, 0x405, 0x407, 0x40b, 0x414, 0x41a, 0x41e, 0x42e, 0x438, 0x43d, 0x440, 0x446, 0x44d, 0x452, 0x456, 0x45c, 0x461, 0x46a, 0x46f, 0x475, 0x47c, 0x483, 0x48a, 0x48e, 0x493, 0x496, 0x49b, 0x4a7, 0x4ad, 0x4b2, 0x4b9, 0x4c1, 0x4c6, 0x4ca, 0x4da, 0x4e1, 0x4e5, 0x4e9, 0x4f0, 0x4f2, 0x4f5, 0x4f8, 0x4fc, 0x500, 0x506, 0x50f, 0x51b, 0x522, 0x52b, 0x533, 0x53a, 0x548, 0x555, 0x562, 0x56b, 0x56f, 0x57d, 0x585, 0x590, 0x599, 0x59f, 0x5a7, 0x5b0, 0x5ba, 0x5bd, 0x5c9, 0x5cc, 0x5d1, 0x5de, 0x5e7, 0x5f3, 0x5f6, 0x600, 0x609, 0x615, 0x622, 0x62a, 0x62d, 0x632, 0x635, 0x638, 0x63b, 0x642, 0x649, 0x64d, 0x658, 0x65b, 0x661, 0x666, 0x66a, 0x66d, 0x670, 0x673, 0x676, 0x679, 0x67e, 0x688, 0x68b, 0x68f, 0x69e, 0x6aa, 0x6ae, 0x6b3, 0x6b8, 0x6bc, 0x6c1, 0x6ca, 0x6d5, 0x6db, 0x6e3, 0x6e7, 0x6eb, 0x6f1, 0x6f7, 0x6fc, 0x6ff, 0x70f, 0x716, 0x719, 0x71c, 0x720, 0x726, 0x72b, 0x730, 0x735, 0x738, 0x73d, 0x740, 0x743, 0x747, 0x74b, 0x74e, 0x75e, 0x76f, 0x774, 0x776, 0x778} - -// idnaSparseValues: 1915 entries, 7660 bytes -var idnaSparseValues = [1915]valueRange{ - // Block 0x0, offset 0x0 - {value: 0x0000, lo: 0x07}, - {value: 0xe105, lo: 0x80, hi: 0x96}, - {value: 0x0018, lo: 0x97, hi: 0x97}, - {value: 0xe105, lo: 0x98, hi: 0x9e}, - {value: 0x001f, lo: 0x9f, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xb6}, - {value: 0x0018, lo: 0xb7, hi: 0xb7}, - {value: 0x0008, lo: 0xb8, hi: 0xbf}, - // Block 0x1, offset 0x8 - {value: 0x0000, lo: 0x10}, - {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0xe01d, lo: 0x81, hi: 0x81}, - {value: 0x0008, lo: 0x82, hi: 0x82}, - {value: 0x0335, lo: 0x83, hi: 0x83}, - {value: 0x034d, lo: 0x84, hi: 0x84}, - {value: 0x0365, lo: 0x85, hi: 0x85}, - {value: 0xe00d, lo: 0x86, hi: 0x86}, - {value: 0x0008, lo: 0x87, hi: 0x87}, - {value: 0xe00d, lo: 0x88, hi: 0x88}, - {value: 0x0008, lo: 0x89, hi: 0x89}, - {value: 0xe00d, lo: 0x8a, hi: 0x8a}, - {value: 0x0008, lo: 0x8b, hi: 0x8b}, - {value: 0xe00d, lo: 0x8c, hi: 0x8c}, - {value: 0x0008, lo: 0x8d, hi: 0x8d}, - {value: 0xe00d, lo: 0x8e, hi: 0x8e}, - {value: 0x0008, lo: 0x8f, hi: 0xbf}, - // Block 0x2, offset 0x19 - {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x0249, lo: 0xb0, hi: 0xb0}, - {value: 0x037d, lo: 0xb1, hi: 0xb1}, - {value: 0x0259, lo: 0xb2, hi: 0xb2}, - {value: 0x0269, lo: 0xb3, hi: 0xb3}, - {value: 0x034d, lo: 0xb4, hi: 0xb4}, - {value: 0x0395, lo: 0xb5, hi: 0xb5}, - {value: 0xe1bd, lo: 0xb6, hi: 0xb6}, - {value: 0x0279, lo: 0xb7, hi: 0xb7}, - {value: 0x0289, lo: 0xb8, hi: 0xb8}, - {value: 0x0008, lo: 0xb9, hi: 0xbf}, - // Block 0x3, offset 0x25 - {value: 0x0000, lo: 0x01}, - {value: 0x3308, lo: 0x80, hi: 0xbf}, - // Block 0x4, offset 0x27 - {value: 0x0000, lo: 0x04}, - {value: 0x03f5, lo: 0x80, hi: 0x8f}, - {value: 0xe105, lo: 0x90, hi: 0x9f}, - {value: 0x049d, lo: 0xa0, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x5, offset 0x2c - {value: 0x0000, lo: 0x07}, - {value: 0xe185, lo: 0x80, hi: 0x8f}, - {value: 0x0545, lo: 0x90, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x98}, - {value: 0x0008, lo: 0x99, hi: 0x99}, - {value: 0x0018, lo: 0x9a, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xa0}, - {value: 0x0008, lo: 0xa1, hi: 0xbf}, - // Block 0x6, offset 0x34 - {value: 0x0000, lo: 0x0a}, - {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x0401, lo: 0x87, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x88}, - {value: 0x0018, lo: 0x89, hi: 0x8a}, - {value: 0x0040, lo: 0x8b, hi: 0x8c}, - {value: 0x0018, lo: 0x8d, hi: 0x8f}, - {value: 0x0040, lo: 0x90, hi: 0x90}, - {value: 0x3308, lo: 0x91, hi: 0xbd}, - {value: 0x0818, lo: 0xbe, hi: 0xbe}, - {value: 0x3308, lo: 0xbf, hi: 0xbf}, - // Block 0x7, offset 0x3f - {value: 0x0000, lo: 0x0b}, - {value: 0x0818, lo: 0x80, hi: 0x80}, - {value: 0x3308, lo: 0x81, hi: 0x82}, - {value: 0x0818, lo: 0x83, hi: 0x83}, - {value: 0x3308, lo: 0x84, hi: 0x85}, - {value: 0x0818, lo: 0x86, hi: 0x86}, - {value: 0x3308, lo: 0x87, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0808, lo: 0x90, hi: 0xaa}, - {value: 0x0040, lo: 0xab, hi: 0xaf}, - {value: 0x0808, lo: 0xb0, hi: 0xb4}, - {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0x8, offset 0x4b - {value: 0x0000, lo: 0x03}, - {value: 0x0a08, lo: 0x80, hi: 0x87}, - {value: 0x0c08, lo: 0x88, hi: 0x99}, - {value: 0x0a08, lo: 0x9a, hi: 0xbf}, - // Block 0x9, offset 0x4f - {value: 0x0000, lo: 0x0e}, - {value: 0x3308, lo: 0x80, hi: 0x8a}, - {value: 0x0040, lo: 0x8b, hi: 0x8c}, - {value: 0x0c08, lo: 0x8d, hi: 0x8d}, - {value: 0x0a08, lo: 0x8e, hi: 0x98}, - {value: 0x0c08, lo: 0x99, hi: 0x9b}, - {value: 0x0a08, lo: 0x9c, hi: 0xaa}, - {value: 0x0c08, lo: 0xab, hi: 0xac}, - {value: 0x0a08, lo: 0xad, hi: 0xb0}, - {value: 0x0c08, lo: 0xb1, hi: 0xb1}, - {value: 0x0a08, lo: 0xb2, hi: 0xb2}, - {value: 0x0c08, lo: 0xb3, hi: 0xb4}, - {value: 0x0a08, lo: 0xb5, hi: 0xb7}, - {value: 0x0c08, lo: 0xb8, hi: 0xb9}, - {value: 0x0a08, lo: 0xba, hi: 0xbf}, - // Block 0xa, offset 0x5e - {value: 0x0000, lo: 0x04}, - {value: 0x0808, lo: 0x80, hi: 0xa5}, - {value: 0x3308, lo: 0xa6, hi: 0xb0}, - {value: 0x0808, lo: 0xb1, hi: 0xb1}, - {value: 0x0040, lo: 0xb2, hi: 0xbf}, - // Block 0xb, offset 0x63 - {value: 0x0000, lo: 0x07}, - {value: 0x0808, lo: 0x80, hi: 0x89}, - {value: 0x0a08, lo: 0x8a, hi: 0xaa}, - {value: 0x3308, lo: 0xab, hi: 0xb3}, - {value: 0x0808, lo: 0xb4, hi: 0xb5}, - {value: 0x0018, lo: 0xb6, hi: 0xb9}, - {value: 0x0818, lo: 0xba, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbf}, - // Block 0xc, offset 0x6b - {value: 0x0000, lo: 0x0b}, - {value: 0x0808, lo: 0x80, hi: 0x95}, - {value: 0x3308, lo: 0x96, hi: 0x99}, - {value: 0x0808, lo: 0x9a, hi: 0x9a}, - {value: 0x3308, lo: 0x9b, hi: 0xa3}, - {value: 0x0808, lo: 0xa4, hi: 0xa4}, - {value: 0x3308, lo: 0xa5, hi: 0xa7}, - {value: 0x0808, lo: 0xa8, hi: 0xa8}, - {value: 0x3308, lo: 0xa9, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x0818, lo: 0xb0, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xd, offset 0x77 - {value: 0x0000, lo: 0x0d}, - {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x0a08, lo: 0xa0, hi: 0xa9}, - {value: 0x0c08, lo: 0xaa, hi: 0xac}, - {value: 0x0808, lo: 0xad, hi: 0xad}, - {value: 0x0c08, lo: 0xae, hi: 0xae}, - {value: 0x0a08, lo: 0xaf, hi: 0xb0}, - {value: 0x0c08, lo: 0xb1, hi: 0xb2}, - {value: 0x0a08, lo: 0xb3, hi: 0xb4}, - {value: 0x0040, lo: 0xb5, hi: 0xb5}, - {value: 0x0a08, lo: 0xb6, hi: 0xb8}, - {value: 0x0c08, lo: 0xb9, hi: 0xb9}, - {value: 0x0a08, lo: 0xba, hi: 0xbd}, - {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0xe, offset 0x85 - {value: 0x0000, lo: 0x04}, - {value: 0x0040, lo: 0x80, hi: 0x93}, - {value: 0x3308, lo: 0x94, hi: 0xa1}, - {value: 0x0840, lo: 0xa2, hi: 0xa2}, - {value: 0x3308, lo: 0xa3, hi: 0xbf}, - // Block 0xf, offset 0x8a - {value: 0x0000, lo: 0x08}, - {value: 0x3308, lo: 0x80, hi: 0x82}, - {value: 0x3008, lo: 0x83, hi: 0x83}, - {value: 0x0008, lo: 0x84, hi: 0xb9}, - {value: 0x3308, lo: 0xba, hi: 0xba}, - {value: 0x3008, lo: 0xbb, hi: 0xbb}, - {value: 0x3308, lo: 0xbc, hi: 0xbc}, - {value: 0x0008, lo: 0xbd, hi: 0xbd}, - {value: 0x3008, lo: 0xbe, hi: 0xbf}, - // Block 0x10, offset 0x93 - {value: 0x0000, lo: 0x0f}, - {value: 0x3308, lo: 0x80, hi: 0x80}, - {value: 0x3008, lo: 0x81, hi: 0x82}, - {value: 0x0040, lo: 0x83, hi: 0x85}, - {value: 0x3008, lo: 0x86, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x3008, lo: 0x8a, hi: 0x8c}, - {value: 0x3b08, lo: 0x8d, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x90}, - {value: 0x0040, lo: 0x91, hi: 0x96}, - {value: 0x3008, lo: 0x97, hi: 0x97}, - {value: 0x0040, lo: 0x98, hi: 0xa5}, - {value: 0x0008, lo: 0xa6, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbf}, - // Block 0x11, offset 0xa3 - {value: 0x0000, lo: 0x0d}, - {value: 0x3308, lo: 0x80, hi: 0x80}, - {value: 0x3008, lo: 0x81, hi: 0x83}, - {value: 0x0040, lo: 0x84, hi: 0x84}, - {value: 0x0008, lo: 0x85, hi: 0x8c}, - {value: 0x0040, lo: 0x8d, hi: 0x8d}, - {value: 0x0008, lo: 0x8e, hi: 0x90}, - {value: 0x0040, lo: 0x91, hi: 0x91}, - {value: 0x0008, lo: 0x92, hi: 0xa8}, - {value: 0x0040, lo: 0xa9, hi: 0xa9}, - {value: 0x0008, lo: 0xaa, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbc}, - {value: 0x0008, lo: 0xbd, hi: 0xbd}, - {value: 0x3308, lo: 0xbe, hi: 0xbf}, - // Block 0x12, offset 0xb1 - {value: 0x0000, lo: 0x0b}, - {value: 0x3308, lo: 0x80, hi: 0x81}, - {value: 0x3008, lo: 0x82, hi: 0x83}, - {value: 0x0040, lo: 0x84, hi: 0x84}, - {value: 0x0008, lo: 0x85, hi: 0x8c}, - {value: 0x0040, lo: 0x8d, hi: 0x8d}, - {value: 0x0008, lo: 0x8e, hi: 0x90}, - {value: 0x0040, lo: 0x91, hi: 0x91}, - {value: 0x0008, lo: 0x92, hi: 0xba}, - {value: 0x3b08, lo: 0xbb, hi: 0xbc}, - {value: 0x0008, lo: 0xbd, hi: 0xbd}, - {value: 0x3008, lo: 0xbe, hi: 0xbf}, - // Block 0x13, offset 0xbd - {value: 0x0000, lo: 0x0b}, - {value: 0x0040, lo: 0x80, hi: 0x81}, - {value: 0x3008, lo: 0x82, hi: 0x83}, - {value: 0x0040, lo: 0x84, hi: 0x84}, - {value: 0x0008, lo: 0x85, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x99}, - {value: 0x0008, lo: 0x9a, hi: 0xb1}, - {value: 0x0040, lo: 0xb2, hi: 0xb2}, - {value: 0x0008, lo: 0xb3, hi: 0xbb}, - {value: 0x0040, lo: 0xbc, hi: 0xbc}, - {value: 0x0008, lo: 0xbd, hi: 0xbd}, - {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x14, offset 0xc9 - {value: 0x0000, lo: 0x10}, - {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x89}, - {value: 0x3b08, lo: 0x8a, hi: 0x8a}, - {value: 0x0040, lo: 0x8b, hi: 0x8e}, - {value: 0x3008, lo: 0x8f, hi: 0x91}, - {value: 0x3308, lo: 0x92, hi: 0x94}, - {value: 0x0040, lo: 0x95, hi: 0x95}, - {value: 0x3308, lo: 0x96, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x97}, - {value: 0x3008, lo: 0x98, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xa5}, - {value: 0x0008, lo: 0xa6, hi: 0xaf}, - {value: 0x0040, lo: 0xb0, hi: 0xb1}, - {value: 0x3008, lo: 0xb2, hi: 0xb3}, - {value: 0x0018, lo: 0xb4, hi: 0xb4}, - {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0x15, offset 0xda - {value: 0x0000, lo: 0x09}, - {value: 0x0040, lo: 0x80, hi: 0x80}, - {value: 0x0008, lo: 0x81, hi: 0xb0}, - {value: 0x3308, lo: 0xb1, hi: 0xb1}, - {value: 0x0008, lo: 0xb2, hi: 0xb2}, - {value: 0x08f1, lo: 0xb3, hi: 0xb3}, - {value: 0x3308, lo: 0xb4, hi: 0xb9}, - {value: 0x3b08, lo: 0xba, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbe}, - {value: 0x0018, lo: 0xbf, hi: 0xbf}, - // Block 0x16, offset 0xe4 - {value: 0x0000, lo: 0x06}, - {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x3308, lo: 0x87, hi: 0x8e}, - {value: 0x0018, lo: 0x8f, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0018, lo: 0x9a, hi: 0x9b}, - {value: 0x0040, lo: 0x9c, hi: 0xbf}, - // Block 0x17, offset 0xeb - {value: 0x0000, lo: 0x0c}, - {value: 0x0008, lo: 0x80, hi: 0x84}, - {value: 0x0040, lo: 0x85, hi: 0x85}, - {value: 0x0008, lo: 0x86, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x87}, - {value: 0x3308, lo: 0x88, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9b}, - {value: 0x0961, lo: 0x9c, hi: 0x9c}, - {value: 0x0999, lo: 0x9d, hi: 0x9d}, - {value: 0x0008, lo: 0x9e, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0x18, offset 0xf8 - {value: 0x0000, lo: 0x10}, - {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0x0018, lo: 0x81, hi: 0x8a}, - {value: 0x0008, lo: 0x8b, hi: 0x8b}, - {value: 0xe03d, lo: 0x8c, hi: 0x8c}, - {value: 0x0018, lo: 0x8d, hi: 0x97}, - {value: 0x3308, lo: 0x98, hi: 0x99}, - {value: 0x0018, lo: 0x9a, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa9}, - {value: 0x0018, lo: 0xaa, hi: 0xb4}, - {value: 0x3308, lo: 0xb5, hi: 0xb5}, - {value: 0x0018, lo: 0xb6, hi: 0xb6}, - {value: 0x3308, lo: 0xb7, hi: 0xb7}, - {value: 0x0018, lo: 0xb8, hi: 0xb8}, - {value: 0x3308, lo: 0xb9, hi: 0xb9}, - {value: 0x0018, lo: 0xba, hi: 0xbd}, - {value: 0x3008, lo: 0xbe, hi: 0xbf}, - // Block 0x19, offset 0x109 - {value: 0x0000, lo: 0x06}, - {value: 0x0018, lo: 0x80, hi: 0x85}, - {value: 0x3308, lo: 0x86, hi: 0x86}, - {value: 0x0018, lo: 0x87, hi: 0x8c}, - {value: 0x0040, lo: 0x8d, hi: 0x8d}, - {value: 0x0018, lo: 0x8e, hi: 0x9a}, - {value: 0x0040, lo: 0x9b, hi: 0xbf}, - // Block 0x1a, offset 0x110 - {value: 0x0000, lo: 0x0a}, - {value: 0x0008, lo: 0x80, hi: 0xaa}, - {value: 0x3008, lo: 0xab, hi: 0xac}, - {value: 0x3308, lo: 0xad, hi: 0xb0}, - {value: 0x3008, lo: 0xb1, hi: 0xb1}, - {value: 0x3308, lo: 0xb2, hi: 0xb7}, - {value: 0x3008, lo: 0xb8, hi: 0xb8}, - {value: 0x3b08, lo: 0xb9, hi: 0xba}, - {value: 0x3008, lo: 0xbb, hi: 0xbc}, - {value: 0x3308, lo: 0xbd, hi: 0xbe}, - {value: 0x0008, lo: 0xbf, hi: 0xbf}, - // Block 0x1b, offset 0x11b - {value: 0x0000, lo: 0x0e}, - {value: 0x0008, lo: 0x80, hi: 0x89}, - {value: 0x0018, lo: 0x8a, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x95}, - {value: 0x3008, lo: 0x96, hi: 0x97}, - {value: 0x3308, lo: 0x98, hi: 0x99}, - {value: 0x0008, lo: 0x9a, hi: 0x9d}, - {value: 0x3308, lo: 0x9e, hi: 0xa0}, - {value: 0x0008, lo: 0xa1, hi: 0xa1}, - {value: 0x3008, lo: 0xa2, hi: 0xa4}, - {value: 0x0008, lo: 0xa5, hi: 0xa6}, - {value: 0x3008, lo: 0xa7, hi: 0xad}, - {value: 0x0008, lo: 0xae, hi: 0xb0}, - {value: 0x3308, lo: 0xb1, hi: 0xb4}, - {value: 0x0008, lo: 0xb5, hi: 0xbf}, - // Block 0x1c, offset 0x12a - {value: 0x0000, lo: 0x0d}, - {value: 0x0008, lo: 0x80, hi: 0x81}, - {value: 0x3308, lo: 0x82, hi: 0x82}, - {value: 0x3008, lo: 0x83, hi: 0x84}, - {value: 0x3308, lo: 0x85, hi: 0x86}, - {value: 0x3008, lo: 0x87, hi: 0x8c}, - {value: 0x3308, lo: 0x8d, hi: 0x8d}, - {value: 0x0008, lo: 0x8e, hi: 0x8e}, - {value: 0x3008, lo: 0x8f, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x3008, lo: 0x9a, hi: 0x9c}, - {value: 0x3308, lo: 0x9d, hi: 0x9d}, - {value: 0x0018, lo: 0x9e, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0x1d, offset 0x138 - {value: 0x0000, lo: 0x09}, - {value: 0x0040, lo: 0x80, hi: 0x86}, - {value: 0x055d, lo: 0x87, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8c}, - {value: 0x055d, lo: 0x8d, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xba}, - {value: 0x0018, lo: 0xbb, hi: 0xbb}, - {value: 0xe105, lo: 0xbc, hi: 0xbc}, - {value: 0x0008, lo: 0xbd, hi: 0xbf}, - // Block 0x1e, offset 0x142 - {value: 0x0000, lo: 0x01}, - {value: 0x0018, lo: 0x80, hi: 0xbf}, - // Block 0x1f, offset 0x144 - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0xa0}, - {value: 0x2018, lo: 0xa1, hi: 0xb5}, - {value: 0x0018, lo: 0xb6, hi: 0xbf}, - // Block 0x20, offset 0x149 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0xa7}, - {value: 0x2018, lo: 0xa8, hi: 0xbf}, - // Block 0x21, offset 0x14c - {value: 0x0000, lo: 0x02}, - {value: 0x2018, lo: 0x80, hi: 0x82}, - {value: 0x0018, lo: 0x83, hi: 0xbf}, - // Block 0x22, offset 0x14f - {value: 0x0000, lo: 0x01}, - {value: 0x0008, lo: 0x80, hi: 0xbf}, - // Block 0x23, offset 0x151 - {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x0008, lo: 0x8a, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x97}, - {value: 0x0008, lo: 0x98, hi: 0x98}, - {value: 0x0040, lo: 0x99, hi: 0x99}, - {value: 0x0008, lo: 0x9a, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x24, offset 0x15d - {value: 0x0000, lo: 0x0a}, - {value: 0x0008, lo: 0x80, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x0008, lo: 0x8a, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xb0}, - {value: 0x0040, lo: 0xb1, hi: 0xb1}, - {value: 0x0008, lo: 0xb2, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xb7}, - {value: 0x0008, lo: 0xb8, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x25, offset 0x168 - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0x0040, lo: 0x81, hi: 0x81}, - {value: 0x0008, lo: 0x82, hi: 0x85}, - {value: 0x0040, lo: 0x86, hi: 0x87}, - {value: 0x0008, lo: 0x88, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x97}, - {value: 0x0008, lo: 0x98, hi: 0xbf}, - // Block 0x26, offset 0x170 - {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0x90}, - {value: 0x0040, lo: 0x91, hi: 0x91}, - {value: 0x0008, lo: 0x92, hi: 0x95}, - {value: 0x0040, lo: 0x96, hi: 0x97}, - {value: 0x0008, lo: 0x98, hi: 0xbf}, - // Block 0x27, offset 0x176 - {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0x9a}, - {value: 0x0040, lo: 0x9b, hi: 0x9c}, - {value: 0x3308, lo: 0x9d, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xbc}, - {value: 0x0040, lo: 0xbd, hi: 0xbf}, - // Block 0x28, offset 0x17c - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x29, offset 0x181 - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xb7}, - {value: 0xe045, lo: 0xb8, hi: 0xbd}, - {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x2a, offset 0x186 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0x80}, - {value: 0x0008, lo: 0x81, hi: 0xbf}, - // Block 0x2b, offset 0x189 - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xac}, - {value: 0x0018, lo: 0xad, hi: 0xae}, - {value: 0x0008, lo: 0xaf, hi: 0xbf}, - // Block 0x2c, offset 0x18d - {value: 0x0000, lo: 0x05}, - {value: 0x0040, lo: 0x80, hi: 0x80}, - {value: 0x0008, lo: 0x81, hi: 0x9a}, - {value: 0x0018, lo: 0x9b, hi: 0x9c}, - {value: 0x0040, lo: 0x9d, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x2d, offset 0x193 - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0xaa}, - {value: 0x0018, lo: 0xab, hi: 0xb0}, - {value: 0x0008, lo: 0xb1, hi: 0xb8}, - {value: 0x0040, lo: 0xb9, hi: 0xbf}, - // Block 0x2e, offset 0x198 - {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0x8c}, - {value: 0x0040, lo: 0x8d, hi: 0x8d}, - {value: 0x0008, lo: 0x8e, hi: 0x91}, - {value: 0x3308, lo: 0x92, hi: 0x93}, - {value: 0x3b08, lo: 0x94, hi: 0x94}, - {value: 0x0040, lo: 0x95, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xb1}, - {value: 0x3308, lo: 0xb2, hi: 0xb3}, - {value: 0x3b08, lo: 0xb4, hi: 0xb4}, - {value: 0x0018, lo: 0xb5, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0x2f, offset 0x1a4 - {value: 0x0000, lo: 0x09}, - {value: 0x0008, lo: 0x80, hi: 0x91}, - {value: 0x3308, lo: 0x92, hi: 0x93}, - {value: 0x0040, lo: 0x94, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xac}, - {value: 0x0040, lo: 0xad, hi: 0xad}, - {value: 0x0008, lo: 0xae, hi: 0xb0}, - {value: 0x0040, lo: 0xb1, hi: 0xb1}, - {value: 0x3308, lo: 0xb2, hi: 0xb3}, - {value: 0x0040, lo: 0xb4, hi: 0xbf}, - // Block 0x30, offset 0x1ae - {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0xb3}, - {value: 0x3340, lo: 0xb4, hi: 0xb5}, - {value: 0x3008, lo: 0xb6, hi: 0xb6}, - {value: 0x3308, lo: 0xb7, hi: 0xbd}, - {value: 0x3008, lo: 0xbe, hi: 0xbf}, - // Block 0x31, offset 0x1b4 - {value: 0x0000, lo: 0x10}, - {value: 0x3008, lo: 0x80, hi: 0x85}, - {value: 0x3308, lo: 0x86, hi: 0x86}, - {value: 0x3008, lo: 0x87, hi: 0x88}, - {value: 0x3308, lo: 0x89, hi: 0x91}, - {value: 0x3b08, lo: 0x92, hi: 0x92}, - {value: 0x3308, lo: 0x93, hi: 0x93}, - {value: 0x0018, lo: 0x94, hi: 0x96}, - {value: 0x0008, lo: 0x97, hi: 0x97}, - {value: 0x0018, lo: 0x98, hi: 0x9b}, - {value: 0x0008, lo: 0x9c, hi: 0x9c}, - {value: 0x3308, lo: 0x9d, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa9}, - {value: 0x0040, lo: 0xaa, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0x32, offset 0x1c5 - {value: 0x0000, lo: 0x09}, - {value: 0x0018, lo: 0x80, hi: 0x85}, - {value: 0x0040, lo: 0x86, hi: 0x86}, - {value: 0x0218, lo: 0x87, hi: 0x87}, - {value: 0x0018, lo: 0x88, hi: 0x8a}, - {value: 0x33c0, lo: 0x8b, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9f}, - {value: 0x0208, lo: 0xa0, hi: 0xbf}, - // Block 0x33, offset 0x1cf - {value: 0x0000, lo: 0x02}, - {value: 0x0208, lo: 0x80, hi: 0xb7}, - {value: 0x0040, lo: 0xb8, hi: 0xbf}, - // Block 0x34, offset 0x1d2 - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0x84}, - {value: 0x3308, lo: 0x85, hi: 0x86}, - {value: 0x0208, lo: 0x87, hi: 0xa8}, - {value: 0x3308, lo: 0xa9, hi: 0xa9}, - {value: 0x0208, lo: 0xaa, hi: 0xaa}, - {value: 0x0040, lo: 0xab, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x35, offset 0x1da - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xbf}, - // Block 0x36, offset 0x1dd - {value: 0x0000, lo: 0x0c}, - {value: 0x0008, lo: 0x80, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x3308, lo: 0xa0, hi: 0xa2}, - {value: 0x3008, lo: 0xa3, hi: 0xa6}, - {value: 0x3308, lo: 0xa7, hi: 0xa8}, - {value: 0x3008, lo: 0xa9, hi: 0xab}, - {value: 0x0040, lo: 0xac, hi: 0xaf}, - {value: 0x3008, lo: 0xb0, hi: 0xb1}, - {value: 0x3308, lo: 0xb2, hi: 0xb2}, - {value: 0x3008, lo: 0xb3, hi: 0xb8}, - {value: 0x3308, lo: 0xb9, hi: 0xbb}, - {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0x37, offset 0x1ea - {value: 0x0000, lo: 0x07}, - {value: 0x0018, lo: 0x80, hi: 0x80}, - {value: 0x0040, lo: 0x81, hi: 0x83}, - {value: 0x0018, lo: 0x84, hi: 0x85}, - {value: 0x0008, lo: 0x86, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xb4}, - {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0x38, offset 0x1f2 - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xab}, - {value: 0x0040, lo: 0xac, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x39, offset 0x1f6 - {value: 0x0000, lo: 0x06}, - {value: 0x0008, lo: 0x80, hi: 0x89}, - {value: 0x0040, lo: 0x8a, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0028, lo: 0x9a, hi: 0x9a}, - {value: 0x0040, lo: 0x9b, hi: 0x9d}, - {value: 0x0018, lo: 0x9e, hi: 0xbf}, - // Block 0x3a, offset 0x1fd - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0x96}, - {value: 0x3308, lo: 0x97, hi: 0x98}, - {value: 0x3008, lo: 0x99, hi: 0x9a}, - {value: 0x3308, lo: 0x9b, hi: 0x9b}, - {value: 0x0040, lo: 0x9c, hi: 0x9d}, - {value: 0x0018, lo: 0x9e, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x3b, offset 0x205 - {value: 0x0000, lo: 0x0f}, - {value: 0x0008, lo: 0x80, hi: 0x94}, - {value: 0x3008, lo: 0x95, hi: 0x95}, - {value: 0x3308, lo: 0x96, hi: 0x96}, - {value: 0x3008, lo: 0x97, hi: 0x97}, - {value: 0x3308, lo: 0x98, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x3b08, lo: 0xa0, hi: 0xa0}, - {value: 0x3008, lo: 0xa1, hi: 0xa1}, - {value: 0x3308, lo: 0xa2, hi: 0xa2}, - {value: 0x3008, lo: 0xa3, hi: 0xa4}, - {value: 0x3308, lo: 0xa5, hi: 0xac}, - {value: 0x3008, lo: 0xad, hi: 0xb2}, - {value: 0x3308, lo: 0xb3, hi: 0xbc}, - {value: 0x0040, lo: 0xbd, hi: 0xbe}, - {value: 0x3308, lo: 0xbf, hi: 0xbf}, - // Block 0x3c, offset 0x215 - {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0x89}, - {value: 0x0040, lo: 0x8a, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xa6}, - {value: 0x0008, lo: 0xa7, hi: 0xa7}, - {value: 0x0018, lo: 0xa8, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x3308, lo: 0xb0, hi: 0xbd}, - {value: 0x3318, lo: 0xbe, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x3d, offset 0x221 - {value: 0x0000, lo: 0x01}, - {value: 0x0040, lo: 0x80, hi: 0xbf}, - // Block 0x3e, offset 0x223 - {value: 0x0000, lo: 0x09}, - {value: 0x3308, lo: 0x80, hi: 0x83}, - {value: 0x3008, lo: 0x84, hi: 0x84}, - {value: 0x0008, lo: 0x85, hi: 0xb3}, - {value: 0x3308, lo: 0xb4, hi: 0xb4}, - {value: 0x3008, lo: 0xb5, hi: 0xb5}, - {value: 0x3308, lo: 0xb6, hi: 0xba}, - {value: 0x3008, lo: 0xbb, hi: 0xbb}, - {value: 0x3308, lo: 0xbc, hi: 0xbc}, - {value: 0x3008, lo: 0xbd, hi: 0xbf}, - // Block 0x3f, offset 0x22d - {value: 0x0000, lo: 0x0b}, - {value: 0x3008, lo: 0x80, hi: 0x81}, - {value: 0x3308, lo: 0x82, hi: 0x82}, - {value: 0x3008, lo: 0x83, hi: 0x83}, - {value: 0x3808, lo: 0x84, hi: 0x84}, - {value: 0x0008, lo: 0x85, hi: 0x8b}, - {value: 0x0040, lo: 0x8c, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0018, lo: 0x9a, hi: 0xaa}, - {value: 0x3308, lo: 0xab, hi: 0xb3}, - {value: 0x0018, lo: 0xb4, hi: 0xbc}, - {value: 0x0040, lo: 0xbd, hi: 0xbf}, - // Block 0x40, offset 0x239 - {value: 0x0000, lo: 0x0b}, - {value: 0x3308, lo: 0x80, hi: 0x81}, - {value: 0x3008, lo: 0x82, hi: 0x82}, - {value: 0x0008, lo: 0x83, hi: 0xa0}, - {value: 0x3008, lo: 0xa1, hi: 0xa1}, - {value: 0x3308, lo: 0xa2, hi: 0xa5}, - {value: 0x3008, lo: 0xa6, hi: 0xa7}, - {value: 0x3308, lo: 0xa8, hi: 0xa9}, - {value: 0x3808, lo: 0xaa, hi: 0xaa}, - {value: 0x3b08, lo: 0xab, hi: 0xab}, - {value: 0x3308, lo: 0xac, hi: 0xad}, - {value: 0x0008, lo: 0xae, hi: 0xbf}, - // Block 0x41, offset 0x245 - {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0xa5}, - {value: 0x3308, lo: 0xa6, hi: 0xa6}, - {value: 0x3008, lo: 0xa7, hi: 0xa7}, - {value: 0x3308, lo: 0xa8, hi: 0xa9}, - {value: 0x3008, lo: 0xaa, hi: 0xac}, - {value: 0x3308, lo: 0xad, hi: 0xad}, - {value: 0x3008, lo: 0xae, hi: 0xae}, - {value: 0x3308, lo: 0xaf, hi: 0xb1}, - {value: 0x3808, lo: 0xb2, hi: 0xb3}, - {value: 0x0040, lo: 0xb4, hi: 0xbb}, - {value: 0x0018, lo: 0xbc, hi: 0xbf}, - // Block 0x42, offset 0x251 - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0xa3}, - {value: 0x3008, lo: 0xa4, hi: 0xab}, - {value: 0x3308, lo: 0xac, hi: 0xb3}, - {value: 0x3008, lo: 0xb4, hi: 0xb5}, - {value: 0x3308, lo: 0xb6, hi: 0xb7}, - {value: 0x0040, lo: 0xb8, hi: 0xba}, - {value: 0x0018, lo: 0xbb, hi: 0xbf}, - // Block 0x43, offset 0x259 - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0x89}, - {value: 0x0040, lo: 0x8a, hi: 0x8c}, - {value: 0x0008, lo: 0x8d, hi: 0xbd}, - {value: 0x0018, lo: 0xbe, hi: 0xbf}, - // Block 0x44, offset 0x25e - {value: 0x0000, lo: 0x09}, - {value: 0x0e29, lo: 0x80, hi: 0x80}, - {value: 0x0e41, lo: 0x81, hi: 0x81}, - {value: 0x0e59, lo: 0x82, hi: 0x82}, - {value: 0x0e71, lo: 0x83, hi: 0x83}, - {value: 0x0e89, lo: 0x84, hi: 0x85}, - {value: 0x0ea1, lo: 0x86, hi: 0x86}, - {value: 0x0eb9, lo: 0x87, hi: 0x87}, - {value: 0x057d, lo: 0x88, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0xbf}, - // Block 0x45, offset 0x268 - {value: 0x0000, lo: 0x10}, - {value: 0x0018, lo: 0x80, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x3308, lo: 0x90, hi: 0x92}, - {value: 0x0018, lo: 0x93, hi: 0x93}, - {value: 0x3308, lo: 0x94, hi: 0xa0}, - {value: 0x3008, lo: 0xa1, hi: 0xa1}, - {value: 0x3308, lo: 0xa2, hi: 0xa8}, - {value: 0x0008, lo: 0xa9, hi: 0xac}, - {value: 0x3308, lo: 0xad, hi: 0xad}, - {value: 0x0008, lo: 0xae, hi: 0xb1}, - {value: 0x3008, lo: 0xb2, hi: 0xb3}, - {value: 0x3308, lo: 0xb4, hi: 0xb4}, - {value: 0x0008, lo: 0xb5, hi: 0xb6}, - {value: 0x3008, lo: 0xb7, hi: 0xb7}, - {value: 0x3308, lo: 0xb8, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0x46, offset 0x279 - {value: 0x0000, lo: 0x03}, - {value: 0x3308, lo: 0x80, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xba}, - {value: 0x3308, lo: 0xbb, hi: 0xbf}, - // Block 0x47, offset 0x27d - {value: 0x0000, lo: 0x0a}, - {value: 0x0008, lo: 0x80, hi: 0x87}, - {value: 0xe045, lo: 0x88, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x95}, - {value: 0x0040, lo: 0x96, hi: 0x97}, - {value: 0xe045, lo: 0x98, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa7}, - {value: 0xe045, lo: 0xa8, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xb7}, - {value: 0xe045, lo: 0xb8, hi: 0xbf}, - // Block 0x48, offset 0x288 - {value: 0x0000, lo: 0x03}, - {value: 0x0040, lo: 0x80, hi: 0x8f}, - {value: 0x3318, lo: 0x90, hi: 0xb0}, - {value: 0x0040, lo: 0xb1, hi: 0xbf}, - // Block 0x49, offset 0x28c - {value: 0x0000, lo: 0x08}, - {value: 0x0018, lo: 0x80, hi: 0x82}, - {value: 0x0040, lo: 0x83, hi: 0x83}, - {value: 0x0008, lo: 0x84, hi: 0x84}, - {value: 0x0018, lo: 0x85, hi: 0x88}, - {value: 0x24c1, lo: 0x89, hi: 0x89}, - {value: 0x0018, lo: 0x8a, hi: 0x8b}, - {value: 0x0040, lo: 0x8c, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0xbf}, - // Block 0x4a, offset 0x295 - {value: 0x0000, lo: 0x07}, - {value: 0x0018, lo: 0x80, hi: 0xab}, - {value: 0x24f1, lo: 0xac, hi: 0xac}, - {value: 0x2529, lo: 0xad, hi: 0xad}, - {value: 0x0018, lo: 0xae, hi: 0xae}, - {value: 0x2579, lo: 0xaf, hi: 0xaf}, - {value: 0x25b1, lo: 0xb0, hi: 0xb0}, - {value: 0x0018, lo: 0xb1, hi: 0xbf}, - // Block 0x4b, offset 0x29d - {value: 0x0000, lo: 0x05}, - {value: 0x0018, lo: 0x80, hi: 0x9f}, - {value: 0x0080, lo: 0xa0, hi: 0xa0}, - {value: 0x0018, lo: 0xa1, hi: 0xad}, - {value: 0x0080, lo: 0xae, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xbf}, - // Block 0x4c, offset 0x2a3 - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0xa8}, - {value: 0x09c5, lo: 0xa9, hi: 0xa9}, - {value: 0x09e5, lo: 0xaa, hi: 0xaa}, - {value: 0x0018, lo: 0xab, hi: 0xbf}, - // Block 0x4d, offset 0x2a8 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0xa6}, - {value: 0x0040, lo: 0xa7, hi: 0xbf}, - // Block 0x4e, offset 0x2ab - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0x8b}, - {value: 0x28c1, lo: 0x8c, hi: 0x8c}, - {value: 0x0018, lo: 0x8d, hi: 0xbf}, - // Block 0x4f, offset 0x2af - {value: 0x0000, lo: 0x05}, - {value: 0x0018, lo: 0x80, hi: 0xb3}, - {value: 0x0e66, lo: 0xb4, hi: 0xb4}, - {value: 0x292a, lo: 0xb5, hi: 0xb5}, - {value: 0x0e86, lo: 0xb6, hi: 0xb6}, - {value: 0x0018, lo: 0xb7, hi: 0xbf}, - // Block 0x50, offset 0x2b5 - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0x9b}, - {value: 0x2941, lo: 0x9c, hi: 0x9c}, - {value: 0x0018, lo: 0x9d, hi: 0xbf}, - // Block 0x51, offset 0x2b9 - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0xb3}, - {value: 0x0040, lo: 0xb4, hi: 0xb5}, - {value: 0x0018, lo: 0xb6, hi: 0xbf}, - // Block 0x52, offset 0x2bd - {value: 0x0000, lo: 0x05}, - {value: 0x0018, lo: 0x80, hi: 0x95}, - {value: 0x0040, lo: 0x96, hi: 0x97}, - {value: 0x0018, lo: 0x98, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbc}, - {value: 0x0018, lo: 0xbd, hi: 0xbf}, - // Block 0x53, offset 0x2c3 - {value: 0x0000, lo: 0x06}, - {value: 0x0018, lo: 0x80, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x0018, lo: 0x8a, hi: 0x92}, - {value: 0x0040, lo: 0x93, hi: 0xab}, - {value: 0x0018, lo: 0xac, hi: 0xaf}, - {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0x54, offset 0x2ca - {value: 0x0000, lo: 0x05}, - {value: 0xe185, lo: 0x80, hi: 0x8f}, - {value: 0x03f5, lo: 0x90, hi: 0x9f}, - {value: 0x0ea5, lo: 0xa0, hi: 0xae}, - {value: 0x0040, lo: 0xaf, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x55, offset 0x2d0 - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0xa5}, - {value: 0x0040, lo: 0xa6, hi: 0xa6}, - {value: 0x0008, lo: 0xa7, hi: 0xa7}, - {value: 0x0040, lo: 0xa8, hi: 0xac}, - {value: 0x0008, lo: 0xad, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x56, offset 0x2d8 - {value: 0x0000, lo: 0x06}, - {value: 0x0008, lo: 0x80, hi: 0xa7}, - {value: 0x0040, lo: 0xa8, hi: 0xae}, - {value: 0xe075, lo: 0xaf, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb0}, - {value: 0x0040, lo: 0xb1, hi: 0xbe}, - {value: 0x3b08, lo: 0xbf, hi: 0xbf}, - // Block 0x57, offset 0x2df - {value: 0x0000, lo: 0x0a}, - {value: 0x0008, lo: 0x80, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa6}, - {value: 0x0040, lo: 0xa7, hi: 0xa7}, - {value: 0x0008, lo: 0xa8, hi: 0xae}, - {value: 0x0040, lo: 0xaf, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xb7}, - {value: 0x0008, lo: 0xb8, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x58, offset 0x2ea - {value: 0x0000, lo: 0x09}, - {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x87}, - {value: 0x0008, lo: 0x88, hi: 0x8e}, - {value: 0x0040, lo: 0x8f, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x97}, - {value: 0x0008, lo: 0x98, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x3308, lo: 0xa0, hi: 0xbf}, - // Block 0x59, offset 0x2f4 - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0xae}, - {value: 0x0008, lo: 0xaf, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xbf}, - // Block 0x5a, offset 0x2f8 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0x89}, - {value: 0x0040, lo: 0x8a, hi: 0xbf}, - // Block 0x5b, offset 0x2fb - {value: 0x0000, lo: 0x05}, - {value: 0x0018, lo: 0x80, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9a}, - {value: 0x0018, lo: 0x9b, hi: 0x9e}, - {value: 0x0edd, lo: 0x9f, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xbf}, - // Block 0x5c, offset 0x301 - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0xb2}, - {value: 0x0efd, lo: 0xb3, hi: 0xb3}, - {value: 0x0040, lo: 0xb4, hi: 0xbf}, - // Block 0x5d, offset 0x305 - {value: 0x0020, lo: 0x01}, - {value: 0x0f1d, lo: 0x80, hi: 0xbf}, - // Block 0x5e, offset 0x307 - {value: 0x0020, lo: 0x02}, - {value: 0x171d, lo: 0x80, hi: 0x8f}, - {value: 0x18fd, lo: 0x90, hi: 0xbf}, - // Block 0x5f, offset 0x30a - {value: 0x0020, lo: 0x01}, - {value: 0x1efd, lo: 0x80, hi: 0xbf}, - // Block 0x60, offset 0x30c - {value: 0x0000, lo: 0x02}, - {value: 0x0040, lo: 0x80, hi: 0x80}, - {value: 0x0008, lo: 0x81, hi: 0xbf}, - // Block 0x61, offset 0x30f - {value: 0x0000, lo: 0x09}, - {value: 0x0008, lo: 0x80, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x98}, - {value: 0x3308, lo: 0x99, hi: 0x9a}, - {value: 0x29e2, lo: 0x9b, hi: 0x9b}, - {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, - {value: 0x0008, lo: 0x9d, hi: 0x9e}, - {value: 0x2a31, lo: 0x9f, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xa0}, - {value: 0x0008, lo: 0xa1, hi: 0xbf}, - // Block 0x62, offset 0x319 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xbe}, - {value: 0x2a69, lo: 0xbf, hi: 0xbf}, - // Block 0x63, offset 0x31c - {value: 0x0000, lo: 0x0e}, - {value: 0x0040, lo: 0x80, hi: 0x84}, - {value: 0x0008, lo: 0x85, hi: 0xae}, - {value: 0x0040, lo: 0xaf, hi: 0xb0}, - {value: 0x2a1d, lo: 0xb1, hi: 0xb1}, - {value: 0x2a3d, lo: 0xb2, hi: 0xb2}, - {value: 0x2a5d, lo: 0xb3, hi: 0xb3}, - {value: 0x2a7d, lo: 0xb4, hi: 0xb4}, - {value: 0x2a5d, lo: 0xb5, hi: 0xb5}, - {value: 0x2a9d, lo: 0xb6, hi: 0xb6}, - {value: 0x2abd, lo: 0xb7, hi: 0xb7}, - {value: 0x2add, lo: 0xb8, hi: 0xb9}, - {value: 0x2afd, lo: 0xba, hi: 0xbb}, - {value: 0x2b1d, lo: 0xbc, hi: 0xbd}, - {value: 0x2afd, lo: 0xbe, hi: 0xbf}, - // Block 0x64, offset 0x32b - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0xa3}, - {value: 0x0040, lo: 0xa4, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x65, offset 0x32f - {value: 0x0030, lo: 0x04}, - {value: 0x2aa2, lo: 0x80, hi: 0x9d}, - {value: 0x305a, lo: 0x9e, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x30a2, lo: 0xa0, hi: 0xbf}, - // Block 0x66, offset 0x334 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xaa}, - {value: 0x0040, lo: 0xab, hi: 0xbf}, - // Block 0x67, offset 0x337 - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0x8c}, - {value: 0x0040, lo: 0x8d, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0xbf}, - // Block 0x68, offset 0x33b - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xbd}, - {value: 0x0018, lo: 0xbe, hi: 0xbf}, - // Block 0x69, offset 0x340 - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0x8c}, - {value: 0x0018, lo: 0x8d, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xab}, - {value: 0x0040, lo: 0xac, hi: 0xbf}, - // Block 0x6a, offset 0x345 - {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0xa5}, - {value: 0x0018, lo: 0xa6, hi: 0xaf}, - {value: 0x3308, lo: 0xb0, hi: 0xb1}, - {value: 0x0018, lo: 0xb2, hi: 0xb7}, - {value: 0x0040, lo: 0xb8, hi: 0xbf}, - // Block 0x6b, offset 0x34b - {value: 0x0000, lo: 0x05}, - {value: 0x0040, lo: 0x80, hi: 0xb6}, - {value: 0x0008, lo: 0xb7, hi: 0xb7}, - {value: 0x2009, lo: 0xb8, hi: 0xb8}, - {value: 0x6e89, lo: 0xb9, hi: 0xb9}, - {value: 0x0008, lo: 0xba, hi: 0xbf}, - // Block 0x6c, offset 0x351 - {value: 0x0000, lo: 0x0e}, - {value: 0x0008, lo: 0x80, hi: 0x81}, - {value: 0x3308, lo: 0x82, hi: 0x82}, - {value: 0x0008, lo: 0x83, hi: 0x85}, - {value: 0x3b08, lo: 0x86, hi: 0x86}, - {value: 0x0008, lo: 0x87, hi: 0x8a}, - {value: 0x3308, lo: 0x8b, hi: 0x8b}, - {value: 0x0008, lo: 0x8c, hi: 0xa2}, - {value: 0x3008, lo: 0xa3, hi: 0xa4}, - {value: 0x3308, lo: 0xa5, hi: 0xa6}, - {value: 0x3008, lo: 0xa7, hi: 0xa7}, - {value: 0x0018, lo: 0xa8, hi: 0xab}, - {value: 0x0040, lo: 0xac, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0x6d, offset 0x360 - {value: 0x0000, lo: 0x05}, - {value: 0x0208, lo: 0x80, hi: 0xb1}, - {value: 0x0108, lo: 0xb2, hi: 0xb2}, - {value: 0x0008, lo: 0xb3, hi: 0xb3}, - {value: 0x0018, lo: 0xb4, hi: 0xb7}, - {value: 0x0040, lo: 0xb8, hi: 0xbf}, - // Block 0x6e, offset 0x366 - {value: 0x0000, lo: 0x03}, - {value: 0x3008, lo: 0x80, hi: 0x81}, - {value: 0x0008, lo: 0x82, hi: 0xb3}, - {value: 0x3008, lo: 0xb4, hi: 0xbf}, - // Block 0x6f, offset 0x36a - {value: 0x0000, lo: 0x0e}, - {value: 0x3008, lo: 0x80, hi: 0x83}, - {value: 0x3b08, lo: 0x84, hi: 0x84}, - {value: 0x3308, lo: 0x85, hi: 0x85}, - {value: 0x0040, lo: 0x86, hi: 0x8d}, - {value: 0x0018, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9f}, - {value: 0x3308, lo: 0xa0, hi: 0xb1}, - {value: 0x0008, lo: 0xb2, hi: 0xb7}, - {value: 0x0018, lo: 0xb8, hi: 0xba}, - {value: 0x0008, lo: 0xbb, hi: 0xbb}, - {value: 0x0018, lo: 0xbc, hi: 0xbc}, - {value: 0x0008, lo: 0xbd, hi: 0xbd}, - {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x70, offset 0x379 - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0xa5}, - {value: 0x3308, lo: 0xa6, hi: 0xad}, - {value: 0x0018, lo: 0xae, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x71, offset 0x37e - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x3308, lo: 0x87, hi: 0x91}, - {value: 0x3008, lo: 0x92, hi: 0x92}, - {value: 0x3808, lo: 0x93, hi: 0x93}, - {value: 0x0040, lo: 0x94, hi: 0x9e}, - {value: 0x0018, lo: 0x9f, hi: 0xbc}, - {value: 0x0040, lo: 0xbd, hi: 0xbf}, - // Block 0x72, offset 0x386 - {value: 0x0000, lo: 0x09}, - {value: 0x3308, lo: 0x80, hi: 0x82}, - {value: 0x3008, lo: 0x83, hi: 0x83}, - {value: 0x0008, lo: 0x84, hi: 0xb2}, - {value: 0x3308, lo: 0xb3, hi: 0xb3}, - {value: 0x3008, lo: 0xb4, hi: 0xb5}, - {value: 0x3308, lo: 0xb6, hi: 0xb9}, - {value: 0x3008, lo: 0xba, hi: 0xbb}, - {value: 0x3308, lo: 0xbc, hi: 0xbc}, - {value: 0x3008, lo: 0xbd, hi: 0xbf}, - // Block 0x73, offset 0x390 - {value: 0x0000, lo: 0x0a}, - {value: 0x3808, lo: 0x80, hi: 0x80}, - {value: 0x0018, lo: 0x81, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8e}, - {value: 0x0008, lo: 0x8f, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9d}, - {value: 0x0018, lo: 0x9e, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa4}, - {value: 0x3308, lo: 0xa5, hi: 0xa5}, - {value: 0x0008, lo: 0xa6, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x74, offset 0x39b - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0xa8}, - {value: 0x3308, lo: 0xa9, hi: 0xae}, - {value: 0x3008, lo: 0xaf, hi: 0xb0}, - {value: 0x3308, lo: 0xb1, hi: 0xb2}, - {value: 0x3008, lo: 0xb3, hi: 0xb4}, - {value: 0x3308, lo: 0xb5, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0x75, offset 0x3a3 - {value: 0x0000, lo: 0x10}, - {value: 0x0008, lo: 0x80, hi: 0x82}, - {value: 0x3308, lo: 0x83, hi: 0x83}, - {value: 0x0008, lo: 0x84, hi: 0x8b}, - {value: 0x3308, lo: 0x8c, hi: 0x8c}, - {value: 0x3008, lo: 0x8d, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9b}, - {value: 0x0018, lo: 0x9c, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xb6}, - {value: 0x0018, lo: 0xb7, hi: 0xb9}, - {value: 0x0008, lo: 0xba, hi: 0xba}, - {value: 0x3008, lo: 0xbb, hi: 0xbb}, - {value: 0x3308, lo: 0xbc, hi: 0xbc}, - {value: 0x3008, lo: 0xbd, hi: 0xbd}, - {value: 0x0008, lo: 0xbe, hi: 0xbf}, - // Block 0x76, offset 0x3b4 - {value: 0x0000, lo: 0x08}, - {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x3308, lo: 0xb0, hi: 0xb0}, - {value: 0x0008, lo: 0xb1, hi: 0xb1}, - {value: 0x3308, lo: 0xb2, hi: 0xb4}, - {value: 0x0008, lo: 0xb5, hi: 0xb6}, - {value: 0x3308, lo: 0xb7, hi: 0xb8}, - {value: 0x0008, lo: 0xb9, hi: 0xbd}, - {value: 0x3308, lo: 0xbe, hi: 0xbf}, - // Block 0x77, offset 0x3bd - {value: 0x0000, lo: 0x0f}, - {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0x3308, lo: 0x81, hi: 0x81}, - {value: 0x0008, lo: 0x82, hi: 0x82}, - {value: 0x0040, lo: 0x83, hi: 0x9a}, - {value: 0x0008, lo: 0x9b, hi: 0x9d}, - {value: 0x0018, lo: 0x9e, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xaa}, - {value: 0x3008, lo: 0xab, hi: 0xab}, - {value: 0x3308, lo: 0xac, hi: 0xad}, - {value: 0x3008, lo: 0xae, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb1}, - {value: 0x0008, lo: 0xb2, hi: 0xb4}, - {value: 0x3008, lo: 0xb5, hi: 0xb5}, - {value: 0x3b08, lo: 0xb6, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0x78, offset 0x3cd - {value: 0x0000, lo: 0x0c}, - {value: 0x0040, lo: 0x80, hi: 0x80}, - {value: 0x0008, lo: 0x81, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x88}, - {value: 0x0008, lo: 0x89, hi: 0x8e}, - {value: 0x0040, lo: 0x8f, hi: 0x90}, - {value: 0x0008, lo: 0x91, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa6}, - {value: 0x0040, lo: 0xa7, hi: 0xa7}, - {value: 0x0008, lo: 0xa8, hi: 0xae}, - {value: 0x0040, lo: 0xaf, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x79, offset 0x3da - {value: 0x0000, lo: 0x09}, - {value: 0x0008, lo: 0x80, hi: 0x9a}, - {value: 0x0018, lo: 0x9b, hi: 0x9b}, - {value: 0x4465, lo: 0x9c, hi: 0x9c}, - {value: 0x447d, lo: 0x9d, hi: 0x9d}, - {value: 0x2971, lo: 0x9e, hi: 0x9e}, - {value: 0xe06d, lo: 0x9f, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa5}, - {value: 0x0040, lo: 0xa6, hi: 0xaf}, - {value: 0x4495, lo: 0xb0, hi: 0xbf}, - // Block 0x7a, offset 0x3e4 - {value: 0x0000, lo: 0x04}, - {value: 0x44b5, lo: 0x80, hi: 0x8f}, - {value: 0x44d5, lo: 0x90, hi: 0x9f}, - {value: 0x44f5, lo: 0xa0, hi: 0xaf}, - {value: 0x44d5, lo: 0xb0, hi: 0xbf}, - // Block 0x7b, offset 0x3e9 - {value: 0x0000, lo: 0x0c}, - {value: 0x0008, lo: 0x80, hi: 0xa2}, - {value: 0x3008, lo: 0xa3, hi: 0xa4}, - {value: 0x3308, lo: 0xa5, hi: 0xa5}, - {value: 0x3008, lo: 0xa6, hi: 0xa7}, - {value: 0x3308, lo: 0xa8, hi: 0xa8}, - {value: 0x3008, lo: 0xa9, hi: 0xaa}, - {value: 0x0018, lo: 0xab, hi: 0xab}, - {value: 0x3008, lo: 0xac, hi: 0xac}, - {value: 0x3b08, lo: 0xad, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0x7c, offset 0x3f6 - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xa3}, - {value: 0x0040, lo: 0xa4, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xbf}, - // Block 0x7d, offset 0x3fa - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x8a}, - {value: 0x0018, lo: 0x8b, hi: 0xbb}, - {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0x7e, offset 0x3ff - {value: 0x0020, lo: 0x01}, - {value: 0x4515, lo: 0x80, hi: 0xbf}, - // Block 0x7f, offset 0x401 - {value: 0x0020, lo: 0x03}, - {value: 0x4d15, lo: 0x80, hi: 0x94}, - {value: 0x4ad5, lo: 0x95, hi: 0x95}, - {value: 0x4fb5, lo: 0x96, hi: 0xbf}, - // Block 0x80, offset 0x405 - {value: 0x0020, lo: 0x01}, - {value: 0x54f5, lo: 0x80, hi: 0xbf}, - // Block 0x81, offset 0x407 - {value: 0x0020, lo: 0x03}, - {value: 0x5cf5, lo: 0x80, hi: 0x84}, - {value: 0x5655, lo: 0x85, hi: 0x85}, - {value: 0x5d95, lo: 0x86, hi: 0xbf}, - // Block 0x82, offset 0x40b - {value: 0x0020, lo: 0x08}, - {value: 0x6b55, lo: 0x80, hi: 0x8f}, - {value: 0x6d15, lo: 0x90, hi: 0x90}, - {value: 0x6d55, lo: 0x91, hi: 0xab}, - {value: 0x6ea1, lo: 0xac, hi: 0xac}, - {value: 0x70b5, lo: 0xad, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xae}, - {value: 0x0040, lo: 0xaf, hi: 0xaf}, - {value: 0x70d5, lo: 0xb0, hi: 0xbf}, - // Block 0x83, offset 0x414 - {value: 0x0020, lo: 0x05}, - {value: 0x72d5, lo: 0x80, hi: 0xad}, - {value: 0x6535, lo: 0xae, hi: 0xae}, - {value: 0x7895, lo: 0xaf, hi: 0xb5}, - {value: 0x6f55, lo: 0xb6, hi: 0xb6}, - {value: 0x7975, lo: 0xb7, hi: 0xbf}, - // Block 0x84, offset 0x41a - {value: 0x0028, lo: 0x03}, - {value: 0x7c21, lo: 0x80, hi: 0x82}, - {value: 0x7be1, lo: 0x83, hi: 0x83}, - {value: 0x7c99, lo: 0x84, hi: 0xbf}, - // Block 0x85, offset 0x41e - {value: 0x0038, lo: 0x0f}, - {value: 0x9db1, lo: 0x80, hi: 0x83}, - {value: 0x9e59, lo: 0x84, hi: 0x85}, - {value: 0x9e91, lo: 0x86, hi: 0x87}, - {value: 0x9ec9, lo: 0x88, hi: 0x8f}, - {value: 0x0040, lo: 0x90, hi: 0x90}, - {value: 0x0040, lo: 0x91, hi: 0x91}, - {value: 0xa089, lo: 0x92, hi: 0x97}, - {value: 0xa1a1, lo: 0x98, hi: 0x9c}, - {value: 0xa281, lo: 0x9d, hi: 0xb3}, - {value: 0x9d41, lo: 0xb4, hi: 0xb4}, - {value: 0x9db1, lo: 0xb5, hi: 0xb5}, - {value: 0xa789, lo: 0xb6, hi: 0xbb}, - {value: 0xa869, lo: 0xbc, hi: 0xbc}, - {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, - {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, - // Block 0x86, offset 0x42e - {value: 0x0000, lo: 0x09}, - {value: 0x0008, lo: 0x80, hi: 0x8b}, - {value: 0x0040, lo: 0x8c, hi: 0x8c}, - {value: 0x0008, lo: 0x8d, hi: 0xa6}, - {value: 0x0040, lo: 0xa7, hi: 0xa7}, - {value: 0x0008, lo: 0xa8, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbb}, - {value: 0x0008, lo: 0xbc, hi: 0xbd}, - {value: 0x0040, lo: 0xbe, hi: 0xbe}, - {value: 0x0008, lo: 0xbf, hi: 0xbf}, - // Block 0x87, offset 0x438 - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0xbf}, - // Block 0x88, offset 0x43d - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbf}, - // Block 0x89, offset 0x440 - {value: 0x0000, lo: 0x05}, - {value: 0x0018, lo: 0x80, hi: 0x82}, - {value: 0x0040, lo: 0x83, hi: 0x86}, - {value: 0x0018, lo: 0x87, hi: 0xb3}, - {value: 0x0040, lo: 0xb4, hi: 0xb6}, - {value: 0x0018, lo: 0xb7, hi: 0xbf}, - // Block 0x8a, offset 0x446 - {value: 0x0000, lo: 0x06}, - {value: 0x0018, lo: 0x80, hi: 0x8e}, - {value: 0x0040, lo: 0x8f, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0x9b}, - {value: 0x0040, lo: 0x9c, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xa0}, - {value: 0x0040, lo: 0xa1, hi: 0xbf}, - // Block 0x8b, offset 0x44d - {value: 0x0000, lo: 0x04}, - {value: 0x0040, lo: 0x80, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0xbc}, - {value: 0x3308, lo: 0xbd, hi: 0xbd}, - {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x8c, offset 0x452 - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0x9c}, - {value: 0x0040, lo: 0x9d, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x8d, offset 0x456 - {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0x90}, - {value: 0x0040, lo: 0x91, hi: 0x9f}, - {value: 0x3308, lo: 0xa0, hi: 0xa0}, - {value: 0x0018, lo: 0xa1, hi: 0xbb}, - {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0x8e, offset 0x45c - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xa3}, - {value: 0x0040, lo: 0xa4, hi: 0xac}, - {value: 0x0008, lo: 0xad, hi: 0xbf}, - // Block 0x8f, offset 0x461 - {value: 0x0000, lo: 0x08}, - {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0x0018, lo: 0x81, hi: 0x81}, - {value: 0x0008, lo: 0x82, hi: 0x89}, - {value: 0x0018, lo: 0x8a, hi: 0x8a}, - {value: 0x0040, lo: 0x8b, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xb5}, - {value: 0x3308, lo: 0xb6, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbf}, - // Block 0x90, offset 0x46a - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0x9e}, - {value: 0x0018, lo: 0x9f, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x91, offset 0x46f - {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0x83}, - {value: 0x0040, lo: 0x84, hi: 0x87}, - {value: 0x0008, lo: 0x88, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0x95}, - {value: 0x0040, lo: 0x96, hi: 0xbf}, - // Block 0x92, offset 0x475 - {value: 0x0000, lo: 0x06}, - {value: 0xe145, lo: 0x80, hi: 0x87}, - {value: 0xe1c5, lo: 0x88, hi: 0x8f}, - {value: 0xe145, lo: 0x90, hi: 0x97}, - {value: 0x8ad5, lo: 0x98, hi: 0x9f}, - {value: 0x8aed, lo: 0xa0, hi: 0xa7}, - {value: 0x0008, lo: 0xa8, hi: 0xbf}, - // Block 0x93, offset 0x47c - {value: 0x0000, lo: 0x06}, - {value: 0x0008, lo: 0x80, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa9}, - {value: 0x0040, lo: 0xaa, hi: 0xaf}, - {value: 0x8aed, lo: 0xb0, hi: 0xb7}, - {value: 0x8ad5, lo: 0xb8, hi: 0xbf}, - // Block 0x94, offset 0x483 - {value: 0x0000, lo: 0x06}, - {value: 0xe145, lo: 0x80, hi: 0x87}, - {value: 0xe1c5, lo: 0x88, hi: 0x8f}, - {value: 0xe145, lo: 0x90, hi: 0x93}, - {value: 0x0040, lo: 0x94, hi: 0x97}, - {value: 0x0008, lo: 0x98, hi: 0xbb}, - {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0x95, offset 0x48a - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xa7}, - {value: 0x0040, lo: 0xa8, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x96, offset 0x48e - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0xa3}, - {value: 0x0040, lo: 0xa4, hi: 0xae}, - {value: 0x0018, lo: 0xaf, hi: 0xaf}, - {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0x97, offset 0x493 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0x98, offset 0x496 - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0x95}, - {value: 0x0040, lo: 0x96, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa7}, - {value: 0x0040, lo: 0xa8, hi: 0xbf}, - // Block 0x99, offset 0x49b - {value: 0x0000, lo: 0x0b}, - {value: 0x0808, lo: 0x80, hi: 0x85}, - {value: 0x0040, lo: 0x86, hi: 0x87}, - {value: 0x0808, lo: 0x88, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x0808, lo: 0x8a, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xb6}, - {value: 0x0808, lo: 0xb7, hi: 0xb8}, - {value: 0x0040, lo: 0xb9, hi: 0xbb}, - {value: 0x0808, lo: 0xbc, hi: 0xbc}, - {value: 0x0040, lo: 0xbd, hi: 0xbe}, - {value: 0x0808, lo: 0xbf, hi: 0xbf}, - // Block 0x9a, offset 0x4a7 - {value: 0x0000, lo: 0x05}, - {value: 0x0808, lo: 0x80, hi: 0x95}, - {value: 0x0040, lo: 0x96, hi: 0x96}, - {value: 0x0818, lo: 0x97, hi: 0x9f}, - {value: 0x0808, lo: 0xa0, hi: 0xb6}, - {value: 0x0818, lo: 0xb7, hi: 0xbf}, - // Block 0x9b, offset 0x4ad - {value: 0x0000, lo: 0x04}, - {value: 0x0808, lo: 0x80, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0xa6}, - {value: 0x0818, lo: 0xa7, hi: 0xaf}, - {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0x9c, offset 0x4b2 - {value: 0x0000, lo: 0x06}, - {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x0808, lo: 0xa0, hi: 0xb2}, - {value: 0x0040, lo: 0xb3, hi: 0xb3}, - {value: 0x0808, lo: 0xb4, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xba}, - {value: 0x0818, lo: 0xbb, hi: 0xbf}, - // Block 0x9d, offset 0x4b9 - {value: 0x0000, lo: 0x07}, - {value: 0x0808, lo: 0x80, hi: 0x95}, - {value: 0x0818, lo: 0x96, hi: 0x9b}, - {value: 0x0040, lo: 0x9c, hi: 0x9e}, - {value: 0x0018, lo: 0x9f, hi: 0x9f}, - {value: 0x0808, lo: 0xa0, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbe}, - {value: 0x0818, lo: 0xbf, hi: 0xbf}, - // Block 0x9e, offset 0x4c1 - {value: 0x0000, lo: 0x04}, - {value: 0x0808, lo: 0x80, hi: 0xb7}, - {value: 0x0040, lo: 0xb8, hi: 0xbb}, - {value: 0x0818, lo: 0xbc, hi: 0xbd}, - {value: 0x0808, lo: 0xbe, hi: 0xbf}, - // Block 0x9f, offset 0x4c6 - {value: 0x0000, lo: 0x03}, - {value: 0x0818, lo: 0x80, hi: 0x8f}, - {value: 0x0040, lo: 0x90, hi: 0x91}, - {value: 0x0818, lo: 0x92, hi: 0xbf}, - // Block 0xa0, offset 0x4ca - {value: 0x0000, lo: 0x0f}, - {value: 0x0808, lo: 0x80, hi: 0x80}, - {value: 0x3308, lo: 0x81, hi: 0x83}, - {value: 0x0040, lo: 0x84, hi: 0x84}, - {value: 0x3308, lo: 0x85, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x8b}, - {value: 0x3308, lo: 0x8c, hi: 0x8f}, - {value: 0x0808, lo: 0x90, hi: 0x93}, - {value: 0x0040, lo: 0x94, hi: 0x94}, - {value: 0x0808, lo: 0x95, hi: 0x97}, - {value: 0x0040, lo: 0x98, hi: 0x98}, - {value: 0x0808, lo: 0x99, hi: 0xb3}, - {value: 0x0040, lo: 0xb4, hi: 0xb7}, - {value: 0x3308, lo: 0xb8, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbe}, - {value: 0x3b08, lo: 0xbf, hi: 0xbf}, - // Block 0xa1, offset 0x4da - {value: 0x0000, lo: 0x06}, - {value: 0x0818, lo: 0x80, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0818, lo: 0x90, hi: 0x98}, - {value: 0x0040, lo: 0x99, hi: 0x9f}, - {value: 0x0808, lo: 0xa0, hi: 0xbc}, - {value: 0x0818, lo: 0xbd, hi: 0xbf}, - // Block 0xa2, offset 0x4e1 - {value: 0x0000, lo: 0x03}, - {value: 0x0808, lo: 0x80, hi: 0x9c}, - {value: 0x0818, lo: 0x9d, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0xa3, offset 0x4e5 - {value: 0x0000, lo: 0x03}, - {value: 0x0808, lo: 0x80, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xb8}, - {value: 0x0018, lo: 0xb9, hi: 0xbf}, - // Block 0xa4, offset 0x4e9 - {value: 0x0000, lo: 0x06}, - {value: 0x0808, lo: 0x80, hi: 0x95}, - {value: 0x0040, lo: 0x96, hi: 0x97}, - {value: 0x0818, lo: 0x98, hi: 0x9f}, - {value: 0x0808, lo: 0xa0, hi: 0xb2}, - {value: 0x0040, lo: 0xb3, hi: 0xb7}, - {value: 0x0818, lo: 0xb8, hi: 0xbf}, - // Block 0xa5, offset 0x4f0 - {value: 0x0000, lo: 0x01}, - {value: 0x0808, lo: 0x80, hi: 0xbf}, - // Block 0xa6, offset 0x4f2 - {value: 0x0000, lo: 0x02}, - {value: 0x0808, lo: 0x80, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0xbf}, - // Block 0xa7, offset 0x4f5 - {value: 0x0000, lo: 0x02}, - {value: 0x03dd, lo: 0x80, hi: 0xb2}, - {value: 0x0040, lo: 0xb3, hi: 0xbf}, - // Block 0xa8, offset 0x4f8 - {value: 0x0000, lo: 0x03}, - {value: 0x0808, lo: 0x80, hi: 0xb2}, - {value: 0x0040, lo: 0xb3, hi: 0xb9}, - {value: 0x0818, lo: 0xba, hi: 0xbf}, - // Block 0xa9, offset 0x4fc - {value: 0x0000, lo: 0x03}, - {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x0818, lo: 0xa0, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xaa, offset 0x500 - {value: 0x0000, lo: 0x05}, - {value: 0x3008, lo: 0x80, hi: 0x80}, - {value: 0x3308, lo: 0x81, hi: 0x81}, - {value: 0x3008, lo: 0x82, hi: 0x82}, - {value: 0x0008, lo: 0x83, hi: 0xb7}, - {value: 0x3308, lo: 0xb8, hi: 0xbf}, - // Block 0xab, offset 0x506 - {value: 0x0000, lo: 0x08}, - {value: 0x3308, lo: 0x80, hi: 0x85}, - {value: 0x3b08, lo: 0x86, hi: 0x86}, - {value: 0x0018, lo: 0x87, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x91}, - {value: 0x0018, lo: 0x92, hi: 0xa5}, - {value: 0x0008, lo: 0xa6, hi: 0xaf}, - {value: 0x0040, lo: 0xb0, hi: 0xbe}, - {value: 0x3b08, lo: 0xbf, hi: 0xbf}, - // Block 0xac, offset 0x50f - {value: 0x0000, lo: 0x0b}, - {value: 0x3308, lo: 0x80, hi: 0x81}, - {value: 0x3008, lo: 0x82, hi: 0x82}, - {value: 0x0008, lo: 0x83, hi: 0xaf}, - {value: 0x3008, lo: 0xb0, hi: 0xb2}, - {value: 0x3308, lo: 0xb3, hi: 0xb6}, - {value: 0x3008, lo: 0xb7, hi: 0xb8}, - {value: 0x3b08, lo: 0xb9, hi: 0xb9}, - {value: 0x3308, lo: 0xba, hi: 0xba}, - {value: 0x0018, lo: 0xbb, hi: 0xbc}, - {value: 0x0340, lo: 0xbd, hi: 0xbd}, - {value: 0x0018, lo: 0xbe, hi: 0xbf}, - // Block 0xad, offset 0x51b - {value: 0x0000, lo: 0x06}, - {value: 0x0018, lo: 0x80, hi: 0x81}, - {value: 0x0040, lo: 0x82, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xa8}, - {value: 0x0040, lo: 0xa9, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0xae, offset 0x522 - {value: 0x0000, lo: 0x08}, - {value: 0x3308, lo: 0x80, hi: 0x82}, - {value: 0x0008, lo: 0x83, hi: 0xa6}, - {value: 0x3308, lo: 0xa7, hi: 0xab}, - {value: 0x3008, lo: 0xac, hi: 0xac}, - {value: 0x3308, lo: 0xad, hi: 0xb2}, - {value: 0x3b08, lo: 0xb3, hi: 0xb4}, - {value: 0x0040, lo: 0xb5, hi: 0xb5}, - {value: 0x0008, lo: 0xb6, hi: 0xbf}, - // Block 0xaf, offset 0x52b - {value: 0x0000, lo: 0x07}, - {value: 0x0018, lo: 0x80, hi: 0x83}, - {value: 0x0040, lo: 0x84, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xb2}, - {value: 0x3308, lo: 0xb3, hi: 0xb3}, - {value: 0x0018, lo: 0xb4, hi: 0xb5}, - {value: 0x0008, lo: 0xb6, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0xb0, offset 0x533 - {value: 0x0000, lo: 0x06}, - {value: 0x3308, lo: 0x80, hi: 0x81}, - {value: 0x3008, lo: 0x82, hi: 0x82}, - {value: 0x0008, lo: 0x83, hi: 0xb2}, - {value: 0x3008, lo: 0xb3, hi: 0xb5}, - {value: 0x3308, lo: 0xb6, hi: 0xbe}, - {value: 0x3008, lo: 0xbf, hi: 0xbf}, - // Block 0xb1, offset 0x53a - {value: 0x0000, lo: 0x0d}, - {value: 0x3808, lo: 0x80, hi: 0x80}, - {value: 0x0008, lo: 0x81, hi: 0x84}, - {value: 0x0018, lo: 0x85, hi: 0x89}, - {value: 0x3308, lo: 0x8a, hi: 0x8c}, - {value: 0x0018, lo: 0x8d, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x9a}, - {value: 0x0018, lo: 0x9b, hi: 0x9b}, - {value: 0x0008, lo: 0x9c, hi: 0x9c}, - {value: 0x0018, lo: 0x9d, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xa0}, - {value: 0x0018, lo: 0xa1, hi: 0xb4}, - {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0xb2, offset 0x548 - {value: 0x0000, lo: 0x0c}, - {value: 0x0008, lo: 0x80, hi: 0x91}, - {value: 0x0040, lo: 0x92, hi: 0x92}, - {value: 0x0008, lo: 0x93, hi: 0xab}, - {value: 0x3008, lo: 0xac, hi: 0xae}, - {value: 0x3308, lo: 0xaf, hi: 0xb1}, - {value: 0x3008, lo: 0xb2, hi: 0xb3}, - {value: 0x3308, lo: 0xb4, hi: 0xb4}, - {value: 0x3808, lo: 0xb5, hi: 0xb5}, - {value: 0x3308, lo: 0xb6, hi: 0xb7}, - {value: 0x0018, lo: 0xb8, hi: 0xbd}, - {value: 0x3308, lo: 0xbe, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xb3, offset 0x555 - {value: 0x0000, lo: 0x0c}, - {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x87}, - {value: 0x0008, lo: 0x88, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x0008, lo: 0x8a, hi: 0x8d}, - {value: 0x0040, lo: 0x8e, hi: 0x8e}, - {value: 0x0008, lo: 0x8f, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0x9e}, - {value: 0x0008, lo: 0x9f, hi: 0xa8}, - {value: 0x0018, lo: 0xa9, hi: 0xa9}, - {value: 0x0040, lo: 0xaa, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0xb4, offset 0x562 - {value: 0x0000, lo: 0x08}, - {value: 0x0008, lo: 0x80, hi: 0x9e}, - {value: 0x3308, lo: 0x9f, hi: 0x9f}, - {value: 0x3008, lo: 0xa0, hi: 0xa2}, - {value: 0x3308, lo: 0xa3, hi: 0xa9}, - {value: 0x3b08, lo: 0xaa, hi: 0xaa}, - {value: 0x0040, lo: 0xab, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xb9}, - {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0xb5, offset 0x56b - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xb4}, - {value: 0x3008, lo: 0xb5, hi: 0xb7}, - {value: 0x3308, lo: 0xb8, hi: 0xbf}, - // Block 0xb6, offset 0x56f - {value: 0x0000, lo: 0x0d}, - {value: 0x3008, lo: 0x80, hi: 0x81}, - {value: 0x3b08, lo: 0x82, hi: 0x82}, - {value: 0x3308, lo: 0x83, hi: 0x84}, - {value: 0x3008, lo: 0x85, hi: 0x85}, - {value: 0x3308, lo: 0x86, hi: 0x86}, - {value: 0x0008, lo: 0x87, hi: 0x8a}, - {value: 0x0018, lo: 0x8b, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9a}, - {value: 0x0018, lo: 0x9b, hi: 0x9b}, - {value: 0x0040, lo: 0x9c, hi: 0x9c}, - {value: 0x0018, lo: 0x9d, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0xbf}, - // Block 0xb7, offset 0x57d - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x3008, lo: 0xb0, hi: 0xb2}, - {value: 0x3308, lo: 0xb3, hi: 0xb8}, - {value: 0x3008, lo: 0xb9, hi: 0xb9}, - {value: 0x3308, lo: 0xba, hi: 0xba}, - {value: 0x3008, lo: 0xbb, hi: 0xbe}, - {value: 0x3308, lo: 0xbf, hi: 0xbf}, - // Block 0xb8, offset 0x585 - {value: 0x0000, lo: 0x0a}, - {value: 0x3308, lo: 0x80, hi: 0x80}, - {value: 0x3008, lo: 0x81, hi: 0x81}, - {value: 0x3b08, lo: 0x82, hi: 0x82}, - {value: 0x3308, lo: 0x83, hi: 0x83}, - {value: 0x0008, lo: 0x84, hi: 0x85}, - {value: 0x0018, lo: 0x86, hi: 0x86}, - {value: 0x0008, lo: 0x87, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0xbf}, - // Block 0xb9, offset 0x590 - {value: 0x0000, lo: 0x08}, - {value: 0x0008, lo: 0x80, hi: 0xae}, - {value: 0x3008, lo: 0xaf, hi: 0xb1}, - {value: 0x3308, lo: 0xb2, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xb7}, - {value: 0x3008, lo: 0xb8, hi: 0xbb}, - {value: 0x3308, lo: 0xbc, hi: 0xbd}, - {value: 0x3008, lo: 0xbe, hi: 0xbe}, - {value: 0x3b08, lo: 0xbf, hi: 0xbf}, - // Block 0xba, offset 0x599 - {value: 0x0000, lo: 0x05}, - {value: 0x3308, lo: 0x80, hi: 0x80}, - {value: 0x0018, lo: 0x81, hi: 0x97}, - {value: 0x0008, lo: 0x98, hi: 0x9b}, - {value: 0x3308, lo: 0x9c, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0xbf}, - // Block 0xbb, offset 0x59f - {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x3008, lo: 0xb0, hi: 0xb2}, - {value: 0x3308, lo: 0xb3, hi: 0xba}, - {value: 0x3008, lo: 0xbb, hi: 0xbc}, - {value: 0x3308, lo: 0xbd, hi: 0xbd}, - {value: 0x3008, lo: 0xbe, hi: 0xbe}, - {value: 0x3b08, lo: 0xbf, hi: 0xbf}, - // Block 0xbc, offset 0x5a7 - {value: 0x0000, lo: 0x08}, - {value: 0x3308, lo: 0x80, hi: 0x80}, - {value: 0x0018, lo: 0x81, hi: 0x83}, - {value: 0x0008, lo: 0x84, hi: 0x84}, - {value: 0x0040, lo: 0x85, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xac}, - {value: 0x0040, lo: 0xad, hi: 0xbf}, - // Block 0xbd, offset 0x5b0 - {value: 0x0000, lo: 0x09}, - {value: 0x0008, lo: 0x80, hi: 0xaa}, - {value: 0x3308, lo: 0xab, hi: 0xab}, - {value: 0x3008, lo: 0xac, hi: 0xac}, - {value: 0x3308, lo: 0xad, hi: 0xad}, - {value: 0x3008, lo: 0xae, hi: 0xaf}, - {value: 0x3308, lo: 0xb0, hi: 0xb5}, - {value: 0x3808, lo: 0xb6, hi: 0xb6}, - {value: 0x3308, lo: 0xb7, hi: 0xb7}, - {value: 0x0040, lo: 0xb8, hi: 0xbf}, - // Block 0xbe, offset 0x5ba - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x89}, - {value: 0x0040, lo: 0x8a, hi: 0xbf}, - // Block 0xbf, offset 0x5bd - {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9c}, - {value: 0x3308, lo: 0x9d, hi: 0x9f}, - {value: 0x3008, lo: 0xa0, hi: 0xa1}, - {value: 0x3308, lo: 0xa2, hi: 0xa5}, - {value: 0x3008, lo: 0xa6, hi: 0xa6}, - {value: 0x3308, lo: 0xa7, hi: 0xaa}, - {value: 0x3b08, lo: 0xab, hi: 0xab}, - {value: 0x0040, lo: 0xac, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xb9}, - {value: 0x0018, lo: 0xba, hi: 0xbf}, - // Block 0xc0, offset 0x5c9 - {value: 0x0000, lo: 0x02}, - {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x049d, lo: 0xa0, hi: 0xbf}, - // Block 0xc1, offset 0x5cc - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0xa9}, - {value: 0x0018, lo: 0xaa, hi: 0xb2}, - {value: 0x0040, lo: 0xb3, hi: 0xbe}, - {value: 0x0008, lo: 0xbf, hi: 0xbf}, - // Block 0xc2, offset 0x5d1 - {value: 0x0000, lo: 0x0c}, - {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0x3308, lo: 0x81, hi: 0x86}, - {value: 0x3008, lo: 0x87, hi: 0x88}, - {value: 0x3308, lo: 0x89, hi: 0x8a}, - {value: 0x0008, lo: 0x8b, hi: 0xb2}, - {value: 0x3308, lo: 0xb3, hi: 0xb3}, - {value: 0x3b08, lo: 0xb4, hi: 0xb4}, - {value: 0x3308, lo: 0xb5, hi: 0xb8}, - {value: 0x3008, lo: 0xb9, hi: 0xb9}, - {value: 0x0008, lo: 0xba, hi: 0xba}, - {value: 0x3308, lo: 0xbb, hi: 0xbe}, - {value: 0x0018, lo: 0xbf, hi: 0xbf}, - // Block 0xc3, offset 0x5de - {value: 0x0000, lo: 0x08}, - {value: 0x0018, lo: 0x80, hi: 0x86}, - {value: 0x3b08, lo: 0x87, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x90}, - {value: 0x3308, lo: 0x91, hi: 0x96}, - {value: 0x3008, lo: 0x97, hi: 0x98}, - {value: 0x3308, lo: 0x99, hi: 0x9b}, - {value: 0x0008, lo: 0x9c, hi: 0xbf}, - // Block 0xc4, offset 0x5e7 - {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0x83}, - {value: 0x0040, lo: 0x84, hi: 0x85}, - {value: 0x0008, lo: 0x86, hi: 0x89}, - {value: 0x3308, lo: 0x8a, hi: 0x96}, - {value: 0x3008, lo: 0x97, hi: 0x97}, - {value: 0x3308, lo: 0x98, hi: 0x98}, - {value: 0x3b08, lo: 0x99, hi: 0x99}, - {value: 0x0018, lo: 0x9a, hi: 0x9c}, - {value: 0x0040, lo: 0x9d, hi: 0x9d}, - {value: 0x0018, lo: 0x9e, hi: 0xa2}, - {value: 0x0040, lo: 0xa3, hi: 0xbf}, - // Block 0xc5, offset 0x5f3 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xb8}, - {value: 0x0040, lo: 0xb9, hi: 0xbf}, - // Block 0xc6, offset 0x5f6 - {value: 0x0000, lo: 0x09}, - {value: 0x0008, lo: 0x80, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x0008, lo: 0x8a, hi: 0xae}, - {value: 0x3008, lo: 0xaf, hi: 0xaf}, - {value: 0x3308, lo: 0xb0, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xb7}, - {value: 0x3308, lo: 0xb8, hi: 0xbd}, - {value: 0x3008, lo: 0xbe, hi: 0xbe}, - {value: 0x3b08, lo: 0xbf, hi: 0xbf}, - // Block 0xc7, offset 0x600 - {value: 0x0000, lo: 0x08}, - {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0x0018, lo: 0x81, hi: 0x85}, - {value: 0x0040, lo: 0x86, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0018, lo: 0x9a, hi: 0xac}, - {value: 0x0040, lo: 0xad, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb1}, - {value: 0x0008, lo: 0xb2, hi: 0xbf}, - // Block 0xc8, offset 0x609 - {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0x8f}, - {value: 0x0040, lo: 0x90, hi: 0x91}, - {value: 0x3308, lo: 0x92, hi: 0xa7}, - {value: 0x0040, lo: 0xa8, hi: 0xa8}, - {value: 0x3008, lo: 0xa9, hi: 0xa9}, - {value: 0x3308, lo: 0xaa, hi: 0xb0}, - {value: 0x3008, lo: 0xb1, hi: 0xb1}, - {value: 0x3308, lo: 0xb2, hi: 0xb3}, - {value: 0x3008, lo: 0xb4, hi: 0xb4}, - {value: 0x3308, lo: 0xb5, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0xc9, offset 0x615 - {value: 0x0000, lo: 0x0c}, - {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x87}, - {value: 0x0008, lo: 0x88, hi: 0x89}, - {value: 0x0040, lo: 0x8a, hi: 0x8a}, - {value: 0x0008, lo: 0x8b, hi: 0xb0}, - {value: 0x3308, lo: 0xb1, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xb9}, - {value: 0x3308, lo: 0xba, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbb}, - {value: 0x3308, lo: 0xbc, hi: 0xbd}, - {value: 0x0040, lo: 0xbe, hi: 0xbe}, - {value: 0x3308, lo: 0xbf, hi: 0xbf}, - // Block 0xca, offset 0x622 - {value: 0x0000, lo: 0x07}, - {value: 0x3308, lo: 0x80, hi: 0x83}, - {value: 0x3b08, lo: 0x84, hi: 0x85}, - {value: 0x0008, lo: 0x86, hi: 0x86}, - {value: 0x3308, lo: 0x87, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0xbf}, - // Block 0xcb, offset 0x62a - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0xbf}, - // Block 0xcc, offset 0x62d - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0xae}, - {value: 0x0040, lo: 0xaf, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb4}, - {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0xcd, offset 0x632 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x83}, - {value: 0x0040, lo: 0x84, hi: 0xbf}, - // Block 0xce, offset 0x635 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xae}, - {value: 0x0040, lo: 0xaf, hi: 0xbf}, - // Block 0xcf, offset 0x638 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0xbf}, - // Block 0xd0, offset 0x63b - {value: 0x0000, lo: 0x06}, - {value: 0x0008, lo: 0x80, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa9}, - {value: 0x0040, lo: 0xaa, hi: 0xad}, - {value: 0x0018, lo: 0xae, hi: 0xaf}, - {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0xd1, offset 0x642 - {value: 0x0000, lo: 0x06}, - {value: 0x0040, lo: 0x80, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x3308, lo: 0xb0, hi: 0xb4}, - {value: 0x0018, lo: 0xb5, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xbf}, - // Block 0xd2, offset 0x649 - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x3308, lo: 0xb0, hi: 0xb6}, - {value: 0x0018, lo: 0xb7, hi: 0xbf}, - // Block 0xd3, offset 0x64d - {value: 0x0000, lo: 0x0a}, - {value: 0x0008, lo: 0x80, hi: 0x83}, - {value: 0x0018, lo: 0x84, hi: 0x85}, - {value: 0x0040, lo: 0x86, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9a}, - {value: 0x0018, lo: 0x9b, hi: 0xa1}, - {value: 0x0040, lo: 0xa2, hi: 0xa2}, - {value: 0x0008, lo: 0xa3, hi: 0xb7}, - {value: 0x0040, lo: 0xb8, hi: 0xbc}, - {value: 0x0008, lo: 0xbd, hi: 0xbf}, - // Block 0xd4, offset 0x658 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x8f}, - {value: 0x0040, lo: 0x90, hi: 0xbf}, - // Block 0xd5, offset 0x65b - {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0x84}, - {value: 0x0040, lo: 0x85, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x90}, - {value: 0x3008, lo: 0x91, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xd6, offset 0x661 - {value: 0x0000, lo: 0x04}, - {value: 0x0040, lo: 0x80, hi: 0x8e}, - {value: 0x3308, lo: 0x8f, hi: 0x92}, - {value: 0x0008, lo: 0x93, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0xd7, offset 0x666 - {value: 0x0000, lo: 0x03}, - {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa1}, - {value: 0x0040, lo: 0xa2, hi: 0xbf}, - // Block 0xd8, offset 0x66a - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xac}, - {value: 0x0040, lo: 0xad, hi: 0xbf}, - // Block 0xd9, offset 0x66d - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xb2}, - {value: 0x0040, lo: 0xb3, hi: 0xbf}, - // Block 0xda, offset 0x670 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0xbf}, - // Block 0xdb, offset 0x673 - {value: 0x0000, lo: 0x02}, - {value: 0x0040, lo: 0x80, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0xdc, offset 0x676 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xbb}, - {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0xdd, offset 0x679 - {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0xaa}, - {value: 0x0040, lo: 0xab, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbc}, - {value: 0x0040, lo: 0xbd, hi: 0xbf}, - // Block 0xde, offset 0x67e - {value: 0x0000, lo: 0x09}, - {value: 0x0008, lo: 0x80, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9b}, - {value: 0x0018, lo: 0x9c, hi: 0x9c}, - {value: 0x3308, lo: 0x9d, hi: 0x9e}, - {value: 0x0018, lo: 0x9f, hi: 0x9f}, - {value: 0x03c0, lo: 0xa0, hi: 0xa3}, - {value: 0x0040, lo: 0xa4, hi: 0xbf}, - // Block 0xdf, offset 0x688 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xbf}, - // Block 0xe0, offset 0x68b - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0xa6}, - {value: 0x0040, lo: 0xa7, hi: 0xa8}, - {value: 0x0018, lo: 0xa9, hi: 0xbf}, - // Block 0xe1, offset 0x68f - {value: 0x0000, lo: 0x0e}, - {value: 0x0018, lo: 0x80, hi: 0x9d}, - {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, - {value: 0xb601, lo: 0x9f, hi: 0x9f}, - {value: 0xb649, lo: 0xa0, hi: 0xa0}, - {value: 0xb6b1, lo: 0xa1, hi: 0xa1}, - {value: 0xb719, lo: 0xa2, hi: 0xa2}, - {value: 0xb781, lo: 0xa3, hi: 0xa3}, - {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, - {value: 0x3018, lo: 0xa5, hi: 0xa6}, - {value: 0x3318, lo: 0xa7, hi: 0xa9}, - {value: 0x0018, lo: 0xaa, hi: 0xac}, - {value: 0x3018, lo: 0xad, hi: 0xb2}, - {value: 0x0340, lo: 0xb3, hi: 0xba}, - {value: 0x3318, lo: 0xbb, hi: 0xbf}, - // Block 0xe2, offset 0x69e - {value: 0x0000, lo: 0x0b}, - {value: 0x3318, lo: 0x80, hi: 0x82}, - {value: 0x0018, lo: 0x83, hi: 0x84}, - {value: 0x3318, lo: 0x85, hi: 0x8b}, - {value: 0x0018, lo: 0x8c, hi: 0xa9}, - {value: 0x3318, lo: 0xaa, hi: 0xad}, - {value: 0x0018, lo: 0xae, hi: 0xba}, - {value: 0xb851, lo: 0xbb, hi: 0xbb}, - {value: 0xb899, lo: 0xbc, hi: 0xbc}, - {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, - {value: 0xb949, lo: 0xbe, hi: 0xbe}, - {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, - // Block 0xe3, offset 0x6aa - {value: 0x0000, lo: 0x03}, - {value: 0xba19, lo: 0x80, hi: 0x80}, - {value: 0x0018, lo: 0x81, hi: 0xa8}, - {value: 0x0040, lo: 0xa9, hi: 0xbf}, - // Block 0xe4, offset 0x6ae - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x81}, - {value: 0x3318, lo: 0x82, hi: 0x84}, - {value: 0x0018, lo: 0x85, hi: 0x85}, - {value: 0x0040, lo: 0x86, hi: 0xbf}, - // Block 0xe5, offset 0x6b3 - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xb1}, - {value: 0x0040, lo: 0xb2, hi: 0xbf}, - // Block 0xe6, offset 0x6b8 - {value: 0x0000, lo: 0x03}, - {value: 0x3308, lo: 0x80, hi: 0xb6}, - {value: 0x0018, lo: 0xb7, hi: 0xba}, - {value: 0x3308, lo: 0xbb, hi: 0xbf}, - // Block 0xe7, offset 0x6bc - {value: 0x0000, lo: 0x04}, - {value: 0x3308, lo: 0x80, hi: 0xac}, - {value: 0x0018, lo: 0xad, hi: 0xb4}, - {value: 0x3308, lo: 0xb5, hi: 0xb5}, - {value: 0x0018, lo: 0xb6, hi: 0xbf}, - // Block 0xe8, offset 0x6c1 - {value: 0x0000, lo: 0x08}, - {value: 0x0018, lo: 0x80, hi: 0x83}, - {value: 0x3308, lo: 0x84, hi: 0x84}, - {value: 0x0018, lo: 0x85, hi: 0x8b}, - {value: 0x0040, lo: 0x8c, hi: 0x9a}, - {value: 0x3308, lo: 0x9b, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xa0}, - {value: 0x3308, lo: 0xa1, hi: 0xaf}, - {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0xe9, offset 0x6ca - {value: 0x0000, lo: 0x0a}, - {value: 0x3308, lo: 0x80, hi: 0x86}, - {value: 0x0040, lo: 0x87, hi: 0x87}, - {value: 0x3308, lo: 0x88, hi: 0x98}, - {value: 0x0040, lo: 0x99, hi: 0x9a}, - {value: 0x3308, lo: 0x9b, hi: 0xa1}, - {value: 0x0040, lo: 0xa2, hi: 0xa2}, - {value: 0x3308, lo: 0xa3, hi: 0xa4}, - {value: 0x0040, lo: 0xa5, hi: 0xa5}, - {value: 0x3308, lo: 0xa6, hi: 0xaa}, - {value: 0x0040, lo: 0xab, hi: 0xbf}, - // Block 0xea, offset 0x6d5 - {value: 0x0000, lo: 0x05}, - {value: 0x0808, lo: 0x80, hi: 0x84}, - {value: 0x0040, lo: 0x85, hi: 0x86}, - {value: 0x0818, lo: 0x87, hi: 0x8f}, - {value: 0x3308, lo: 0x90, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0xbf}, - // Block 0xeb, offset 0x6db - {value: 0x0000, lo: 0x07}, - {value: 0x0a08, lo: 0x80, hi: 0x83}, - {value: 0x3308, lo: 0x84, hi: 0x8a}, - {value: 0x0040, lo: 0x8b, hi: 0x8f}, - {value: 0x0808, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9d}, - {value: 0x0818, lo: 0x9e, hi: 0x9f}, - {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0xec, offset 0x6e3 - {value: 0x0000, lo: 0x03}, - {value: 0x0040, lo: 0x80, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb1}, - {value: 0x0040, lo: 0xb2, hi: 0xbf}, - // Block 0xed, offset 0x6e7 - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0xab}, - {value: 0x0040, lo: 0xac, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xbf}, - // Block 0xee, offset 0x6eb - {value: 0x0000, lo: 0x05}, - {value: 0x0018, lo: 0x80, hi: 0x93}, - {value: 0x0040, lo: 0x94, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xae}, - {value: 0x0040, lo: 0xaf, hi: 0xb0}, - {value: 0x0018, lo: 0xb1, hi: 0xbf}, - // Block 0xef, offset 0x6f1 - {value: 0x0000, lo: 0x05}, - {value: 0x0040, lo: 0x80, hi: 0x80}, - {value: 0x0018, lo: 0x81, hi: 0x8f}, - {value: 0x0040, lo: 0x90, hi: 0x90}, - {value: 0x0018, lo: 0x91, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xbf}, - // Block 0xf0, offset 0x6f7 - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x8f}, - {value: 0xc1c1, lo: 0x90, hi: 0x90}, - {value: 0x0018, lo: 0x91, hi: 0xac}, - {value: 0x0040, lo: 0xad, hi: 0xbf}, - // Block 0xf1, offset 0x6fc - {value: 0x0000, lo: 0x02}, - {value: 0x0040, lo: 0x80, hi: 0xa5}, - {value: 0x0018, lo: 0xa6, hi: 0xbf}, - // Block 0xf2, offset 0x6ff - {value: 0x0000, lo: 0x0f}, - {value: 0xc7e9, lo: 0x80, hi: 0x80}, - {value: 0xc839, lo: 0x81, hi: 0x81}, - {value: 0xc889, lo: 0x82, hi: 0x82}, - {value: 0xc8d9, lo: 0x83, hi: 0x83}, - {value: 0xc929, lo: 0x84, hi: 0x84}, - {value: 0xc979, lo: 0x85, hi: 0x85}, - {value: 0xc9c9, lo: 0x86, hi: 0x86}, - {value: 0xca19, lo: 0x87, hi: 0x87}, - {value: 0xca69, lo: 0x88, hi: 0x88}, - {value: 0x0040, lo: 0x89, hi: 0x8f}, - {value: 0xcab9, lo: 0x90, hi: 0x90}, - {value: 0xcad9, lo: 0x91, hi: 0x91}, - {value: 0x0040, lo: 0x92, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xa5}, - {value: 0x0040, lo: 0xa6, hi: 0xbf}, - // Block 0xf3, offset 0x70f - {value: 0x0000, lo: 0x06}, - {value: 0x0018, lo: 0x80, hi: 0x94}, - {value: 0x0040, lo: 0x95, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xac}, - {value: 0x0040, lo: 0xad, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb8}, - {value: 0x0040, lo: 0xb9, hi: 0xbf}, - // Block 0xf4, offset 0x716 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0xb3}, - {value: 0x0040, lo: 0xb4, hi: 0xbf}, - // Block 0xf5, offset 0x719 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0x94}, - {value: 0x0040, lo: 0x95, hi: 0xbf}, - // Block 0xf6, offset 0x71c - {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0x8b}, - {value: 0x0040, lo: 0x8c, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0xbf}, - // Block 0xf7, offset 0x720 - {value: 0x0000, lo: 0x05}, - {value: 0x0018, lo: 0x80, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0x99}, - {value: 0x0040, lo: 0x9a, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xbf}, - // Block 0xf8, offset 0x726 - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x87}, - {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xbf}, - // Block 0xf9, offset 0x72b - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x8b}, - {value: 0x0040, lo: 0x8c, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xfa, offset 0x730 - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x8c}, - {value: 0x0040, lo: 0x8d, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0xab}, - {value: 0x0040, lo: 0xac, hi: 0xbf}, - // Block 0xfb, offset 0x735 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0x97}, - {value: 0x0040, lo: 0x98, hi: 0xbf}, - // Block 0xfc, offset 0x738 - {value: 0x0000, lo: 0x04}, - {value: 0x0018, lo: 0x80, hi: 0x80}, - {value: 0x0040, lo: 0x81, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0xa6}, - {value: 0x0040, lo: 0xa7, hi: 0xbf}, - // Block 0xfd, offset 0x73d - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x96}, - {value: 0x0040, lo: 0x97, hi: 0xbf}, - // Block 0xfe, offset 0x740 - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xb4}, - {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0xff, offset 0x743 - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0x9d}, - {value: 0x0040, lo: 0x9e, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x100, offset 0x747 - {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xa1}, - {value: 0x0040, lo: 0xa2, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x101, offset 0x74b - {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0xa0}, - {value: 0x0040, lo: 0xa1, hi: 0xbf}, - // Block 0x102, offset 0x74e - {value: 0x0020, lo: 0x0f}, - {value: 0xdeb9, lo: 0x80, hi: 0x89}, - {value: 0x8dfd, lo: 0x8a, hi: 0x8a}, - {value: 0xdff9, lo: 0x8b, hi: 0x9c}, - {value: 0x8e1d, lo: 0x9d, hi: 0x9d}, - {value: 0xe239, lo: 0x9e, hi: 0xa2}, - {value: 0x8e3d, lo: 0xa3, hi: 0xa3}, - {value: 0xe2d9, lo: 0xa4, hi: 0xab}, - {value: 0x7ed5, lo: 0xac, hi: 0xac}, - {value: 0xe3d9, lo: 0xad, hi: 0xaf}, - {value: 0x8e5d, lo: 0xb0, hi: 0xb0}, - {value: 0xe439, lo: 0xb1, hi: 0xb6}, - {value: 0x8e7d, lo: 0xb7, hi: 0xb9}, - {value: 0xe4f9, lo: 0xba, hi: 0xba}, - {value: 0x8edd, lo: 0xbb, hi: 0xbb}, - {value: 0xe519, lo: 0xbc, hi: 0xbf}, - // Block 0x103, offset 0x75e - {value: 0x0020, lo: 0x10}, - {value: 0x937d, lo: 0x80, hi: 0x80}, - {value: 0xf099, lo: 0x81, hi: 0x86}, - {value: 0x939d, lo: 0x87, hi: 0x8a}, - {value: 0xd9f9, lo: 0x8b, hi: 0x8b}, - {value: 0xf159, lo: 0x8c, hi: 0x96}, - {value: 0x941d, lo: 0x97, hi: 0x97}, - {value: 0xf2b9, lo: 0x98, hi: 0xa3}, - {value: 0x943d, lo: 0xa4, hi: 0xa6}, - {value: 0xf439, lo: 0xa7, hi: 0xaa}, - {value: 0x949d, lo: 0xab, hi: 0xab}, - {value: 0xf4b9, lo: 0xac, hi: 0xac}, - {value: 0x94bd, lo: 0xad, hi: 0xad}, - {value: 0xf4d9, lo: 0xae, hi: 0xaf}, - {value: 0x94dd, lo: 0xb0, hi: 0xb1}, - {value: 0xf519, lo: 0xb2, hi: 0xbe}, - {value: 0x2040, lo: 0xbf, hi: 0xbf}, - // Block 0x104, offset 0x76f - {value: 0x0000, lo: 0x04}, - {value: 0x0040, lo: 0x80, hi: 0x80}, - {value: 0x0340, lo: 0x81, hi: 0x81}, - {value: 0x0040, lo: 0x82, hi: 0x9f}, - {value: 0x0340, lo: 0xa0, hi: 0xbf}, - // Block 0x105, offset 0x774 - {value: 0x0000, lo: 0x01}, - {value: 0x0340, lo: 0x80, hi: 0xbf}, - // Block 0x106, offset 0x776 - {value: 0x0000, lo: 0x01}, - {value: 0x33c0, lo: 0x80, hi: 0xbf}, - // Block 0x107, offset 0x778 - {value: 0x0000, lo: 0x02}, - {value: 0x33c0, lo: 0x80, hi: 0xaf}, - {value: 0x0040, lo: 0xb0, hi: 0xbf}, -} - -// Total table size 42115 bytes (41KiB); checksum: F4A1FA4E diff --git a/vendor/golang.org/x/net/idna/tables10.0.0.go b/vendor/golang.org/x/net/idna/tables10.0.0.go new file mode 100644 index 000000000000..54fddb4b16cc --- /dev/null +++ b/vendor/golang.org/x/net/idna/tables10.0.0.go @@ -0,0 +1,4559 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.10,!go1.13 + +package idna + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "10.0.0" + +var mappings string = "" + // Size: 8175 bytes + "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + + "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + + "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + + "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" + + "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" + + "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" + + "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" + + "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" + + "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" + + "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" + + "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" + + "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" + + "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" + + "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" + + "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" + + "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" + + "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" + + "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" + + "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" + + "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" + + "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" + + "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" + + "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" + + "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" + + "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" + + "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" + + ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" + + "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" + + "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" + + "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" + + "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" + + "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" + + "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" + + "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" + + "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" + + "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" + + "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" + + "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" + + "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" + + "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" + + "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" + + "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" + + "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" + + "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" + + "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" + + "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" + + "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" + + "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" + + "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" + + "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" + + "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" + + "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" + + "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" + + "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" + + "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" + + "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" + + "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" + + "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" + + "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" + + "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" + + "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" + + "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" + + "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" + + "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" + + "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" + + "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" + + "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" + + "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" + + "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" + + "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" + + "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" + + "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" + + "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" + + " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" + + "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" + + "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" + + "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" + + "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" + + "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" + + "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" + + "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" + + "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" + + "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" + + "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" + + "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" + + "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" + + "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" + + "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" + + "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" + + "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" + + "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" + + "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" + + "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" + + "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" + + "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" + + "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" + + "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" + + "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" + + "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" + + "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" + + "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" + + "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" + + "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" + + "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" + + "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" + + "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" + + "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" + + "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" + + "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" + + "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" + + "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" + + "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" + + "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" + + "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" + + "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" + + "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" + + "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" + + "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" + + "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" + + "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" + + "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" + + "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" + + "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" + + "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" + + "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" + + "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" + + "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" + + "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" + + "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" + + "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" + + "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" + + "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" + + "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" + + "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" + + "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" + + "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" + + "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻" + +var xorData string = "" + // Size: 4855 bytes + "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" + + "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" + + "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" + + "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" + + "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" + + "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" + + "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" + + "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" + + "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" + + "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" + + "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" + + "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" + + "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" + + "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" + + "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" + + "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" + + "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" + + "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" + + "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" + + "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" + + "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" + + "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" + + "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" + + "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" + + "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" + + "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" + + "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" + + "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" + + "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" + + "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" + + "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" + + "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" + + "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" + + "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" + + "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" + + "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" + + "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " + + "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" + + "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" + + "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" + + "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" + + "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" + + ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" + + "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" + + "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" + + "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" + + "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" + + "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" + + "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" + + "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" + + "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" + + "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" + + "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" + + "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" + + "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" + + "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" + + "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" + + "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" + + "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" + + "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" + + "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" + + "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" + + "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" + + "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" + + "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" + + "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" + + "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" + + "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" + + "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" + + "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" + + "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" + + "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" + + "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" + + "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" + + "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" + + "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" + + "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" + + "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" + + "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" + + "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" + + "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" + + "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" + + "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" + + "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" + + "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" + + "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" + + "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" + + "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" + + "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," + + "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" + + "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" + + "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" + + "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" + + ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" + + "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" + + "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" + + "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" + + "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" + + "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" + + "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" + + "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" + + "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" + + "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" + + "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" + + "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" + + "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" + + "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" + + "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" + + "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" + + "\x08\x1a\x0a\x03\x07</\x03\x07:+\x03\x07\x07*\x03\x06&\x1c\x03\x09\x0c" + + "\x16\x03\x09\x10\x0e\x03\x08'\x0f\x03\x08+\x09\x03\x074%\x03\x06!3\x03" + + "\x06\x03+\x03\x0b\x1e\x19\x03\x0a))\x03\x09\x08\x19\x03\x08,\x05\x03\x07" + + "<2\x03\x06\x1c>\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" + + "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" + + "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" + + "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" + + "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" + + "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" + + "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" + + "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" + + "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" + + "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" + + "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" + + "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" + + "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" + + "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" + + "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" + + "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" + + "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" + + "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." + + "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" + + "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" + + "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " + + "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" + + "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" + + "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" + + "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" + + "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" + + "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" + + "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," + + "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" + + "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" + + "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" + + "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" + + "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" + + "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" + + "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" + + "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" + + "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" + + "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" + + "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" + + "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" + + "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" + + "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" + + "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" + + "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" + + "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" + + "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" + + "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" + + "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" + + "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" + + "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" + + "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" + + "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" + + "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" + + "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" + + "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" + + "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" + + "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" + + "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" + + "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" + + "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" + + "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" + + "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" + + "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" + + "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" + + "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" + + "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" + + "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," + + "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" + + "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" + + "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" + + "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" + + "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" + + "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" + + "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" + + "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" + + "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" + + "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" + + "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" + + "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" + + "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" + + "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" + + "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" + + "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" + + "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" + + "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" + + "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" + + "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" + + "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" + + "\x04\x03\x0c?\x05\x03\x0c<?\x03\x0c=\x00\x03\x0c=\x06\x03\x0c=\x05\x03" + + "\x0c=\x0c\x03\x0c=\x0f\x03\x0c=\x0d\x03\x0c=\x0b\x03\x0c=\x07\x03\x0c=" + + "\x19\x03\x0c=\x15\x03\x0c=\x11\x03\x0c=1\x03\x0c=3\x03\x0c=0\x03\x0c=>" + + "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" + + "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" + + "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" + + "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" + + "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" + + "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" + + "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" + + "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" + + "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" + + "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" + + "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" + + "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" + + "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" + + "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" + + "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" + + "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" + + "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" + + "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" + + "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" + + "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" + + "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" + + "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" + + "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" + + "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" + + "\x05\x22\x05\x03\x050\x1d" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// idnaTrie. Total size: 29052 bytes (28.37 KiB). Checksum: ef06e7ecc26f36dd. +type idnaTrie struct{} + +func newIdnaTrie(i int) *idnaTrie { + return &idnaTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 125: + return uint16(idnaValues[n<<6+uint32(b)]) + default: + n -= 125 + return uint16(idnaSparse.lookup(n, b)) + } +} + +// idnaValues: 127 blocks, 8128 entries, 16256 bytes +// The third block is the zero block. +var idnaValues = [8128]uint16{ + // Block 0x0, offset 0x0 + 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, + 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, + 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080, + 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080, + 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080, + 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080, + 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080, + 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080, + 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008, + 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080, + 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080, + // Block 0x1, offset 0x40 + 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105, + 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105, + 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105, + 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105, + 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080, + 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008, + 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008, + 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008, + 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008, + 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080, + 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018, + 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018, + 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a, + 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005, + 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018, + 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018, + // Block 0x4, offset 0x100 + 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008, + 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008, + 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008, + 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008, + 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008, + 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008, + 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008, + 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008, + 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008, + 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d, + 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199, + // Block 0x5, offset 0x140 + 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d, + 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008, + 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008, + 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008, + 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008, + 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008, + 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008, + 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008, + 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008, + 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d, + 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9, + // Block 0x6, offset 0x180 + 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008, + 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d, + 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d, + 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d, + 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155, + 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008, + 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d, + 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd, + 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d, + 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008, + 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9, + 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d, + 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d, + 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d, + 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008, + 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008, + 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008, + 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008, + 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008, + 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008, + 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008, + // Block 0x8, offset 0x200 + 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008, + 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008, + 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008, + 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008, + 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008, + 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008, + 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008, + 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008, + 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008, + 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d, + 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008, + // Block 0x9, offset 0x240 + 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018, + 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008, + 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008, + 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018, + 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a, + 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369, + 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018, + 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018, + 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018, + 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, + 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, + // Block 0xa, offset 0x280 + 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, + 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, + 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, + 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, + 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, + 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, + 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, + 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, + 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, + 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, + 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2, + 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040, + 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105, + 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105, + 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105, + 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d, + 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d, + 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008, + 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008, + 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008, + 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008, + // Block 0xc, offset 0x300 + 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008, + 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008, + 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd, + 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008, + 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008, + 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008, + 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008, + 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008, + 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd, + 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008, + 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d, + // Block 0xd, offset 0x340 + 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008, + 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008, + 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008, + 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008, + 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008, + 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008, + 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008, + 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008, + 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008, + 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, + 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, + // Block 0xe, offset 0x380 + 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, + 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, + 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, + 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, + 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, + 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008, + 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008, + 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008, + 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008, + 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008, + 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d, + 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d, + 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008, + 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008, + 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008, + 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008, + 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008, + 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008, + 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008, + 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008, + 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008, + // Block 0x10, offset 0x400 + 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008, + 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008, + 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008, + 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008, + 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008, + 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008, + 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008, + 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008, + 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5, + 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, + 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, + // Block 0x11, offset 0x440 + 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, + 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, + 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, + 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, + 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, + 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, + 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, + 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, + 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, + 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, + 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, + // Block 0x12, offset 0x480 + 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, + 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, + 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, + 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, + 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, + 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, + 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, + 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, + 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, + 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, + 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, + 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, + 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, + 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, + 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, + 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, + 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, + 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, + 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, + 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, + 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, + // Block 0x14, offset 0x500 + 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, + 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, + 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, + 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, + 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, + 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, + 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, + 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, + 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, + 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, + 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, + // Block 0x15, offset 0x540 + 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08, + 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08, + 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08, + 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808, + 0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040, + 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08, + 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08, + 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040, + 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040, + 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040, + 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040, + // Block 0x16, offset 0x580 + 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308, + 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008, + 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308, + 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308, + 0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1, + 0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308, + 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008, + 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, + 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008, + 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008, + 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008, + 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008, + 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040, + 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008, + 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008, + 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008, + 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040, + 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, + 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040, + 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040, + 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008, + // Block 0x18, offset 0x600 + 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040, + 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008, + 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040, + 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008, + 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1, + 0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308, + 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008, + 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, + 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018, + 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018, + 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x0040, 0x63f: 0x0040, + // Block 0x19, offset 0x640 + 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008, + 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040, + 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040, + 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008, + 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008, + 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008, + 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040, + 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, + 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008, + 0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040, + 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008, + // Block 0x1a, offset 0x680 + 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040, + 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308, + 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308, + 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040, + 0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040, + 0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040, + 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008, + 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, + 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308, + 0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040, + 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008, + 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008, + 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008, + 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008, + 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008, + 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008, + 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040, + 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, + 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008, + 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, + 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008, + // Block 0x1c, offset 0x700 + 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308, + 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008, + 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040, + 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040, + 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040, + 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308, + 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008, + 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, + 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040, + 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308, + 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308, + // Block 0x1d, offset 0x740 + 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008, + 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008, + 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040, + 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008, + 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008, + 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008, + 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040, + 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, + 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008, + 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040, + 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308, + // Block 0x1e, offset 0x780 + 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040, + 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008, + 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040, + 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008, + 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9, + 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308, + 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008, + 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008, + 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018, + 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040, + 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008, + 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040, + 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040, + 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040, + 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040, + 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008, + 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008, + 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008, + 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008, + 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040, + 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008, + // Block 0x20, offset 0x800 + 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040, + 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308, + 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040, + 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040, + 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040, + 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308, + 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008, + 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, + 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040, + 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018, + 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018, + // Block 0x21, offset 0x840 + 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0040, 0x845: 0x0008, + 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008, + 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040, + 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008, + 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008, + 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008, + 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040, + 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, + 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008, + 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040, + 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308, + // Block 0x22, offset 0x880 + 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040, + 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, + 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040, + 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040, + 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040, + 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, + 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, + 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, + 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040, + 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040, + 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040, + 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008, + 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040, + 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008, + 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018, + 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308, + 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008, + 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, + 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018, + 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008, + 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008, + // Block 0x24, offset 0x900 + 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040, + 0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040, + 0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040, + 0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008, + 0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008, + 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, + 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040, + 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008, + 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308, + 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308, + 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040, + // Block 0x25, offset 0x940 + 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008, + 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, + 0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008, + 0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79, + 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008, + 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008, + 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9, + 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040, + 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59, + 0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308, + 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008, + // Block 0x26, offset 0x980 + 0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018, + 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, + 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308, + 0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308, + 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11, + 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308, + 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308, + 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308, + 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308, + 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308, + 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008, + 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008, + 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008, + 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008, + 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008, + 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008, + 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008, + 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008, + 0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41, + 0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008, + 0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269, + // Block 0x28, offset 0xa00 + 0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1, + 0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011, + 0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041, + 0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9, + 0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099, + 0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269, + 0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1, + 0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008, + 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008, + 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008, + 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008, + // Block 0x29, offset 0xa40 + 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008, + 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008, + 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008, + 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008, + 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169, + 0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9, + 0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251, + 0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9, + 0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359, + 0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1, + 0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429, + // Block 0x2a, offset 0xa80 + 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, + 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, + 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, + 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008, + 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008, + 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, + 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, + 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, + 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, + 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, + 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, + // Block 0x2b, offset 0xac0 + 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008, + 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008, + 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008, + 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, + 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008, + 0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008, + 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008, + 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008, + 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008, + 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008, + 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008, + // Block 0x2c, offset 0xb00 + 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008, + 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045, + 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008, + 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008, + 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045, + 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008, + 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045, + 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045, + 0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489, + 0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1, + 0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040, + // Block 0x2d, offset 0xb40 + 0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1, + 0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591, + 0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1, + 0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1, + 0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771, + 0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891, + 0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831, + 0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951, + 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040, + 0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459, + 0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686, + // Block 0x2e, offset 0xb80 + 0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040, + 0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489, + 0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008, + 0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008, + 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2, + 0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61, + 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045, + 0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa, + 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040, + 0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9, + 0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a, + 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0, + 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d, + 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e, + 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, + 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018, + 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040, + 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a, + 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018, + 0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018, + 0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018, + // Block 0x30, offset 0xc00 + 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018, + 0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018, + 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018, + 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9, + 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018, + 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340, + 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040, + 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340, + 0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61, + 0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd, + 0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71, + // Block 0x31, offset 0xc40 + 0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61, + 0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5, + 0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09, + 0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359, + 0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040, + 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018, + 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018, + 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018, + 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018, + 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018, + 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018, + // Block 0x32, offset 0xc80 + 0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e, + 0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249, + 0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41, + 0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018, + 0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269, + 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018, + 0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018, + 0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09, + 0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9, + 0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd, + 0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9, + 0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018, + 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151, + 0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279, + 0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399, + 0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439, + 0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369, + 0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61, + 0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451, + 0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5, + 0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61, + // Block 0x34, offset 0xd00 + 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018, + 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040, + 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, + 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, + 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040, + 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51, + 0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601, + 0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691, + 0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26, + 0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6, + 0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a, + // Block 0x35, offset 0xd40 + 0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a, + 0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040, + 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040, + 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040, + 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46, + 0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06, + 0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6, + 0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86, + 0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46, + 0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199, + 0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259, + // Block 0x36, offset 0xd80 + 0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99, + 0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089, + 0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9, + 0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249, + 0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71, + 0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9, + 0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1, + 0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018, + 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018, + 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018, + 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008, + 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008, + 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008, + 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008, + 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008, + 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd, + 0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d, + 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9, + 0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d, + 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008, + 0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9, + // Block 0x38, offset 0xe00 + 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008, + 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008, + 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008, + 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008, + 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008, + 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008, + 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018, + 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308, + 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040, + 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018, + 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018, + // Block 0x39, offset 0xe40 + 0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d, + 0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d, + 0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d, + 0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040, + 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040, + 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040, + 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040, + 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040, + 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040, + 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040, + 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040, + // Block 0x3a, offset 0xe80 + 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008, + 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018, + 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018, + 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018, + 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018, + 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018, + 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018, + 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018, + 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018, + 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018, + 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018, + // Block 0x3b, offset 0xec0 + 0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd, + 0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd, + 0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d, + 0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d, + 0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d, + 0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd, + 0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d, + 0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd, + 0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d, + 0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd, + 0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d, + // Block 0x3c, offset 0xf00 + 0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd, + 0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d, + 0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018, + 0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd, + 0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d, + 0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008, + 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008, + 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008, + 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008, + 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040, + 0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040, + // Block 0x3d, offset 0xf40 + 0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd, + 0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018, + 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761, + 0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1, + 0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881, + 0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd, + 0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d, + 0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d, + 0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd, + 0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d, + 0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018, + // Block 0x3e, offset 0xf80 + 0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d, + 0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d, + 0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd, + 0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd, + 0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d, + 0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d, + 0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd, + 0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d, + 0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999, + 0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29, + 0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69, + 0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69, + 0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15, + 0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75, + 0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded, + 0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d, + 0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5, + 0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d, + 0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d, + 0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd, + 0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040, + // Block 0x40, offset 0x1000 + 0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9, + 0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1, + 0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9, + 0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549, + 0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1, + 0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11, + 0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91, + 0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9, + 0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011, + 0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209, + 0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361, + // Block 0x41, offset 0x1040 + 0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541, + 0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781, + 0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979, + 0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89, + 0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1, + 0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99, + 0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9, + 0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9, + 0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069, + 0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9, + 0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9, + // Block 0x42, offset 0x1080 + 0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271, + 0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9, + 0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed, + 0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371, + 0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9, + 0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d, + 0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211, + 0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1, + 0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599, + 0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9, + 0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671, + 0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709, + 0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781, + 0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1, + 0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811, + 0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901, + 0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1, + 0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11, + 0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31, + 0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51, + 0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d, + // Block 0x44, offset 0x1100 + 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, + 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, + 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, + 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, + 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008, + 0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008, + 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008, + 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308, + 0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308, + 0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308, + 0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008, + // Block 0x45, offset 0x1140 + 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008, + 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008, + 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008, + 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008, + 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11, + 0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008, + 0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008, + 0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008, + 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008, + 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008, + 0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008, + // Block 0x46, offset 0x1180 + 0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018, + 0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018, + 0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018, + 0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008, + 0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008, + 0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008, + 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, + 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, + 0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008, + 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008, + 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008, + // Block 0x47, offset 0x11c0 + 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, + 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008, + 0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, + 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, + 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, + 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, + 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, + 0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008, + 0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008, + 0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d, + 0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008, + // Block 0x48, offset 0x1200 + 0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008, + 0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d, + 0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008, + 0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008, + 0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008, + 0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008, + 0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008, + 0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0040, + 0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008, + 0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040, + 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040, + // Block 0x49, offset 0x1240 + 0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575, + 0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635, + 0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008, + 0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715, + 0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5, + 0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008, + 0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008, + 0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935, + 0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5, + 0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5, + 0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35, + // Block 0x4a, offset 0x1280 + 0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35, + 0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5, + 0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19, + 0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91, + 0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040, + 0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040, + 0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040, + 0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040, + 0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040, + 0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040, + 0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001, + 0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040, + 0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040, + 0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9, + 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1, + 0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149, + 0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2, + 0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1, + 0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1, + 0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479, + 0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040, + // Block 0x4c, offset 0x1300 + 0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040, + 0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659, + 0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721, + 0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751, + 0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769, + 0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799, + 0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1, + 0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1, + 0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9, + 0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829, + 0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841, + // Block 0x4d, offset 0x1340 + 0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871, + 0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9, + 0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9, + 0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919, + 0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931, + 0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961, + 0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991, + 0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1, + 0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818, + 0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818, + 0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040, + 0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040, + 0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040, + 0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09, + 0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479, + 0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81, + 0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1, + 0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19, + 0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91, + 0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1, + 0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1, + 0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1, + 0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1, + 0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991, + 0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81, + 0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a, + 0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99, + 0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89, + 0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79, + 0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19, + 0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469, + // Block 0x50, offset 0x1400 + 0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649, + 0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9, + 0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49, + 0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21, + 0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9, + 0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01, + 0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91, + 0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9, + 0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171, + 0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289, + 0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329, + // Block 0x51, offset 0x1440 + 0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1, + 0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621, + 0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739, + 0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1, + 0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9, + 0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29, + 0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079, + 0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1, + 0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171, + 0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261, + 0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301, + // Block 0x52, offset 0x1480 + 0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1, + 0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1, + 0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171, + 0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261, + 0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351, + 0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441, + 0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509, + 0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1, + 0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081, + 0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239, + 0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040, + 0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, + 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609, + 0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721, + 0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839, + 0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919, + 0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9, + 0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9, + 0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9, + 0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1, + 0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79, + // Block 0x54, offset 0x1500 + 0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989, + 0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040, + 0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040, + 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040, + 0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, + 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040, + 0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040, + 0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040, + 0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9, + 0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12, + 0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040, + // Block 0x55, offset 0x1540 + 0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0, + 0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0, + 0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55, + 0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75, + 0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040, + 0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308, + 0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308, + 0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308, + 0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2, + 0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35, + 0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55, + // Block 0x56, offset 0x1580 + 0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018, + 0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56, + 0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95, + 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa, + 0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95, + 0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99, + 0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda, + 0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040, + 0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040, + 0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081, + 0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1, + // Block 0x57, offset 0x15c0 + 0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141, + 0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171, + 0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1, + 0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1, + 0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201, + 0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219, + 0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249, + 0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291, + 0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1, + 0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9, + 0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1, + // Block 0x58, offset 0x1600 + 0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321, + 0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339, + 0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369, + 0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381, + 0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1, + 0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9, + 0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9, + 0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1, + 0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441, + 0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9, + 0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea, + 0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2, + 0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9, + 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81, + 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2, + 0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159, + 0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41, + 0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9, + 0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9, + 0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a, + 0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09, + 0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51, + 0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039, + 0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279, + 0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a, + 0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115, + 0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5, + 0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295, + 0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355, + 0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415, + 0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515, + 0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595, + 0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5, + 0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655, + 0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115, + 0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735, + 0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5, + 0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5, + 0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5, + 0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5, + 0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040, + // Block 0x5c, offset 0x1700 + 0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5, + 0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715, + 0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040, + 0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935, + 0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040, + 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6, + 0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35, + 0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040, + 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040, + 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340, + 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, + // Block 0x5d, offset 0x1740 + 0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08, + 0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808, + 0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08, + 0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908, + 0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08, + 0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808, + 0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040, + 0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18, + 0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818, + 0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, + 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, + // Block 0x5e, offset 0x1780 + 0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08, + 0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08, + 0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08, + 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040, + 0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040, + 0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040, + 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18, + 0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818, + 0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040, + 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040, + 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008, + 0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008, + 0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040, + 0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008, + 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008, + 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008, + 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040, + 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008, + 0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008, + 0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x0040, + 0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008, + // Block 0x60, offset 0x1800 + 0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040, + 0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008, + 0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040, + 0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008, + 0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008, + 0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008, + 0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308, + 0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040, + 0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040, + 0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040, + 0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040, + // Block 0x61, offset 0x1840 + 0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199, + 0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359, + 0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269, + 0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369, + 0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9, + 0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259, + 0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99, + 0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089, + 0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9, + 0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249, + 0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359, + // Block 0x62, offset 0x1880 + 0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269, + 0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369, + 0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9, + 0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259, + 0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99, + 0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089, + 0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9, + 0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249, + 0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71, + 0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9, + 0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9, + 0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259, + 0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99, + 0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089, + 0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040, + 0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040, + 0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71, + 0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9, + 0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1, + 0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199, + 0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259, + // Block 0x64, offset 0x1900 + 0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99, + 0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089, + 0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9, + 0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249, + 0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71, + 0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9, + 0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1, + 0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199, + 0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359, + 0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269, + 0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089, + // Block 0x65, offset 0x1940 + 0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9, + 0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040, + 0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71, + 0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9, + 0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040, + 0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199, + 0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359, + 0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269, + 0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369, + 0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9, + 0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040, + // Block 0x66, offset 0x1980 + 0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040, + 0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9, + 0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040, + 0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199, + 0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359, + 0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269, + 0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369, + 0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9, + 0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259, + 0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99, + 0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1, + 0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199, + 0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359, + 0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269, + 0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369, + 0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9, + 0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259, + 0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99, + 0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089, + 0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9, + 0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359, + 0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269, + 0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369, + 0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9, + 0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259, + 0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99, + 0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089, + 0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9, + 0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249, + 0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71, + 0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369, + 0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9, + 0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259, + 0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99, + 0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089, + 0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9, + 0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249, + 0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71, + 0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9, + 0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1, + 0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259, + 0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99, + 0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089, + 0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9, + 0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249, + 0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71, + 0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9, + 0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1, + 0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199, + 0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359, + 0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089, + 0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9, + 0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249, + 0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71, + 0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9, + 0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1, + 0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099, + 0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429, + 0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71, + 0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9, + 0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9, + 0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11, + 0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109, + 0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1, + 0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429, + 0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099, + 0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429, + 0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71, + 0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9, + 0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01, + 0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11, + 0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109, + 0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1, + 0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429, + 0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099, + 0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429, + 0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71, + 0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9, + 0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01, + 0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1, + 0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109, + 0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1, + 0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429, + 0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099, + 0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429, + 0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71, + 0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9, + 0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01, + 0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1, + 0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41, + 0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1, + 0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429, + 0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099, + 0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429, + 0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71, + 0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9, + 0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01, + 0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1, + 0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41, + 0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1, + 0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429, + 0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41, + 0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079, + 0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1, + 0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61, + 0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9, + 0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81, + 0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079, + 0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1, + 0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61, + 0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1, + // Block 0x71, offset 0x1c40 + 0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115, + 0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135, + 0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115, + 0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175, + 0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115, + 0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08, + 0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08, + 0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08, + 0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08, + 0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08, + 0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08, + // Block 0x72, offset 0x1c80 + 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411, + 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1, + 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9, + 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231, + 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949, + 0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, + 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429, + 0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, + 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, + 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351, + 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040, + 0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, + 0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9, + 0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231, + 0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949, + 0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040, + 0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, + 0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, + 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, + 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, + 0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040, + // Block 0x74, offset 0x1d00 + 0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411, + 0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1, + 0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9, + 0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231, + 0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040, + 0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249, + 0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429, + 0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339, + 0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1, + 0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351, + 0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02, + 0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018, + 0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2, + 0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72, + 0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32, + 0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2, + 0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2, + 0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0040, + 0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199, + 0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359, + 0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089, + 0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1, + 0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018, + 0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018, + 0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018, + 0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018, + 0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018, + 0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040, + 0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018, + 0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018, + 0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040, + 0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040, + 0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289, + 0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349, + 0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409, + 0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9, + 0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589, + 0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649, + 0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709, + 0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9, + 0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040, + // Block 0x78, offset 0x1e00 + 0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79, + 0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39, + 0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9, + 0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39, + 0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9, + 0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79, + 0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39, + 0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9, + 0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059, + 0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9, + 0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179, + // Block 0x79, offset 0x1e40 + 0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239, + 0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9, + 0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399, + 0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459, + 0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309, + 0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559, + 0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9, + 0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679, + 0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9, + 0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d, + 0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9, + 0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959, + 0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d, + 0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d, + 0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9, + 0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99, + 0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9, + 0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9, + 0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99, + 0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39, + 0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639, + 0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9, + 0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d, + 0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9, + 0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d, + 0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd, + 0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979, + 0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19, + 0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d, + 0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d, + 0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99, + 0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39, + 0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9, + 0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39, + 0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd, + 0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19, + 0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9, + 0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59, + 0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd, + 0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d, + 0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d, + 0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d, + 0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879, + 0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919, + 0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd, + 0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9, + 0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99, + 0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39, + 0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9, + 0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d, + 0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19, + 0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9, + 0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59, + 0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9, + 0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d, + 0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040, + 0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040, + 0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040, + 0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040, + 0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040, + 0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040, +} + +// idnaIndex: 36 blocks, 2304 entries, 4608 bytes +// Block 0 is the zero block. +var idnaIndex = [2304]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, + 0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21, + // Block 0x4, offset 0x100 + 0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16, + 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d, + 0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91, + 0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96, + // Block 0x5, offset 0x140 + 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, + 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, + 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, + 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, + 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, + 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, + 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3, + 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c, + // Block 0x6, offset 0x180 + 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b, + 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b, + 0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, + 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, + 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, + 0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0, + 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5, + 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1, + 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41, + 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, + 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, + 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, + 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, + 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, + 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, + // Block 0x8, offset 0x200 + 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, + 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, + 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, + 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, + 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, + 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, + 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, + 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, + // Block 0x9, offset 0x240 + 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, + 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, + 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, + 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, + 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, + 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, + 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, + 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, + // Block 0xa, offset 0x280 + 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, + 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, + 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, + 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, + 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, + 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, + 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, + 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, + 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, + 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, + 0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8, + 0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0, + 0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8, + 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, + 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, + // Block 0xc, offset 0x300 + 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, + 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, + 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, + 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa, + // Block 0xd, offset 0x340 + 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, + 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, + 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, + 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, + 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, + 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, + 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, + 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, + // Block 0xe, offset 0x380 + 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, + 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, + 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, + 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, + 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe, + 0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c, + 0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52, + 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108, + 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e, + 0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba, + 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba, + 0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c, + 0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba, + 0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, + 0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba, + // Block 0x10, offset 0x400 + 0x400: 0x127, 0x401: 0x128, 0x402: 0x129, 0x403: 0x12a, 0x404: 0x12b, 0x405: 0x12c, 0x406: 0x12d, 0x407: 0x12e, + 0x408: 0x12f, 0x409: 0xba, 0x40a: 0x130, 0x40b: 0x131, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba, + 0x410: 0x132, 0x411: 0x133, 0x412: 0x134, 0x413: 0x135, 0x414: 0xba, 0x415: 0xba, 0x416: 0x136, 0x417: 0x137, + 0x418: 0x138, 0x419: 0x139, 0x41a: 0x13a, 0x41b: 0x13b, 0x41c: 0x13c, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, + 0x420: 0xba, 0x421: 0xba, 0x422: 0x13d, 0x423: 0x13e, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba, + 0x428: 0x13f, 0x429: 0x140, 0x42a: 0x141, 0x42b: 0x142, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, + 0x430: 0x143, 0x431: 0x144, 0x432: 0x145, 0x433: 0xba, 0x434: 0x146, 0x435: 0x147, 0x436: 0xba, 0x437: 0xba, + 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba, + // Block 0x11, offset 0x440 + 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, + 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x148, 0x44f: 0xba, + 0x450: 0x9b, 0x451: 0x149, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x14a, 0x456: 0xba, 0x457: 0xba, + 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, + 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, + 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, + 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, + 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, + // Block 0x12, offset 0x480 + 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, + 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, + 0x490: 0x14b, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, + 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, + 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, + 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, + 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, + 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, + // Block 0x13, offset 0x4c0 + 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, + 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, + 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, + 0x4d8: 0x9f, 0x4d9: 0x14c, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, + 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, + 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, + 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, + 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, + // Block 0x14, offset 0x500 + 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, + 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, + 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, + 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, + 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, + 0x528: 0x142, 0x529: 0x14d, 0x52a: 0xba, 0x52b: 0x14e, 0x52c: 0x14f, 0x52d: 0x150, 0x52e: 0x151, 0x52f: 0xba, + 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, + 0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x152, 0x53e: 0x153, 0x53f: 0x154, + // Block 0x15, offset 0x540 + 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, + 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, + 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, + 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x155, + 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, + 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x156, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, + 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, + 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, + // Block 0x16, offset 0x580 + 0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x157, 0x585: 0x158, 0x586: 0x9f, 0x587: 0x9f, + 0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x159, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, + 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, + 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, + 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, + 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, + 0x5b0: 0x9f, 0x5b1: 0x15a, 0x5b2: 0x15b, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, + 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x15c, 0x5c4: 0x15d, 0x5c5: 0x15e, 0x5c6: 0x15f, 0x5c7: 0x160, + 0x5c8: 0x9b, 0x5c9: 0x161, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x162, 0x5ce: 0xba, 0x5cf: 0xba, + 0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66, + 0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e, + 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, + 0x5e8: 0x163, 0x5e9: 0x164, 0x5ea: 0x165, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, + 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, + 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, + // Block 0x18, offset 0x600 + 0x600: 0x166, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba, + 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, + 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, + 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, + 0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x167, 0x624: 0x6f, 0x625: 0x168, 0x626: 0xba, 0x627: 0xba, + 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, + 0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, + 0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x169, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, + // Block 0x19, offset 0x640 + 0x640: 0x16a, 0x641: 0x9b, 0x642: 0x16b, 0x643: 0x16c, 0x644: 0x73, 0x645: 0x74, 0x646: 0x16d, 0x647: 0x16e, + 0x648: 0x75, 0x649: 0x16f, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, + 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, + 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x170, 0x65c: 0x9b, 0x65d: 0x171, 0x65e: 0x9b, 0x65f: 0x172, + 0x660: 0x173, 0x661: 0x174, 0x662: 0x175, 0x663: 0xba, 0x664: 0x176, 0x665: 0x177, 0x666: 0x178, 0x667: 0x179, + 0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, + 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, + 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, + // Block 0x1a, offset 0x680 + 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, + 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, + 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, + 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x17a, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, + 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, + 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, + 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, + 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, + 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, + 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, + 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x17b, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, + 0x6e0: 0x17c, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, + 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, + 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, + 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, + // Block 0x1c, offset 0x700 + 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, + 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, + 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, + 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, + 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, + 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, + 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, + 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x17d, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f, + // Block 0x1d, offset 0x740 + 0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f, + 0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f, + 0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f, + 0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f, + 0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f, + 0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x17e, + 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, + 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, + // Block 0x1e, offset 0x780 + 0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba, + 0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba, + 0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba, + 0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba, + 0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x17f, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x180, 0x7a7: 0x7b, + 0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba, + 0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba, + 0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba, + // Block 0x1f, offset 0x7c0 + 0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07, + 0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17, + 0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07, + 0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c, + 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, + 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, + // Block 0x20, offset 0x800 + 0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b, + 0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b, + 0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b, + 0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b, + 0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b, + 0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b, + 0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b, + 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b, + // Block 0x21, offset 0x840 + 0x840: 0x181, 0x841: 0x182, 0x842: 0xba, 0x843: 0xba, 0x844: 0x183, 0x845: 0x183, 0x846: 0x183, 0x847: 0x184, + 0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba, + 0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba, + 0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba, + 0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba, + 0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba, + 0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba, + 0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba, + // Block 0x22, offset 0x880 + 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, + 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, + 0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b, + 0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b, + 0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b, + 0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b, + 0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b, + 0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b, + 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b, +} + +// idnaSparseOffset: 264 entries, 528 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x8a, 0x93, 0xa3, 0xb1, 0xbd, 0xc9, 0xda, 0xe4, 0xeb, 0xf8, 0x109, 0x110, 0x11b, 0x12a, 0x138, 0x142, 0x144, 0x149, 0x14c, 0x14f, 0x151, 0x15d, 0x168, 0x170, 0x176, 0x17c, 0x181, 0x186, 0x189, 0x18d, 0x193, 0x198, 0x1a4, 0x1ae, 0x1b4, 0x1c5, 0x1cf, 0x1d2, 0x1da, 0x1dd, 0x1ea, 0x1f2, 0x1f6, 0x1fd, 0x205, 0x215, 0x221, 0x223, 0x22d, 0x239, 0x245, 0x251, 0x259, 0x25e, 0x268, 0x279, 0x27d, 0x288, 0x28c, 0x295, 0x29d, 0x2a3, 0x2a8, 0x2ab, 0x2af, 0x2b5, 0x2b9, 0x2bd, 0x2c3, 0x2ca, 0x2d0, 0x2d8, 0x2df, 0x2ea, 0x2f4, 0x2f8, 0x2fb, 0x301, 0x305, 0x307, 0x30a, 0x30c, 0x30f, 0x319, 0x31c, 0x32b, 0x32f, 0x334, 0x337, 0x33b, 0x340, 0x345, 0x34b, 0x351, 0x360, 0x366, 0x36a, 0x379, 0x37e, 0x386, 0x390, 0x39b, 0x3a3, 0x3b4, 0x3bd, 0x3cd, 0x3da, 0x3e4, 0x3e9, 0x3f6, 0x3fa, 0x3ff, 0x401, 0x405, 0x407, 0x40b, 0x414, 0x41a, 0x41e, 0x42e, 0x438, 0x43d, 0x440, 0x446, 0x44d, 0x452, 0x456, 0x45c, 0x461, 0x46a, 0x46f, 0x475, 0x47c, 0x483, 0x48a, 0x48e, 0x493, 0x496, 0x49b, 0x4a7, 0x4ad, 0x4b2, 0x4b9, 0x4c1, 0x4c6, 0x4ca, 0x4da, 0x4e1, 0x4e5, 0x4e9, 0x4f0, 0x4f2, 0x4f5, 0x4f8, 0x4fc, 0x500, 0x506, 0x50f, 0x51b, 0x522, 0x52b, 0x533, 0x53a, 0x548, 0x555, 0x562, 0x56b, 0x56f, 0x57d, 0x585, 0x590, 0x599, 0x59f, 0x5a7, 0x5b0, 0x5ba, 0x5bd, 0x5c9, 0x5cc, 0x5d1, 0x5de, 0x5e7, 0x5f3, 0x5f6, 0x600, 0x609, 0x615, 0x622, 0x62a, 0x62d, 0x632, 0x635, 0x638, 0x63b, 0x642, 0x649, 0x64d, 0x658, 0x65b, 0x661, 0x666, 0x66a, 0x66d, 0x670, 0x673, 0x676, 0x679, 0x67e, 0x688, 0x68b, 0x68f, 0x69e, 0x6aa, 0x6ae, 0x6b3, 0x6b8, 0x6bc, 0x6c1, 0x6ca, 0x6d5, 0x6db, 0x6e3, 0x6e7, 0x6eb, 0x6f1, 0x6f7, 0x6fc, 0x6ff, 0x70f, 0x716, 0x719, 0x71c, 0x720, 0x726, 0x72b, 0x730, 0x735, 0x738, 0x73d, 0x740, 0x743, 0x747, 0x74b, 0x74e, 0x75e, 0x76f, 0x774, 0x776, 0x778} + +// idnaSparseValues: 1915 entries, 7660 bytes +var idnaSparseValues = [1915]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x07}, + {value: 0xe105, lo: 0x80, hi: 0x96}, + {value: 0x0018, lo: 0x97, hi: 0x97}, + {value: 0xe105, lo: 0x98, hi: 0x9e}, + {value: 0x001f, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbf}, + // Block 0x1, offset 0x8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0xe01d, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0335, lo: 0x83, hi: 0x83}, + {value: 0x034d, lo: 0x84, hi: 0x84}, + {value: 0x0365, lo: 0x85, hi: 0x85}, + {value: 0xe00d, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0xe00d, lo: 0x88, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x89}, + {value: 0xe00d, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe00d, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0x8d}, + {value: 0xe00d, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0xbf}, + // Block 0x2, offset 0x19 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0249, lo: 0xb0, hi: 0xb0}, + {value: 0x037d, lo: 0xb1, hi: 0xb1}, + {value: 0x0259, lo: 0xb2, hi: 0xb2}, + {value: 0x0269, lo: 0xb3, hi: 0xb3}, + {value: 0x034d, lo: 0xb4, hi: 0xb4}, + {value: 0x0395, lo: 0xb5, hi: 0xb5}, + {value: 0xe1bd, lo: 0xb6, hi: 0xb6}, + {value: 0x0279, lo: 0xb7, hi: 0xb7}, + {value: 0x0289, lo: 0xb8, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbf}, + // Block 0x3, offset 0x25 + {value: 0x0000, lo: 0x01}, + {value: 0x3308, lo: 0x80, hi: 0xbf}, + // Block 0x4, offset 0x27 + {value: 0x0000, lo: 0x04}, + {value: 0x03f5, lo: 0x80, hi: 0x8f}, + {value: 0xe105, lo: 0x90, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x5, offset 0x2c + {value: 0x0000, lo: 0x07}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x0545, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x0008, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x6, offset 0x34 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0401, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x88}, + {value: 0x0018, lo: 0x89, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x7, offset 0x3f + {value: 0x0000, lo: 0x0b}, + {value: 0x0818, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x82}, + {value: 0x0818, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x85}, + {value: 0x0818, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0808, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x8, offset 0x4b + {value: 0x0000, lo: 0x03}, + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0c08, lo: 0x88, hi: 0x99}, + {value: 0x0a08, lo: 0x9a, hi: 0xbf}, + // Block 0x9, offset 0x4f + {value: 0x0000, lo: 0x0e}, + {value: 0x3308, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0c08, lo: 0x8d, hi: 0x8d}, + {value: 0x0a08, lo: 0x8e, hi: 0x98}, + {value: 0x0c08, lo: 0x99, hi: 0x9b}, + {value: 0x0a08, lo: 0x9c, hi: 0xaa}, + {value: 0x0c08, lo: 0xab, hi: 0xac}, + {value: 0x0a08, lo: 0xad, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xb5, hi: 0xb7}, + {value: 0x0c08, lo: 0xb8, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbf}, + // Block 0xa, offset 0x5e + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xb, offset 0x63 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0xc, offset 0x6b + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x99}, + {value: 0x0808, lo: 0x9a, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa3}, + {value: 0x0808, lo: 0xa4, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa7}, + {value: 0x0808, lo: 0xa8, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0818, lo: 0xb0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd, offset 0x77 + {value: 0x0000, lo: 0x0d}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0a08, lo: 0xa0, hi: 0xa9}, + {value: 0x0c08, lo: 0xaa, hi: 0xac}, + {value: 0x0808, lo: 0xad, hi: 0xad}, + {value: 0x0c08, lo: 0xae, hi: 0xae}, + {value: 0x0a08, lo: 0xaf, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb2}, + {value: 0x0a08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0a08, lo: 0xb6, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xe, offset 0x85 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa1}, + {value: 0x0840, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xbf}, + // Block 0xf, offset 0x8a + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x10, offset 0x93 + {value: 0x0000, lo: 0x0f}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x85}, + {value: 0x3008, lo: 0x86, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8c}, + {value: 0x3b08, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x11, offset 0xa3 + {value: 0x0000, lo: 0x0d}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x12, offset 0xb1 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xba}, + {value: 0x3b08, lo: 0xbb, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x13, offset 0xbd + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x14, offset 0xc9 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x89}, + {value: 0x3b08, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x3008, lo: 0x98, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x15, offset 0xda + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb2}, + {value: 0x08f1, lo: 0xb3, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb9}, + {value: 0x3b08, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0x16, offset 0xe4 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x8e}, + {value: 0x0018, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0xbf}, + // Block 0x17, offset 0xeb + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0961, lo: 0x9c, hi: 0x9c}, + {value: 0x0999, lo: 0x9d, hi: 0x9d}, + {value: 0x0008, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x18, offset 0xf8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe03d, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x19, offset 0x109 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0x1a, offset 0x110 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x1b, offset 0x11b + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xa1}, + {value: 0x3008, lo: 0xa2, hi: 0xa4}, + {value: 0x0008, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xbf}, + // Block 0x1c, offset 0x12a + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x8c}, + {value: 0x3308, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x3008, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x1d, offset 0x138 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x86}, + {value: 0x055d, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8c}, + {value: 0x055d, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0xe105, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0x1e, offset 0x142 + {value: 0x0000, lo: 0x01}, + {value: 0x0018, lo: 0x80, hi: 0xbf}, + // Block 0x1f, offset 0x144 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa0}, + {value: 0x2018, lo: 0xa1, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x20, offset 0x149 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa7}, + {value: 0x2018, lo: 0xa8, hi: 0xbf}, + // Block 0x21, offset 0x14c + {value: 0x0000, lo: 0x02}, + {value: 0x2018, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0xbf}, + // Block 0x22, offset 0x14f + {value: 0x0000, lo: 0x01}, + {value: 0x0008, lo: 0x80, hi: 0xbf}, + // Block 0x23, offset 0x151 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x24, offset 0x15d + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x25, offset 0x168 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x26, offset 0x170 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x27, offset 0x176 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x28, offset 0x17c + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x29, offset 0x181 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x2a, offset 0x186 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x2b, offset 0x189 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xbf}, + // Block 0x2c, offset 0x18d + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2d, offset 0x193 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x2e, offset 0x198 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x3b08, lo: 0x94, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x2f, offset 0x1a4 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x30, offset 0x1ae + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xb3}, + {value: 0x3340, lo: 0xb4, hi: 0xb5}, + {value: 0x3008, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x31, offset 0x1b4 + {value: 0x0000, lo: 0x10}, + {value: 0x3008, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x91}, + {value: 0x3b08, lo: 0x92, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0x93}, + {value: 0x0018, lo: 0x94, hi: 0x96}, + {value: 0x0008, lo: 0x97, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x32, offset 0x1c5 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x86}, + {value: 0x0218, lo: 0x87, hi: 0x87}, + {value: 0x0018, lo: 0x88, hi: 0x8a}, + {value: 0x33c0, lo: 0x8b, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0208, lo: 0xa0, hi: 0xbf}, + // Block 0x33, offset 0x1cf + {value: 0x0000, lo: 0x02}, + {value: 0x0208, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x34, offset 0x1d2 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0208, lo: 0x87, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xa9}, + {value: 0x0208, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x35, offset 0x1da + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0x36, offset 0x1dd + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x37, offset 0x1ea + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x38, offset 0x1f2 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x39, offset 0x1f6 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0028, lo: 0x9a, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xbf}, + // Block 0x3a, offset 0x1fd + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x3308, lo: 0x97, hi: 0x98}, + {value: 0x3008, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x3b, offset 0x205 + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x94}, + {value: 0x3008, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xac}, + {value: 0x3008, lo: 0xad, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3c, offset 0x215 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xbd}, + {value: 0x3318, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x221 + {value: 0x0000, lo: 0x01}, + {value: 0x0040, lo: 0x80, hi: 0xbf}, + // Block 0x3e, offset 0x223 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3008, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x3f, offset 0x22d + {value: 0x0000, lo: 0x0b}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x3808, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x40, offset 0x239 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3808, lo: 0xaa, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xbf}, + // Block 0x41, offset 0x245 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3008, lo: 0xaa, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3808, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x42, offset 0x251 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x3008, lo: 0xa4, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbf}, + // Block 0x43, offset 0x259 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x44, offset 0x25e + {value: 0x0000, lo: 0x09}, + {value: 0x0e29, lo: 0x80, hi: 0x80}, + {value: 0x0e41, lo: 0x81, hi: 0x81}, + {value: 0x0e59, lo: 0x82, hi: 0x82}, + {value: 0x0e71, lo: 0x83, hi: 0x83}, + {value: 0x0e89, lo: 0x84, hi: 0x85}, + {value: 0x0ea1, lo: 0x86, hi: 0x86}, + {value: 0x0eb9, lo: 0x87, hi: 0x87}, + {value: 0x057d, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0x45, offset 0x268 + {value: 0x0000, lo: 0x10}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x92}, + {value: 0x0018, lo: 0x93, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa8}, + {value: 0x0008, lo: 0xa9, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x46, offset 0x279 + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0x47, offset 0x27d + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x87}, + {value: 0xe045, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0xe045, lo: 0x98, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0xe045, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbf}, + // Block 0x48, offset 0x288 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x3318, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbf}, + // Block 0x49, offset 0x28c + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x24c1, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x4a, offset 0x295 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x24f1, lo: 0xac, hi: 0xac}, + {value: 0x2529, lo: 0xad, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xae}, + {value: 0x2579, lo: 0xaf, hi: 0xaf}, + {value: 0x25b1, lo: 0xb0, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0x4b, offset 0x29d + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x9f}, + {value: 0x0080, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xad}, + {value: 0x0080, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x4c, offset 0x2a3 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa8}, + {value: 0x09c5, lo: 0xa9, hi: 0xa9}, + {value: 0x09e5, lo: 0xaa, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xbf}, + // Block 0x4d, offset 0x2a8 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0x4e, offset 0x2ab + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x28c1, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x4f, offset 0x2af + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0e66, lo: 0xb4, hi: 0xb4}, + {value: 0x292a, lo: 0xb5, hi: 0xb5}, + {value: 0x0e86, lo: 0xb6, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x50, offset 0x2b5 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x9b}, + {value: 0x2941, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0xbf}, + // Block 0x51, offset 0x2b9 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x52, offset 0x2bd + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0018, lo: 0xbd, hi: 0xbf}, + // Block 0x53, offset 0x2c3 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x92}, + {value: 0x0040, lo: 0x93, hi: 0xab}, + {value: 0x0018, lo: 0xac, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x54, offset 0x2ca + {value: 0x0000, lo: 0x05}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x03f5, lo: 0x90, hi: 0x9f}, + {value: 0x0ea5, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x55, offset 0x2d0 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x56, offset 0x2d8 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xae}, + {value: 0xe075, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0x57, offset 0x2df + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x58, offset 0x2ea + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xbf}, + // Block 0x59, offset 0x2f4 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x5a, offset 0x2f8 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0x5b, offset 0x2fb + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9e}, + {value: 0x0edd, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x5c, offset 0x301 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb2}, + {value: 0x0efd, lo: 0xb3, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x5d, offset 0x305 + {value: 0x0020, lo: 0x01}, + {value: 0x0f1d, lo: 0x80, hi: 0xbf}, + // Block 0x5e, offset 0x307 + {value: 0x0020, lo: 0x02}, + {value: 0x171d, lo: 0x80, hi: 0x8f}, + {value: 0x18fd, lo: 0x90, hi: 0xbf}, + // Block 0x5f, offset 0x30a + {value: 0x0020, lo: 0x01}, + {value: 0x1efd, lo: 0x80, hi: 0xbf}, + // Block 0x60, offset 0x30c + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x61, offset 0x30f + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9a}, + {value: 0x29e2, lo: 0x9b, hi: 0x9b}, + {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9e}, + {value: 0x2a31, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x62, offset 0x319 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbe}, + {value: 0x2a69, lo: 0xbf, hi: 0xbf}, + // Block 0x63, offset 0x31c + {value: 0x0000, lo: 0x0e}, + {value: 0x0040, lo: 0x80, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x2a1d, lo: 0xb1, hi: 0xb1}, + {value: 0x2a3d, lo: 0xb2, hi: 0xb2}, + {value: 0x2a5d, lo: 0xb3, hi: 0xb3}, + {value: 0x2a7d, lo: 0xb4, hi: 0xb4}, + {value: 0x2a5d, lo: 0xb5, hi: 0xb5}, + {value: 0x2a9d, lo: 0xb6, hi: 0xb6}, + {value: 0x2abd, lo: 0xb7, hi: 0xb7}, + {value: 0x2add, lo: 0xb8, hi: 0xb9}, + {value: 0x2afd, lo: 0xba, hi: 0xbb}, + {value: 0x2b1d, lo: 0xbc, hi: 0xbd}, + {value: 0x2afd, lo: 0xbe, hi: 0xbf}, + // Block 0x64, offset 0x32b + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x65, offset 0x32f + {value: 0x0030, lo: 0x04}, + {value: 0x2aa2, lo: 0x80, hi: 0x9d}, + {value: 0x305a, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x30a2, lo: 0xa0, hi: 0xbf}, + // Block 0x66, offset 0x334 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0x67, offset 0x337 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x68, offset 0x33b + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x69, offset 0x340 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0x6a, offset 0x345 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb1}, + {value: 0x0018, lo: 0xb2, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6b, offset 0x34b + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0xb6}, + {value: 0x0008, lo: 0xb7, hi: 0xb7}, + {value: 0x2009, lo: 0xb8, hi: 0xb8}, + {value: 0x6e89, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xbf}, + // Block 0x6c, offset 0x351 + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x3308, lo: 0x8b, hi: 0x8b}, + {value: 0x0008, lo: 0x8c, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x6d, offset 0x360 + {value: 0x0000, lo: 0x05}, + {value: 0x0208, lo: 0x80, hi: 0xb1}, + {value: 0x0108, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6e, offset 0x366 + {value: 0x0000, lo: 0x03}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xbf}, + // Block 0x6f, offset 0x36a + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0008, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x70, offset 0x379 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x71, offset 0x37e + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x91}, + {value: 0x3008, lo: 0x92, hi: 0x92}, + {value: 0x3808, lo: 0x93, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x72, offset 0x386 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb9}, + {value: 0x3008, lo: 0xba, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x73, offset 0x390 + {value: 0x0000, lo: 0x0a}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x74, offset 0x39b + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x75, offset 0x3a3 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8c}, + {value: 0x3008, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbd}, + {value: 0x0008, lo: 0xbe, hi: 0xbf}, + // Block 0x76, offset 0x3b4 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x77, offset 0x3bd + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x9a}, + {value: 0x0008, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3b08, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x78, offset 0x3cd + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x90}, + {value: 0x0008, lo: 0x91, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x79, offset 0x3da + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x4465, lo: 0x9c, hi: 0x9c}, + {value: 0x447d, lo: 0x9d, hi: 0x9d}, + {value: 0x2971, lo: 0x9e, hi: 0x9e}, + {value: 0xe06d, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xaf}, + {value: 0x4495, lo: 0xb0, hi: 0xbf}, + // Block 0x7a, offset 0x3e4 + {value: 0x0000, lo: 0x04}, + {value: 0x44b5, lo: 0x80, hi: 0x8f}, + {value: 0x44d5, lo: 0x90, hi: 0x9f}, + {value: 0x44f5, lo: 0xa0, hi: 0xaf}, + {value: 0x44d5, lo: 0xb0, hi: 0xbf}, + // Block 0x7b, offset 0x3e9 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3b08, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x7c, offset 0x3f6 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x7d, offset 0x3fa + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x7e, offset 0x3ff + {value: 0x0020, lo: 0x01}, + {value: 0x4515, lo: 0x80, hi: 0xbf}, + // Block 0x7f, offset 0x401 + {value: 0x0020, lo: 0x03}, + {value: 0x4d15, lo: 0x80, hi: 0x94}, + {value: 0x4ad5, lo: 0x95, hi: 0x95}, + {value: 0x4fb5, lo: 0x96, hi: 0xbf}, + // Block 0x80, offset 0x405 + {value: 0x0020, lo: 0x01}, + {value: 0x54f5, lo: 0x80, hi: 0xbf}, + // Block 0x81, offset 0x407 + {value: 0x0020, lo: 0x03}, + {value: 0x5cf5, lo: 0x80, hi: 0x84}, + {value: 0x5655, lo: 0x85, hi: 0x85}, + {value: 0x5d95, lo: 0x86, hi: 0xbf}, + // Block 0x82, offset 0x40b + {value: 0x0020, lo: 0x08}, + {value: 0x6b55, lo: 0x80, hi: 0x8f}, + {value: 0x6d15, lo: 0x90, hi: 0x90}, + {value: 0x6d55, lo: 0x91, hi: 0xab}, + {value: 0x6ea1, lo: 0xac, hi: 0xac}, + {value: 0x70b5, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x70d5, lo: 0xb0, hi: 0xbf}, + // Block 0x83, offset 0x414 + {value: 0x0020, lo: 0x05}, + {value: 0x72d5, lo: 0x80, hi: 0xad}, + {value: 0x6535, lo: 0xae, hi: 0xae}, + {value: 0x7895, lo: 0xaf, hi: 0xb5}, + {value: 0x6f55, lo: 0xb6, hi: 0xb6}, + {value: 0x7975, lo: 0xb7, hi: 0xbf}, + // Block 0x84, offset 0x41a + {value: 0x0028, lo: 0x03}, + {value: 0x7c21, lo: 0x80, hi: 0x82}, + {value: 0x7be1, lo: 0x83, hi: 0x83}, + {value: 0x7c99, lo: 0x84, hi: 0xbf}, + // Block 0x85, offset 0x41e + {value: 0x0038, lo: 0x0f}, + {value: 0x9db1, lo: 0x80, hi: 0x83}, + {value: 0x9e59, lo: 0x84, hi: 0x85}, + {value: 0x9e91, lo: 0x86, hi: 0x87}, + {value: 0x9ec9, lo: 0x88, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0xa089, lo: 0x92, hi: 0x97}, + {value: 0xa1a1, lo: 0x98, hi: 0x9c}, + {value: 0xa281, lo: 0x9d, hi: 0xb3}, + {value: 0x9d41, lo: 0xb4, hi: 0xb4}, + {value: 0x9db1, lo: 0xb5, hi: 0xb5}, + {value: 0xa789, lo: 0xb6, hi: 0xbb}, + {value: 0xa869, lo: 0xbc, hi: 0xbc}, + {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, + {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, + // Block 0x86, offset 0x42e + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0008, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x87, offset 0x438 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0x88, offset 0x43d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x89, offset 0x440 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x8a, offset 0x446 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x8b, offset 0x44d + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x8c, offset 0x452 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x8d, offset 0x456 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x8e, offset 0x45c + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xbf}, + // Block 0x8f, offset 0x461 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x90, offset 0x46a + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x91, offset 0x46f + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x92, offset 0x475 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x97}, + {value: 0x8ad5, lo: 0x98, hi: 0x9f}, + {value: 0x8aed, lo: 0xa0, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xbf}, + // Block 0x93, offset 0x47c + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x8aed, lo: 0xb0, hi: 0xb7}, + {value: 0x8ad5, lo: 0xb8, hi: 0xbf}, + // Block 0x94, offset 0x483 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x95, offset 0x48a + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x96, offset 0x48e + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xae}, + {value: 0x0018, lo: 0xaf, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x97, offset 0x493 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x98, offset 0x496 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xbf}, + // Block 0x99, offset 0x49b + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0808, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0808, lo: 0x8a, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb6}, + {value: 0x0808, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbb}, + {value: 0x0808, lo: 0xbc, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x0808, lo: 0xbf, hi: 0xbf}, + // Block 0x9a, offset 0x4a7 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x96}, + {value: 0x0818, lo: 0x97, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0818, lo: 0xb7, hi: 0xbf}, + // Block 0x9b, offset 0x4ad + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa6}, + {value: 0x0818, lo: 0xa7, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x9c, offset 0x4b2 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x0818, lo: 0xbb, hi: 0xbf}, + // Block 0x9d, offset 0x4b9 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0818, lo: 0x96, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbe}, + {value: 0x0818, lo: 0xbf, hi: 0xbf}, + // Block 0x9e, offset 0x4c1 + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbb}, + {value: 0x0818, lo: 0xbc, hi: 0xbd}, + {value: 0x0808, lo: 0xbe, hi: 0xbf}, + // Block 0x9f, offset 0x4c6 + {value: 0x0000, lo: 0x03}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0xa0, offset 0x4ca + {value: 0x0000, lo: 0x0f}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x94}, + {value: 0x0808, lo: 0x95, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x98}, + {value: 0x0808, lo: 0x99, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xa1, offset 0x4da + {value: 0x0000, lo: 0x06}, + {value: 0x0818, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0818, lo: 0x90, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xbc}, + {value: 0x0818, lo: 0xbd, hi: 0xbf}, + // Block 0xa2, offset 0x4e1 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xa3, offset 0x4e5 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb8}, + {value: 0x0018, lo: 0xb9, hi: 0xbf}, + // Block 0xa4, offset 0x4e9 + {value: 0x0000, lo: 0x06}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0818, lo: 0x98, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb7}, + {value: 0x0818, lo: 0xb8, hi: 0xbf}, + // Block 0xa5, offset 0x4f0 + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa6, offset 0x4f2 + {value: 0x0000, lo: 0x02}, + {value: 0x0808, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xa7, offset 0x4f5 + {value: 0x0000, lo: 0x02}, + {value: 0x03dd, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xa8, offset 0x4f8 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xa9, offset 0x4fc + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xaa, offset 0x500 + {value: 0x0000, lo: 0x05}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xab, offset 0x506 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x91}, + {value: 0x0018, lo: 0x92, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xac, offset 0x50f + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbc}, + {value: 0x0340, lo: 0xbd, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0xad, offset 0x51b + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xae, offset 0x522 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb2}, + {value: 0x3b08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xbf}, + // Block 0xaf, offset 0x52b + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xb0, offset 0x533 + {value: 0x0000, lo: 0x06}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xbe}, + {value: 0x3008, lo: 0xbf, hi: 0xbf}, + // Block 0xb1, offset 0x53a + {value: 0x0000, lo: 0x0d}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xb2, offset 0x548 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3808, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xb3, offset 0x555 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0008, lo: 0x9f, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xb4, offset 0x562 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x3308, lo: 0x9f, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa9}, + {value: 0x3b08, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb5, offset 0x56b + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xb6, offset 0x56f + {value: 0x0000, lo: 0x0d}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xb7, offset 0x57d + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xb8, offset 0x585 + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x85}, + {value: 0x0018, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xb9, offset 0x590 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xba, offset 0x599 + {value: 0x0000, lo: 0x05}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9b}, + {value: 0x3308, lo: 0x9c, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xbb, offset 0x59f + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbc, offset 0x5a7 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xbd, offset 0x5b0 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb5}, + {value: 0x3808, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0xbe, offset 0x5ba + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0xbf, offset 0x5bd + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0xc0, offset 0x5c9 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xbf}, + // Block 0xc1, offset 0x5cc + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0xc2, offset 0x5d1 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xc3, offset 0x5de + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x3b08, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0xbf}, + // Block 0xc4, offset 0x5e7 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x98}, + {value: 0x3b08, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xbf}, + // Block 0xc5, offset 0x5f3 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xc6, offset 0x5f6 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xc7, offset 0x600 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xbf}, + // Block 0xc8, offset 0x609 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xaa, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xc9, offset 0x615 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xca, offset 0x622 + {value: 0x0000, lo: 0x07}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xcb, offset 0x62a + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xcc, offset 0x62d + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xcd, offset 0x632 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0xbf}, + // Block 0xce, offset 0x635 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xbf}, + // Block 0xcf, offset 0x638 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xbf}, + // Block 0xd0, offset 0x63b + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xd1, offset 0x642 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xd2, offset 0x649 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0xd3, offset 0x64d + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0xd4, offset 0x658 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xd5, offset 0x65b + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3008, lo: 0x91, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd6, offset 0x661 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xd7, offset 0x666 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xbf}, + // Block 0xd8, offset 0x66a + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xd9, offset 0x66d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xda, offset 0x670 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xdb, offset 0x673 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xdc, offset 0x676 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xdd, offset 0x679 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0xde, offset 0x67e + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x03c0, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xbf}, + // Block 0xdf, offset 0x688 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xe0, offset 0x68b + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xbf}, + // Block 0xe1, offset 0x68f + {value: 0x0000, lo: 0x0e}, + {value: 0x0018, lo: 0x80, hi: 0x9d}, + {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, + {value: 0xb601, lo: 0x9f, hi: 0x9f}, + {value: 0xb649, lo: 0xa0, hi: 0xa0}, + {value: 0xb6b1, lo: 0xa1, hi: 0xa1}, + {value: 0xb719, lo: 0xa2, hi: 0xa2}, + {value: 0xb781, lo: 0xa3, hi: 0xa3}, + {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, + {value: 0x3018, lo: 0xa5, hi: 0xa6}, + {value: 0x3318, lo: 0xa7, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xac}, + {value: 0x3018, lo: 0xad, hi: 0xb2}, + {value: 0x0340, lo: 0xb3, hi: 0xba}, + {value: 0x3318, lo: 0xbb, hi: 0xbf}, + // Block 0xe2, offset 0x69e + {value: 0x0000, lo: 0x0b}, + {value: 0x3318, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0x84}, + {value: 0x3318, lo: 0x85, hi: 0x8b}, + {value: 0x0018, lo: 0x8c, hi: 0xa9}, + {value: 0x3318, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xba}, + {value: 0xb851, lo: 0xbb, hi: 0xbb}, + {value: 0xb899, lo: 0xbc, hi: 0xbc}, + {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, + {value: 0xb949, lo: 0xbe, hi: 0xbe}, + {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, + // Block 0xe3, offset 0x6aa + {value: 0x0000, lo: 0x03}, + {value: 0xba19, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xbf}, + // Block 0xe4, offset 0x6ae + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x3318, lo: 0x82, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0xbf}, + // Block 0xe5, offset 0x6b3 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe6, offset 0x6b8 + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xe7, offset 0x6bc + {value: 0x0000, lo: 0x04}, + {value: 0x3308, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0xe8, offset 0x6c1 + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x3308, lo: 0xa1, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xe9, offset 0x6ca + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0xea, offset 0x6d5 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x86}, + {value: 0x0818, lo: 0x87, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xeb, offset 0x6db + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xec, offset 0x6e3 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xed, offset 0x6e7 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0xee, offset 0x6eb + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0xef, offset 0x6f1 + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xf0, offset 0x6f7 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0xc1c1, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xf1, offset 0x6fc + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xbf}, + // Block 0xf2, offset 0x6ff + {value: 0x0000, lo: 0x0f}, + {value: 0xc7e9, lo: 0x80, hi: 0x80}, + {value: 0xc839, lo: 0x81, hi: 0x81}, + {value: 0xc889, lo: 0x82, hi: 0x82}, + {value: 0xc8d9, lo: 0x83, hi: 0x83}, + {value: 0xc929, lo: 0x84, hi: 0x84}, + {value: 0xc979, lo: 0x85, hi: 0x85}, + {value: 0xc9c9, lo: 0x86, hi: 0x86}, + {value: 0xca19, lo: 0x87, hi: 0x87}, + {value: 0xca69, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0xcab9, lo: 0x90, hi: 0x90}, + {value: 0xcad9, lo: 0x91, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xbf}, + // Block 0xf3, offset 0x70f + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xf4, offset 0x716 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0xf5, offset 0x719 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0xbf}, + // Block 0xf6, offset 0x71c + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0xf7, offset 0x720 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0xf8, offset 0x726 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0xf9, offset 0x72b + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xfa, offset 0x730 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0xfb, offset 0x735 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xbf}, + // Block 0xfc, offset 0x738 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0xfd, offset 0x73d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xfe, offset 0x740 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xff, offset 0x743 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x100, offset 0x747 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x101, offset 0x74b + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x102, offset 0x74e + {value: 0x0020, lo: 0x0f}, + {value: 0xdeb9, lo: 0x80, hi: 0x89}, + {value: 0x8dfd, lo: 0x8a, hi: 0x8a}, + {value: 0xdff9, lo: 0x8b, hi: 0x9c}, + {value: 0x8e1d, lo: 0x9d, hi: 0x9d}, + {value: 0xe239, lo: 0x9e, hi: 0xa2}, + {value: 0x8e3d, lo: 0xa3, hi: 0xa3}, + {value: 0xe2d9, lo: 0xa4, hi: 0xab}, + {value: 0x7ed5, lo: 0xac, hi: 0xac}, + {value: 0xe3d9, lo: 0xad, hi: 0xaf}, + {value: 0x8e5d, lo: 0xb0, hi: 0xb0}, + {value: 0xe439, lo: 0xb1, hi: 0xb6}, + {value: 0x8e7d, lo: 0xb7, hi: 0xb9}, + {value: 0xe4f9, lo: 0xba, hi: 0xba}, + {value: 0x8edd, lo: 0xbb, hi: 0xbb}, + {value: 0xe519, lo: 0xbc, hi: 0xbf}, + // Block 0x103, offset 0x75e + {value: 0x0020, lo: 0x10}, + {value: 0x937d, lo: 0x80, hi: 0x80}, + {value: 0xf099, lo: 0x81, hi: 0x86}, + {value: 0x939d, lo: 0x87, hi: 0x8a}, + {value: 0xd9f9, lo: 0x8b, hi: 0x8b}, + {value: 0xf159, lo: 0x8c, hi: 0x96}, + {value: 0x941d, lo: 0x97, hi: 0x97}, + {value: 0xf2b9, lo: 0x98, hi: 0xa3}, + {value: 0x943d, lo: 0xa4, hi: 0xa6}, + {value: 0xf439, lo: 0xa7, hi: 0xaa}, + {value: 0x949d, lo: 0xab, hi: 0xab}, + {value: 0xf4b9, lo: 0xac, hi: 0xac}, + {value: 0x94bd, lo: 0xad, hi: 0xad}, + {value: 0xf4d9, lo: 0xae, hi: 0xaf}, + {value: 0x94dd, lo: 0xb0, hi: 0xb1}, + {value: 0xf519, lo: 0xb2, hi: 0xbe}, + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0x104, offset 0x76f + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0340, lo: 0x81, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x9f}, + {value: 0x0340, lo: 0xa0, hi: 0xbf}, + // Block 0x105, offset 0x774 + {value: 0x0000, lo: 0x01}, + {value: 0x0340, lo: 0x80, hi: 0xbf}, + // Block 0x106, offset 0x776 + {value: 0x0000, lo: 0x01}, + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x107, offset 0x778 + {value: 0x0000, lo: 0x02}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, +} + +// Total table size 42114 bytes (41KiB); checksum: 355A58A4 diff --git a/vendor/golang.org/x/net/idna/tables11.0.0.go b/vendor/golang.org/x/net/idna/tables11.0.0.go new file mode 100644 index 000000000000..c515d7ad2a20 --- /dev/null +++ b/vendor/golang.org/x/net/idna/tables11.0.0.go @@ -0,0 +1,4653 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.13 + +package idna + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "11.0.0" + +var mappings string = "" + // Size: 8175 bytes + "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + + "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + + "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + + "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" + + "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" + + "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" + + "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" + + "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" + + "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" + + "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" + + "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" + + "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" + + "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" + + "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" + + "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" + + "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" + + "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" + + "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" + + "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" + + "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" + + "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" + + "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" + + "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" + + "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" + + "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" + + "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" + + ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" + + "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" + + "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" + + "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" + + "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" + + "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" + + "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" + + "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" + + "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" + + "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" + + "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" + + "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" + + "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" + + "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" + + "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" + + "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" + + "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" + + "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" + + "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" + + "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" + + "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" + + "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" + + "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" + + "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" + + "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" + + "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" + + "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" + + "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" + + "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" + + "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" + + "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" + + "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" + + "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" + + "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" + + "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" + + "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" + + "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" + + "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" + + "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" + + "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" + + "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" + + "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" + + "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" + + "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" + + "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" + + "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" + + "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" + + " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" + + "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" + + "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" + + "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" + + "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" + + "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" + + "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" + + "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" + + "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" + + "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" + + "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" + + "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" + + "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" + + "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" + + "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" + + "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" + + "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" + + "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" + + "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" + + "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" + + "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" + + "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" + + "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" + + "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" + + "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" + + "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" + + "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" + + "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" + + "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" + + "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" + + "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" + + "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" + + "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" + + "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" + + "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" + + "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" + + "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" + + "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" + + "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" + + "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" + + "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" + + "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" + + "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" + + "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" + + "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" + + "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" + + "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" + + "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" + + "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" + + "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" + + "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" + + "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" + + "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" + + "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" + + "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" + + "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" + + "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" + + "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" + + "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" + + "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" + + "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" + + "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" + + "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" + + "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻" + +var xorData string = "" + // Size: 4855 bytes + "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" + + "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" + + "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" + + "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" + + "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" + + "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" + + "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" + + "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" + + "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" + + "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" + + "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" + + "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" + + "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" + + "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" + + "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" + + "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" + + "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" + + "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" + + "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" + + "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" + + "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" + + "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" + + "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" + + "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" + + "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" + + "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" + + "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" + + "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" + + "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" + + "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" + + "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" + + "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" + + "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" + + "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" + + "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" + + "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" + + "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " + + "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" + + "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" + + "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" + + "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" + + "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" + + ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" + + "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" + + "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" + + "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" + + "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" + + "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" + + "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" + + "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" + + "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" + + "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" + + "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" + + "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" + + "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" + + "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" + + "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" + + "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" + + "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" + + "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" + + "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" + + "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" + + "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" + + "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" + + "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" + + "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" + + "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" + + "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" + + "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" + + "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" + + "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" + + "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" + + "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" + + "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" + + "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" + + "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" + + "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" + + "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" + + "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" + + "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" + + "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" + + "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" + + "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" + + "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" + + "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" + + "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" + + "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" + + "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" + + "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," + + "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" + + "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" + + "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" + + "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" + + ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" + + "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" + + "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" + + "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" + + "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" + + "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" + + "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" + + "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" + + "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" + + "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" + + "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" + + "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" + + "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" + + "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" + + "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" + + "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" + + "\x08\x1a\x0a\x03\x07</\x03\x07:+\x03\x07\x07*\x03\x06&\x1c\x03\x09\x0c" + + "\x16\x03\x09\x10\x0e\x03\x08'\x0f\x03\x08+\x09\x03\x074%\x03\x06!3\x03" + + "\x06\x03+\x03\x0b\x1e\x19\x03\x0a))\x03\x09\x08\x19\x03\x08,\x05\x03\x07" + + "<2\x03\x06\x1c>\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" + + "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" + + "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" + + "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" + + "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" + + "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" + + "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" + + "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" + + "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" + + "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" + + "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" + + "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" + + "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" + + "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" + + "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" + + "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" + + "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" + + "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." + + "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" + + "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" + + "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " + + "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" + + "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" + + "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" + + "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" + + "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" + + "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" + + "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," + + "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" + + "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" + + "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" + + "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" + + "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" + + "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" + + "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" + + "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" + + "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" + + "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" + + "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" + + "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" + + "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" + + "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" + + "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" + + "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" + + "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" + + "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" + + "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" + + "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" + + "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" + + "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" + + "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" + + "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" + + "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" + + "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" + + "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" + + "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" + + "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" + + "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" + + "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" + + "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" + + "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" + + "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" + + "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" + + "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" + + "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" + + "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" + + "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," + + "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" + + "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" + + "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" + + "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" + + "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" + + "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" + + "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" + + "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" + + "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" + + "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" + + "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" + + "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" + + "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" + + "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" + + "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" + + "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" + + "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" + + "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" + + "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" + + "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" + + "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" + + "\x04\x03\x0c?\x05\x03\x0c<?\x03\x0c=\x00\x03\x0c=\x06\x03\x0c=\x05\x03" + + "\x0c=\x0c\x03\x0c=\x0f\x03\x0c=\x0d\x03\x0c=\x0b\x03\x0c=\x07\x03\x0c=" + + "\x19\x03\x0c=\x15\x03\x0c=\x11\x03\x0c=1\x03\x0c=3\x03\x0c=0\x03\x0c=>" + + "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" + + "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" + + "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" + + "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" + + "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" + + "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" + + "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" + + "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" + + "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" + + "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" + + "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" + + "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" + + "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" + + "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" + + "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" + + "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" + + "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" + + "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" + + "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" + + "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" + + "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" + + "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" + + "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" + + "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" + + "\x05\x22\x05\x03\x050\x1d" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// idnaTrie. Total size: 29404 bytes (28.71 KiB). Checksum: 848c45acb5f7991c. +type idnaTrie struct{} + +func newIdnaTrie(i int) *idnaTrie { + return &idnaTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 125: + return uint16(idnaValues[n<<6+uint32(b)]) + default: + n -= 125 + return uint16(idnaSparse.lookup(n, b)) + } +} + +// idnaValues: 127 blocks, 8128 entries, 16256 bytes +// The third block is the zero block. +var idnaValues = [8128]uint16{ + // Block 0x0, offset 0x0 + 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, + 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, + 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080, + 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080, + 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080, + 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080, + 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080, + 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080, + 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008, + 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080, + 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080, + // Block 0x1, offset 0x40 + 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105, + 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105, + 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105, + 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105, + 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080, + 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008, + 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008, + 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008, + 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008, + 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080, + 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018, + 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018, + 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a, + 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005, + 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018, + 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018, + // Block 0x4, offset 0x100 + 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008, + 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008, + 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008, + 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008, + 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008, + 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008, + 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008, + 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008, + 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008, + 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d, + 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199, + // Block 0x5, offset 0x140 + 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d, + 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008, + 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008, + 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008, + 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008, + 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008, + 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008, + 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008, + 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008, + 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d, + 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9, + // Block 0x6, offset 0x180 + 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008, + 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d, + 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d, + 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d, + 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155, + 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008, + 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d, + 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd, + 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d, + 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008, + 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9, + 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d, + 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d, + 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d, + 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008, + 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008, + 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008, + 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008, + 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008, + 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008, + 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008, + // Block 0x8, offset 0x200 + 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008, + 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008, + 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008, + 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008, + 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008, + 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008, + 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008, + 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008, + 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008, + 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d, + 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008, + // Block 0x9, offset 0x240 + 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018, + 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008, + 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008, + 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018, + 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a, + 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369, + 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018, + 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018, + 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018, + 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, + 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, + // Block 0xa, offset 0x280 + 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, + 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, + 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, + 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, + 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, + 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, + 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, + 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, + 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, + 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, + 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2, + 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040, + 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105, + 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105, + 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105, + 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d, + 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d, + 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008, + 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008, + 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008, + 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008, + // Block 0xc, offset 0x300 + 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008, + 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008, + 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd, + 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008, + 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008, + 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008, + 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008, + 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008, + 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd, + 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008, + 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d, + // Block 0xd, offset 0x340 + 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008, + 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008, + 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008, + 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008, + 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008, + 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008, + 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008, + 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008, + 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008, + 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, + 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, + // Block 0xe, offset 0x380 + 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, + 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, + 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, + 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, + 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, + 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008, + 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008, + 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008, + 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008, + 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008, + 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d, + 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d, + 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008, + 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008, + 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008, + 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008, + 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008, + 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008, + 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008, + 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008, + 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008, + // Block 0x10, offset 0x400 + 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008, + 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008, + 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008, + 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008, + 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008, + 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008, + 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008, + 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008, + 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5, + 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, + 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, + // Block 0x11, offset 0x440 + 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, + 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, + 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, + 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, + 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, + 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, + 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, + 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, + 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, + 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, + 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, + // Block 0x12, offset 0x480 + 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, + 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, + 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, + 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, + 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, + 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, + 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, + 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, + 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, + 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, + 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, + 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, + 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, + 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, + 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, + 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, + 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, + 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, + 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, + 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, + 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, + // Block 0x14, offset 0x500 + 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, + 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, + 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, + 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, + 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, + 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, + 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, + 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, + 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, + 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, + 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, + // Block 0x15, offset 0x540 + 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08, + 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08, + 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08, + 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808, + 0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040, + 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08, + 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08, + 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040, + 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040, + 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040, + 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040, + // Block 0x16, offset 0x580 + 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308, + 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008, + 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308, + 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308, + 0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1, + 0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308, + 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008, + 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, + 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008, + 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008, + 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008, + 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008, + 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040, + 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008, + 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008, + 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008, + 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040, + 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, + 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040, + 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040, + 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008, + // Block 0x18, offset 0x600 + 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040, + 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008, + 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040, + 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008, + 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1, + 0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308, + 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008, + 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, + 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018, + 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018, + 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040, + // Block 0x19, offset 0x640 + 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008, + 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040, + 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040, + 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008, + 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008, + 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008, + 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040, + 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, + 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008, + 0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040, + 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008, + // Block 0x1a, offset 0x680 + 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040, + 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308, + 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308, + 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040, + 0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040, + 0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040, + 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008, + 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, + 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308, + 0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040, + 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008, + 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008, + 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008, + 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008, + 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008, + 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008, + 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040, + 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, + 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008, + 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, + 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008, + // Block 0x1c, offset 0x700 + 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308, + 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008, + 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040, + 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040, + 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040, + 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308, + 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008, + 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, + 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040, + 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308, + 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308, + // Block 0x1d, offset 0x740 + 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008, + 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008, + 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040, + 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008, + 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008, + 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008, + 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040, + 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, + 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008, + 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040, + 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308, + // Block 0x1e, offset 0x780 + 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040, + 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008, + 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040, + 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008, + 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9, + 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308, + 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008, + 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008, + 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018, + 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040, + 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008, + 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040, + 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040, + 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040, + 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040, + 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008, + 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008, + 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008, + 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008, + 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040, + 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008, + // Block 0x20, offset 0x800 + 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040, + 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308, + 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040, + 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040, + 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040, + 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308, + 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008, + 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, + 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040, + 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018, + 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018, + // Block 0x21, offset 0x840 + 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008, + 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008, + 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040, + 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008, + 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008, + 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008, + 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040, + 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, + 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008, + 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040, + 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308, + // Block 0x22, offset 0x880 + 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040, + 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, + 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040, + 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040, + 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040, + 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, + 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, + 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, + 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040, + 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040, + 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040, + 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008, + 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040, + 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008, + 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018, + 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308, + 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008, + 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, + 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018, + 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008, + 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008, + // Block 0x24, offset 0x900 + 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040, + 0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040, + 0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040, + 0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008, + 0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008, + 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, + 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040, + 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008, + 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308, + 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308, + 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040, + // Block 0x25, offset 0x940 + 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008, + 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, + 0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008, + 0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79, + 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008, + 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008, + 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9, + 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040, + 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59, + 0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308, + 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008, + // Block 0x26, offset 0x980 + 0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018, + 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, + 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308, + 0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308, + 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11, + 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308, + 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308, + 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308, + 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308, + 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308, + 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008, + 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008, + 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008, + 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008, + 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008, + 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008, + 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008, + 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008, + 0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41, + 0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008, + 0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269, + // Block 0x28, offset 0xa00 + 0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1, + 0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011, + 0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041, + 0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9, + 0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099, + 0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269, + 0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1, + 0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008, + 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008, + 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008, + 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008, + // Block 0x29, offset 0xa40 + 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008, + 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008, + 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008, + 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008, + 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169, + 0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9, + 0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251, + 0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9, + 0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359, + 0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1, + 0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429, + // Block 0x2a, offset 0xa80 + 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, + 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, + 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, + 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008, + 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008, + 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, + 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, + 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, + 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, + 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, + 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, + // Block 0x2b, offset 0xac0 + 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008, + 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008, + 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008, + 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, + 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008, + 0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008, + 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008, + 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008, + 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008, + 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008, + 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008, + // Block 0x2c, offset 0xb00 + 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008, + 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045, + 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008, + 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008, + 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045, + 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008, + 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045, + 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045, + 0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489, + 0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1, + 0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040, + // Block 0x2d, offset 0xb40 + 0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1, + 0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591, + 0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1, + 0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1, + 0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771, + 0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891, + 0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831, + 0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951, + 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040, + 0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459, + 0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686, + // Block 0x2e, offset 0xb80 + 0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040, + 0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489, + 0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008, + 0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008, + 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2, + 0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61, + 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045, + 0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa, + 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040, + 0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9, + 0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a, + 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0, + 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d, + 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e, + 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, + 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018, + 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040, + 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a, + 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018, + 0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018, + 0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018, + // Block 0x30, offset 0xc00 + 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018, + 0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018, + 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018, + 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9, + 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018, + 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340, + 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040, + 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340, + 0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61, + 0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd, + 0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71, + // Block 0x31, offset 0xc40 + 0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61, + 0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5, + 0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09, + 0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359, + 0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040, + 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018, + 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018, + 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018, + 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018, + 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018, + 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018, + // Block 0x32, offset 0xc80 + 0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e, + 0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249, + 0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41, + 0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018, + 0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269, + 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018, + 0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018, + 0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09, + 0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9, + 0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd, + 0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9, + 0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018, + 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151, + 0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279, + 0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399, + 0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439, + 0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369, + 0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61, + 0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451, + 0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5, + 0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61, + // Block 0x34, offset 0xd00 + 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018, + 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040, + 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, + 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, + 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040, + 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51, + 0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601, + 0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691, + 0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26, + 0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6, + 0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a, + // Block 0x35, offset 0xd40 + 0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a, + 0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040, + 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040, + 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040, + 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46, + 0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06, + 0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6, + 0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86, + 0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46, + 0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199, + 0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259, + // Block 0x36, offset 0xd80 + 0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99, + 0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089, + 0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9, + 0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249, + 0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71, + 0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9, + 0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1, + 0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018, + 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018, + 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018, + 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008, + 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008, + 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008, + 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008, + 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008, + 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd, + 0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d, + 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9, + 0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d, + 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008, + 0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9, + // Block 0x38, offset 0xe00 + 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008, + 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008, + 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008, + 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008, + 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008, + 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008, + 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018, + 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308, + 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040, + 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018, + 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018, + // Block 0x39, offset 0xe40 + 0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d, + 0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d, + 0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d, + 0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040, + 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040, + 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040, + 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040, + 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040, + 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040, + 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040, + 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040, + // Block 0x3a, offset 0xe80 + 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008, + 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018, + 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018, + 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018, + 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018, + 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018, + 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018, + 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018, + 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018, + 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018, + 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018, + // Block 0x3b, offset 0xec0 + 0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd, + 0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd, + 0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d, + 0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d, + 0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d, + 0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd, + 0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d, + 0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd, + 0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d, + 0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd, + 0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d, + // Block 0x3c, offset 0xf00 + 0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd, + 0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d, + 0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018, + 0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd, + 0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d, + 0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008, + 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008, + 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008, + 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008, + 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040, + 0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040, + // Block 0x3d, offset 0xf40 + 0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd, + 0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018, + 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761, + 0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1, + 0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881, + 0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd, + 0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d, + 0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d, + 0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd, + 0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d, + 0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018, + // Block 0x3e, offset 0xf80 + 0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d, + 0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d, + 0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd, + 0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd, + 0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d, + 0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d, + 0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd, + 0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d, + 0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999, + 0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29, + 0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69, + 0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69, + 0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15, + 0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75, + 0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded, + 0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d, + 0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5, + 0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d, + 0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d, + 0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd, + 0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040, + // Block 0x40, offset 0x1000 + 0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9, + 0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1, + 0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9, + 0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549, + 0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1, + 0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11, + 0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91, + 0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9, + 0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011, + 0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209, + 0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361, + // Block 0x41, offset 0x1040 + 0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541, + 0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781, + 0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979, + 0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89, + 0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1, + 0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99, + 0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9, + 0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9, + 0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069, + 0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9, + 0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9, + // Block 0x42, offset 0x1080 + 0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271, + 0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9, + 0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed, + 0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371, + 0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9, + 0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d, + 0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211, + 0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1, + 0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599, + 0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9, + 0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671, + 0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709, + 0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781, + 0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1, + 0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811, + 0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901, + 0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1, + 0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11, + 0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31, + 0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51, + 0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d, + // Block 0x44, offset 0x1100 + 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, + 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, + 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, + 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, + 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008, + 0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008, + 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008, + 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308, + 0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308, + 0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308, + 0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008, + // Block 0x45, offset 0x1140 + 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008, + 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008, + 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008, + 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008, + 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11, + 0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008, + 0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008, + 0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008, + 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008, + 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008, + 0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008, + // Block 0x46, offset 0x1180 + 0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018, + 0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018, + 0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018, + 0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008, + 0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008, + 0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008, + 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, + 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, + 0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008, + 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008, + 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008, + // Block 0x47, offset 0x11c0 + 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, + 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008, + 0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, + 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, + 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, + 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, + 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, + 0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008, + 0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008, + 0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d, + 0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008, + // Block 0x48, offset 0x1200 + 0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008, + 0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d, + 0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008, + 0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008, + 0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008, + 0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008, + 0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008, + 0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0008, + 0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008, + 0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0008, 0x123a: 0x0040, 0x123b: 0x0040, + 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040, + // Block 0x49, offset 0x1240 + 0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575, + 0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635, + 0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008, + 0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715, + 0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5, + 0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008, + 0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008, + 0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935, + 0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5, + 0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5, + 0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35, + // Block 0x4a, offset 0x1280 + 0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35, + 0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5, + 0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19, + 0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91, + 0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040, + 0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040, + 0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040, + 0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040, + 0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040, + 0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040, + 0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001, + 0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040, + 0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040, + 0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9, + 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1, + 0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149, + 0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2, + 0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1, + 0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1, + 0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479, + 0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040, + // Block 0x4c, offset 0x1300 + 0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040, + 0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659, + 0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721, + 0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751, + 0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769, + 0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799, + 0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1, + 0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1, + 0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9, + 0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829, + 0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841, + // Block 0x4d, offset 0x1340 + 0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871, + 0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9, + 0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9, + 0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919, + 0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931, + 0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961, + 0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991, + 0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1, + 0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818, + 0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818, + 0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040, + 0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040, + 0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040, + 0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09, + 0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479, + 0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81, + 0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1, + 0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19, + 0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91, + 0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1, + 0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1, + 0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1, + 0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1, + 0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991, + 0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81, + 0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a, + 0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99, + 0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89, + 0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79, + 0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19, + 0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469, + // Block 0x50, offset 0x1400 + 0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649, + 0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9, + 0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49, + 0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21, + 0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9, + 0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01, + 0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91, + 0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9, + 0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171, + 0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289, + 0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329, + // Block 0x51, offset 0x1440 + 0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1, + 0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621, + 0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739, + 0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1, + 0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9, + 0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29, + 0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079, + 0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1, + 0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171, + 0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261, + 0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301, + // Block 0x52, offset 0x1480 + 0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1, + 0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1, + 0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171, + 0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261, + 0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351, + 0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441, + 0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509, + 0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1, + 0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081, + 0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239, + 0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040, + 0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, + 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609, + 0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721, + 0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839, + 0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919, + 0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9, + 0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9, + 0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9, + 0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1, + 0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79, + // Block 0x54, offset 0x1500 + 0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989, + 0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040, + 0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040, + 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040, + 0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, + 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040, + 0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040, + 0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040, + 0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9, + 0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12, + 0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040, + // Block 0x55, offset 0x1540 + 0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0, + 0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0, + 0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55, + 0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75, + 0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040, + 0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308, + 0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308, + 0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308, + 0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2, + 0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35, + 0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55, + // Block 0x56, offset 0x1580 + 0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018, + 0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56, + 0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95, + 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa, + 0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95, + 0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99, + 0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda, + 0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040, + 0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040, + 0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081, + 0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1, + // Block 0x57, offset 0x15c0 + 0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141, + 0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171, + 0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1, + 0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1, + 0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201, + 0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219, + 0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249, + 0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291, + 0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1, + 0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9, + 0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1, + // Block 0x58, offset 0x1600 + 0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321, + 0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339, + 0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369, + 0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381, + 0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1, + 0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9, + 0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9, + 0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1, + 0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441, + 0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9, + 0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea, + 0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2, + 0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9, + 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81, + 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2, + 0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159, + 0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41, + 0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9, + 0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9, + 0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a, + 0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09, + 0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51, + 0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039, + 0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279, + 0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a, + 0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115, + 0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5, + 0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295, + 0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355, + 0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415, + 0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515, + 0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595, + 0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5, + 0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655, + 0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115, + 0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735, + 0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5, + 0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5, + 0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5, + 0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5, + 0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040, + // Block 0x5c, offset 0x1700 + 0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5, + 0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715, + 0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040, + 0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935, + 0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040, + 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6, + 0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35, + 0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040, + 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040, + 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340, + 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, + // Block 0x5d, offset 0x1740 + 0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08, + 0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808, + 0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08, + 0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908, + 0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08, + 0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808, + 0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040, + 0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18, + 0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818, + 0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, + 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, + // Block 0x5e, offset 0x1780 + 0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08, + 0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08, + 0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08, + 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040, + 0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040, + 0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040, + 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18, + 0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818, + 0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040, + 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040, + 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008, + 0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008, + 0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040, + 0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008, + 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008, + 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008, + 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040, + 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008, + 0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008, + 0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x3308, + 0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008, + // Block 0x60, offset 0x1800 + 0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040, + 0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008, + 0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040, + 0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008, + 0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008, + 0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008, + 0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308, + 0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040, + 0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040, + 0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040, + 0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040, + // Block 0x61, offset 0x1840 + 0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199, + 0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359, + 0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269, + 0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369, + 0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9, + 0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259, + 0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99, + 0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089, + 0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9, + 0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249, + 0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359, + // Block 0x62, offset 0x1880 + 0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269, + 0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369, + 0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9, + 0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259, + 0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99, + 0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089, + 0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9, + 0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249, + 0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71, + 0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9, + 0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9, + 0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259, + 0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99, + 0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089, + 0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040, + 0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040, + 0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71, + 0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9, + 0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1, + 0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199, + 0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259, + // Block 0x64, offset 0x1900 + 0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99, + 0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089, + 0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9, + 0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249, + 0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71, + 0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9, + 0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1, + 0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199, + 0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359, + 0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269, + 0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089, + // Block 0x65, offset 0x1940 + 0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9, + 0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040, + 0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71, + 0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9, + 0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040, + 0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199, + 0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359, + 0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269, + 0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369, + 0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9, + 0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040, + // Block 0x66, offset 0x1980 + 0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040, + 0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9, + 0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040, + 0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199, + 0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359, + 0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269, + 0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369, + 0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9, + 0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259, + 0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99, + 0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1, + 0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199, + 0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359, + 0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269, + 0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369, + 0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9, + 0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259, + 0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99, + 0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089, + 0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9, + 0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359, + 0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269, + 0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369, + 0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9, + 0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259, + 0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99, + 0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089, + 0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9, + 0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249, + 0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71, + 0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369, + 0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9, + 0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259, + 0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99, + 0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089, + 0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9, + 0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249, + 0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71, + 0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9, + 0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1, + 0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259, + 0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99, + 0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089, + 0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9, + 0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249, + 0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71, + 0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9, + 0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1, + 0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199, + 0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359, + 0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089, + 0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9, + 0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249, + 0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71, + 0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9, + 0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1, + 0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099, + 0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429, + 0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71, + 0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9, + 0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9, + 0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11, + 0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109, + 0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1, + 0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429, + 0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099, + 0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429, + 0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71, + 0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9, + 0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01, + 0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11, + 0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109, + 0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1, + 0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429, + 0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099, + 0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429, + 0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71, + 0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9, + 0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01, + 0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1, + 0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109, + 0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1, + 0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429, + 0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099, + 0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429, + 0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71, + 0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9, + 0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01, + 0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1, + 0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41, + 0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1, + 0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429, + 0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099, + 0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429, + 0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71, + 0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9, + 0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01, + 0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1, + 0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41, + 0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1, + 0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429, + 0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41, + 0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079, + 0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1, + 0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61, + 0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9, + 0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81, + 0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079, + 0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1, + 0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61, + 0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1, + // Block 0x71, offset 0x1c40 + 0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115, + 0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135, + 0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115, + 0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175, + 0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115, + 0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08, + 0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08, + 0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08, + 0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08, + 0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08, + 0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08, + // Block 0x72, offset 0x1c80 + 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411, + 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1, + 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9, + 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231, + 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949, + 0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, + 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429, + 0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, + 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, + 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351, + 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040, + 0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, + 0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9, + 0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231, + 0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949, + 0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040, + 0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, + 0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, + 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, + 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, + 0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040, + // Block 0x74, offset 0x1d00 + 0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411, + 0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1, + 0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9, + 0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231, + 0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040, + 0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249, + 0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429, + 0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339, + 0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1, + 0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351, + 0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02, + 0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018, + 0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2, + 0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72, + 0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32, + 0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2, + 0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2, + 0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0018, + 0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199, + 0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359, + 0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089, + 0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1, + 0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018, + 0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018, + 0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018, + 0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018, + 0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018, + 0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040, + 0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018, + 0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018, + 0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040, + 0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040, + 0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289, + 0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349, + 0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409, + 0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9, + 0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589, + 0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649, + 0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709, + 0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9, + 0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040, + // Block 0x78, offset 0x1e00 + 0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79, + 0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39, + 0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9, + 0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39, + 0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9, + 0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79, + 0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39, + 0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9, + 0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059, + 0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9, + 0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179, + // Block 0x79, offset 0x1e40 + 0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239, + 0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9, + 0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399, + 0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459, + 0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309, + 0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559, + 0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9, + 0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679, + 0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9, + 0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d, + 0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9, + 0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959, + 0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d, + 0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d, + 0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9, + 0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99, + 0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9, + 0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9, + 0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99, + 0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39, + 0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639, + 0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9, + 0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d, + 0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9, + 0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d, + 0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd, + 0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979, + 0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19, + 0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d, + 0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d, + 0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99, + 0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39, + 0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9, + 0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39, + 0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd, + 0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19, + 0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9, + 0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59, + 0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd, + 0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d, + 0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d, + 0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d, + 0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879, + 0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919, + 0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd, + 0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9, + 0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99, + 0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39, + 0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9, + 0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d, + 0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19, + 0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9, + 0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59, + 0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9, + 0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d, + 0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040, + 0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040, + 0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040, + 0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040, + 0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040, + 0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040, +} + +// idnaIndex: 36 blocks, 2304 entries, 4608 bytes +// Block 0 is the zero block. +var idnaIndex = [2304]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, + 0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21, + // Block 0x4, offset 0x100 + 0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16, + 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d, + 0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91, + 0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96, + // Block 0x5, offset 0x140 + 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, + 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, + 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, + 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, + 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, + 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, + 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3, + 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c, + // Block 0x6, offset 0x180 + 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b, + 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b, + 0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, + 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, + 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, + 0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0, + 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5, + 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1, + 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41, + 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, + 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, + 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, + 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, + 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, + 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, + // Block 0x8, offset 0x200 + 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, + 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, + 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, + 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, + 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, + 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, + 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, + 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, + // Block 0x9, offset 0x240 + 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, + 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, + 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, + 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, + 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, + 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, + 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, + 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, + // Block 0xa, offset 0x280 + 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, + 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, + 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, + 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, + 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, + 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, + 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, + 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, + 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, + 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, + 0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8, + 0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0, + 0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8, + 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, + 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, + // Block 0xc, offset 0x300 + 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, + 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, + 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, + 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa, + // Block 0xd, offset 0x340 + 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, + 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, + 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, + 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, + 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, + 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, + 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, + 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, + // Block 0xe, offset 0x380 + 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, + 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, + 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, + 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, + 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe, + 0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c, + 0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52, + 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108, + 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e, + 0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba, + 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba, + 0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c, + 0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba, + 0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0x126, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, + 0x3f8: 0xba, 0x3f9: 0x127, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0x128, 0x3fd: 0x129, 0x3fe: 0xba, 0x3ff: 0xba, + // Block 0x10, offset 0x400 + 0x400: 0x12a, 0x401: 0x12b, 0x402: 0x12c, 0x403: 0x12d, 0x404: 0x12e, 0x405: 0x12f, 0x406: 0x130, 0x407: 0x131, + 0x408: 0x132, 0x409: 0xba, 0x40a: 0x133, 0x40b: 0x134, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba, + 0x410: 0x135, 0x411: 0x136, 0x412: 0x137, 0x413: 0x138, 0x414: 0xba, 0x415: 0xba, 0x416: 0x139, 0x417: 0x13a, + 0x418: 0x13b, 0x419: 0x13c, 0x41a: 0x13d, 0x41b: 0x13e, 0x41c: 0x13f, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, + 0x420: 0x140, 0x421: 0xba, 0x422: 0x141, 0x423: 0x142, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba, + 0x428: 0x143, 0x429: 0x144, 0x42a: 0x145, 0x42b: 0x146, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, + 0x430: 0x147, 0x431: 0x148, 0x432: 0x149, 0x433: 0xba, 0x434: 0x14a, 0x435: 0x14b, 0x436: 0x14c, 0x437: 0xba, + 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0x14d, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba, + // Block 0x11, offset 0x440 + 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, + 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x14e, 0x44f: 0xba, + 0x450: 0x9b, 0x451: 0x14f, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x150, 0x456: 0xba, 0x457: 0xba, + 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, + 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, + 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, + 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, + 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, + // Block 0x12, offset 0x480 + 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, + 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, + 0x490: 0x151, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, + 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, + 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, + 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, + 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, + 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, + // Block 0x13, offset 0x4c0 + 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, + 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, + 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, + 0x4d8: 0x9f, 0x4d9: 0x152, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, + 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, + 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, + 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, + 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, + // Block 0x14, offset 0x500 + 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, + 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, + 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, + 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, + 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, + 0x528: 0x146, 0x529: 0x153, 0x52a: 0xba, 0x52b: 0x154, 0x52c: 0x155, 0x52d: 0x156, 0x52e: 0x157, 0x52f: 0xba, + 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, + 0x538: 0xba, 0x539: 0x158, 0x53a: 0x159, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x15a, 0x53e: 0x15b, 0x53f: 0x15c, + // Block 0x15, offset 0x540 + 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, + 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, + 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, + 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x15d, + 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, + 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x15e, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, + 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, + 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, + // Block 0x16, offset 0x580 + 0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x15f, 0x585: 0x160, 0x586: 0x9f, 0x587: 0x9f, + 0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x161, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, + 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, + 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, + 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, + 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, + 0x5b0: 0x9f, 0x5b1: 0x162, 0x5b2: 0x163, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, + 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x164, 0x5c4: 0x165, 0x5c5: 0x166, 0x5c6: 0x167, 0x5c7: 0x168, + 0x5c8: 0x9b, 0x5c9: 0x169, 0x5ca: 0xba, 0x5cb: 0x16a, 0x5cc: 0x9b, 0x5cd: 0x16b, 0x5ce: 0xba, 0x5cf: 0xba, + 0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66, + 0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e, + 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, + 0x5e8: 0x16c, 0x5e9: 0x16d, 0x5ea: 0x16e, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, + 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, + 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, + // Block 0x18, offset 0x600 + 0x600: 0x16f, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba, + 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, + 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, + 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, + 0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x170, 0x624: 0x6f, 0x625: 0x171, 0x626: 0xba, 0x627: 0xba, + 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, + 0x630: 0xba, 0x631: 0x172, 0x632: 0x173, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, + 0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x174, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, + // Block 0x19, offset 0x640 + 0x640: 0x175, 0x641: 0x9b, 0x642: 0x176, 0x643: 0x177, 0x644: 0x73, 0x645: 0x74, 0x646: 0x178, 0x647: 0x179, + 0x648: 0x75, 0x649: 0x17a, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, + 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, + 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x17b, 0x65c: 0x9b, 0x65d: 0x17c, 0x65e: 0x9b, 0x65f: 0x17d, + 0x660: 0x17e, 0x661: 0x17f, 0x662: 0x180, 0x663: 0xba, 0x664: 0x181, 0x665: 0x182, 0x666: 0x183, 0x667: 0x184, + 0x668: 0xba, 0x669: 0x185, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, + 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, + 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, + // Block 0x1a, offset 0x680 + 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, + 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, + 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, + 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x186, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, + 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, + 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, + 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, + 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, + 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, + 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, + 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x187, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, + 0x6e0: 0x188, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, + 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, + 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, + 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, + // Block 0x1c, offset 0x700 + 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, + 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, + 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, + 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, + 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, + 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, + 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, + 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x189, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f, + // Block 0x1d, offset 0x740 + 0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f, + 0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f, + 0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f, + 0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f, + 0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f, + 0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x18a, + 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, + 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, + // Block 0x1e, offset 0x780 + 0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba, + 0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba, + 0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba, + 0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba, + 0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x18b, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x18c, 0x7a7: 0x7b, + 0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba, + 0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba, + 0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba, + // Block 0x1f, offset 0x7c0 + 0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07, + 0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17, + 0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07, + 0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c, + 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, + 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, + // Block 0x20, offset 0x800 + 0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b, + 0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b, + 0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b, + 0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b, + 0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b, + 0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b, + 0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b, + 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b, + // Block 0x21, offset 0x840 + 0x840: 0x18d, 0x841: 0x18e, 0x842: 0xba, 0x843: 0xba, 0x844: 0x18f, 0x845: 0x18f, 0x846: 0x18f, 0x847: 0x190, + 0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba, + 0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba, + 0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba, + 0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba, + 0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba, + 0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba, + 0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba, + // Block 0x22, offset 0x880 + 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, + 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, + 0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b, + 0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b, + 0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b, + 0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b, + 0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b, + 0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b, + 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b, +} + +// idnaSparseOffset: 276 entries, 552 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x86, 0x8b, 0x94, 0xa4, 0xb2, 0xbe, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x224, 0x22e, 0x23a, 0x246, 0x252, 0x25a, 0x25f, 0x269, 0x27a, 0x27e, 0x289, 0x28d, 0x296, 0x29e, 0x2a4, 0x2a9, 0x2ac, 0x2b0, 0x2b6, 0x2ba, 0x2be, 0x2c2, 0x2c7, 0x2cd, 0x2d5, 0x2dc, 0x2e7, 0x2f1, 0x2f5, 0x2f8, 0x2fe, 0x302, 0x304, 0x307, 0x309, 0x30c, 0x316, 0x319, 0x328, 0x32c, 0x331, 0x334, 0x338, 0x33d, 0x342, 0x348, 0x34e, 0x35d, 0x363, 0x367, 0x376, 0x37b, 0x383, 0x38d, 0x398, 0x3a0, 0x3b1, 0x3ba, 0x3ca, 0x3d7, 0x3e1, 0x3e6, 0x3f3, 0x3f7, 0x3fc, 0x3fe, 0x402, 0x404, 0x408, 0x411, 0x417, 0x41b, 0x42b, 0x435, 0x43a, 0x43d, 0x443, 0x44a, 0x44f, 0x453, 0x459, 0x45e, 0x467, 0x46c, 0x472, 0x479, 0x480, 0x487, 0x48b, 0x490, 0x493, 0x498, 0x4a4, 0x4aa, 0x4af, 0x4b6, 0x4be, 0x4c3, 0x4c7, 0x4d7, 0x4de, 0x4e2, 0x4e6, 0x4ed, 0x4ef, 0x4f2, 0x4f5, 0x4f9, 0x502, 0x506, 0x50e, 0x516, 0x51c, 0x525, 0x531, 0x538, 0x541, 0x54b, 0x552, 0x560, 0x56d, 0x57a, 0x583, 0x587, 0x596, 0x59e, 0x5a9, 0x5b2, 0x5b8, 0x5c0, 0x5c9, 0x5d3, 0x5d6, 0x5e2, 0x5eb, 0x5ee, 0x5f3, 0x5fe, 0x607, 0x613, 0x616, 0x620, 0x629, 0x635, 0x642, 0x64f, 0x65d, 0x664, 0x667, 0x66c, 0x66f, 0x672, 0x675, 0x67c, 0x683, 0x687, 0x692, 0x695, 0x698, 0x69b, 0x6a1, 0x6a6, 0x6aa, 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6be, 0x6c8, 0x6cb, 0x6cf, 0x6de, 0x6ea, 0x6ee, 0x6f3, 0x6f7, 0x6fc, 0x700, 0x705, 0x70e, 0x719, 0x71f, 0x727, 0x72a, 0x72d, 0x731, 0x735, 0x73b, 0x741, 0x746, 0x749, 0x759, 0x760, 0x763, 0x766, 0x76a, 0x770, 0x775, 0x77a, 0x782, 0x787, 0x78b, 0x78f, 0x792, 0x795, 0x799, 0x79d, 0x7a0, 0x7b0, 0x7c1, 0x7c6, 0x7c8, 0x7ca} + +// idnaSparseValues: 1997 entries, 7988 bytes +var idnaSparseValues = [1997]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x07}, + {value: 0xe105, lo: 0x80, hi: 0x96}, + {value: 0x0018, lo: 0x97, hi: 0x97}, + {value: 0xe105, lo: 0x98, hi: 0x9e}, + {value: 0x001f, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbf}, + // Block 0x1, offset 0x8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0xe01d, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0335, lo: 0x83, hi: 0x83}, + {value: 0x034d, lo: 0x84, hi: 0x84}, + {value: 0x0365, lo: 0x85, hi: 0x85}, + {value: 0xe00d, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0xe00d, lo: 0x88, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x89}, + {value: 0xe00d, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe00d, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0x8d}, + {value: 0xe00d, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0xbf}, + // Block 0x2, offset 0x19 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0249, lo: 0xb0, hi: 0xb0}, + {value: 0x037d, lo: 0xb1, hi: 0xb1}, + {value: 0x0259, lo: 0xb2, hi: 0xb2}, + {value: 0x0269, lo: 0xb3, hi: 0xb3}, + {value: 0x034d, lo: 0xb4, hi: 0xb4}, + {value: 0x0395, lo: 0xb5, hi: 0xb5}, + {value: 0xe1bd, lo: 0xb6, hi: 0xb6}, + {value: 0x0279, lo: 0xb7, hi: 0xb7}, + {value: 0x0289, lo: 0xb8, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbf}, + // Block 0x3, offset 0x25 + {value: 0x0000, lo: 0x01}, + {value: 0x3308, lo: 0x80, hi: 0xbf}, + // Block 0x4, offset 0x27 + {value: 0x0000, lo: 0x04}, + {value: 0x03f5, lo: 0x80, hi: 0x8f}, + {value: 0xe105, lo: 0x90, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x5, offset 0x2c + {value: 0x0000, lo: 0x06}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x0545, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x0008, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x6, offset 0x33 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0401, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0018, lo: 0x89, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x7, offset 0x3e + {value: 0x0000, lo: 0x0b}, + {value: 0x0818, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x82}, + {value: 0x0818, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x85}, + {value: 0x0818, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xae}, + {value: 0x0808, lo: 0xaf, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x8, offset 0x4a + {value: 0x0000, lo: 0x03}, + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0c08, lo: 0x88, hi: 0x99}, + {value: 0x0a08, lo: 0x9a, hi: 0xbf}, + // Block 0x9, offset 0x4e + {value: 0x0000, lo: 0x0e}, + {value: 0x3308, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0c08, lo: 0x8d, hi: 0x8d}, + {value: 0x0a08, lo: 0x8e, hi: 0x98}, + {value: 0x0c08, lo: 0x99, hi: 0x9b}, + {value: 0x0a08, lo: 0x9c, hi: 0xaa}, + {value: 0x0c08, lo: 0xab, hi: 0xac}, + {value: 0x0a08, lo: 0xad, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xb5, hi: 0xb7}, + {value: 0x0c08, lo: 0xb8, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbf}, + // Block 0xa, offset 0x5d + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xb, offset 0x62 + {value: 0x0000, lo: 0x09}, + {value: 0x0808, lo: 0x80, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbf}, + // Block 0xc, offset 0x6c + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x99}, + {value: 0x0808, lo: 0x9a, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa3}, + {value: 0x0808, lo: 0xa4, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa7}, + {value: 0x0808, lo: 0xa8, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0818, lo: 0xb0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd, offset 0x78 + {value: 0x0000, lo: 0x0d}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0a08, lo: 0xa0, hi: 0xa9}, + {value: 0x0c08, lo: 0xaa, hi: 0xac}, + {value: 0x0808, lo: 0xad, hi: 0xad}, + {value: 0x0c08, lo: 0xae, hi: 0xae}, + {value: 0x0a08, lo: 0xaf, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb2}, + {value: 0x0a08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0a08, lo: 0xb6, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xe, offset 0x86 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0xa1}, + {value: 0x0840, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xbf}, + // Block 0xf, offset 0x8b + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x10, offset 0x94 + {value: 0x0000, lo: 0x0f}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x85}, + {value: 0x3008, lo: 0x86, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8c}, + {value: 0x3b08, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x11, offset 0xa4 + {value: 0x0000, lo: 0x0d}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x12, offset 0xb2 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xba}, + {value: 0x3b08, lo: 0xbb, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x13, offset 0xbe + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x14, offset 0xca + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x89}, + {value: 0x3b08, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x3008, lo: 0x98, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x15, offset 0xdb + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb2}, + {value: 0x08f1, lo: 0xb3, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb9}, + {value: 0x3b08, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0x16, offset 0xe5 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x8e}, + {value: 0x0018, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0xbf}, + // Block 0x17, offset 0xec + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0961, lo: 0x9c, hi: 0x9c}, + {value: 0x0999, lo: 0x9d, hi: 0x9d}, + {value: 0x0008, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x18, offset 0xf9 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe03d, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x19, offset 0x10a + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0x1a, offset 0x111 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x1b, offset 0x11c + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xa1}, + {value: 0x3008, lo: 0xa2, hi: 0xa4}, + {value: 0x0008, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xbf}, + // Block 0x1c, offset 0x12b + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x8c}, + {value: 0x3308, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x3008, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x1d, offset 0x139 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x86}, + {value: 0x055d, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8c}, + {value: 0x055d, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0xe105, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0x1e, offset 0x143 + {value: 0x0000, lo: 0x01}, + {value: 0x0018, lo: 0x80, hi: 0xbf}, + // Block 0x1f, offset 0x145 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa0}, + {value: 0x2018, lo: 0xa1, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x20, offset 0x14a + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa7}, + {value: 0x2018, lo: 0xa8, hi: 0xbf}, + // Block 0x21, offset 0x14d + {value: 0x0000, lo: 0x02}, + {value: 0x2018, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0xbf}, + // Block 0x22, offset 0x150 + {value: 0x0000, lo: 0x01}, + {value: 0x0008, lo: 0x80, hi: 0xbf}, + // Block 0x23, offset 0x152 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x24, offset 0x15e + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x25, offset 0x169 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x26, offset 0x171 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x27, offset 0x177 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x28, offset 0x17d + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x29, offset 0x182 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x2a, offset 0x187 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x2b, offset 0x18a + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xbf}, + // Block 0x2c, offset 0x18e + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2d, offset 0x194 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x2e, offset 0x199 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x3b08, lo: 0x94, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x2f, offset 0x1a5 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x30, offset 0x1af + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xb3}, + {value: 0x3340, lo: 0xb4, hi: 0xb5}, + {value: 0x3008, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x31, offset 0x1b5 + {value: 0x0000, lo: 0x10}, + {value: 0x3008, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x91}, + {value: 0x3b08, lo: 0x92, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0x93}, + {value: 0x0018, lo: 0x94, hi: 0x96}, + {value: 0x0008, lo: 0x97, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x32, offset 0x1c6 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x86}, + {value: 0x0218, lo: 0x87, hi: 0x87}, + {value: 0x0018, lo: 0x88, hi: 0x8a}, + {value: 0x33c0, lo: 0x8b, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0208, lo: 0xa0, hi: 0xbf}, + // Block 0x33, offset 0x1d0 + {value: 0x0000, lo: 0x02}, + {value: 0x0208, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x34, offset 0x1d3 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0208, lo: 0x87, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xa9}, + {value: 0x0208, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x35, offset 0x1db + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0x36, offset 0x1de + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x37, offset 0x1eb + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x38, offset 0x1f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x39, offset 0x1f7 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0028, lo: 0x9a, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xbf}, + // Block 0x3a, offset 0x1fe + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x3308, lo: 0x97, hi: 0x98}, + {value: 0x3008, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x3b, offset 0x206 + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x94}, + {value: 0x3008, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xac}, + {value: 0x3008, lo: 0xad, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3c, offset 0x216 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xbd}, + {value: 0x3318, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x222 + {value: 0x0000, lo: 0x01}, + {value: 0x0040, lo: 0x80, hi: 0xbf}, + // Block 0x3e, offset 0x224 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3008, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x3f, offset 0x22e + {value: 0x0000, lo: 0x0b}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x3808, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x40, offset 0x23a + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3808, lo: 0xaa, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xbf}, + // Block 0x41, offset 0x246 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3008, lo: 0xaa, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3808, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x42, offset 0x252 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x3008, lo: 0xa4, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbf}, + // Block 0x43, offset 0x25a + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x44, offset 0x25f + {value: 0x0000, lo: 0x09}, + {value: 0x0e29, lo: 0x80, hi: 0x80}, + {value: 0x0e41, lo: 0x81, hi: 0x81}, + {value: 0x0e59, lo: 0x82, hi: 0x82}, + {value: 0x0e71, lo: 0x83, hi: 0x83}, + {value: 0x0e89, lo: 0x84, hi: 0x85}, + {value: 0x0ea1, lo: 0x86, hi: 0x86}, + {value: 0x0eb9, lo: 0x87, hi: 0x87}, + {value: 0x057d, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0x45, offset 0x269 + {value: 0x0000, lo: 0x10}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x92}, + {value: 0x0018, lo: 0x93, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa8}, + {value: 0x0008, lo: 0xa9, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x46, offset 0x27a + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0x47, offset 0x27e + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x87}, + {value: 0xe045, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0xe045, lo: 0x98, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0xe045, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbf}, + // Block 0x48, offset 0x289 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x3318, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbf}, + // Block 0x49, offset 0x28d + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x24c1, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x4a, offset 0x296 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x24f1, lo: 0xac, hi: 0xac}, + {value: 0x2529, lo: 0xad, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xae}, + {value: 0x2579, lo: 0xaf, hi: 0xaf}, + {value: 0x25b1, lo: 0xb0, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0x4b, offset 0x29e + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x9f}, + {value: 0x0080, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xad}, + {value: 0x0080, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x4c, offset 0x2a4 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa8}, + {value: 0x09c5, lo: 0xa9, hi: 0xa9}, + {value: 0x09e5, lo: 0xaa, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xbf}, + // Block 0x4d, offset 0x2a9 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0x4e, offset 0x2ac + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x28c1, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x4f, offset 0x2b0 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0e66, lo: 0xb4, hi: 0xb4}, + {value: 0x292a, lo: 0xb5, hi: 0xb5}, + {value: 0x0e86, lo: 0xb6, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x50, offset 0x2b6 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x9b}, + {value: 0x2941, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0xbf}, + // Block 0x51, offset 0x2ba + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x52, offset 0x2be + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0xbf}, + // Block 0x53, offset 0x2c2 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x54, offset 0x2c7 + {value: 0x0000, lo: 0x05}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x03f5, lo: 0x90, hi: 0x9f}, + {value: 0x0ea5, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x55, offset 0x2cd + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x56, offset 0x2d5 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xae}, + {value: 0xe075, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0x57, offset 0x2dc + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x58, offset 0x2e7 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xbf}, + // Block 0x59, offset 0x2f1 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x5a, offset 0x2f5 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0xbf}, + // Block 0x5b, offset 0x2f8 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9e}, + {value: 0x0edd, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x5c, offset 0x2fe + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb2}, + {value: 0x0efd, lo: 0xb3, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x5d, offset 0x302 + {value: 0x0020, lo: 0x01}, + {value: 0x0f1d, lo: 0x80, hi: 0xbf}, + // Block 0x5e, offset 0x304 + {value: 0x0020, lo: 0x02}, + {value: 0x171d, lo: 0x80, hi: 0x8f}, + {value: 0x18fd, lo: 0x90, hi: 0xbf}, + // Block 0x5f, offset 0x307 + {value: 0x0020, lo: 0x01}, + {value: 0x1efd, lo: 0x80, hi: 0xbf}, + // Block 0x60, offset 0x309 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x61, offset 0x30c + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9a}, + {value: 0x29e2, lo: 0x9b, hi: 0x9b}, + {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9e}, + {value: 0x2a31, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x62, offset 0x316 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbe}, + {value: 0x2a69, lo: 0xbf, hi: 0xbf}, + // Block 0x63, offset 0x319 + {value: 0x0000, lo: 0x0e}, + {value: 0x0040, lo: 0x80, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb0}, + {value: 0x2a1d, lo: 0xb1, hi: 0xb1}, + {value: 0x2a3d, lo: 0xb2, hi: 0xb2}, + {value: 0x2a5d, lo: 0xb3, hi: 0xb3}, + {value: 0x2a7d, lo: 0xb4, hi: 0xb4}, + {value: 0x2a5d, lo: 0xb5, hi: 0xb5}, + {value: 0x2a9d, lo: 0xb6, hi: 0xb6}, + {value: 0x2abd, lo: 0xb7, hi: 0xb7}, + {value: 0x2add, lo: 0xb8, hi: 0xb9}, + {value: 0x2afd, lo: 0xba, hi: 0xbb}, + {value: 0x2b1d, lo: 0xbc, hi: 0xbd}, + {value: 0x2afd, lo: 0xbe, hi: 0xbf}, + // Block 0x64, offset 0x328 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x65, offset 0x32c + {value: 0x0030, lo: 0x04}, + {value: 0x2aa2, lo: 0x80, hi: 0x9d}, + {value: 0x305a, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x30a2, lo: 0xa0, hi: 0xbf}, + // Block 0x66, offset 0x331 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x67, offset 0x334 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x68, offset 0x338 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x69, offset 0x33d + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0x6a, offset 0x342 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb1}, + {value: 0x0018, lo: 0xb2, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6b, offset 0x348 + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0xb6}, + {value: 0x0008, lo: 0xb7, hi: 0xb7}, + {value: 0x2009, lo: 0xb8, hi: 0xb8}, + {value: 0x6e89, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xbf}, + // Block 0x6c, offset 0x34e + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x3308, lo: 0x8b, hi: 0x8b}, + {value: 0x0008, lo: 0x8c, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x6d, offset 0x35d + {value: 0x0000, lo: 0x05}, + {value: 0x0208, lo: 0x80, hi: 0xb1}, + {value: 0x0108, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6e, offset 0x363 + {value: 0x0000, lo: 0x03}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xbf}, + // Block 0x6f, offset 0x367 + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0008, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x70, offset 0x376 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x71, offset 0x37b + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x91}, + {value: 0x3008, lo: 0x92, hi: 0x92}, + {value: 0x3808, lo: 0x93, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x72, offset 0x383 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb9}, + {value: 0x3008, lo: 0xba, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x73, offset 0x38d + {value: 0x0000, lo: 0x0a}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x74, offset 0x398 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x75, offset 0x3a0 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8c}, + {value: 0x3008, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbd}, + {value: 0x0008, lo: 0xbe, hi: 0xbf}, + // Block 0x76, offset 0x3b1 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x77, offset 0x3ba + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x9a}, + {value: 0x0008, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3b08, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x78, offset 0x3ca + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x90}, + {value: 0x0008, lo: 0x91, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x79, offset 0x3d7 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x4465, lo: 0x9c, hi: 0x9c}, + {value: 0x447d, lo: 0x9d, hi: 0x9d}, + {value: 0x2971, lo: 0x9e, hi: 0x9e}, + {value: 0xe06d, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xaf}, + {value: 0x4495, lo: 0xb0, hi: 0xbf}, + // Block 0x7a, offset 0x3e1 + {value: 0x0000, lo: 0x04}, + {value: 0x44b5, lo: 0x80, hi: 0x8f}, + {value: 0x44d5, lo: 0x90, hi: 0x9f}, + {value: 0x44f5, lo: 0xa0, hi: 0xaf}, + {value: 0x44d5, lo: 0xb0, hi: 0xbf}, + // Block 0x7b, offset 0x3e6 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3b08, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x7c, offset 0x3f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x7d, offset 0x3f7 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x7e, offset 0x3fc + {value: 0x0020, lo: 0x01}, + {value: 0x4515, lo: 0x80, hi: 0xbf}, + // Block 0x7f, offset 0x3fe + {value: 0x0020, lo: 0x03}, + {value: 0x4d15, lo: 0x80, hi: 0x94}, + {value: 0x4ad5, lo: 0x95, hi: 0x95}, + {value: 0x4fb5, lo: 0x96, hi: 0xbf}, + // Block 0x80, offset 0x402 + {value: 0x0020, lo: 0x01}, + {value: 0x54f5, lo: 0x80, hi: 0xbf}, + // Block 0x81, offset 0x404 + {value: 0x0020, lo: 0x03}, + {value: 0x5cf5, lo: 0x80, hi: 0x84}, + {value: 0x5655, lo: 0x85, hi: 0x85}, + {value: 0x5d95, lo: 0x86, hi: 0xbf}, + // Block 0x82, offset 0x408 + {value: 0x0020, lo: 0x08}, + {value: 0x6b55, lo: 0x80, hi: 0x8f}, + {value: 0x6d15, lo: 0x90, hi: 0x90}, + {value: 0x6d55, lo: 0x91, hi: 0xab}, + {value: 0x6ea1, lo: 0xac, hi: 0xac}, + {value: 0x70b5, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x70d5, lo: 0xb0, hi: 0xbf}, + // Block 0x83, offset 0x411 + {value: 0x0020, lo: 0x05}, + {value: 0x72d5, lo: 0x80, hi: 0xad}, + {value: 0x6535, lo: 0xae, hi: 0xae}, + {value: 0x7895, lo: 0xaf, hi: 0xb5}, + {value: 0x6f55, lo: 0xb6, hi: 0xb6}, + {value: 0x7975, lo: 0xb7, hi: 0xbf}, + // Block 0x84, offset 0x417 + {value: 0x0028, lo: 0x03}, + {value: 0x7c21, lo: 0x80, hi: 0x82}, + {value: 0x7be1, lo: 0x83, hi: 0x83}, + {value: 0x7c99, lo: 0x84, hi: 0xbf}, + // Block 0x85, offset 0x41b + {value: 0x0038, lo: 0x0f}, + {value: 0x9db1, lo: 0x80, hi: 0x83}, + {value: 0x9e59, lo: 0x84, hi: 0x85}, + {value: 0x9e91, lo: 0x86, hi: 0x87}, + {value: 0x9ec9, lo: 0x88, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0xa089, lo: 0x92, hi: 0x97}, + {value: 0xa1a1, lo: 0x98, hi: 0x9c}, + {value: 0xa281, lo: 0x9d, hi: 0xb3}, + {value: 0x9d41, lo: 0xb4, hi: 0xb4}, + {value: 0x9db1, lo: 0xb5, hi: 0xb5}, + {value: 0xa789, lo: 0xb6, hi: 0xbb}, + {value: 0xa869, lo: 0xbc, hi: 0xbc}, + {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, + {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, + // Block 0x86, offset 0x42b + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0008, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x87, offset 0x435 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0x88, offset 0x43a + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x89, offset 0x43d + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x8a, offset 0x443 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x8b, offset 0x44a + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x8c, offset 0x44f + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x8d, offset 0x453 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x8e, offset 0x459 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xbf}, + // Block 0x8f, offset 0x45e + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x90, offset 0x467 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x91, offset 0x46c + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x92, offset 0x472 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x97}, + {value: 0x8ad5, lo: 0x98, hi: 0x9f}, + {value: 0x8aed, lo: 0xa0, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xbf}, + // Block 0x93, offset 0x479 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x8aed, lo: 0xb0, hi: 0xb7}, + {value: 0x8ad5, lo: 0xb8, hi: 0xbf}, + // Block 0x94, offset 0x480 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x95, offset 0x487 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x96, offset 0x48b + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xae}, + {value: 0x0018, lo: 0xaf, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x97, offset 0x490 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x98, offset 0x493 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xbf}, + // Block 0x99, offset 0x498 + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0808, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0808, lo: 0x8a, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb6}, + {value: 0x0808, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbb}, + {value: 0x0808, lo: 0xbc, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x0808, lo: 0xbf, hi: 0xbf}, + // Block 0x9a, offset 0x4a4 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x96}, + {value: 0x0818, lo: 0x97, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0818, lo: 0xb7, hi: 0xbf}, + // Block 0x9b, offset 0x4aa + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa6}, + {value: 0x0818, lo: 0xa7, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x9c, offset 0x4af + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x0818, lo: 0xbb, hi: 0xbf}, + // Block 0x9d, offset 0x4b6 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0818, lo: 0x96, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbe}, + {value: 0x0818, lo: 0xbf, hi: 0xbf}, + // Block 0x9e, offset 0x4be + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbb}, + {value: 0x0818, lo: 0xbc, hi: 0xbd}, + {value: 0x0808, lo: 0xbe, hi: 0xbf}, + // Block 0x9f, offset 0x4c3 + {value: 0x0000, lo: 0x03}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0xa0, offset 0x4c7 + {value: 0x0000, lo: 0x0f}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x94}, + {value: 0x0808, lo: 0x95, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x98}, + {value: 0x0808, lo: 0x99, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xa1, offset 0x4d7 + {value: 0x0000, lo: 0x06}, + {value: 0x0818, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0818, lo: 0x90, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xbc}, + {value: 0x0818, lo: 0xbd, hi: 0xbf}, + // Block 0xa2, offset 0x4de + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xa3, offset 0x4e2 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb8}, + {value: 0x0018, lo: 0xb9, hi: 0xbf}, + // Block 0xa4, offset 0x4e6 + {value: 0x0000, lo: 0x06}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0818, lo: 0x98, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb7}, + {value: 0x0818, lo: 0xb8, hi: 0xbf}, + // Block 0xa5, offset 0x4ed + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa6, offset 0x4ef + {value: 0x0000, lo: 0x02}, + {value: 0x0808, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xa7, offset 0x4f2 + {value: 0x0000, lo: 0x02}, + {value: 0x03dd, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xa8, offset 0x4f5 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xa9, offset 0x4f9 + {value: 0x0000, lo: 0x08}, + {value: 0x0908, lo: 0x80, hi: 0x80}, + {value: 0x0a08, lo: 0x81, hi: 0xa1}, + {value: 0x0c08, lo: 0xa2, hi: 0xa2}, + {value: 0x0a08, lo: 0xa3, hi: 0xa3}, + {value: 0x3308, lo: 0xa4, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0808, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xaa, offset 0x502 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xab, offset 0x506 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0xa6}, + {value: 0x0808, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0a08, lo: 0xb0, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb3}, + {value: 0x0a08, lo: 0xb4, hi: 0xbf}, + // Block 0xac, offset 0x50e + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x84}, + {value: 0x0808, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x90}, + {value: 0x0a18, lo: 0x91, hi: 0x93}, + {value: 0x0c18, lo: 0x94, hi: 0x94}, + {value: 0x0818, lo: 0x95, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xad, offset 0x516 + {value: 0x0000, lo: 0x05}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xae, offset 0x51c + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x91}, + {value: 0x0018, lo: 0x92, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xaf, offset 0x525 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0xb0, offset 0x531 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb1, offset 0x538 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb2}, + {value: 0x3b08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xbf}, + // Block 0xb2, offset 0x541 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xb3, offset 0x54b + {value: 0x0000, lo: 0x06}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xbe}, + {value: 0x3008, lo: 0xbf, hi: 0xbf}, + // Block 0xb4, offset 0x552 + {value: 0x0000, lo: 0x0d}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xb5, offset 0x560 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3808, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xb6, offset 0x56d + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0008, lo: 0x9f, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xb7, offset 0x57a + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x3308, lo: 0x9f, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa9}, + {value: 0x3b08, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb8, offset 0x583 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xb9, offset 0x587 + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xba, offset 0x596 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xbb, offset 0x59e + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x85}, + {value: 0x0018, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xbc, offset 0x5a9 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbd, offset 0x5b2 + {value: 0x0000, lo: 0x05}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9b}, + {value: 0x3308, lo: 0x9c, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xbe, offset 0x5b8 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbf, offset 0x5c0 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xc0, offset 0x5c9 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb5}, + {value: 0x3808, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0xc1, offset 0x5d3 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0xc2, offset 0x5d6 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0xc3, offset 0x5e2 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xc4, offset 0x5eb + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xbf}, + // Block 0xc5, offset 0x5ee + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0xc6, offset 0x5f3 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xc7, offset 0x5fe + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x3b08, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0xbf}, + // Block 0xc8, offset 0x607 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x98}, + {value: 0x3b08, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xbf}, + // Block 0xc9, offset 0x613 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xca, offset 0x616 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xcb, offset 0x620 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xbf}, + // Block 0xcc, offset 0x629 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xaa, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xcd, offset 0x635 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xce, offset 0x642 + {value: 0x0000, lo: 0x0c}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xbf}, + // Block 0xcf, offset 0x64f + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x3008, lo: 0x93, hi: 0x94}, + {value: 0x3308, lo: 0x95, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x96}, + {value: 0x3b08, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xbf}, + // Block 0xd0, offset 0x65d + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xd1, offset 0x664 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xd2, offset 0x667 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xd3, offset 0x66c + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0xbf}, + // Block 0xd4, offset 0x66f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xbf}, + // Block 0xd5, offset 0x672 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xbf}, + // Block 0xd6, offset 0x675 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xd7, offset 0x67c + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xd8, offset 0x683 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0xd9, offset 0x687 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0xda, offset 0x692 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xdb, offset 0x695 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0xdc, offset 0x698 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0xdd, offset 0x69b + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3008, lo: 0x91, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xde, offset 0x6a1 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xdf, offset 0x6a6 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xbf}, + // Block 0xe0, offset 0x6aa + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe1, offset 0x6ad + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xe2, offset 0x6b0 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xe3, offset 0x6b3 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xe4, offset 0x6b6 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xe5, offset 0x6b9 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0xe6, offset 0x6be + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x03c0, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xbf}, + // Block 0xe7, offset 0x6c8 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xe8, offset 0x6cb + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xbf}, + // Block 0xe9, offset 0x6cf + {value: 0x0000, lo: 0x0e}, + {value: 0x0018, lo: 0x80, hi: 0x9d}, + {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, + {value: 0xb601, lo: 0x9f, hi: 0x9f}, + {value: 0xb649, lo: 0xa0, hi: 0xa0}, + {value: 0xb6b1, lo: 0xa1, hi: 0xa1}, + {value: 0xb719, lo: 0xa2, hi: 0xa2}, + {value: 0xb781, lo: 0xa3, hi: 0xa3}, + {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, + {value: 0x3018, lo: 0xa5, hi: 0xa6}, + {value: 0x3318, lo: 0xa7, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xac}, + {value: 0x3018, lo: 0xad, hi: 0xb2}, + {value: 0x0340, lo: 0xb3, hi: 0xba}, + {value: 0x3318, lo: 0xbb, hi: 0xbf}, + // Block 0xea, offset 0x6de + {value: 0x0000, lo: 0x0b}, + {value: 0x3318, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0x84}, + {value: 0x3318, lo: 0x85, hi: 0x8b}, + {value: 0x0018, lo: 0x8c, hi: 0xa9}, + {value: 0x3318, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xba}, + {value: 0xb851, lo: 0xbb, hi: 0xbb}, + {value: 0xb899, lo: 0xbc, hi: 0xbc}, + {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, + {value: 0xb949, lo: 0xbe, hi: 0xbe}, + {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, + // Block 0xeb, offset 0x6ea + {value: 0x0000, lo: 0x03}, + {value: 0xba19, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xbf}, + // Block 0xec, offset 0x6ee + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x3318, lo: 0x82, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0xbf}, + // Block 0xed, offset 0x6f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0xee, offset 0x6f7 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xef, offset 0x6fc + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xf0, offset 0x700 + {value: 0x0000, lo: 0x04}, + {value: 0x3308, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0xf1, offset 0x705 + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x3308, lo: 0xa1, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xf2, offset 0x70e + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0xf3, offset 0x719 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x86}, + {value: 0x0818, lo: 0x87, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xf4, offset 0x71f + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xf5, offset 0x727 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xb0}, + {value: 0x0818, lo: 0xb1, hi: 0xbf}, + // Block 0xf6, offset 0x72a + {value: 0x0000, lo: 0x02}, + {value: 0x0818, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xf7, offset 0x72d + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xf8, offset 0x731 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0xf9, offset 0x735 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0xfa, offset 0x73b + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xfb, offset 0x741 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0xc1c1, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xfc, offset 0x746 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xbf}, + // Block 0xfd, offset 0x749 + {value: 0x0000, lo: 0x0f}, + {value: 0xc7e9, lo: 0x80, hi: 0x80}, + {value: 0xc839, lo: 0x81, hi: 0x81}, + {value: 0xc889, lo: 0x82, hi: 0x82}, + {value: 0xc8d9, lo: 0x83, hi: 0x83}, + {value: 0xc929, lo: 0x84, hi: 0x84}, + {value: 0xc979, lo: 0x85, hi: 0x85}, + {value: 0xc9c9, lo: 0x86, hi: 0x86}, + {value: 0xca19, lo: 0x87, hi: 0x87}, + {value: 0xca69, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0xcab9, lo: 0x90, hi: 0x90}, + {value: 0xcad9, lo: 0x91, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xbf}, + // Block 0xfe, offset 0x759 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xff, offset 0x760 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x100, offset 0x763 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0xbf}, + // Block 0x101, offset 0x766 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x102, offset 0x76a + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x103, offset 0x770 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0x104, offset 0x775 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x105, offset 0x77a + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb2}, + {value: 0x0018, lo: 0xb3, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x106, offset 0x782 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x107, offset 0x787 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x108, offset 0x78b + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0x109, offset 0x78f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0x10a, offset 0x792 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x10b, offset 0x795 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x10c, offset 0x799 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x10d, offset 0x79d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x10e, offset 0x7a0 + {value: 0x0020, lo: 0x0f}, + {value: 0xdeb9, lo: 0x80, hi: 0x89}, + {value: 0x8dfd, lo: 0x8a, hi: 0x8a}, + {value: 0xdff9, lo: 0x8b, hi: 0x9c}, + {value: 0x8e1d, lo: 0x9d, hi: 0x9d}, + {value: 0xe239, lo: 0x9e, hi: 0xa2}, + {value: 0x8e3d, lo: 0xa3, hi: 0xa3}, + {value: 0xe2d9, lo: 0xa4, hi: 0xab}, + {value: 0x7ed5, lo: 0xac, hi: 0xac}, + {value: 0xe3d9, lo: 0xad, hi: 0xaf}, + {value: 0x8e5d, lo: 0xb0, hi: 0xb0}, + {value: 0xe439, lo: 0xb1, hi: 0xb6}, + {value: 0x8e7d, lo: 0xb7, hi: 0xb9}, + {value: 0xe4f9, lo: 0xba, hi: 0xba}, + {value: 0x8edd, lo: 0xbb, hi: 0xbb}, + {value: 0xe519, lo: 0xbc, hi: 0xbf}, + // Block 0x10f, offset 0x7b0 + {value: 0x0020, lo: 0x10}, + {value: 0x937d, lo: 0x80, hi: 0x80}, + {value: 0xf099, lo: 0x81, hi: 0x86}, + {value: 0x939d, lo: 0x87, hi: 0x8a}, + {value: 0xd9f9, lo: 0x8b, hi: 0x8b}, + {value: 0xf159, lo: 0x8c, hi: 0x96}, + {value: 0x941d, lo: 0x97, hi: 0x97}, + {value: 0xf2b9, lo: 0x98, hi: 0xa3}, + {value: 0x943d, lo: 0xa4, hi: 0xa6}, + {value: 0xf439, lo: 0xa7, hi: 0xaa}, + {value: 0x949d, lo: 0xab, hi: 0xab}, + {value: 0xf4b9, lo: 0xac, hi: 0xac}, + {value: 0x94bd, lo: 0xad, hi: 0xad}, + {value: 0xf4d9, lo: 0xae, hi: 0xaf}, + {value: 0x94dd, lo: 0xb0, hi: 0xb1}, + {value: 0xf519, lo: 0xb2, hi: 0xbe}, + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0x110, offset 0x7c1 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0340, lo: 0x81, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x9f}, + {value: 0x0340, lo: 0xa0, hi: 0xbf}, + // Block 0x111, offset 0x7c6 + {value: 0x0000, lo: 0x01}, + {value: 0x0340, lo: 0x80, hi: 0xbf}, + // Block 0x112, offset 0x7c8 + {value: 0x0000, lo: 0x01}, + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x113, offset 0x7ca + {value: 0x0000, lo: 0x02}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, +} + +// Total table size 42466 bytes (41KiB); checksum: 355A58A4 diff --git a/vendor/golang.org/x/net/idna/tables9.0.0.go b/vendor/golang.org/x/net/idna/tables9.0.0.go new file mode 100644 index 000000000000..8b65fa167830 --- /dev/null +++ b/vendor/golang.org/x/net/idna/tables9.0.0.go @@ -0,0 +1,4486 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build !go1.10 + +package idna + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "9.0.0" + +var mappings string = "" + // Size: 8175 bytes + "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + + "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + + "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + + "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" + + "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" + + "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" + + "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" + + "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" + + "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" + + "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" + + "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" + + "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" + + "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" + + "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" + + "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" + + "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" + + "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" + + "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" + + "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" + + "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" + + "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" + + "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" + + "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" + + "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" + + "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" + + "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" + + ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" + + "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" + + "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" + + "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" + + "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" + + "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" + + "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" + + "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" + + "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" + + "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" + + "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" + + "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" + + "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" + + "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" + + "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" + + "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" + + "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" + + "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" + + "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" + + "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" + + "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" + + "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" + + "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" + + "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" + + "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" + + "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" + + "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" + + "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" + + "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" + + "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" + + "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" + + "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" + + "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" + + "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" + + "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" + + "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" + + "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" + + "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" + + "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" + + "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" + + "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" + + "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" + + "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" + + "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" + + "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" + + "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" + + "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" + + " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" + + "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" + + "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" + + "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" + + "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" + + "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" + + "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" + + "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" + + "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" + + "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" + + "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" + + "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" + + "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" + + "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" + + "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" + + "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" + + "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" + + "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" + + "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" + + "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" + + "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" + + "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" + + "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" + + "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" + + "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" + + "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" + + "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" + + "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" + + "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" + + "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" + + "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" + + "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" + + "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" + + "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" + + "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" + + "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" + + "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" + + "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" + + "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" + + "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" + + "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" + + "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" + + "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" + + "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" + + "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" + + "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" + + "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" + + "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" + + "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" + + "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" + + "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" + + "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" + + "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" + + "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" + + "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" + + "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" + + "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" + + "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" + + "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" + + "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" + + "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" + + "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" + + "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" + + "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻" + +var xorData string = "" + // Size: 4855 bytes + "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" + + "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" + + "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" + + "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" + + "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" + + "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" + + "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" + + "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" + + "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" + + "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" + + "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" + + "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" + + "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" + + "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" + + "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" + + "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" + + "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" + + "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" + + "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" + + "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" + + "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" + + "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" + + "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" + + "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" + + "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" + + "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" + + "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" + + "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" + + "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" + + "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" + + "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" + + "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" + + "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" + + "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" + + "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" + + "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" + + "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " + + "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" + + "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" + + "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" + + "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" + + "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" + + ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" + + "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" + + "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" + + "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" + + "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" + + "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" + + "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" + + "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" + + "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" + + "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" + + "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" + + "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" + + "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" + + "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" + + "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" + + "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" + + "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" + + "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" + + "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" + + "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" + + "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" + + "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" + + "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" + + "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" + + "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" + + "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" + + "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" + + "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" + + "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" + + "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" + + "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" + + "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" + + "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" + + "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" + + "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" + + "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" + + "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" + + "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" + + "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" + + "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" + + "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" + + "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" + + "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" + + "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" + + "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" + + "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" + + "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," + + "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" + + "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" + + "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" + + "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" + + ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" + + "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" + + "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" + + "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" + + "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" + + "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" + + "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" + + "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" + + "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" + + "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" + + "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" + + "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" + + "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" + + "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" + + "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" + + "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" + + "\x08\x1a\x0a\x03\x07</\x03\x07:+\x03\x07\x07*\x03\x06&\x1c\x03\x09\x0c" + + "\x16\x03\x09\x10\x0e\x03\x08'\x0f\x03\x08+\x09\x03\x074%\x03\x06!3\x03" + + "\x06\x03+\x03\x0b\x1e\x19\x03\x0a))\x03\x09\x08\x19\x03\x08,\x05\x03\x07" + + "<2\x03\x06\x1c>\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" + + "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" + + "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" + + "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" + + "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" + + "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" + + "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" + + "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" + + "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" + + "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" + + "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" + + "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" + + "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" + + "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" + + "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" + + "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" + + "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" + + "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." + + "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" + + "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" + + "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " + + "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" + + "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" + + "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" + + "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" + + "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" + + "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" + + "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," + + "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" + + "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" + + "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" + + "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" + + "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" + + "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" + + "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" + + "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" + + "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" + + "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" + + "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" + + "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" + + "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" + + "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" + + "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" + + "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" + + "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" + + "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" + + "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" + + "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" + + "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" + + "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" + + "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" + + "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" + + "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" + + "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" + + "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" + + "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" + + "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" + + "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" + + "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" + + "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" + + "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" + + "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" + + "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" + + "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" + + "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" + + "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" + + "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," + + "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" + + "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" + + "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" + + "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" + + "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" + + "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" + + "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" + + "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" + + "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" + + "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" + + "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" + + "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" + + "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" + + "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" + + "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" + + "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" + + "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" + + "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" + + "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" + + "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" + + "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" + + "\x04\x03\x0c?\x05\x03\x0c<?\x03\x0c=\x00\x03\x0c=\x06\x03\x0c=\x05\x03" + + "\x0c=\x0c\x03\x0c=\x0f\x03\x0c=\x0d\x03\x0c=\x0b\x03\x0c=\x07\x03\x0c=" + + "\x19\x03\x0c=\x15\x03\x0c=\x11\x03\x0c=1\x03\x0c=3\x03\x0c=0\x03\x0c=>" + + "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" + + "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" + + "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" + + "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" + + "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" + + "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" + + "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" + + "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" + + "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" + + "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" + + "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" + + "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" + + "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" + + "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" + + "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" + + "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" + + "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" + + "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" + + "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" + + "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" + + "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" + + "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" + + "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" + + "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" + + "\x05\x22\x05\x03\x050\x1d" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// idnaTrie. Total size: 28600 bytes (27.93 KiB). Checksum: 95575047b5d8fff. +type idnaTrie struct{} + +func newIdnaTrie(i int) *idnaTrie { + return &idnaTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 124: + return uint16(idnaValues[n<<6+uint32(b)]) + default: + n -= 124 + return uint16(idnaSparse.lookup(n, b)) + } +} + +// idnaValues: 126 blocks, 8064 entries, 16128 bytes +// The third block is the zero block. +var idnaValues = [8064]uint16{ + // Block 0x0, offset 0x0 + 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, + 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, + 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080, + 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080, + 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080, + 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080, + 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080, + 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080, + 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008, + 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080, + 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080, + // Block 0x1, offset 0x40 + 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105, + 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105, + 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105, + 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105, + 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080, + 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008, + 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008, + 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008, + 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008, + 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080, + 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018, + 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018, + 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a, + 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005, + 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018, + 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018, + // Block 0x4, offset 0x100 + 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008, + 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008, + 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008, + 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008, + 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008, + 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008, + 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008, + 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008, + 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008, + 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d, + 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199, + // Block 0x5, offset 0x140 + 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d, + 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008, + 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008, + 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008, + 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008, + 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008, + 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008, + 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008, + 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008, + 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d, + 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9, + // Block 0x6, offset 0x180 + 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008, + 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d, + 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d, + 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d, + 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155, + 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008, + 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d, + 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd, + 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d, + 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008, + 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9, + 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d, + 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d, + 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d, + 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008, + 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008, + 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008, + 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008, + 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008, + 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008, + 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008, + // Block 0x8, offset 0x200 + 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008, + 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008, + 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008, + 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008, + 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008, + 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008, + 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008, + 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008, + 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008, + 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d, + 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008, + // Block 0x9, offset 0x240 + 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018, + 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008, + 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008, + 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018, + 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a, + 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369, + 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018, + 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018, + 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018, + 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, + 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, + // Block 0xa, offset 0x280 + 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, + 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, + 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, + 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, + 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, + 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, + 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, + 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, + 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, + 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, + 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2, + 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040, + 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105, + 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105, + 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105, + 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d, + 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d, + 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008, + 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008, + 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008, + 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008, + // Block 0xc, offset 0x300 + 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008, + 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008, + 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd, + 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008, + 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008, + 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008, + 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008, + 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008, + 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd, + 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008, + 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d, + // Block 0xd, offset 0x340 + 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008, + 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008, + 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008, + 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008, + 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008, + 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008, + 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008, + 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008, + 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008, + 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, + 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, + // Block 0xe, offset 0x380 + 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, + 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, + 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, + 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, + 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, + 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008, + 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008, + 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008, + 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008, + 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008, + 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d, + 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d, + 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008, + 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008, + 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008, + 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008, + 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008, + 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008, + 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008, + 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008, + 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008, + // Block 0x10, offset 0x400 + 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008, + 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008, + 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008, + 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008, + 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008, + 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008, + 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008, + 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008, + 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5, + 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, + 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, + // Block 0x11, offset 0x440 + 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, + 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, + 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, + 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, + 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, + 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, + 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, + 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, + 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, + 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, + 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, + // Block 0x12, offset 0x480 + 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, + 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, + 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, + 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, + 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, + 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, + 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, + 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, + 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, + 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, + 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, + 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, + 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, + 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, + 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, + 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, + 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, + 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, + 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, + 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, + 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, + // Block 0x14, offset 0x500 + 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, + 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, + 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, + 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, + 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, + 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, + 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, + 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, + 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, + 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, + 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, + // Block 0x15, offset 0x540 + 0x540: 0x3008, 0x541: 0x3308, 0x542: 0x3308, 0x543: 0x3308, 0x544: 0x3308, 0x545: 0x3308, + 0x546: 0x3308, 0x547: 0x3308, 0x548: 0x3308, 0x549: 0x3008, 0x54a: 0x3008, 0x54b: 0x3008, + 0x54c: 0x3008, 0x54d: 0x3b08, 0x54e: 0x3008, 0x54f: 0x3008, 0x550: 0x0008, 0x551: 0x3308, + 0x552: 0x3308, 0x553: 0x3308, 0x554: 0x3308, 0x555: 0x3308, 0x556: 0x3308, 0x557: 0x3308, + 0x558: 0x04c9, 0x559: 0x0501, 0x55a: 0x0539, 0x55b: 0x0571, 0x55c: 0x05a9, 0x55d: 0x05e1, + 0x55e: 0x0619, 0x55f: 0x0651, 0x560: 0x0008, 0x561: 0x0008, 0x562: 0x3308, 0x563: 0x3308, + 0x564: 0x0018, 0x565: 0x0018, 0x566: 0x0008, 0x567: 0x0008, 0x568: 0x0008, 0x569: 0x0008, + 0x56a: 0x0008, 0x56b: 0x0008, 0x56c: 0x0008, 0x56d: 0x0008, 0x56e: 0x0008, 0x56f: 0x0008, + 0x570: 0x0018, 0x571: 0x0008, 0x572: 0x0008, 0x573: 0x0008, 0x574: 0x0008, 0x575: 0x0008, + 0x576: 0x0008, 0x577: 0x0008, 0x578: 0x0008, 0x579: 0x0008, 0x57a: 0x0008, 0x57b: 0x0008, + 0x57c: 0x0008, 0x57d: 0x0008, 0x57e: 0x0008, 0x57f: 0x0008, + // Block 0x16, offset 0x580 + 0x580: 0x0008, 0x581: 0x3308, 0x582: 0x3008, 0x583: 0x3008, 0x584: 0x0040, 0x585: 0x0008, + 0x586: 0x0008, 0x587: 0x0008, 0x588: 0x0008, 0x589: 0x0008, 0x58a: 0x0008, 0x58b: 0x0008, + 0x58c: 0x0008, 0x58d: 0x0040, 0x58e: 0x0040, 0x58f: 0x0008, 0x590: 0x0008, 0x591: 0x0040, + 0x592: 0x0040, 0x593: 0x0008, 0x594: 0x0008, 0x595: 0x0008, 0x596: 0x0008, 0x597: 0x0008, + 0x598: 0x0008, 0x599: 0x0008, 0x59a: 0x0008, 0x59b: 0x0008, 0x59c: 0x0008, 0x59d: 0x0008, + 0x59e: 0x0008, 0x59f: 0x0008, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x0008, 0x5a3: 0x0008, + 0x5a4: 0x0008, 0x5a5: 0x0008, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0040, + 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, + 0x5b0: 0x0008, 0x5b1: 0x0040, 0x5b2: 0x0008, 0x5b3: 0x0040, 0x5b4: 0x0040, 0x5b5: 0x0040, + 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0040, 0x5bb: 0x0040, + 0x5bc: 0x3308, 0x5bd: 0x0008, 0x5be: 0x3008, 0x5bf: 0x3008, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x3008, 0x5c1: 0x3308, 0x5c2: 0x3308, 0x5c3: 0x3308, 0x5c4: 0x3308, 0x5c5: 0x0040, + 0x5c6: 0x0040, 0x5c7: 0x3008, 0x5c8: 0x3008, 0x5c9: 0x0040, 0x5ca: 0x0040, 0x5cb: 0x3008, + 0x5cc: 0x3008, 0x5cd: 0x3b08, 0x5ce: 0x0008, 0x5cf: 0x0040, 0x5d0: 0x0040, 0x5d1: 0x0040, + 0x5d2: 0x0040, 0x5d3: 0x0040, 0x5d4: 0x0040, 0x5d5: 0x0040, 0x5d6: 0x0040, 0x5d7: 0x3008, + 0x5d8: 0x0040, 0x5d9: 0x0040, 0x5da: 0x0040, 0x5db: 0x0040, 0x5dc: 0x0689, 0x5dd: 0x06c1, + 0x5de: 0x0040, 0x5df: 0x06f9, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x3308, 0x5e3: 0x3308, + 0x5e4: 0x0040, 0x5e5: 0x0040, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0008, + 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, + 0x5f0: 0x0008, 0x5f1: 0x0008, 0x5f2: 0x0018, 0x5f3: 0x0018, 0x5f4: 0x0018, 0x5f5: 0x0018, + 0x5f6: 0x0018, 0x5f7: 0x0018, 0x5f8: 0x0018, 0x5f9: 0x0018, 0x5fa: 0x0018, 0x5fb: 0x0018, + 0x5fc: 0x0040, 0x5fd: 0x0040, 0x5fe: 0x0040, 0x5ff: 0x0040, + // Block 0x18, offset 0x600 + 0x600: 0x0040, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3008, 0x604: 0x0040, 0x605: 0x0008, + 0x606: 0x0008, 0x607: 0x0008, 0x608: 0x0008, 0x609: 0x0008, 0x60a: 0x0008, 0x60b: 0x0040, + 0x60c: 0x0040, 0x60d: 0x0040, 0x60e: 0x0040, 0x60f: 0x0008, 0x610: 0x0008, 0x611: 0x0040, + 0x612: 0x0040, 0x613: 0x0008, 0x614: 0x0008, 0x615: 0x0008, 0x616: 0x0008, 0x617: 0x0008, + 0x618: 0x0008, 0x619: 0x0008, 0x61a: 0x0008, 0x61b: 0x0008, 0x61c: 0x0008, 0x61d: 0x0008, + 0x61e: 0x0008, 0x61f: 0x0008, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x0008, 0x623: 0x0008, + 0x624: 0x0008, 0x625: 0x0008, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0040, + 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, + 0x630: 0x0008, 0x631: 0x0040, 0x632: 0x0008, 0x633: 0x0731, 0x634: 0x0040, 0x635: 0x0008, + 0x636: 0x0769, 0x637: 0x0040, 0x638: 0x0008, 0x639: 0x0008, 0x63a: 0x0040, 0x63b: 0x0040, + 0x63c: 0x3308, 0x63d: 0x0040, 0x63e: 0x3008, 0x63f: 0x3008, + // Block 0x19, offset 0x640 + 0x640: 0x3008, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x0040, 0x644: 0x0040, 0x645: 0x0040, + 0x646: 0x0040, 0x647: 0x3308, 0x648: 0x3308, 0x649: 0x0040, 0x64a: 0x0040, 0x64b: 0x3308, + 0x64c: 0x3308, 0x64d: 0x3b08, 0x64e: 0x0040, 0x64f: 0x0040, 0x650: 0x0040, 0x651: 0x3308, + 0x652: 0x0040, 0x653: 0x0040, 0x654: 0x0040, 0x655: 0x0040, 0x656: 0x0040, 0x657: 0x0040, + 0x658: 0x0040, 0x659: 0x07a1, 0x65a: 0x07d9, 0x65b: 0x0811, 0x65c: 0x0008, 0x65d: 0x0040, + 0x65e: 0x0849, 0x65f: 0x0040, 0x660: 0x0040, 0x661: 0x0040, 0x662: 0x0040, 0x663: 0x0040, + 0x664: 0x0040, 0x665: 0x0040, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0008, + 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, + 0x670: 0x3308, 0x671: 0x3308, 0x672: 0x0008, 0x673: 0x0008, 0x674: 0x0008, 0x675: 0x3308, + 0x676: 0x0040, 0x677: 0x0040, 0x678: 0x0040, 0x679: 0x0040, 0x67a: 0x0040, 0x67b: 0x0040, + 0x67c: 0x0040, 0x67d: 0x0040, 0x67e: 0x0040, 0x67f: 0x0040, + // Block 0x1a, offset 0x680 + 0x680: 0x0040, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x3008, 0x684: 0x0040, 0x685: 0x0008, + 0x686: 0x0008, 0x687: 0x0008, 0x688: 0x0008, 0x689: 0x0008, 0x68a: 0x0008, 0x68b: 0x0008, + 0x68c: 0x0008, 0x68d: 0x0008, 0x68e: 0x0040, 0x68f: 0x0008, 0x690: 0x0008, 0x691: 0x0008, + 0x692: 0x0040, 0x693: 0x0008, 0x694: 0x0008, 0x695: 0x0008, 0x696: 0x0008, 0x697: 0x0008, + 0x698: 0x0008, 0x699: 0x0008, 0x69a: 0x0008, 0x69b: 0x0008, 0x69c: 0x0008, 0x69d: 0x0008, + 0x69e: 0x0008, 0x69f: 0x0008, 0x6a0: 0x0008, 0x6a1: 0x0008, 0x6a2: 0x0008, 0x6a3: 0x0008, + 0x6a4: 0x0008, 0x6a5: 0x0008, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0040, + 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, + 0x6b0: 0x0008, 0x6b1: 0x0040, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0040, 0x6b5: 0x0008, + 0x6b6: 0x0008, 0x6b7: 0x0008, 0x6b8: 0x0008, 0x6b9: 0x0008, 0x6ba: 0x0040, 0x6bb: 0x0040, + 0x6bc: 0x3308, 0x6bd: 0x0008, 0x6be: 0x3008, 0x6bf: 0x3008, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x3008, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3308, 0x6c4: 0x3308, 0x6c5: 0x3308, + 0x6c6: 0x0040, 0x6c7: 0x3308, 0x6c8: 0x3308, 0x6c9: 0x3008, 0x6ca: 0x0040, 0x6cb: 0x3008, + 0x6cc: 0x3008, 0x6cd: 0x3b08, 0x6ce: 0x0040, 0x6cf: 0x0040, 0x6d0: 0x0008, 0x6d1: 0x0040, + 0x6d2: 0x0040, 0x6d3: 0x0040, 0x6d4: 0x0040, 0x6d5: 0x0040, 0x6d6: 0x0040, 0x6d7: 0x0040, + 0x6d8: 0x0040, 0x6d9: 0x0040, 0x6da: 0x0040, 0x6db: 0x0040, 0x6dc: 0x0040, 0x6dd: 0x0040, + 0x6de: 0x0040, 0x6df: 0x0040, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x3308, 0x6e3: 0x3308, + 0x6e4: 0x0040, 0x6e5: 0x0040, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0008, + 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, + 0x6f0: 0x0018, 0x6f1: 0x0018, 0x6f2: 0x0040, 0x6f3: 0x0040, 0x6f4: 0x0040, 0x6f5: 0x0040, + 0x6f6: 0x0040, 0x6f7: 0x0040, 0x6f8: 0x0040, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, + 0x6fc: 0x0040, 0x6fd: 0x0040, 0x6fe: 0x0040, 0x6ff: 0x0040, + // Block 0x1c, offset 0x700 + 0x700: 0x0040, 0x701: 0x3308, 0x702: 0x3008, 0x703: 0x3008, 0x704: 0x0040, 0x705: 0x0008, + 0x706: 0x0008, 0x707: 0x0008, 0x708: 0x0008, 0x709: 0x0008, 0x70a: 0x0008, 0x70b: 0x0008, + 0x70c: 0x0008, 0x70d: 0x0040, 0x70e: 0x0040, 0x70f: 0x0008, 0x710: 0x0008, 0x711: 0x0040, + 0x712: 0x0040, 0x713: 0x0008, 0x714: 0x0008, 0x715: 0x0008, 0x716: 0x0008, 0x717: 0x0008, + 0x718: 0x0008, 0x719: 0x0008, 0x71a: 0x0008, 0x71b: 0x0008, 0x71c: 0x0008, 0x71d: 0x0008, + 0x71e: 0x0008, 0x71f: 0x0008, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x0008, 0x723: 0x0008, + 0x724: 0x0008, 0x725: 0x0008, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0040, + 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, + 0x730: 0x0008, 0x731: 0x0040, 0x732: 0x0008, 0x733: 0x0008, 0x734: 0x0040, 0x735: 0x0008, + 0x736: 0x0008, 0x737: 0x0008, 0x738: 0x0008, 0x739: 0x0008, 0x73a: 0x0040, 0x73b: 0x0040, + 0x73c: 0x3308, 0x73d: 0x0008, 0x73e: 0x3008, 0x73f: 0x3308, + // Block 0x1d, offset 0x740 + 0x740: 0x3008, 0x741: 0x3308, 0x742: 0x3308, 0x743: 0x3308, 0x744: 0x3308, 0x745: 0x0040, + 0x746: 0x0040, 0x747: 0x3008, 0x748: 0x3008, 0x749: 0x0040, 0x74a: 0x0040, 0x74b: 0x3008, + 0x74c: 0x3008, 0x74d: 0x3b08, 0x74e: 0x0040, 0x74f: 0x0040, 0x750: 0x0040, 0x751: 0x0040, + 0x752: 0x0040, 0x753: 0x0040, 0x754: 0x0040, 0x755: 0x0040, 0x756: 0x3308, 0x757: 0x3008, + 0x758: 0x0040, 0x759: 0x0040, 0x75a: 0x0040, 0x75b: 0x0040, 0x75c: 0x0881, 0x75d: 0x08b9, + 0x75e: 0x0040, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x3308, 0x763: 0x3308, + 0x764: 0x0040, 0x765: 0x0040, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0008, + 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, + 0x770: 0x0018, 0x771: 0x0008, 0x772: 0x0018, 0x773: 0x0018, 0x774: 0x0018, 0x775: 0x0018, + 0x776: 0x0018, 0x777: 0x0018, 0x778: 0x0040, 0x779: 0x0040, 0x77a: 0x0040, 0x77b: 0x0040, + 0x77c: 0x0040, 0x77d: 0x0040, 0x77e: 0x0040, 0x77f: 0x0040, + // Block 0x1e, offset 0x780 + 0x780: 0x0040, 0x781: 0x0040, 0x782: 0x3308, 0x783: 0x0008, 0x784: 0x0040, 0x785: 0x0008, + 0x786: 0x0008, 0x787: 0x0008, 0x788: 0x0008, 0x789: 0x0008, 0x78a: 0x0008, 0x78b: 0x0040, + 0x78c: 0x0040, 0x78d: 0x0040, 0x78e: 0x0008, 0x78f: 0x0008, 0x790: 0x0008, 0x791: 0x0040, + 0x792: 0x0008, 0x793: 0x0008, 0x794: 0x0008, 0x795: 0x0008, 0x796: 0x0040, 0x797: 0x0040, + 0x798: 0x0040, 0x799: 0x0008, 0x79a: 0x0008, 0x79b: 0x0040, 0x79c: 0x0008, 0x79d: 0x0040, + 0x79e: 0x0008, 0x79f: 0x0008, 0x7a0: 0x0040, 0x7a1: 0x0040, 0x7a2: 0x0040, 0x7a3: 0x0008, + 0x7a4: 0x0008, 0x7a5: 0x0040, 0x7a6: 0x0040, 0x7a7: 0x0040, 0x7a8: 0x0008, 0x7a9: 0x0008, + 0x7aa: 0x0008, 0x7ab: 0x0040, 0x7ac: 0x0040, 0x7ad: 0x0040, 0x7ae: 0x0008, 0x7af: 0x0008, + 0x7b0: 0x0008, 0x7b1: 0x0008, 0x7b2: 0x0008, 0x7b3: 0x0008, 0x7b4: 0x0008, 0x7b5: 0x0008, + 0x7b6: 0x0008, 0x7b7: 0x0008, 0x7b8: 0x0008, 0x7b9: 0x0008, 0x7ba: 0x0040, 0x7bb: 0x0040, + 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x3008, 0x7bf: 0x3008, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x3308, 0x7c1: 0x3008, 0x7c2: 0x3008, 0x7c3: 0x3008, 0x7c4: 0x3008, 0x7c5: 0x0040, + 0x7c6: 0x3308, 0x7c7: 0x3308, 0x7c8: 0x3308, 0x7c9: 0x0040, 0x7ca: 0x3308, 0x7cb: 0x3308, + 0x7cc: 0x3308, 0x7cd: 0x3b08, 0x7ce: 0x0040, 0x7cf: 0x0040, 0x7d0: 0x0040, 0x7d1: 0x0040, + 0x7d2: 0x0040, 0x7d3: 0x0040, 0x7d4: 0x0040, 0x7d5: 0x3308, 0x7d6: 0x3308, 0x7d7: 0x0040, + 0x7d8: 0x0008, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0040, 0x7dd: 0x0040, + 0x7de: 0x0040, 0x7df: 0x0040, 0x7e0: 0x0008, 0x7e1: 0x0008, 0x7e2: 0x3308, 0x7e3: 0x3308, + 0x7e4: 0x0040, 0x7e5: 0x0040, 0x7e6: 0x0008, 0x7e7: 0x0008, 0x7e8: 0x0008, 0x7e9: 0x0008, + 0x7ea: 0x0008, 0x7eb: 0x0008, 0x7ec: 0x0008, 0x7ed: 0x0008, 0x7ee: 0x0008, 0x7ef: 0x0008, + 0x7f0: 0x0040, 0x7f1: 0x0040, 0x7f2: 0x0040, 0x7f3: 0x0040, 0x7f4: 0x0040, 0x7f5: 0x0040, + 0x7f6: 0x0040, 0x7f7: 0x0040, 0x7f8: 0x0018, 0x7f9: 0x0018, 0x7fa: 0x0018, 0x7fb: 0x0018, + 0x7fc: 0x0018, 0x7fd: 0x0018, 0x7fe: 0x0018, 0x7ff: 0x0018, + // Block 0x20, offset 0x800 + 0x800: 0x0008, 0x801: 0x3308, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x0040, 0x805: 0x0008, + 0x806: 0x0008, 0x807: 0x0008, 0x808: 0x0008, 0x809: 0x0008, 0x80a: 0x0008, 0x80b: 0x0008, + 0x80c: 0x0008, 0x80d: 0x0040, 0x80e: 0x0008, 0x80f: 0x0008, 0x810: 0x0008, 0x811: 0x0040, + 0x812: 0x0008, 0x813: 0x0008, 0x814: 0x0008, 0x815: 0x0008, 0x816: 0x0008, 0x817: 0x0008, + 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0008, 0x81c: 0x0008, 0x81d: 0x0008, + 0x81e: 0x0008, 0x81f: 0x0008, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x0008, 0x823: 0x0008, + 0x824: 0x0008, 0x825: 0x0008, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0040, + 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, + 0x830: 0x0008, 0x831: 0x0008, 0x832: 0x0008, 0x833: 0x0008, 0x834: 0x0040, 0x835: 0x0008, + 0x836: 0x0008, 0x837: 0x0008, 0x838: 0x0008, 0x839: 0x0008, 0x83a: 0x0040, 0x83b: 0x0040, + 0x83c: 0x3308, 0x83d: 0x0008, 0x83e: 0x3008, 0x83f: 0x3308, + // Block 0x21, offset 0x840 + 0x840: 0x3008, 0x841: 0x3008, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x3008, 0x845: 0x0040, + 0x846: 0x3308, 0x847: 0x3008, 0x848: 0x3008, 0x849: 0x0040, 0x84a: 0x3008, 0x84b: 0x3008, + 0x84c: 0x3308, 0x84d: 0x3b08, 0x84e: 0x0040, 0x84f: 0x0040, 0x850: 0x0040, 0x851: 0x0040, + 0x852: 0x0040, 0x853: 0x0040, 0x854: 0x0040, 0x855: 0x3008, 0x856: 0x3008, 0x857: 0x0040, + 0x858: 0x0040, 0x859: 0x0040, 0x85a: 0x0040, 0x85b: 0x0040, 0x85c: 0x0040, 0x85d: 0x0040, + 0x85e: 0x0008, 0x85f: 0x0040, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x3308, 0x863: 0x3308, + 0x864: 0x0040, 0x865: 0x0040, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0008, + 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, + 0x870: 0x0040, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0040, 0x874: 0x0040, 0x875: 0x0040, + 0x876: 0x0040, 0x877: 0x0040, 0x878: 0x0040, 0x879: 0x0040, 0x87a: 0x0040, 0x87b: 0x0040, + 0x87c: 0x0040, 0x87d: 0x0040, 0x87e: 0x0040, 0x87f: 0x0040, + // Block 0x22, offset 0x880 + 0x880: 0x3008, 0x881: 0x3308, 0x882: 0x3308, 0x883: 0x3308, 0x884: 0x3308, 0x885: 0x0040, + 0x886: 0x3008, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, + 0x88c: 0x3008, 0x88d: 0x3b08, 0x88e: 0x0008, 0x88f: 0x0018, 0x890: 0x0040, 0x891: 0x0040, + 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0008, 0x895: 0x0008, 0x896: 0x0008, 0x897: 0x3008, + 0x898: 0x0018, 0x899: 0x0018, 0x89a: 0x0018, 0x89b: 0x0018, 0x89c: 0x0018, 0x89d: 0x0018, + 0x89e: 0x0018, 0x89f: 0x0008, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, + 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, + 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, + 0x8b0: 0x0018, 0x8b1: 0x0018, 0x8b2: 0x0018, 0x8b3: 0x0018, 0x8b4: 0x0018, 0x8b5: 0x0018, + 0x8b6: 0x0018, 0x8b7: 0x0018, 0x8b8: 0x0018, 0x8b9: 0x0018, 0x8ba: 0x0008, 0x8bb: 0x0008, + 0x8bc: 0x0008, 0x8bd: 0x0008, 0x8be: 0x0008, 0x8bf: 0x0008, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0040, 0x8c1: 0x0008, 0x8c2: 0x0008, 0x8c3: 0x0040, 0x8c4: 0x0008, 0x8c5: 0x0040, + 0x8c6: 0x0040, 0x8c7: 0x0008, 0x8c8: 0x0008, 0x8c9: 0x0040, 0x8ca: 0x0008, 0x8cb: 0x0040, + 0x8cc: 0x0040, 0x8cd: 0x0008, 0x8ce: 0x0040, 0x8cf: 0x0040, 0x8d0: 0x0040, 0x8d1: 0x0040, + 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x0008, + 0x8d8: 0x0040, 0x8d9: 0x0008, 0x8da: 0x0008, 0x8db: 0x0008, 0x8dc: 0x0008, 0x8dd: 0x0008, + 0x8de: 0x0008, 0x8df: 0x0008, 0x8e0: 0x0040, 0x8e1: 0x0008, 0x8e2: 0x0008, 0x8e3: 0x0008, + 0x8e4: 0x0040, 0x8e5: 0x0008, 0x8e6: 0x0040, 0x8e7: 0x0008, 0x8e8: 0x0040, 0x8e9: 0x0040, + 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0040, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, + 0x8f0: 0x0008, 0x8f1: 0x3308, 0x8f2: 0x0008, 0x8f3: 0x0929, 0x8f4: 0x3308, 0x8f5: 0x3308, + 0x8f6: 0x3308, 0x8f7: 0x3308, 0x8f8: 0x3308, 0x8f9: 0x3308, 0x8fa: 0x0040, 0x8fb: 0x3308, + 0x8fc: 0x3308, 0x8fd: 0x0008, 0x8fe: 0x0040, 0x8ff: 0x0040, + // Block 0x24, offset 0x900 + 0x900: 0x0008, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x09d1, 0x904: 0x0008, 0x905: 0x0008, + 0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0040, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0008, + 0x90c: 0x0008, 0x90d: 0x0a09, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008, + 0x912: 0x0a41, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0a79, + 0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0ab1, 0x91d: 0x0008, + 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, + 0x924: 0x0008, 0x925: 0x0008, 0x926: 0x0008, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0ae9, + 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0040, 0x92e: 0x0040, 0x92f: 0x0040, + 0x930: 0x0040, 0x931: 0x3308, 0x932: 0x3308, 0x933: 0x0b21, 0x934: 0x3308, 0x935: 0x0b59, + 0x936: 0x0b91, 0x937: 0x0bc9, 0x938: 0x0c19, 0x939: 0x0c51, 0x93a: 0x3308, 0x93b: 0x3308, + 0x93c: 0x3308, 0x93d: 0x3308, 0x93e: 0x3308, 0x93f: 0x3008, + // Block 0x25, offset 0x940 + 0x940: 0x3308, 0x941: 0x0ca1, 0x942: 0x3308, 0x943: 0x3308, 0x944: 0x3b08, 0x945: 0x0018, + 0x946: 0x3308, 0x947: 0x3308, 0x948: 0x0008, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, + 0x94c: 0x0008, 0x94d: 0x3308, 0x94e: 0x3308, 0x94f: 0x3308, 0x950: 0x3308, 0x951: 0x3308, + 0x952: 0x3308, 0x953: 0x0cd9, 0x954: 0x3308, 0x955: 0x3308, 0x956: 0x3308, 0x957: 0x3308, + 0x958: 0x0040, 0x959: 0x3308, 0x95a: 0x3308, 0x95b: 0x3308, 0x95c: 0x3308, 0x95d: 0x0d11, + 0x95e: 0x3308, 0x95f: 0x3308, 0x960: 0x3308, 0x961: 0x3308, 0x962: 0x0d49, 0x963: 0x3308, + 0x964: 0x3308, 0x965: 0x3308, 0x966: 0x3308, 0x967: 0x0d81, 0x968: 0x3308, 0x969: 0x3308, + 0x96a: 0x3308, 0x96b: 0x3308, 0x96c: 0x0db9, 0x96d: 0x3308, 0x96e: 0x3308, 0x96f: 0x3308, + 0x970: 0x3308, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x3308, 0x974: 0x3308, 0x975: 0x3308, + 0x976: 0x3308, 0x977: 0x3308, 0x978: 0x3308, 0x979: 0x0df1, 0x97a: 0x3308, 0x97b: 0x3308, + 0x97c: 0x3308, 0x97d: 0x0040, 0x97e: 0x0018, 0x97f: 0x0018, + // Block 0x26, offset 0x980 + 0x980: 0x0008, 0x981: 0x0008, 0x982: 0x0008, 0x983: 0x0008, 0x984: 0x0008, 0x985: 0x0008, + 0x986: 0x0008, 0x987: 0x0008, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, + 0x98c: 0x0008, 0x98d: 0x0008, 0x98e: 0x0008, 0x98f: 0x0008, 0x990: 0x0008, 0x991: 0x0008, + 0x992: 0x0008, 0x993: 0x0008, 0x994: 0x0008, 0x995: 0x0008, 0x996: 0x0008, 0x997: 0x0008, + 0x998: 0x0008, 0x999: 0x0008, 0x99a: 0x0008, 0x99b: 0x0008, 0x99c: 0x0008, 0x99d: 0x0008, + 0x99e: 0x0008, 0x99f: 0x0008, 0x9a0: 0x0008, 0x9a1: 0x0008, 0x9a2: 0x0008, 0x9a3: 0x0008, + 0x9a4: 0x0008, 0x9a5: 0x0008, 0x9a6: 0x0008, 0x9a7: 0x0008, 0x9a8: 0x0008, 0x9a9: 0x0008, + 0x9aa: 0x0008, 0x9ab: 0x0008, 0x9ac: 0x0039, 0x9ad: 0x0ed1, 0x9ae: 0x0ee9, 0x9af: 0x0008, + 0x9b0: 0x0ef9, 0x9b1: 0x0f09, 0x9b2: 0x0f19, 0x9b3: 0x0f31, 0x9b4: 0x0249, 0x9b5: 0x0f41, + 0x9b6: 0x0259, 0x9b7: 0x0f51, 0x9b8: 0x0359, 0x9b9: 0x0f61, 0x9ba: 0x0f71, 0x9bb: 0x0008, + 0x9bc: 0x00d9, 0x9bd: 0x0f81, 0x9be: 0x0f99, 0x9bf: 0x0269, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0fa9, 0x9c1: 0x0fb9, 0x9c2: 0x0279, 0x9c3: 0x0039, 0x9c4: 0x0fc9, 0x9c5: 0x0fe1, + 0x9c6: 0x059d, 0x9c7: 0x0ee9, 0x9c8: 0x0ef9, 0x9c9: 0x0f09, 0x9ca: 0x0ff9, 0x9cb: 0x1011, + 0x9cc: 0x1029, 0x9cd: 0x0f31, 0x9ce: 0x0008, 0x9cf: 0x0f51, 0x9d0: 0x0f61, 0x9d1: 0x1041, + 0x9d2: 0x00d9, 0x9d3: 0x1059, 0x9d4: 0x05b5, 0x9d5: 0x05b5, 0x9d6: 0x0f99, 0x9d7: 0x0fa9, + 0x9d8: 0x0fb9, 0x9d9: 0x059d, 0x9da: 0x1071, 0x9db: 0x1089, 0x9dc: 0x05cd, 0x9dd: 0x1099, + 0x9de: 0x10b1, 0x9df: 0x10c9, 0x9e0: 0x10e1, 0x9e1: 0x10f9, 0x9e2: 0x0f41, 0x9e3: 0x0269, + 0x9e4: 0x0fb9, 0x9e5: 0x1089, 0x9e6: 0x1099, 0x9e7: 0x10b1, 0x9e8: 0x1111, 0x9e9: 0x10e1, + 0x9ea: 0x10f9, 0x9eb: 0x0008, 0x9ec: 0x0008, 0x9ed: 0x0008, 0x9ee: 0x0008, 0x9ef: 0x0008, + 0x9f0: 0x0008, 0x9f1: 0x0008, 0x9f2: 0x0008, 0x9f3: 0x0008, 0x9f4: 0x0008, 0x9f5: 0x0008, + 0x9f6: 0x0008, 0x9f7: 0x0008, 0x9f8: 0x1129, 0x9f9: 0x0008, 0x9fa: 0x0008, 0x9fb: 0x0008, + 0x9fc: 0x0008, 0x9fd: 0x0008, 0x9fe: 0x0008, 0x9ff: 0x0008, + // Block 0x28, offset 0xa00 + 0xa00: 0x0008, 0xa01: 0x0008, 0xa02: 0x0008, 0xa03: 0x0008, 0xa04: 0x0008, 0xa05: 0x0008, + 0xa06: 0x0008, 0xa07: 0x0008, 0xa08: 0x0008, 0xa09: 0x0008, 0xa0a: 0x0008, 0xa0b: 0x0008, + 0xa0c: 0x0008, 0xa0d: 0x0008, 0xa0e: 0x0008, 0xa0f: 0x0008, 0xa10: 0x0008, 0xa11: 0x0008, + 0xa12: 0x0008, 0xa13: 0x0008, 0xa14: 0x0008, 0xa15: 0x0008, 0xa16: 0x0008, 0xa17: 0x0008, + 0xa18: 0x0008, 0xa19: 0x0008, 0xa1a: 0x0008, 0xa1b: 0x1141, 0xa1c: 0x1159, 0xa1d: 0x1169, + 0xa1e: 0x1181, 0xa1f: 0x1029, 0xa20: 0x1199, 0xa21: 0x11a9, 0xa22: 0x11c1, 0xa23: 0x11d9, + 0xa24: 0x11f1, 0xa25: 0x1209, 0xa26: 0x1221, 0xa27: 0x05e5, 0xa28: 0x1239, 0xa29: 0x1251, + 0xa2a: 0xe17d, 0xa2b: 0x1269, 0xa2c: 0x1281, 0xa2d: 0x1299, 0xa2e: 0x12b1, 0xa2f: 0x12c9, + 0xa30: 0x12e1, 0xa31: 0x12f9, 0xa32: 0x1311, 0xa33: 0x1329, 0xa34: 0x1341, 0xa35: 0x1359, + 0xa36: 0x1371, 0xa37: 0x1389, 0xa38: 0x05fd, 0xa39: 0x13a1, 0xa3a: 0x13b9, 0xa3b: 0x13d1, + 0xa3c: 0x13e1, 0xa3d: 0x13f9, 0xa3e: 0x1411, 0xa3f: 0x1429, + // Block 0x29, offset 0xa40 + 0xa40: 0xe00d, 0xa41: 0x0008, 0xa42: 0xe00d, 0xa43: 0x0008, 0xa44: 0xe00d, 0xa45: 0x0008, + 0xa46: 0xe00d, 0xa47: 0x0008, 0xa48: 0xe00d, 0xa49: 0x0008, 0xa4a: 0xe00d, 0xa4b: 0x0008, + 0xa4c: 0xe00d, 0xa4d: 0x0008, 0xa4e: 0xe00d, 0xa4f: 0x0008, 0xa50: 0xe00d, 0xa51: 0x0008, + 0xa52: 0xe00d, 0xa53: 0x0008, 0xa54: 0xe00d, 0xa55: 0x0008, 0xa56: 0xe00d, 0xa57: 0x0008, + 0xa58: 0xe00d, 0xa59: 0x0008, 0xa5a: 0xe00d, 0xa5b: 0x0008, 0xa5c: 0xe00d, 0xa5d: 0x0008, + 0xa5e: 0xe00d, 0xa5f: 0x0008, 0xa60: 0xe00d, 0xa61: 0x0008, 0xa62: 0xe00d, 0xa63: 0x0008, + 0xa64: 0xe00d, 0xa65: 0x0008, 0xa66: 0xe00d, 0xa67: 0x0008, 0xa68: 0xe00d, 0xa69: 0x0008, + 0xa6a: 0xe00d, 0xa6b: 0x0008, 0xa6c: 0xe00d, 0xa6d: 0x0008, 0xa6e: 0xe00d, 0xa6f: 0x0008, + 0xa70: 0xe00d, 0xa71: 0x0008, 0xa72: 0xe00d, 0xa73: 0x0008, 0xa74: 0xe00d, 0xa75: 0x0008, + 0xa76: 0xe00d, 0xa77: 0x0008, 0xa78: 0xe00d, 0xa79: 0x0008, 0xa7a: 0xe00d, 0xa7b: 0x0008, + 0xa7c: 0xe00d, 0xa7d: 0x0008, 0xa7e: 0xe00d, 0xa7f: 0x0008, + // Block 0x2a, offset 0xa80 + 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, + 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, + 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, + 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0x0008, 0xa97: 0x0008, + 0xa98: 0x0008, 0xa99: 0x0008, 0xa9a: 0x0615, 0xa9b: 0x0635, 0xa9c: 0x0008, 0xa9d: 0x0008, + 0xa9e: 0x1441, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, + 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, + 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, + 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, + 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, + 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, + // Block 0x2b, offset 0xac0 + 0xac0: 0x0008, 0xac1: 0x0008, 0xac2: 0x0008, 0xac3: 0x0008, 0xac4: 0x0008, 0xac5: 0x0008, + 0xac6: 0x0040, 0xac7: 0x0040, 0xac8: 0xe045, 0xac9: 0xe045, 0xaca: 0xe045, 0xacb: 0xe045, + 0xacc: 0xe045, 0xacd: 0xe045, 0xace: 0x0040, 0xacf: 0x0040, 0xad0: 0x0008, 0xad1: 0x0008, + 0xad2: 0x0008, 0xad3: 0x0008, 0xad4: 0x0008, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, + 0xad8: 0x0040, 0xad9: 0xe045, 0xada: 0x0040, 0xadb: 0xe045, 0xadc: 0x0040, 0xadd: 0xe045, + 0xade: 0x0040, 0xadf: 0xe045, 0xae0: 0x0008, 0xae1: 0x0008, 0xae2: 0x0008, 0xae3: 0x0008, + 0xae4: 0x0008, 0xae5: 0x0008, 0xae6: 0x0008, 0xae7: 0x0008, 0xae8: 0xe045, 0xae9: 0xe045, + 0xaea: 0xe045, 0xaeb: 0xe045, 0xaec: 0xe045, 0xaed: 0xe045, 0xaee: 0xe045, 0xaef: 0xe045, + 0xaf0: 0x0008, 0xaf1: 0x1459, 0xaf2: 0x0008, 0xaf3: 0x1471, 0xaf4: 0x0008, 0xaf5: 0x1489, + 0xaf6: 0x0008, 0xaf7: 0x14a1, 0xaf8: 0x0008, 0xaf9: 0x14b9, 0xafa: 0x0008, 0xafb: 0x14d1, + 0xafc: 0x0008, 0xafd: 0x14e9, 0xafe: 0x0040, 0xaff: 0x0040, + // Block 0x2c, offset 0xb00 + 0xb00: 0x1501, 0xb01: 0x1531, 0xb02: 0x1561, 0xb03: 0x1591, 0xb04: 0x15c1, 0xb05: 0x15f1, + 0xb06: 0x1621, 0xb07: 0x1651, 0xb08: 0x1501, 0xb09: 0x1531, 0xb0a: 0x1561, 0xb0b: 0x1591, + 0xb0c: 0x15c1, 0xb0d: 0x15f1, 0xb0e: 0x1621, 0xb0f: 0x1651, 0xb10: 0x1681, 0xb11: 0x16b1, + 0xb12: 0x16e1, 0xb13: 0x1711, 0xb14: 0x1741, 0xb15: 0x1771, 0xb16: 0x17a1, 0xb17: 0x17d1, + 0xb18: 0x1681, 0xb19: 0x16b1, 0xb1a: 0x16e1, 0xb1b: 0x1711, 0xb1c: 0x1741, 0xb1d: 0x1771, + 0xb1e: 0x17a1, 0xb1f: 0x17d1, 0xb20: 0x1801, 0xb21: 0x1831, 0xb22: 0x1861, 0xb23: 0x1891, + 0xb24: 0x18c1, 0xb25: 0x18f1, 0xb26: 0x1921, 0xb27: 0x1951, 0xb28: 0x1801, 0xb29: 0x1831, + 0xb2a: 0x1861, 0xb2b: 0x1891, 0xb2c: 0x18c1, 0xb2d: 0x18f1, 0xb2e: 0x1921, 0xb2f: 0x1951, + 0xb30: 0x0008, 0xb31: 0x0008, 0xb32: 0x1981, 0xb33: 0x19b1, 0xb34: 0x19d9, 0xb35: 0x0040, + 0xb36: 0x0008, 0xb37: 0x1a01, 0xb38: 0xe045, 0xb39: 0xe045, 0xb3a: 0x064d, 0xb3b: 0x1459, + 0xb3c: 0x19b1, 0xb3d: 0x0666, 0xb3e: 0x1a31, 0xb3f: 0x0686, + // Block 0x2d, offset 0xb40 + 0xb40: 0x06a6, 0xb41: 0x1a4a, 0xb42: 0x1a79, 0xb43: 0x1aa9, 0xb44: 0x1ad1, 0xb45: 0x0040, + 0xb46: 0x0008, 0xb47: 0x1af9, 0xb48: 0x06c5, 0xb49: 0x1471, 0xb4a: 0x06dd, 0xb4b: 0x1489, + 0xb4c: 0x1aa9, 0xb4d: 0x1b2a, 0xb4e: 0x1b5a, 0xb4f: 0x1b8a, 0xb50: 0x0008, 0xb51: 0x0008, + 0xb52: 0x0008, 0xb53: 0x1bb9, 0xb54: 0x0040, 0xb55: 0x0040, 0xb56: 0x0008, 0xb57: 0x0008, + 0xb58: 0xe045, 0xb59: 0xe045, 0xb5a: 0x06f5, 0xb5b: 0x14a1, 0xb5c: 0x0040, 0xb5d: 0x1bd2, + 0xb5e: 0x1c02, 0xb5f: 0x1c32, 0xb60: 0x0008, 0xb61: 0x0008, 0xb62: 0x0008, 0xb63: 0x1c61, + 0xb64: 0x0008, 0xb65: 0x0008, 0xb66: 0x0008, 0xb67: 0x0008, 0xb68: 0xe045, 0xb69: 0xe045, + 0xb6a: 0x070d, 0xb6b: 0x14d1, 0xb6c: 0xe04d, 0xb6d: 0x1c7a, 0xb6e: 0x03d2, 0xb6f: 0x1caa, + 0xb70: 0x0040, 0xb71: 0x0040, 0xb72: 0x1cb9, 0xb73: 0x1ce9, 0xb74: 0x1d11, 0xb75: 0x0040, + 0xb76: 0x0008, 0xb77: 0x1d39, 0xb78: 0x0725, 0xb79: 0x14b9, 0xb7a: 0x0515, 0xb7b: 0x14e9, + 0xb7c: 0x1ce9, 0xb7d: 0x073e, 0xb7e: 0x075e, 0xb7f: 0x0040, + // Block 0x2e, offset 0xb80 + 0xb80: 0x000a, 0xb81: 0x000a, 0xb82: 0x000a, 0xb83: 0x000a, 0xb84: 0x000a, 0xb85: 0x000a, + 0xb86: 0x000a, 0xb87: 0x000a, 0xb88: 0x000a, 0xb89: 0x000a, 0xb8a: 0x000a, 0xb8b: 0x03c0, + 0xb8c: 0x0003, 0xb8d: 0x0003, 0xb8e: 0x0340, 0xb8f: 0x0b40, 0xb90: 0x0018, 0xb91: 0xe00d, + 0xb92: 0x0018, 0xb93: 0x0018, 0xb94: 0x0018, 0xb95: 0x0018, 0xb96: 0x0018, 0xb97: 0x077e, + 0xb98: 0x0018, 0xb99: 0x0018, 0xb9a: 0x0018, 0xb9b: 0x0018, 0xb9c: 0x0018, 0xb9d: 0x0018, + 0xb9e: 0x0018, 0xb9f: 0x0018, 0xba0: 0x0018, 0xba1: 0x0018, 0xba2: 0x0018, 0xba3: 0x0018, + 0xba4: 0x0040, 0xba5: 0x0040, 0xba6: 0x0040, 0xba7: 0x0018, 0xba8: 0x0040, 0xba9: 0x0040, + 0xbaa: 0x0340, 0xbab: 0x0340, 0xbac: 0x0340, 0xbad: 0x0340, 0xbae: 0x0340, 0xbaf: 0x000a, + 0xbb0: 0x0018, 0xbb1: 0x0018, 0xbb2: 0x0018, 0xbb3: 0x1d69, 0xbb4: 0x1da1, 0xbb5: 0x0018, + 0xbb6: 0x1df1, 0xbb7: 0x1e29, 0xbb8: 0x0018, 0xbb9: 0x0018, 0xbba: 0x0018, 0xbbb: 0x0018, + 0xbbc: 0x1e7a, 0xbbd: 0x0018, 0xbbe: 0x079e, 0xbbf: 0x0018, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x0018, 0xbc1: 0x0018, 0xbc2: 0x0018, 0xbc3: 0x0018, 0xbc4: 0x0018, 0xbc5: 0x0018, + 0xbc6: 0x0018, 0xbc7: 0x1e92, 0xbc8: 0x1eaa, 0xbc9: 0x1ec2, 0xbca: 0x0018, 0xbcb: 0x0018, + 0xbcc: 0x0018, 0xbcd: 0x0018, 0xbce: 0x0018, 0xbcf: 0x0018, 0xbd0: 0x0018, 0xbd1: 0x0018, + 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x1ed9, + 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, + 0xbde: 0x0018, 0xbdf: 0x000a, 0xbe0: 0x03c0, 0xbe1: 0x0340, 0xbe2: 0x0340, 0xbe3: 0x0340, + 0xbe4: 0x03c0, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0040, 0xbe8: 0x0040, 0xbe9: 0x0040, + 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x0340, + 0xbf0: 0x1f41, 0xbf1: 0x0f41, 0xbf2: 0x0040, 0xbf3: 0x0040, 0xbf4: 0x1f51, 0xbf5: 0x1f61, + 0xbf6: 0x1f71, 0xbf7: 0x1f81, 0xbf8: 0x1f91, 0xbf9: 0x1fa1, 0xbfa: 0x1fb2, 0xbfb: 0x07bd, + 0xbfc: 0x1fc2, 0xbfd: 0x1fd2, 0xbfe: 0x1fe2, 0xbff: 0x0f71, + // Block 0x30, offset 0xc00 + 0xc00: 0x1f41, 0xc01: 0x00c9, 0xc02: 0x0069, 0xc03: 0x0079, 0xc04: 0x1f51, 0xc05: 0x1f61, + 0xc06: 0x1f71, 0xc07: 0x1f81, 0xc08: 0x1f91, 0xc09: 0x1fa1, 0xc0a: 0x1fb2, 0xc0b: 0x07d5, + 0xc0c: 0x1fc2, 0xc0d: 0x1fd2, 0xc0e: 0x1fe2, 0xc0f: 0x0040, 0xc10: 0x0039, 0xc11: 0x0f09, + 0xc12: 0x00d9, 0xc13: 0x0369, 0xc14: 0x0ff9, 0xc15: 0x0249, 0xc16: 0x0f51, 0xc17: 0x0359, + 0xc18: 0x0f61, 0xc19: 0x0f71, 0xc1a: 0x0f99, 0xc1b: 0x01d9, 0xc1c: 0x0fa9, 0xc1d: 0x0040, + 0xc1e: 0x0040, 0xc1f: 0x0040, 0xc20: 0x0018, 0xc21: 0x0018, 0xc22: 0x0018, 0xc23: 0x0018, + 0xc24: 0x0018, 0xc25: 0x0018, 0xc26: 0x0018, 0xc27: 0x0018, 0xc28: 0x1ff1, 0xc29: 0x0018, + 0xc2a: 0x0018, 0xc2b: 0x0018, 0xc2c: 0x0018, 0xc2d: 0x0018, 0xc2e: 0x0018, 0xc2f: 0x0018, + 0xc30: 0x0018, 0xc31: 0x0018, 0xc32: 0x0018, 0xc33: 0x0018, 0xc34: 0x0018, 0xc35: 0x0018, + 0xc36: 0x0018, 0xc37: 0x0018, 0xc38: 0x0018, 0xc39: 0x0018, 0xc3a: 0x0018, 0xc3b: 0x0018, + 0xc3c: 0x0018, 0xc3d: 0x0018, 0xc3e: 0x0018, 0xc3f: 0x0040, + // Block 0x31, offset 0xc40 + 0xc40: 0x07ee, 0xc41: 0x080e, 0xc42: 0x1159, 0xc43: 0x082d, 0xc44: 0x0018, 0xc45: 0x084e, + 0xc46: 0x086e, 0xc47: 0x1011, 0xc48: 0x0018, 0xc49: 0x088d, 0xc4a: 0x0f31, 0xc4b: 0x0249, + 0xc4c: 0x0249, 0xc4d: 0x0249, 0xc4e: 0x0249, 0xc4f: 0x2009, 0xc50: 0x0f41, 0xc51: 0x0f41, + 0xc52: 0x0359, 0xc53: 0x0359, 0xc54: 0x0018, 0xc55: 0x0f71, 0xc56: 0x2021, 0xc57: 0x0018, + 0xc58: 0x0018, 0xc59: 0x0f99, 0xc5a: 0x2039, 0xc5b: 0x0269, 0xc5c: 0x0269, 0xc5d: 0x0269, + 0xc5e: 0x0018, 0xc5f: 0x0018, 0xc60: 0x2049, 0xc61: 0x08ad, 0xc62: 0x2061, 0xc63: 0x0018, + 0xc64: 0x13d1, 0xc65: 0x0018, 0xc66: 0x2079, 0xc67: 0x0018, 0xc68: 0x13d1, 0xc69: 0x0018, + 0xc6a: 0x0f51, 0xc6b: 0x2091, 0xc6c: 0x0ee9, 0xc6d: 0x1159, 0xc6e: 0x0018, 0xc6f: 0x0f09, + 0xc70: 0x0f09, 0xc71: 0x1199, 0xc72: 0x0040, 0xc73: 0x0f61, 0xc74: 0x00d9, 0xc75: 0x20a9, + 0xc76: 0x20c1, 0xc77: 0x20d9, 0xc78: 0x20f1, 0xc79: 0x0f41, 0xc7a: 0x0018, 0xc7b: 0x08cd, + 0xc7c: 0x2109, 0xc7d: 0x10b1, 0xc7e: 0x10b1, 0xc7f: 0x2109, + // Block 0x32, offset 0xc80 + 0xc80: 0x08ed, 0xc81: 0x0018, 0xc82: 0x0018, 0xc83: 0x0018, 0xc84: 0x0018, 0xc85: 0x0ef9, + 0xc86: 0x0ef9, 0xc87: 0x0f09, 0xc88: 0x0f41, 0xc89: 0x0259, 0xc8a: 0x0018, 0xc8b: 0x0018, + 0xc8c: 0x0018, 0xc8d: 0x0018, 0xc8e: 0x0008, 0xc8f: 0x0018, 0xc90: 0x2121, 0xc91: 0x2151, + 0xc92: 0x2181, 0xc93: 0x21b9, 0xc94: 0x21e9, 0xc95: 0x2219, 0xc96: 0x2249, 0xc97: 0x2279, + 0xc98: 0x22a9, 0xc99: 0x22d9, 0xc9a: 0x2309, 0xc9b: 0x2339, 0xc9c: 0x2369, 0xc9d: 0x2399, + 0xc9e: 0x23c9, 0xc9f: 0x23f9, 0xca0: 0x0f41, 0xca1: 0x2421, 0xca2: 0x0905, 0xca3: 0x2439, + 0xca4: 0x1089, 0xca5: 0x2451, 0xca6: 0x0925, 0xca7: 0x2469, 0xca8: 0x2491, 0xca9: 0x0369, + 0xcaa: 0x24a9, 0xcab: 0x0945, 0xcac: 0x0359, 0xcad: 0x1159, 0xcae: 0x0ef9, 0xcaf: 0x0f61, + 0xcb0: 0x0f41, 0xcb1: 0x2421, 0xcb2: 0x0965, 0xcb3: 0x2439, 0xcb4: 0x1089, 0xcb5: 0x2451, + 0xcb6: 0x0985, 0xcb7: 0x2469, 0xcb8: 0x2491, 0xcb9: 0x0369, 0xcba: 0x24a9, 0xcbb: 0x09a5, + 0xcbc: 0x0359, 0xcbd: 0x1159, 0xcbe: 0x0ef9, 0xcbf: 0x0f61, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x0018, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0018, + 0xcc6: 0x0018, 0xcc7: 0x0018, 0xcc8: 0x0018, 0xcc9: 0x0018, 0xcca: 0x0018, 0xccb: 0x0040, + 0xccc: 0x0040, 0xccd: 0x0040, 0xcce: 0x0040, 0xccf: 0x0040, 0xcd0: 0x0040, 0xcd1: 0x0040, + 0xcd2: 0x0040, 0xcd3: 0x0040, 0xcd4: 0x0040, 0xcd5: 0x0040, 0xcd6: 0x0040, 0xcd7: 0x0040, + 0xcd8: 0x0040, 0xcd9: 0x0040, 0xcda: 0x0040, 0xcdb: 0x0040, 0xcdc: 0x0040, 0xcdd: 0x0040, + 0xcde: 0x0040, 0xcdf: 0x0040, 0xce0: 0x00c9, 0xce1: 0x0069, 0xce2: 0x0079, 0xce3: 0x1f51, + 0xce4: 0x1f61, 0xce5: 0x1f71, 0xce6: 0x1f81, 0xce7: 0x1f91, 0xce8: 0x1fa1, 0xce9: 0x2601, + 0xcea: 0x2619, 0xceb: 0x2631, 0xcec: 0x2649, 0xced: 0x2661, 0xcee: 0x2679, 0xcef: 0x2691, + 0xcf0: 0x26a9, 0xcf1: 0x26c1, 0xcf2: 0x26d9, 0xcf3: 0x26f1, 0xcf4: 0x0a06, 0xcf5: 0x0a26, + 0xcf6: 0x0a46, 0xcf7: 0x0a66, 0xcf8: 0x0a86, 0xcf9: 0x0aa6, 0xcfa: 0x0ac6, 0xcfb: 0x0ae6, + 0xcfc: 0x0b06, 0xcfd: 0x270a, 0xcfe: 0x2732, 0xcff: 0x275a, + // Block 0x34, offset 0xd00 + 0xd00: 0x2782, 0xd01: 0x27aa, 0xd02: 0x27d2, 0xd03: 0x27fa, 0xd04: 0x2822, 0xd05: 0x284a, + 0xd06: 0x2872, 0xd07: 0x289a, 0xd08: 0x0040, 0xd09: 0x0040, 0xd0a: 0x0040, 0xd0b: 0x0040, + 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, + 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, + 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0b26, 0xd1d: 0x0b46, + 0xd1e: 0x0b66, 0xd1f: 0x0b86, 0xd20: 0x0ba6, 0xd21: 0x0bc6, 0xd22: 0x0be6, 0xd23: 0x0c06, + 0xd24: 0x0c26, 0xd25: 0x0c46, 0xd26: 0x0c66, 0xd27: 0x0c86, 0xd28: 0x0ca6, 0xd29: 0x0cc6, + 0xd2a: 0x0ce6, 0xd2b: 0x0d06, 0xd2c: 0x0d26, 0xd2d: 0x0d46, 0xd2e: 0x0d66, 0xd2f: 0x0d86, + 0xd30: 0x0da6, 0xd31: 0x0dc6, 0xd32: 0x0de6, 0xd33: 0x0e06, 0xd34: 0x0e26, 0xd35: 0x0e46, + 0xd36: 0x0039, 0xd37: 0x0ee9, 0xd38: 0x1159, 0xd39: 0x0ef9, 0xd3a: 0x0f09, 0xd3b: 0x1199, + 0xd3c: 0x0f31, 0xd3d: 0x0249, 0xd3e: 0x0f41, 0xd3f: 0x0259, + // Block 0x35, offset 0xd40 + 0xd40: 0x0f51, 0xd41: 0x0359, 0xd42: 0x0f61, 0xd43: 0x0f71, 0xd44: 0x00d9, 0xd45: 0x0f99, + 0xd46: 0x2039, 0xd47: 0x0269, 0xd48: 0x01d9, 0xd49: 0x0fa9, 0xd4a: 0x0fb9, 0xd4b: 0x1089, + 0xd4c: 0x0279, 0xd4d: 0x0369, 0xd4e: 0x0289, 0xd4f: 0x13d1, 0xd50: 0x0039, 0xd51: 0x0ee9, + 0xd52: 0x1159, 0xd53: 0x0ef9, 0xd54: 0x0f09, 0xd55: 0x1199, 0xd56: 0x0f31, 0xd57: 0x0249, + 0xd58: 0x0f41, 0xd59: 0x0259, 0xd5a: 0x0f51, 0xd5b: 0x0359, 0xd5c: 0x0f61, 0xd5d: 0x0f71, + 0xd5e: 0x00d9, 0xd5f: 0x0f99, 0xd60: 0x2039, 0xd61: 0x0269, 0xd62: 0x01d9, 0xd63: 0x0fa9, + 0xd64: 0x0fb9, 0xd65: 0x1089, 0xd66: 0x0279, 0xd67: 0x0369, 0xd68: 0x0289, 0xd69: 0x13d1, + 0xd6a: 0x1f41, 0xd6b: 0x0018, 0xd6c: 0x0018, 0xd6d: 0x0018, 0xd6e: 0x0018, 0xd6f: 0x0018, + 0xd70: 0x0018, 0xd71: 0x0018, 0xd72: 0x0018, 0xd73: 0x0018, 0xd74: 0x0018, 0xd75: 0x0018, + 0xd76: 0x0018, 0xd77: 0x0018, 0xd78: 0x0018, 0xd79: 0x0018, 0xd7a: 0x0018, 0xd7b: 0x0018, + 0xd7c: 0x0018, 0xd7d: 0x0018, 0xd7e: 0x0018, 0xd7f: 0x0018, + // Block 0x36, offset 0xd80 + 0xd80: 0x0008, 0xd81: 0x0008, 0xd82: 0x0008, 0xd83: 0x0008, 0xd84: 0x0008, 0xd85: 0x0008, + 0xd86: 0x0008, 0xd87: 0x0008, 0xd88: 0x0008, 0xd89: 0x0008, 0xd8a: 0x0008, 0xd8b: 0x0008, + 0xd8c: 0x0008, 0xd8d: 0x0008, 0xd8e: 0x0008, 0xd8f: 0x0008, 0xd90: 0x0008, 0xd91: 0x0008, + 0xd92: 0x0008, 0xd93: 0x0008, 0xd94: 0x0008, 0xd95: 0x0008, 0xd96: 0x0008, 0xd97: 0x0008, + 0xd98: 0x0008, 0xd99: 0x0008, 0xd9a: 0x0008, 0xd9b: 0x0008, 0xd9c: 0x0008, 0xd9d: 0x0008, + 0xd9e: 0x0008, 0xd9f: 0x0040, 0xda0: 0xe00d, 0xda1: 0x0008, 0xda2: 0x2971, 0xda3: 0x0ebd, + 0xda4: 0x2989, 0xda5: 0x0008, 0xda6: 0x0008, 0xda7: 0xe07d, 0xda8: 0x0008, 0xda9: 0xe01d, + 0xdaa: 0x0008, 0xdab: 0xe03d, 0xdac: 0x0008, 0xdad: 0x0fe1, 0xdae: 0x1281, 0xdaf: 0x0fc9, + 0xdb0: 0x1141, 0xdb1: 0x0008, 0xdb2: 0xe00d, 0xdb3: 0x0008, 0xdb4: 0x0008, 0xdb5: 0xe01d, + 0xdb6: 0x0008, 0xdb7: 0x0008, 0xdb8: 0x0008, 0xdb9: 0x0008, 0xdba: 0x0008, 0xdbb: 0x0008, + 0xdbc: 0x0259, 0xdbd: 0x1089, 0xdbe: 0x29a1, 0xdbf: 0x29b9, + // Block 0x37, offset 0xdc0 + 0xdc0: 0xe00d, 0xdc1: 0x0008, 0xdc2: 0xe00d, 0xdc3: 0x0008, 0xdc4: 0xe00d, 0xdc5: 0x0008, + 0xdc6: 0xe00d, 0xdc7: 0x0008, 0xdc8: 0xe00d, 0xdc9: 0x0008, 0xdca: 0xe00d, 0xdcb: 0x0008, + 0xdcc: 0xe00d, 0xdcd: 0x0008, 0xdce: 0xe00d, 0xdcf: 0x0008, 0xdd0: 0xe00d, 0xdd1: 0x0008, + 0xdd2: 0xe00d, 0xdd3: 0x0008, 0xdd4: 0xe00d, 0xdd5: 0x0008, 0xdd6: 0xe00d, 0xdd7: 0x0008, + 0xdd8: 0xe00d, 0xdd9: 0x0008, 0xdda: 0xe00d, 0xddb: 0x0008, 0xddc: 0xe00d, 0xddd: 0x0008, + 0xdde: 0xe00d, 0xddf: 0x0008, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0xe00d, 0xde3: 0x0008, + 0xde4: 0x0008, 0xde5: 0x0018, 0xde6: 0x0018, 0xde7: 0x0018, 0xde8: 0x0018, 0xde9: 0x0018, + 0xdea: 0x0018, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0xe01d, 0xdee: 0x0008, 0xdef: 0x3308, + 0xdf0: 0x3308, 0xdf1: 0x3308, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0040, 0xdf5: 0x0040, + 0xdf6: 0x0040, 0xdf7: 0x0040, 0xdf8: 0x0040, 0xdf9: 0x0018, 0xdfa: 0x0018, 0xdfb: 0x0018, + 0xdfc: 0x0018, 0xdfd: 0x0018, 0xdfe: 0x0018, 0xdff: 0x0018, + // Block 0x38, offset 0xe00 + 0xe00: 0x26fd, 0xe01: 0x271d, 0xe02: 0x273d, 0xe03: 0x275d, 0xe04: 0x277d, 0xe05: 0x279d, + 0xe06: 0x27bd, 0xe07: 0x27dd, 0xe08: 0x27fd, 0xe09: 0x281d, 0xe0a: 0x283d, 0xe0b: 0x285d, + 0xe0c: 0x287d, 0xe0d: 0x289d, 0xe0e: 0x28bd, 0xe0f: 0x28dd, 0xe10: 0x28fd, 0xe11: 0x291d, + 0xe12: 0x293d, 0xe13: 0x295d, 0xe14: 0x297d, 0xe15: 0x299d, 0xe16: 0x0040, 0xe17: 0x0040, + 0xe18: 0x0040, 0xe19: 0x0040, 0xe1a: 0x0040, 0xe1b: 0x0040, 0xe1c: 0x0040, 0xe1d: 0x0040, + 0xe1e: 0x0040, 0xe1f: 0x0040, 0xe20: 0x0040, 0xe21: 0x0040, 0xe22: 0x0040, 0xe23: 0x0040, + 0xe24: 0x0040, 0xe25: 0x0040, 0xe26: 0x0040, 0xe27: 0x0040, 0xe28: 0x0040, 0xe29: 0x0040, + 0xe2a: 0x0040, 0xe2b: 0x0040, 0xe2c: 0x0040, 0xe2d: 0x0040, 0xe2e: 0x0040, 0xe2f: 0x0040, + 0xe30: 0x0040, 0xe31: 0x0040, 0xe32: 0x0040, 0xe33: 0x0040, 0xe34: 0x0040, 0xe35: 0x0040, + 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0040, 0xe3a: 0x0040, 0xe3b: 0x0040, + 0xe3c: 0x0040, 0xe3d: 0x0040, 0xe3e: 0x0040, 0xe3f: 0x0040, + // Block 0x39, offset 0xe40 + 0xe40: 0x000a, 0xe41: 0x0018, 0xe42: 0x29d1, 0xe43: 0x0018, 0xe44: 0x0018, 0xe45: 0x0008, + 0xe46: 0x0008, 0xe47: 0x0008, 0xe48: 0x0018, 0xe49: 0x0018, 0xe4a: 0x0018, 0xe4b: 0x0018, + 0xe4c: 0x0018, 0xe4d: 0x0018, 0xe4e: 0x0018, 0xe4f: 0x0018, 0xe50: 0x0018, 0xe51: 0x0018, + 0xe52: 0x0018, 0xe53: 0x0018, 0xe54: 0x0018, 0xe55: 0x0018, 0xe56: 0x0018, 0xe57: 0x0018, + 0xe58: 0x0018, 0xe59: 0x0018, 0xe5a: 0x0018, 0xe5b: 0x0018, 0xe5c: 0x0018, 0xe5d: 0x0018, + 0xe5e: 0x0018, 0xe5f: 0x0018, 0xe60: 0x0018, 0xe61: 0x0018, 0xe62: 0x0018, 0xe63: 0x0018, + 0xe64: 0x0018, 0xe65: 0x0018, 0xe66: 0x0018, 0xe67: 0x0018, 0xe68: 0x0018, 0xe69: 0x0018, + 0xe6a: 0x3308, 0xe6b: 0x3308, 0xe6c: 0x3308, 0xe6d: 0x3308, 0xe6e: 0x3018, 0xe6f: 0x3018, + 0xe70: 0x0018, 0xe71: 0x0018, 0xe72: 0x0018, 0xe73: 0x0018, 0xe74: 0x0018, 0xe75: 0x0018, + 0xe76: 0xe125, 0xe77: 0x0018, 0xe78: 0x29bd, 0xe79: 0x29dd, 0xe7a: 0x29fd, 0xe7b: 0x0018, + 0xe7c: 0x0008, 0xe7d: 0x0018, 0xe7e: 0x0018, 0xe7f: 0x0018, + // Block 0x3a, offset 0xe80 + 0xe80: 0x2b3d, 0xe81: 0x2b5d, 0xe82: 0x2b7d, 0xe83: 0x2b9d, 0xe84: 0x2bbd, 0xe85: 0x2bdd, + 0xe86: 0x2bdd, 0xe87: 0x2bdd, 0xe88: 0x2bfd, 0xe89: 0x2bfd, 0xe8a: 0x2bfd, 0xe8b: 0x2bfd, + 0xe8c: 0x2c1d, 0xe8d: 0x2c1d, 0xe8e: 0x2c1d, 0xe8f: 0x2c3d, 0xe90: 0x2c5d, 0xe91: 0x2c5d, + 0xe92: 0x2a7d, 0xe93: 0x2a7d, 0xe94: 0x2c5d, 0xe95: 0x2c5d, 0xe96: 0x2c7d, 0xe97: 0x2c7d, + 0xe98: 0x2c5d, 0xe99: 0x2c5d, 0xe9a: 0x2a7d, 0xe9b: 0x2a7d, 0xe9c: 0x2c5d, 0xe9d: 0x2c5d, + 0xe9e: 0x2c3d, 0xe9f: 0x2c3d, 0xea0: 0x2c9d, 0xea1: 0x2c9d, 0xea2: 0x2cbd, 0xea3: 0x2cbd, + 0xea4: 0x0040, 0xea5: 0x2cdd, 0xea6: 0x2cfd, 0xea7: 0x2d1d, 0xea8: 0x2d1d, 0xea9: 0x2d3d, + 0xeaa: 0x2d5d, 0xeab: 0x2d7d, 0xeac: 0x2d9d, 0xead: 0x2dbd, 0xeae: 0x2ddd, 0xeaf: 0x2dfd, + 0xeb0: 0x2e1d, 0xeb1: 0x2e3d, 0xeb2: 0x2e3d, 0xeb3: 0x2e5d, 0xeb4: 0x2e7d, 0xeb5: 0x2e7d, + 0xeb6: 0x2e9d, 0xeb7: 0x2ebd, 0xeb8: 0x2e5d, 0xeb9: 0x2edd, 0xeba: 0x2efd, 0xebb: 0x2edd, + 0xebc: 0x2e5d, 0xebd: 0x2f1d, 0xebe: 0x2f3d, 0xebf: 0x2f5d, + // Block 0x3b, offset 0xec0 + 0xec0: 0x2f7d, 0xec1: 0x2f9d, 0xec2: 0x2cfd, 0xec3: 0x2cdd, 0xec4: 0x2fbd, 0xec5: 0x2fdd, + 0xec6: 0x2ffd, 0xec7: 0x301d, 0xec8: 0x303d, 0xec9: 0x305d, 0xeca: 0x307d, 0xecb: 0x309d, + 0xecc: 0x30bd, 0xecd: 0x30dd, 0xece: 0x30fd, 0xecf: 0x0040, 0xed0: 0x0018, 0xed1: 0x0018, + 0xed2: 0x311d, 0xed3: 0x313d, 0xed4: 0x315d, 0xed5: 0x317d, 0xed6: 0x319d, 0xed7: 0x31bd, + 0xed8: 0x31dd, 0xed9: 0x31fd, 0xeda: 0x321d, 0xedb: 0x323d, 0xedc: 0x315d, 0xedd: 0x325d, + 0xede: 0x327d, 0xedf: 0x329d, 0xee0: 0x0008, 0xee1: 0x0008, 0xee2: 0x0008, 0xee3: 0x0008, + 0xee4: 0x0008, 0xee5: 0x0008, 0xee6: 0x0008, 0xee7: 0x0008, 0xee8: 0x0008, 0xee9: 0x0008, + 0xeea: 0x0008, 0xeeb: 0x0008, 0xeec: 0x0008, 0xeed: 0x0008, 0xeee: 0x0008, 0xeef: 0x0008, + 0xef0: 0x0008, 0xef1: 0x0008, 0xef2: 0x0008, 0xef3: 0x0008, 0xef4: 0x0008, 0xef5: 0x0008, + 0xef6: 0x0008, 0xef7: 0x0008, 0xef8: 0x0008, 0xef9: 0x0008, 0xefa: 0x0008, 0xefb: 0x0040, + 0xefc: 0x0040, 0xefd: 0x0040, 0xefe: 0x0040, 0xeff: 0x0040, + // Block 0x3c, offset 0xf00 + 0xf00: 0x36a2, 0xf01: 0x36d2, 0xf02: 0x3702, 0xf03: 0x3732, 0xf04: 0x32bd, 0xf05: 0x32dd, + 0xf06: 0x32fd, 0xf07: 0x331d, 0xf08: 0x0018, 0xf09: 0x0018, 0xf0a: 0x0018, 0xf0b: 0x0018, + 0xf0c: 0x0018, 0xf0d: 0x0018, 0xf0e: 0x0018, 0xf0f: 0x0018, 0xf10: 0x333d, 0xf11: 0x3761, + 0xf12: 0x3779, 0xf13: 0x3791, 0xf14: 0x37a9, 0xf15: 0x37c1, 0xf16: 0x37d9, 0xf17: 0x37f1, + 0xf18: 0x3809, 0xf19: 0x3821, 0xf1a: 0x3839, 0xf1b: 0x3851, 0xf1c: 0x3869, 0xf1d: 0x3881, + 0xf1e: 0x3899, 0xf1f: 0x38b1, 0xf20: 0x335d, 0xf21: 0x337d, 0xf22: 0x339d, 0xf23: 0x33bd, + 0xf24: 0x33dd, 0xf25: 0x33dd, 0xf26: 0x33fd, 0xf27: 0x341d, 0xf28: 0x343d, 0xf29: 0x345d, + 0xf2a: 0x347d, 0xf2b: 0x349d, 0xf2c: 0x34bd, 0xf2d: 0x34dd, 0xf2e: 0x34fd, 0xf2f: 0x351d, + 0xf30: 0x353d, 0xf31: 0x355d, 0xf32: 0x357d, 0xf33: 0x359d, 0xf34: 0x35bd, 0xf35: 0x35dd, + 0xf36: 0x35fd, 0xf37: 0x361d, 0xf38: 0x363d, 0xf39: 0x365d, 0xf3a: 0x367d, 0xf3b: 0x369d, + 0xf3c: 0x38c9, 0xf3d: 0x3901, 0xf3e: 0x36bd, 0xf3f: 0x0018, + // Block 0x3d, offset 0xf40 + 0xf40: 0x36dd, 0xf41: 0x36fd, 0xf42: 0x371d, 0xf43: 0x373d, 0xf44: 0x375d, 0xf45: 0x377d, + 0xf46: 0x379d, 0xf47: 0x37bd, 0xf48: 0x37dd, 0xf49: 0x37fd, 0xf4a: 0x381d, 0xf4b: 0x383d, + 0xf4c: 0x385d, 0xf4d: 0x387d, 0xf4e: 0x389d, 0xf4f: 0x38bd, 0xf50: 0x38dd, 0xf51: 0x38fd, + 0xf52: 0x391d, 0xf53: 0x393d, 0xf54: 0x395d, 0xf55: 0x397d, 0xf56: 0x399d, 0xf57: 0x39bd, + 0xf58: 0x39dd, 0xf59: 0x39fd, 0xf5a: 0x3a1d, 0xf5b: 0x3a3d, 0xf5c: 0x3a5d, 0xf5d: 0x3a7d, + 0xf5e: 0x3a9d, 0xf5f: 0x3abd, 0xf60: 0x3add, 0xf61: 0x3afd, 0xf62: 0x3b1d, 0xf63: 0x3b3d, + 0xf64: 0x3b5d, 0xf65: 0x3b7d, 0xf66: 0x127d, 0xf67: 0x3b9d, 0xf68: 0x3bbd, 0xf69: 0x3bdd, + 0xf6a: 0x3bfd, 0xf6b: 0x3c1d, 0xf6c: 0x3c3d, 0xf6d: 0x3c5d, 0xf6e: 0x239d, 0xf6f: 0x3c7d, + 0xf70: 0x3c9d, 0xf71: 0x3939, 0xf72: 0x3951, 0xf73: 0x3969, 0xf74: 0x3981, 0xf75: 0x3999, + 0xf76: 0x39b1, 0xf77: 0x39c9, 0xf78: 0x39e1, 0xf79: 0x39f9, 0xf7a: 0x3a11, 0xf7b: 0x3a29, + 0xf7c: 0x3a41, 0xf7d: 0x3a59, 0xf7e: 0x3a71, 0xf7f: 0x3a89, + // Block 0x3e, offset 0xf80 + 0xf80: 0x3aa1, 0xf81: 0x3ac9, 0xf82: 0x3af1, 0xf83: 0x3b19, 0xf84: 0x3b41, 0xf85: 0x3b69, + 0xf86: 0x3b91, 0xf87: 0x3bb9, 0xf88: 0x3be1, 0xf89: 0x3c09, 0xf8a: 0x3c39, 0xf8b: 0x3c69, + 0xf8c: 0x3c99, 0xf8d: 0x3cbd, 0xf8e: 0x3cb1, 0xf8f: 0x3cdd, 0xf90: 0x3cfd, 0xf91: 0x3d15, + 0xf92: 0x3d2d, 0xf93: 0x3d45, 0xf94: 0x3d5d, 0xf95: 0x3d5d, 0xf96: 0x3d45, 0xf97: 0x3d75, + 0xf98: 0x07bd, 0xf99: 0x3d8d, 0xf9a: 0x3da5, 0xf9b: 0x3dbd, 0xf9c: 0x3dd5, 0xf9d: 0x3ded, + 0xf9e: 0x3e05, 0xf9f: 0x3e1d, 0xfa0: 0x3e35, 0xfa1: 0x3e4d, 0xfa2: 0x3e65, 0xfa3: 0x3e7d, + 0xfa4: 0x3e95, 0xfa5: 0x3e95, 0xfa6: 0x3ead, 0xfa7: 0x3ead, 0xfa8: 0x3ec5, 0xfa9: 0x3ec5, + 0xfaa: 0x3edd, 0xfab: 0x3ef5, 0xfac: 0x3f0d, 0xfad: 0x3f25, 0xfae: 0x3f3d, 0xfaf: 0x3f3d, + 0xfb0: 0x3f55, 0xfb1: 0x3f55, 0xfb2: 0x3f55, 0xfb3: 0x3f6d, 0xfb4: 0x3f85, 0xfb5: 0x3f9d, + 0xfb6: 0x3fb5, 0xfb7: 0x3f9d, 0xfb8: 0x3fcd, 0xfb9: 0x3fe5, 0xfba: 0x3f6d, 0xfbb: 0x3ffd, + 0xfbc: 0x4015, 0xfbd: 0x4015, 0xfbe: 0x4015, 0xfbf: 0x0040, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x3cc9, 0xfc1: 0x3d31, 0xfc2: 0x3d99, 0xfc3: 0x3e01, 0xfc4: 0x3e51, 0xfc5: 0x3eb9, + 0xfc6: 0x3f09, 0xfc7: 0x3f59, 0xfc8: 0x3fd9, 0xfc9: 0x4041, 0xfca: 0x4091, 0xfcb: 0x40e1, + 0xfcc: 0x4131, 0xfcd: 0x4199, 0xfce: 0x4201, 0xfcf: 0x4251, 0xfd0: 0x42a1, 0xfd1: 0x42d9, + 0xfd2: 0x4329, 0xfd3: 0x4391, 0xfd4: 0x43f9, 0xfd5: 0x4431, 0xfd6: 0x44b1, 0xfd7: 0x4549, + 0xfd8: 0x45c9, 0xfd9: 0x4619, 0xfda: 0x4699, 0xfdb: 0x4719, 0xfdc: 0x4781, 0xfdd: 0x47d1, + 0xfde: 0x4821, 0xfdf: 0x4871, 0xfe0: 0x48d9, 0xfe1: 0x4959, 0xfe2: 0x49c1, 0xfe3: 0x4a11, + 0xfe4: 0x4a61, 0xfe5: 0x4ab1, 0xfe6: 0x4ae9, 0xfe7: 0x4b21, 0xfe8: 0x4b59, 0xfe9: 0x4b91, + 0xfea: 0x4be1, 0xfeb: 0x4c31, 0xfec: 0x4cb1, 0xfed: 0x4d01, 0xfee: 0x4d69, 0xfef: 0x4de9, + 0xff0: 0x4e39, 0xff1: 0x4e71, 0xff2: 0x4ea9, 0xff3: 0x4f29, 0xff4: 0x4f91, 0xff5: 0x5011, + 0xff6: 0x5061, 0xff7: 0x50e1, 0xff8: 0x5119, 0xff9: 0x5169, 0xffa: 0x51b9, 0xffb: 0x5209, + 0xffc: 0x5259, 0xffd: 0x52a9, 0xffe: 0x5311, 0xfff: 0x5361, + // Block 0x40, offset 0x1000 + 0x1000: 0x5399, 0x1001: 0x53e9, 0x1002: 0x5439, 0x1003: 0x5489, 0x1004: 0x54f1, 0x1005: 0x5541, + 0x1006: 0x5591, 0x1007: 0x55e1, 0x1008: 0x5661, 0x1009: 0x56c9, 0x100a: 0x5701, 0x100b: 0x5781, + 0x100c: 0x57b9, 0x100d: 0x5821, 0x100e: 0x5889, 0x100f: 0x58d9, 0x1010: 0x5929, 0x1011: 0x5979, + 0x1012: 0x59e1, 0x1013: 0x5a19, 0x1014: 0x5a69, 0x1015: 0x5ad1, 0x1016: 0x5b09, 0x1017: 0x5b89, + 0x1018: 0x5bd9, 0x1019: 0x5c01, 0x101a: 0x5c29, 0x101b: 0x5c51, 0x101c: 0x5c79, 0x101d: 0x5ca1, + 0x101e: 0x5cc9, 0x101f: 0x5cf1, 0x1020: 0x5d19, 0x1021: 0x5d41, 0x1022: 0x5d69, 0x1023: 0x5d99, + 0x1024: 0x5dc9, 0x1025: 0x5df9, 0x1026: 0x5e29, 0x1027: 0x5e59, 0x1028: 0x5e89, 0x1029: 0x5eb9, + 0x102a: 0x5ee9, 0x102b: 0x5f19, 0x102c: 0x5f49, 0x102d: 0x5f79, 0x102e: 0x5fa9, 0x102f: 0x5fd9, + 0x1030: 0x6009, 0x1031: 0x402d, 0x1032: 0x6039, 0x1033: 0x6051, 0x1034: 0x404d, 0x1035: 0x6069, + 0x1036: 0x6081, 0x1037: 0x6099, 0x1038: 0x406d, 0x1039: 0x406d, 0x103a: 0x60b1, 0x103b: 0x60c9, + 0x103c: 0x6101, 0x103d: 0x6139, 0x103e: 0x6171, 0x103f: 0x61a9, + // Block 0x41, offset 0x1040 + 0x1040: 0x6211, 0x1041: 0x6229, 0x1042: 0x408d, 0x1043: 0x6241, 0x1044: 0x6259, 0x1045: 0x6271, + 0x1046: 0x6289, 0x1047: 0x62a1, 0x1048: 0x40ad, 0x1049: 0x62b9, 0x104a: 0x62e1, 0x104b: 0x62f9, + 0x104c: 0x40cd, 0x104d: 0x40cd, 0x104e: 0x6311, 0x104f: 0x6329, 0x1050: 0x6341, 0x1051: 0x40ed, + 0x1052: 0x410d, 0x1053: 0x412d, 0x1054: 0x414d, 0x1055: 0x416d, 0x1056: 0x6359, 0x1057: 0x6371, + 0x1058: 0x6389, 0x1059: 0x63a1, 0x105a: 0x63b9, 0x105b: 0x418d, 0x105c: 0x63d1, 0x105d: 0x63e9, + 0x105e: 0x6401, 0x105f: 0x41ad, 0x1060: 0x41cd, 0x1061: 0x6419, 0x1062: 0x41ed, 0x1063: 0x420d, + 0x1064: 0x422d, 0x1065: 0x6431, 0x1066: 0x424d, 0x1067: 0x6449, 0x1068: 0x6479, 0x1069: 0x6211, + 0x106a: 0x426d, 0x106b: 0x428d, 0x106c: 0x42ad, 0x106d: 0x42cd, 0x106e: 0x64b1, 0x106f: 0x64f1, + 0x1070: 0x6539, 0x1071: 0x6551, 0x1072: 0x42ed, 0x1073: 0x6569, 0x1074: 0x6581, 0x1075: 0x6599, + 0x1076: 0x430d, 0x1077: 0x65b1, 0x1078: 0x65c9, 0x1079: 0x65b1, 0x107a: 0x65e1, 0x107b: 0x65f9, + 0x107c: 0x432d, 0x107d: 0x6611, 0x107e: 0x6629, 0x107f: 0x6611, + // Block 0x42, offset 0x1080 + 0x1080: 0x434d, 0x1081: 0x436d, 0x1082: 0x0040, 0x1083: 0x6641, 0x1084: 0x6659, 0x1085: 0x6671, + 0x1086: 0x6689, 0x1087: 0x0040, 0x1088: 0x66c1, 0x1089: 0x66d9, 0x108a: 0x66f1, 0x108b: 0x6709, + 0x108c: 0x6721, 0x108d: 0x6739, 0x108e: 0x6401, 0x108f: 0x6751, 0x1090: 0x6769, 0x1091: 0x6781, + 0x1092: 0x438d, 0x1093: 0x6799, 0x1094: 0x6289, 0x1095: 0x43ad, 0x1096: 0x43cd, 0x1097: 0x67b1, + 0x1098: 0x0040, 0x1099: 0x43ed, 0x109a: 0x67c9, 0x109b: 0x67e1, 0x109c: 0x67f9, 0x109d: 0x6811, + 0x109e: 0x6829, 0x109f: 0x6859, 0x10a0: 0x6889, 0x10a1: 0x68b1, 0x10a2: 0x68d9, 0x10a3: 0x6901, + 0x10a4: 0x6929, 0x10a5: 0x6951, 0x10a6: 0x6979, 0x10a7: 0x69a1, 0x10a8: 0x69c9, 0x10a9: 0x69f1, + 0x10aa: 0x6a21, 0x10ab: 0x6a51, 0x10ac: 0x6a81, 0x10ad: 0x6ab1, 0x10ae: 0x6ae1, 0x10af: 0x6b11, + 0x10b0: 0x6b41, 0x10b1: 0x6b71, 0x10b2: 0x6ba1, 0x10b3: 0x6bd1, 0x10b4: 0x6c01, 0x10b5: 0x6c31, + 0x10b6: 0x6c61, 0x10b7: 0x6c91, 0x10b8: 0x6cc1, 0x10b9: 0x6cf1, 0x10ba: 0x6d21, 0x10bb: 0x6d51, + 0x10bc: 0x6d81, 0x10bd: 0x6db1, 0x10be: 0x6de1, 0x10bf: 0x440d, + // Block 0x43, offset 0x10c0 + 0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008, + 0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008, + 0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008, + 0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008, + 0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0xe00d, 0x10dd: 0x0008, + 0x10de: 0xe00d, 0x10df: 0x0008, 0x10e0: 0xe00d, 0x10e1: 0x0008, 0x10e2: 0xe00d, 0x10e3: 0x0008, + 0x10e4: 0xe00d, 0x10e5: 0x0008, 0x10e6: 0xe00d, 0x10e7: 0x0008, 0x10e8: 0xe00d, 0x10e9: 0x0008, + 0x10ea: 0xe00d, 0x10eb: 0x0008, 0x10ec: 0xe00d, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x3308, + 0x10f0: 0x3318, 0x10f1: 0x3318, 0x10f2: 0x3318, 0x10f3: 0x0018, 0x10f4: 0x3308, 0x10f5: 0x3308, + 0x10f6: 0x3308, 0x10f7: 0x3308, 0x10f8: 0x3308, 0x10f9: 0x3308, 0x10fa: 0x3308, 0x10fb: 0x3308, + 0x10fc: 0x3308, 0x10fd: 0x3308, 0x10fe: 0x0018, 0x10ff: 0x0008, + // Block 0x44, offset 0x1100 + 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, + 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, + 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, + 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, + 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0x0ea1, 0x111d: 0x6e11, + 0x111e: 0x3308, 0x111f: 0x3308, 0x1120: 0x0008, 0x1121: 0x0008, 0x1122: 0x0008, 0x1123: 0x0008, + 0x1124: 0x0008, 0x1125: 0x0008, 0x1126: 0x0008, 0x1127: 0x0008, 0x1128: 0x0008, 0x1129: 0x0008, + 0x112a: 0x0008, 0x112b: 0x0008, 0x112c: 0x0008, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x0008, + 0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0x0008, 0x1133: 0x0008, 0x1134: 0x0008, 0x1135: 0x0008, + 0x1136: 0x0008, 0x1137: 0x0008, 0x1138: 0x0008, 0x1139: 0x0008, 0x113a: 0x0008, 0x113b: 0x0008, + 0x113c: 0x0008, 0x113d: 0x0008, 0x113e: 0x0008, 0x113f: 0x0008, + // Block 0x45, offset 0x1140 + 0x1140: 0x0018, 0x1141: 0x0018, 0x1142: 0x0018, 0x1143: 0x0018, 0x1144: 0x0018, 0x1145: 0x0018, + 0x1146: 0x0018, 0x1147: 0x0018, 0x1148: 0x0018, 0x1149: 0x0018, 0x114a: 0x0018, 0x114b: 0x0018, + 0x114c: 0x0018, 0x114d: 0x0018, 0x114e: 0x0018, 0x114f: 0x0018, 0x1150: 0x0018, 0x1151: 0x0018, + 0x1152: 0x0018, 0x1153: 0x0018, 0x1154: 0x0018, 0x1155: 0x0018, 0x1156: 0x0018, 0x1157: 0x0008, + 0x1158: 0x0008, 0x1159: 0x0008, 0x115a: 0x0008, 0x115b: 0x0008, 0x115c: 0x0008, 0x115d: 0x0008, + 0x115e: 0x0008, 0x115f: 0x0008, 0x1160: 0x0018, 0x1161: 0x0018, 0x1162: 0xe00d, 0x1163: 0x0008, + 0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008, + 0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008, + 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0xe00d, 0x1173: 0x0008, 0x1174: 0xe00d, 0x1175: 0x0008, + 0x1176: 0xe00d, 0x1177: 0x0008, 0x1178: 0xe00d, 0x1179: 0x0008, 0x117a: 0xe00d, 0x117b: 0x0008, + 0x117c: 0xe00d, 0x117d: 0x0008, 0x117e: 0xe00d, 0x117f: 0x0008, + // Block 0x46, offset 0x1180 + 0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008, + 0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0xe00d, 0x1189: 0x0008, 0x118a: 0xe00d, 0x118b: 0x0008, + 0x118c: 0xe00d, 0x118d: 0x0008, 0x118e: 0xe00d, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008, + 0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0xe00d, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008, + 0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008, + 0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008, + 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, + 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, + 0x11b0: 0xe0fd, 0x11b1: 0x0008, 0x11b2: 0x0008, 0x11b3: 0x0008, 0x11b4: 0x0008, 0x11b5: 0x0008, + 0x11b6: 0x0008, 0x11b7: 0x0008, 0x11b8: 0x0008, 0x11b9: 0xe01d, 0x11ba: 0x0008, 0x11bb: 0xe03d, + 0x11bc: 0x0008, 0x11bd: 0x442d, 0x11be: 0xe00d, 0x11bf: 0x0008, + // Block 0x47, offset 0x11c0 + 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, + 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0x0008, 0x11c9: 0x0018, 0x11ca: 0x0018, 0x11cb: 0xe03d, + 0x11cc: 0x0008, 0x11cd: 0x11d9, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, + 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, + 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, + 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, + 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, + 0x11ea: 0x6e29, 0x11eb: 0x1029, 0x11ec: 0x11c1, 0x11ed: 0x6e41, 0x11ee: 0x1221, 0x11ef: 0x0040, + 0x11f0: 0x6e59, 0x11f1: 0x6e71, 0x11f2: 0x1239, 0x11f3: 0x444d, 0x11f4: 0xe00d, 0x11f5: 0x0008, + 0x11f6: 0xe00d, 0x11f7: 0x0008, 0x11f8: 0x0040, 0x11f9: 0x0040, 0x11fa: 0x0040, 0x11fb: 0x0040, + 0x11fc: 0x0040, 0x11fd: 0x0040, 0x11fe: 0x0040, 0x11ff: 0x0040, + // Block 0x48, offset 0x1200 + 0x1200: 0x64d5, 0x1201: 0x64f5, 0x1202: 0x6515, 0x1203: 0x6535, 0x1204: 0x6555, 0x1205: 0x6575, + 0x1206: 0x6595, 0x1207: 0x65b5, 0x1208: 0x65d5, 0x1209: 0x65f5, 0x120a: 0x6615, 0x120b: 0x6635, + 0x120c: 0x6655, 0x120d: 0x6675, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0x6695, 0x1211: 0x0008, + 0x1212: 0x66b5, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x66d5, 0x1216: 0x66f5, 0x1217: 0x6715, + 0x1218: 0x6735, 0x1219: 0x6755, 0x121a: 0x6775, 0x121b: 0x6795, 0x121c: 0x67b5, 0x121d: 0x67d5, + 0x121e: 0x67f5, 0x121f: 0x0008, 0x1220: 0x6815, 0x1221: 0x0008, 0x1222: 0x6835, 0x1223: 0x0008, + 0x1224: 0x0008, 0x1225: 0x6855, 0x1226: 0x6875, 0x1227: 0x0008, 0x1228: 0x0008, 0x1229: 0x0008, + 0x122a: 0x6895, 0x122b: 0x68b5, 0x122c: 0x68d5, 0x122d: 0x68f5, 0x122e: 0x6915, 0x122f: 0x6935, + 0x1230: 0x6955, 0x1231: 0x6975, 0x1232: 0x6995, 0x1233: 0x69b5, 0x1234: 0x69d5, 0x1235: 0x69f5, + 0x1236: 0x6a15, 0x1237: 0x6a35, 0x1238: 0x6a55, 0x1239: 0x6a75, 0x123a: 0x6a95, 0x123b: 0x6ab5, + 0x123c: 0x6ad5, 0x123d: 0x6af5, 0x123e: 0x6b15, 0x123f: 0x6b35, + // Block 0x49, offset 0x1240 + 0x1240: 0x7a95, 0x1241: 0x7ab5, 0x1242: 0x7ad5, 0x1243: 0x7af5, 0x1244: 0x7b15, 0x1245: 0x7b35, + 0x1246: 0x7b55, 0x1247: 0x7b75, 0x1248: 0x7b95, 0x1249: 0x7bb5, 0x124a: 0x7bd5, 0x124b: 0x7bf5, + 0x124c: 0x7c15, 0x124d: 0x7c35, 0x124e: 0x7c55, 0x124f: 0x6ec9, 0x1250: 0x6ef1, 0x1251: 0x6f19, + 0x1252: 0x7c75, 0x1253: 0x7c95, 0x1254: 0x7cb5, 0x1255: 0x6f41, 0x1256: 0x6f69, 0x1257: 0x6f91, + 0x1258: 0x7cd5, 0x1259: 0x7cf5, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x0040, + 0x125e: 0x0040, 0x125f: 0x0040, 0x1260: 0x0040, 0x1261: 0x0040, 0x1262: 0x0040, 0x1263: 0x0040, + 0x1264: 0x0040, 0x1265: 0x0040, 0x1266: 0x0040, 0x1267: 0x0040, 0x1268: 0x0040, 0x1269: 0x0040, + 0x126a: 0x0040, 0x126b: 0x0040, 0x126c: 0x0040, 0x126d: 0x0040, 0x126e: 0x0040, 0x126f: 0x0040, + 0x1270: 0x0040, 0x1271: 0x0040, 0x1272: 0x0040, 0x1273: 0x0040, 0x1274: 0x0040, 0x1275: 0x0040, + 0x1276: 0x0040, 0x1277: 0x0040, 0x1278: 0x0040, 0x1279: 0x0040, 0x127a: 0x0040, 0x127b: 0x0040, + 0x127c: 0x0040, 0x127d: 0x0040, 0x127e: 0x0040, 0x127f: 0x0040, + // Block 0x4a, offset 0x1280 + 0x1280: 0x6fb9, 0x1281: 0x6fd1, 0x1282: 0x6fe9, 0x1283: 0x7d15, 0x1284: 0x7d35, 0x1285: 0x7001, + 0x1286: 0x7001, 0x1287: 0x0040, 0x1288: 0x0040, 0x1289: 0x0040, 0x128a: 0x0040, 0x128b: 0x0040, + 0x128c: 0x0040, 0x128d: 0x0040, 0x128e: 0x0040, 0x128f: 0x0040, 0x1290: 0x0040, 0x1291: 0x0040, + 0x1292: 0x0040, 0x1293: 0x7019, 0x1294: 0x7041, 0x1295: 0x7069, 0x1296: 0x7091, 0x1297: 0x70b9, + 0x1298: 0x0040, 0x1299: 0x0040, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x70e1, + 0x129e: 0x3308, 0x129f: 0x7109, 0x12a0: 0x7131, 0x12a1: 0x20a9, 0x12a2: 0x20f1, 0x12a3: 0x7149, + 0x12a4: 0x7161, 0x12a5: 0x7179, 0x12a6: 0x7191, 0x12a7: 0x71a9, 0x12a8: 0x71c1, 0x12a9: 0x1fb2, + 0x12aa: 0x71d9, 0x12ab: 0x7201, 0x12ac: 0x7229, 0x12ad: 0x7261, 0x12ae: 0x7299, 0x12af: 0x72c1, + 0x12b0: 0x72e9, 0x12b1: 0x7311, 0x12b2: 0x7339, 0x12b3: 0x7361, 0x12b4: 0x7389, 0x12b5: 0x73b1, + 0x12b6: 0x73d9, 0x12b7: 0x0040, 0x12b8: 0x7401, 0x12b9: 0x7429, 0x12ba: 0x7451, 0x12bb: 0x7479, + 0x12bc: 0x74a1, 0x12bd: 0x0040, 0x12be: 0x74c9, 0x12bf: 0x0040, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x74f1, 0x12c1: 0x7519, 0x12c2: 0x0040, 0x12c3: 0x7541, 0x12c4: 0x7569, 0x12c5: 0x0040, + 0x12c6: 0x7591, 0x12c7: 0x75b9, 0x12c8: 0x75e1, 0x12c9: 0x7609, 0x12ca: 0x7631, 0x12cb: 0x7659, + 0x12cc: 0x7681, 0x12cd: 0x76a9, 0x12ce: 0x76d1, 0x12cf: 0x76f9, 0x12d0: 0x7721, 0x12d1: 0x7721, + 0x12d2: 0x7739, 0x12d3: 0x7739, 0x12d4: 0x7739, 0x12d5: 0x7739, 0x12d6: 0x7751, 0x12d7: 0x7751, + 0x12d8: 0x7751, 0x12d9: 0x7751, 0x12da: 0x7769, 0x12db: 0x7769, 0x12dc: 0x7769, 0x12dd: 0x7769, + 0x12de: 0x7781, 0x12df: 0x7781, 0x12e0: 0x7781, 0x12e1: 0x7781, 0x12e2: 0x7799, 0x12e3: 0x7799, + 0x12e4: 0x7799, 0x12e5: 0x7799, 0x12e6: 0x77b1, 0x12e7: 0x77b1, 0x12e8: 0x77b1, 0x12e9: 0x77b1, + 0x12ea: 0x77c9, 0x12eb: 0x77c9, 0x12ec: 0x77c9, 0x12ed: 0x77c9, 0x12ee: 0x77e1, 0x12ef: 0x77e1, + 0x12f0: 0x77e1, 0x12f1: 0x77e1, 0x12f2: 0x77f9, 0x12f3: 0x77f9, 0x12f4: 0x77f9, 0x12f5: 0x77f9, + 0x12f6: 0x7811, 0x12f7: 0x7811, 0x12f8: 0x7811, 0x12f9: 0x7811, 0x12fa: 0x7829, 0x12fb: 0x7829, + 0x12fc: 0x7829, 0x12fd: 0x7829, 0x12fe: 0x7841, 0x12ff: 0x7841, + // Block 0x4c, offset 0x1300 + 0x1300: 0x7841, 0x1301: 0x7841, 0x1302: 0x7859, 0x1303: 0x7859, 0x1304: 0x7871, 0x1305: 0x7871, + 0x1306: 0x7889, 0x1307: 0x7889, 0x1308: 0x78a1, 0x1309: 0x78a1, 0x130a: 0x78b9, 0x130b: 0x78b9, + 0x130c: 0x78d1, 0x130d: 0x78d1, 0x130e: 0x78e9, 0x130f: 0x78e9, 0x1310: 0x78e9, 0x1311: 0x78e9, + 0x1312: 0x7901, 0x1313: 0x7901, 0x1314: 0x7901, 0x1315: 0x7901, 0x1316: 0x7919, 0x1317: 0x7919, + 0x1318: 0x7919, 0x1319: 0x7919, 0x131a: 0x7931, 0x131b: 0x7931, 0x131c: 0x7931, 0x131d: 0x7931, + 0x131e: 0x7949, 0x131f: 0x7949, 0x1320: 0x7961, 0x1321: 0x7961, 0x1322: 0x7961, 0x1323: 0x7961, + 0x1324: 0x7979, 0x1325: 0x7979, 0x1326: 0x7991, 0x1327: 0x7991, 0x1328: 0x7991, 0x1329: 0x7991, + 0x132a: 0x79a9, 0x132b: 0x79a9, 0x132c: 0x79a9, 0x132d: 0x79a9, 0x132e: 0x79c1, 0x132f: 0x79c1, + 0x1330: 0x79d9, 0x1331: 0x79d9, 0x1332: 0x0818, 0x1333: 0x0818, 0x1334: 0x0818, 0x1335: 0x0818, + 0x1336: 0x0818, 0x1337: 0x0818, 0x1338: 0x0818, 0x1339: 0x0818, 0x133a: 0x0818, 0x133b: 0x0818, + 0x133c: 0x0818, 0x133d: 0x0818, 0x133e: 0x0818, 0x133f: 0x0818, + // Block 0x4d, offset 0x1340 + 0x1340: 0x0818, 0x1341: 0x0818, 0x1342: 0x0040, 0x1343: 0x0040, 0x1344: 0x0040, 0x1345: 0x0040, + 0x1346: 0x0040, 0x1347: 0x0040, 0x1348: 0x0040, 0x1349: 0x0040, 0x134a: 0x0040, 0x134b: 0x0040, + 0x134c: 0x0040, 0x134d: 0x0040, 0x134e: 0x0040, 0x134f: 0x0040, 0x1350: 0x0040, 0x1351: 0x0040, + 0x1352: 0x0040, 0x1353: 0x79f1, 0x1354: 0x79f1, 0x1355: 0x79f1, 0x1356: 0x79f1, 0x1357: 0x7a09, + 0x1358: 0x7a09, 0x1359: 0x7a21, 0x135a: 0x7a21, 0x135b: 0x7a39, 0x135c: 0x7a39, 0x135d: 0x0479, + 0x135e: 0x7a51, 0x135f: 0x7a51, 0x1360: 0x7a69, 0x1361: 0x7a69, 0x1362: 0x7a81, 0x1363: 0x7a81, + 0x1364: 0x7a99, 0x1365: 0x7a99, 0x1366: 0x7a99, 0x1367: 0x7a99, 0x1368: 0x7ab1, 0x1369: 0x7ab1, + 0x136a: 0x7ac9, 0x136b: 0x7ac9, 0x136c: 0x7af1, 0x136d: 0x7af1, 0x136e: 0x7b19, 0x136f: 0x7b19, + 0x1370: 0x7b41, 0x1371: 0x7b41, 0x1372: 0x7b69, 0x1373: 0x7b69, 0x1374: 0x7b91, 0x1375: 0x7b91, + 0x1376: 0x7bb9, 0x1377: 0x7bb9, 0x1378: 0x7bb9, 0x1379: 0x7be1, 0x137a: 0x7be1, 0x137b: 0x7be1, + 0x137c: 0x7c09, 0x137d: 0x7c09, 0x137e: 0x7c09, 0x137f: 0x7c09, + // Block 0x4e, offset 0x1380 + 0x1380: 0x85f9, 0x1381: 0x8621, 0x1382: 0x8649, 0x1383: 0x8671, 0x1384: 0x8699, 0x1385: 0x86c1, + 0x1386: 0x86e9, 0x1387: 0x8711, 0x1388: 0x8739, 0x1389: 0x8761, 0x138a: 0x8789, 0x138b: 0x87b1, + 0x138c: 0x87d9, 0x138d: 0x8801, 0x138e: 0x8829, 0x138f: 0x8851, 0x1390: 0x8879, 0x1391: 0x88a1, + 0x1392: 0x88c9, 0x1393: 0x88f1, 0x1394: 0x8919, 0x1395: 0x8941, 0x1396: 0x8969, 0x1397: 0x8991, + 0x1398: 0x89b9, 0x1399: 0x89e1, 0x139a: 0x8a09, 0x139b: 0x8a31, 0x139c: 0x8a59, 0x139d: 0x8a81, + 0x139e: 0x8aaa, 0x139f: 0x8ada, 0x13a0: 0x8b0a, 0x13a1: 0x8b3a, 0x13a2: 0x8b6a, 0x13a3: 0x8b9a, + 0x13a4: 0x8bc9, 0x13a5: 0x8bf1, 0x13a6: 0x7c71, 0x13a7: 0x8c19, 0x13a8: 0x7be1, 0x13a9: 0x7c99, + 0x13aa: 0x8c41, 0x13ab: 0x8c69, 0x13ac: 0x7d39, 0x13ad: 0x8c91, 0x13ae: 0x7d61, 0x13af: 0x7d89, + 0x13b0: 0x8cb9, 0x13b1: 0x8ce1, 0x13b2: 0x7e29, 0x13b3: 0x8d09, 0x13b4: 0x7e51, 0x13b5: 0x7e79, + 0x13b6: 0x8d31, 0x13b7: 0x8d59, 0x13b8: 0x7ec9, 0x13b9: 0x8d81, 0x13ba: 0x7ef1, 0x13bb: 0x7f19, + 0x13bc: 0x83a1, 0x13bd: 0x83c9, 0x13be: 0x8441, 0x13bf: 0x8469, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x8491, 0x13c1: 0x8531, 0x13c2: 0x8559, 0x13c3: 0x8581, 0x13c4: 0x85a9, 0x13c5: 0x8649, + 0x13c6: 0x8671, 0x13c7: 0x8699, 0x13c8: 0x8da9, 0x13c9: 0x8739, 0x13ca: 0x8dd1, 0x13cb: 0x8df9, + 0x13cc: 0x8829, 0x13cd: 0x8e21, 0x13ce: 0x8851, 0x13cf: 0x8879, 0x13d0: 0x8a81, 0x13d1: 0x8e49, + 0x13d2: 0x8e71, 0x13d3: 0x89b9, 0x13d4: 0x8e99, 0x13d5: 0x89e1, 0x13d6: 0x8a09, 0x13d7: 0x7c21, + 0x13d8: 0x7c49, 0x13d9: 0x8ec1, 0x13da: 0x7c71, 0x13db: 0x8ee9, 0x13dc: 0x7cc1, 0x13dd: 0x7ce9, + 0x13de: 0x7d11, 0x13df: 0x7d39, 0x13e0: 0x8f11, 0x13e1: 0x7db1, 0x13e2: 0x7dd9, 0x13e3: 0x7e01, + 0x13e4: 0x7e29, 0x13e5: 0x8f39, 0x13e6: 0x7ec9, 0x13e7: 0x7f41, 0x13e8: 0x7f69, 0x13e9: 0x7f91, + 0x13ea: 0x7fb9, 0x13eb: 0x7fe1, 0x13ec: 0x8031, 0x13ed: 0x8059, 0x13ee: 0x8081, 0x13ef: 0x80a9, + 0x13f0: 0x80d1, 0x13f1: 0x80f9, 0x13f2: 0x8f61, 0x13f3: 0x8121, 0x13f4: 0x8149, 0x13f5: 0x8171, + 0x13f6: 0x8199, 0x13f7: 0x81c1, 0x13f8: 0x81e9, 0x13f9: 0x8239, 0x13fa: 0x8261, 0x13fb: 0x8289, + 0x13fc: 0x82b1, 0x13fd: 0x82d9, 0x13fe: 0x8301, 0x13ff: 0x8329, + // Block 0x50, offset 0x1400 + 0x1400: 0x8351, 0x1401: 0x8379, 0x1402: 0x83f1, 0x1403: 0x8419, 0x1404: 0x84b9, 0x1405: 0x84e1, + 0x1406: 0x8509, 0x1407: 0x8531, 0x1408: 0x8559, 0x1409: 0x85d1, 0x140a: 0x85f9, 0x140b: 0x8621, + 0x140c: 0x8649, 0x140d: 0x8f89, 0x140e: 0x86c1, 0x140f: 0x86e9, 0x1410: 0x8711, 0x1411: 0x8739, + 0x1412: 0x87b1, 0x1413: 0x87d9, 0x1414: 0x8801, 0x1415: 0x8829, 0x1416: 0x8fb1, 0x1417: 0x88a1, + 0x1418: 0x88c9, 0x1419: 0x8fd9, 0x141a: 0x8941, 0x141b: 0x8969, 0x141c: 0x8991, 0x141d: 0x89b9, + 0x141e: 0x9001, 0x141f: 0x7c71, 0x1420: 0x8ee9, 0x1421: 0x7d39, 0x1422: 0x8f11, 0x1423: 0x7e29, + 0x1424: 0x8f39, 0x1425: 0x7ec9, 0x1426: 0x9029, 0x1427: 0x80d1, 0x1428: 0x9051, 0x1429: 0x9079, + 0x142a: 0x90a1, 0x142b: 0x8531, 0x142c: 0x8559, 0x142d: 0x8649, 0x142e: 0x8829, 0x142f: 0x8fb1, + 0x1430: 0x89b9, 0x1431: 0x9001, 0x1432: 0x90c9, 0x1433: 0x9101, 0x1434: 0x9139, 0x1435: 0x9171, + 0x1436: 0x9199, 0x1437: 0x91c1, 0x1438: 0x91e9, 0x1439: 0x9211, 0x143a: 0x9239, 0x143b: 0x9261, + 0x143c: 0x9289, 0x143d: 0x92b1, 0x143e: 0x92d9, 0x143f: 0x9301, + // Block 0x51, offset 0x1440 + 0x1440: 0x9329, 0x1441: 0x9351, 0x1442: 0x9379, 0x1443: 0x93a1, 0x1444: 0x93c9, 0x1445: 0x93f1, + 0x1446: 0x9419, 0x1447: 0x9441, 0x1448: 0x9469, 0x1449: 0x9491, 0x144a: 0x94b9, 0x144b: 0x94e1, + 0x144c: 0x9079, 0x144d: 0x9509, 0x144e: 0x9531, 0x144f: 0x9559, 0x1450: 0x9581, 0x1451: 0x9171, + 0x1452: 0x9199, 0x1453: 0x91c1, 0x1454: 0x91e9, 0x1455: 0x9211, 0x1456: 0x9239, 0x1457: 0x9261, + 0x1458: 0x9289, 0x1459: 0x92b1, 0x145a: 0x92d9, 0x145b: 0x9301, 0x145c: 0x9329, 0x145d: 0x9351, + 0x145e: 0x9379, 0x145f: 0x93a1, 0x1460: 0x93c9, 0x1461: 0x93f1, 0x1462: 0x9419, 0x1463: 0x9441, + 0x1464: 0x9469, 0x1465: 0x9491, 0x1466: 0x94b9, 0x1467: 0x94e1, 0x1468: 0x9079, 0x1469: 0x9509, + 0x146a: 0x9531, 0x146b: 0x9559, 0x146c: 0x9581, 0x146d: 0x9491, 0x146e: 0x94b9, 0x146f: 0x94e1, + 0x1470: 0x9079, 0x1471: 0x9051, 0x1472: 0x90a1, 0x1473: 0x8211, 0x1474: 0x8059, 0x1475: 0x8081, + 0x1476: 0x80a9, 0x1477: 0x9491, 0x1478: 0x94b9, 0x1479: 0x94e1, 0x147a: 0x8211, 0x147b: 0x8239, + 0x147c: 0x95a9, 0x147d: 0x95a9, 0x147e: 0x0018, 0x147f: 0x0018, + // Block 0x52, offset 0x1480 + 0x1480: 0x0040, 0x1481: 0x0040, 0x1482: 0x0040, 0x1483: 0x0040, 0x1484: 0x0040, 0x1485: 0x0040, + 0x1486: 0x0040, 0x1487: 0x0040, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040, + 0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x95d1, 0x1491: 0x9609, + 0x1492: 0x9609, 0x1493: 0x9641, 0x1494: 0x9679, 0x1495: 0x96b1, 0x1496: 0x96e9, 0x1497: 0x9721, + 0x1498: 0x9759, 0x1499: 0x9759, 0x149a: 0x9791, 0x149b: 0x97c9, 0x149c: 0x9801, 0x149d: 0x9839, + 0x149e: 0x9871, 0x149f: 0x98a9, 0x14a0: 0x98a9, 0x14a1: 0x98e1, 0x14a2: 0x9919, 0x14a3: 0x9919, + 0x14a4: 0x9951, 0x14a5: 0x9951, 0x14a6: 0x9989, 0x14a7: 0x99c1, 0x14a8: 0x99c1, 0x14a9: 0x99f9, + 0x14aa: 0x9a31, 0x14ab: 0x9a31, 0x14ac: 0x9a69, 0x14ad: 0x9a69, 0x14ae: 0x9aa1, 0x14af: 0x9ad9, + 0x14b0: 0x9ad9, 0x14b1: 0x9b11, 0x14b2: 0x9b11, 0x14b3: 0x9b49, 0x14b4: 0x9b81, 0x14b5: 0x9bb9, + 0x14b6: 0x9bf1, 0x14b7: 0x9bf1, 0x14b8: 0x9c29, 0x14b9: 0x9c61, 0x14ba: 0x9c99, 0x14bb: 0x9cd1, + 0x14bc: 0x9d09, 0x14bd: 0x9d09, 0x14be: 0x9d41, 0x14bf: 0x9d79, + // Block 0x53, offset 0x14c0 + 0x14c0: 0xa949, 0x14c1: 0xa981, 0x14c2: 0xa9b9, 0x14c3: 0xa8a1, 0x14c4: 0x9bb9, 0x14c5: 0x9989, + 0x14c6: 0xa9f1, 0x14c7: 0xaa29, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, + 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x0040, 0x14d1: 0x0040, + 0x14d2: 0x0040, 0x14d3: 0x0040, 0x14d4: 0x0040, 0x14d5: 0x0040, 0x14d6: 0x0040, 0x14d7: 0x0040, + 0x14d8: 0x0040, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040, + 0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x0040, 0x14e1: 0x0040, 0x14e2: 0x0040, 0x14e3: 0x0040, + 0x14e4: 0x0040, 0x14e5: 0x0040, 0x14e6: 0x0040, 0x14e7: 0x0040, 0x14e8: 0x0040, 0x14e9: 0x0040, + 0x14ea: 0x0040, 0x14eb: 0x0040, 0x14ec: 0x0040, 0x14ed: 0x0040, 0x14ee: 0x0040, 0x14ef: 0x0040, + 0x14f0: 0xaa61, 0x14f1: 0xaa99, 0x14f2: 0xaad1, 0x14f3: 0xab19, 0x14f4: 0xab61, 0x14f5: 0xaba9, + 0x14f6: 0xabf1, 0x14f7: 0xac39, 0x14f8: 0xac81, 0x14f9: 0xacc9, 0x14fa: 0xad02, 0x14fb: 0xae12, + 0x14fc: 0xae91, 0x14fd: 0x0018, 0x14fe: 0x0040, 0x14ff: 0x0040, + // Block 0x54, offset 0x1500 + 0x1500: 0x33c0, 0x1501: 0x33c0, 0x1502: 0x33c0, 0x1503: 0x33c0, 0x1504: 0x33c0, 0x1505: 0x33c0, + 0x1506: 0x33c0, 0x1507: 0x33c0, 0x1508: 0x33c0, 0x1509: 0x33c0, 0x150a: 0x33c0, 0x150b: 0x33c0, + 0x150c: 0x33c0, 0x150d: 0x33c0, 0x150e: 0x33c0, 0x150f: 0x33c0, 0x1510: 0xaeda, 0x1511: 0x7d55, + 0x1512: 0x0040, 0x1513: 0xaeea, 0x1514: 0x03c2, 0x1515: 0xaefa, 0x1516: 0xaf0a, 0x1517: 0x7d75, + 0x1518: 0x7d95, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, + 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x3308, 0x1521: 0x3308, 0x1522: 0x3308, 0x1523: 0x3308, + 0x1524: 0x3308, 0x1525: 0x3308, 0x1526: 0x3308, 0x1527: 0x3308, 0x1528: 0x3308, 0x1529: 0x3308, + 0x152a: 0x3308, 0x152b: 0x3308, 0x152c: 0x3308, 0x152d: 0x3308, 0x152e: 0x3308, 0x152f: 0x3308, + 0x1530: 0x0040, 0x1531: 0x7db5, 0x1532: 0x7dd5, 0x1533: 0xaf1a, 0x1534: 0xaf1a, 0x1535: 0x1fd2, + 0x1536: 0x1fe2, 0x1537: 0xaf2a, 0x1538: 0xaf3a, 0x1539: 0x7df5, 0x153a: 0x7e15, 0x153b: 0x7e35, + 0x153c: 0x7df5, 0x153d: 0x7e55, 0x153e: 0x7e75, 0x153f: 0x7e55, + // Block 0x55, offset 0x1540 + 0x1540: 0x7e95, 0x1541: 0x7eb5, 0x1542: 0x7ed5, 0x1543: 0x7eb5, 0x1544: 0x7ef5, 0x1545: 0x0018, + 0x1546: 0x0018, 0x1547: 0xaf4a, 0x1548: 0xaf5a, 0x1549: 0x7f16, 0x154a: 0x7f36, 0x154b: 0x7f56, + 0x154c: 0x7f76, 0x154d: 0xaf1a, 0x154e: 0xaf1a, 0x154f: 0xaf1a, 0x1550: 0xaeda, 0x1551: 0x7f95, + 0x1552: 0x0040, 0x1553: 0x0040, 0x1554: 0x03c2, 0x1555: 0xaeea, 0x1556: 0xaf0a, 0x1557: 0xaefa, + 0x1558: 0x7fb5, 0x1559: 0x1fd2, 0x155a: 0x1fe2, 0x155b: 0xaf2a, 0x155c: 0xaf3a, 0x155d: 0x7e95, + 0x155e: 0x7ef5, 0x155f: 0xaf6a, 0x1560: 0xaf7a, 0x1561: 0xaf8a, 0x1562: 0x1fb2, 0x1563: 0xaf99, + 0x1564: 0xafaa, 0x1565: 0xafba, 0x1566: 0x1fc2, 0x1567: 0x0040, 0x1568: 0xafca, 0x1569: 0xafda, + 0x156a: 0xafea, 0x156b: 0xaffa, 0x156c: 0x0040, 0x156d: 0x0040, 0x156e: 0x0040, 0x156f: 0x0040, + 0x1570: 0x7fd6, 0x1571: 0xb009, 0x1572: 0x7ff6, 0x1573: 0x0808, 0x1574: 0x8016, 0x1575: 0x0040, + 0x1576: 0x8036, 0x1577: 0xb031, 0x1578: 0x8056, 0x1579: 0xb059, 0x157a: 0x8076, 0x157b: 0xb081, + 0x157c: 0x8096, 0x157d: 0xb0a9, 0x157e: 0x80b6, 0x157f: 0xb0d1, + // Block 0x56, offset 0x1580 + 0x1580: 0xb0f9, 0x1581: 0xb111, 0x1582: 0xb111, 0x1583: 0xb129, 0x1584: 0xb129, 0x1585: 0xb141, + 0x1586: 0xb141, 0x1587: 0xb159, 0x1588: 0xb159, 0x1589: 0xb171, 0x158a: 0xb171, 0x158b: 0xb171, + 0x158c: 0xb171, 0x158d: 0xb189, 0x158e: 0xb189, 0x158f: 0xb1a1, 0x1590: 0xb1a1, 0x1591: 0xb1a1, + 0x1592: 0xb1a1, 0x1593: 0xb1b9, 0x1594: 0xb1b9, 0x1595: 0xb1d1, 0x1596: 0xb1d1, 0x1597: 0xb1d1, + 0x1598: 0xb1d1, 0x1599: 0xb1e9, 0x159a: 0xb1e9, 0x159b: 0xb1e9, 0x159c: 0xb1e9, 0x159d: 0xb201, + 0x159e: 0xb201, 0x159f: 0xb201, 0x15a0: 0xb201, 0x15a1: 0xb219, 0x15a2: 0xb219, 0x15a3: 0xb219, + 0x15a4: 0xb219, 0x15a5: 0xb231, 0x15a6: 0xb231, 0x15a7: 0xb231, 0x15a8: 0xb231, 0x15a9: 0xb249, + 0x15aa: 0xb249, 0x15ab: 0xb261, 0x15ac: 0xb261, 0x15ad: 0xb279, 0x15ae: 0xb279, 0x15af: 0xb291, + 0x15b0: 0xb291, 0x15b1: 0xb2a9, 0x15b2: 0xb2a9, 0x15b3: 0xb2a9, 0x15b4: 0xb2a9, 0x15b5: 0xb2c1, + 0x15b6: 0xb2c1, 0x15b7: 0xb2c1, 0x15b8: 0xb2c1, 0x15b9: 0xb2d9, 0x15ba: 0xb2d9, 0x15bb: 0xb2d9, + 0x15bc: 0xb2d9, 0x15bd: 0xb2f1, 0x15be: 0xb2f1, 0x15bf: 0xb2f1, + // Block 0x57, offset 0x15c0 + 0x15c0: 0xb2f1, 0x15c1: 0xb309, 0x15c2: 0xb309, 0x15c3: 0xb309, 0x15c4: 0xb309, 0x15c5: 0xb321, + 0x15c6: 0xb321, 0x15c7: 0xb321, 0x15c8: 0xb321, 0x15c9: 0xb339, 0x15ca: 0xb339, 0x15cb: 0xb339, + 0x15cc: 0xb339, 0x15cd: 0xb351, 0x15ce: 0xb351, 0x15cf: 0xb351, 0x15d0: 0xb351, 0x15d1: 0xb369, + 0x15d2: 0xb369, 0x15d3: 0xb369, 0x15d4: 0xb369, 0x15d5: 0xb381, 0x15d6: 0xb381, 0x15d7: 0xb381, + 0x15d8: 0xb381, 0x15d9: 0xb399, 0x15da: 0xb399, 0x15db: 0xb399, 0x15dc: 0xb399, 0x15dd: 0xb3b1, + 0x15de: 0xb3b1, 0x15df: 0xb3b1, 0x15e0: 0xb3b1, 0x15e1: 0xb3c9, 0x15e2: 0xb3c9, 0x15e3: 0xb3c9, + 0x15e4: 0xb3c9, 0x15e5: 0xb3e1, 0x15e6: 0xb3e1, 0x15e7: 0xb3e1, 0x15e8: 0xb3e1, 0x15e9: 0xb3f9, + 0x15ea: 0xb3f9, 0x15eb: 0xb3f9, 0x15ec: 0xb3f9, 0x15ed: 0xb411, 0x15ee: 0xb411, 0x15ef: 0x7ab1, + 0x15f0: 0x7ab1, 0x15f1: 0xb429, 0x15f2: 0xb429, 0x15f3: 0xb429, 0x15f4: 0xb429, 0x15f5: 0xb441, + 0x15f6: 0xb441, 0x15f7: 0xb469, 0x15f8: 0xb469, 0x15f9: 0xb491, 0x15fa: 0xb491, 0x15fb: 0xb4b9, + 0x15fc: 0xb4b9, 0x15fd: 0x0040, 0x15fe: 0x0040, 0x15ff: 0x03c0, + // Block 0x58, offset 0x1600 + 0x1600: 0x0040, 0x1601: 0xaefa, 0x1602: 0xb4e2, 0x1603: 0xaf6a, 0x1604: 0xafda, 0x1605: 0xafea, + 0x1606: 0xaf7a, 0x1607: 0xb4f2, 0x1608: 0x1fd2, 0x1609: 0x1fe2, 0x160a: 0xaf8a, 0x160b: 0x1fb2, + 0x160c: 0xaeda, 0x160d: 0xaf99, 0x160e: 0x29d1, 0x160f: 0xb502, 0x1610: 0x1f41, 0x1611: 0x00c9, + 0x1612: 0x0069, 0x1613: 0x0079, 0x1614: 0x1f51, 0x1615: 0x1f61, 0x1616: 0x1f71, 0x1617: 0x1f81, + 0x1618: 0x1f91, 0x1619: 0x1fa1, 0x161a: 0xaeea, 0x161b: 0x03c2, 0x161c: 0xafaa, 0x161d: 0x1fc2, + 0x161e: 0xafba, 0x161f: 0xaf0a, 0x1620: 0xaffa, 0x1621: 0x0039, 0x1622: 0x0ee9, 0x1623: 0x1159, + 0x1624: 0x0ef9, 0x1625: 0x0f09, 0x1626: 0x1199, 0x1627: 0x0f31, 0x1628: 0x0249, 0x1629: 0x0f41, + 0x162a: 0x0259, 0x162b: 0x0f51, 0x162c: 0x0359, 0x162d: 0x0f61, 0x162e: 0x0f71, 0x162f: 0x00d9, + 0x1630: 0x0f99, 0x1631: 0x2039, 0x1632: 0x0269, 0x1633: 0x01d9, 0x1634: 0x0fa9, 0x1635: 0x0fb9, + 0x1636: 0x1089, 0x1637: 0x0279, 0x1638: 0x0369, 0x1639: 0x0289, 0x163a: 0x13d1, 0x163b: 0xaf4a, + 0x163c: 0xafca, 0x163d: 0xaf5a, 0x163e: 0xb512, 0x163f: 0xaf1a, + // Block 0x59, offset 0x1640 + 0x1640: 0x1caa, 0x1641: 0x0039, 0x1642: 0x0ee9, 0x1643: 0x1159, 0x1644: 0x0ef9, 0x1645: 0x0f09, + 0x1646: 0x1199, 0x1647: 0x0f31, 0x1648: 0x0249, 0x1649: 0x0f41, 0x164a: 0x0259, 0x164b: 0x0f51, + 0x164c: 0x0359, 0x164d: 0x0f61, 0x164e: 0x0f71, 0x164f: 0x00d9, 0x1650: 0x0f99, 0x1651: 0x2039, + 0x1652: 0x0269, 0x1653: 0x01d9, 0x1654: 0x0fa9, 0x1655: 0x0fb9, 0x1656: 0x1089, 0x1657: 0x0279, + 0x1658: 0x0369, 0x1659: 0x0289, 0x165a: 0x13d1, 0x165b: 0xaf2a, 0x165c: 0xb522, 0x165d: 0xaf3a, + 0x165e: 0xb532, 0x165f: 0x80d5, 0x1660: 0x80f5, 0x1661: 0x29d1, 0x1662: 0x8115, 0x1663: 0x8115, + 0x1664: 0x8135, 0x1665: 0x8155, 0x1666: 0x8175, 0x1667: 0x8195, 0x1668: 0x81b5, 0x1669: 0x81d5, + 0x166a: 0x81f5, 0x166b: 0x8215, 0x166c: 0x8235, 0x166d: 0x8255, 0x166e: 0x8275, 0x166f: 0x8295, + 0x1670: 0x82b5, 0x1671: 0x82d5, 0x1672: 0x82f5, 0x1673: 0x8315, 0x1674: 0x8335, 0x1675: 0x8355, + 0x1676: 0x8375, 0x1677: 0x8395, 0x1678: 0x83b5, 0x1679: 0x83d5, 0x167a: 0x83f5, 0x167b: 0x8415, + 0x167c: 0x81b5, 0x167d: 0x8435, 0x167e: 0x8455, 0x167f: 0x8215, + // Block 0x5a, offset 0x1680 + 0x1680: 0x8475, 0x1681: 0x8495, 0x1682: 0x84b5, 0x1683: 0x84d5, 0x1684: 0x84f5, 0x1685: 0x8515, + 0x1686: 0x8535, 0x1687: 0x8555, 0x1688: 0x84d5, 0x1689: 0x8575, 0x168a: 0x84d5, 0x168b: 0x8595, + 0x168c: 0x8595, 0x168d: 0x85b5, 0x168e: 0x85b5, 0x168f: 0x85d5, 0x1690: 0x8515, 0x1691: 0x85f5, + 0x1692: 0x8615, 0x1693: 0x85f5, 0x1694: 0x8635, 0x1695: 0x8615, 0x1696: 0x8655, 0x1697: 0x8655, + 0x1698: 0x8675, 0x1699: 0x8675, 0x169a: 0x8695, 0x169b: 0x8695, 0x169c: 0x8615, 0x169d: 0x8115, + 0x169e: 0x86b5, 0x169f: 0x86d5, 0x16a0: 0x0040, 0x16a1: 0x86f5, 0x16a2: 0x8715, 0x16a3: 0x8735, + 0x16a4: 0x8755, 0x16a5: 0x8735, 0x16a6: 0x8775, 0x16a7: 0x8795, 0x16a8: 0x87b5, 0x16a9: 0x87b5, + 0x16aa: 0x87d5, 0x16ab: 0x87d5, 0x16ac: 0x87f5, 0x16ad: 0x87f5, 0x16ae: 0x87d5, 0x16af: 0x87d5, + 0x16b0: 0x8815, 0x16b1: 0x8835, 0x16b2: 0x8855, 0x16b3: 0x8875, 0x16b4: 0x8895, 0x16b5: 0x88b5, + 0x16b6: 0x88b5, 0x16b7: 0x88b5, 0x16b8: 0x88d5, 0x16b9: 0x88d5, 0x16ba: 0x88d5, 0x16bb: 0x88d5, + 0x16bc: 0x87b5, 0x16bd: 0x87b5, 0x16be: 0x87b5, 0x16bf: 0x0040, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x0040, 0x16c1: 0x0040, 0x16c2: 0x8715, 0x16c3: 0x86f5, 0x16c4: 0x88f5, 0x16c5: 0x86f5, + 0x16c6: 0x8715, 0x16c7: 0x86f5, 0x16c8: 0x0040, 0x16c9: 0x0040, 0x16ca: 0x8915, 0x16cb: 0x8715, + 0x16cc: 0x8935, 0x16cd: 0x88f5, 0x16ce: 0x8935, 0x16cf: 0x8715, 0x16d0: 0x0040, 0x16d1: 0x0040, + 0x16d2: 0x8955, 0x16d3: 0x8975, 0x16d4: 0x8875, 0x16d5: 0x8935, 0x16d6: 0x88f5, 0x16d7: 0x8935, + 0x16d8: 0x0040, 0x16d9: 0x0040, 0x16da: 0x8995, 0x16db: 0x89b5, 0x16dc: 0x8995, 0x16dd: 0x0040, + 0x16de: 0x0040, 0x16df: 0x0040, 0x16e0: 0xb541, 0x16e1: 0xb559, 0x16e2: 0xb571, 0x16e3: 0x89d6, + 0x16e4: 0xb589, 0x16e5: 0xb5a1, 0x16e6: 0x89f5, 0x16e7: 0x0040, 0x16e8: 0x8a15, 0x16e9: 0x8a35, + 0x16ea: 0x8a55, 0x16eb: 0x8a35, 0x16ec: 0x8a75, 0x16ed: 0x8a95, 0x16ee: 0x8ab5, 0x16ef: 0x0040, + 0x16f0: 0x0040, 0x16f1: 0x0040, 0x16f2: 0x0040, 0x16f3: 0x0040, 0x16f4: 0x0040, 0x16f5: 0x0040, + 0x16f6: 0x0040, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0340, 0x16fa: 0x0340, 0x16fb: 0x0340, + 0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040, + // Block 0x5c, offset 0x1700 + 0x1700: 0x0a08, 0x1701: 0x0a08, 0x1702: 0x0a08, 0x1703: 0x0a08, 0x1704: 0x0a08, 0x1705: 0x0c08, + 0x1706: 0x0808, 0x1707: 0x0c08, 0x1708: 0x0818, 0x1709: 0x0c08, 0x170a: 0x0c08, 0x170b: 0x0808, + 0x170c: 0x0808, 0x170d: 0x0908, 0x170e: 0x0c08, 0x170f: 0x0c08, 0x1710: 0x0c08, 0x1711: 0x0c08, + 0x1712: 0x0c08, 0x1713: 0x0a08, 0x1714: 0x0a08, 0x1715: 0x0a08, 0x1716: 0x0a08, 0x1717: 0x0908, + 0x1718: 0x0a08, 0x1719: 0x0a08, 0x171a: 0x0a08, 0x171b: 0x0a08, 0x171c: 0x0a08, 0x171d: 0x0c08, + 0x171e: 0x0a08, 0x171f: 0x0a08, 0x1720: 0x0a08, 0x1721: 0x0c08, 0x1722: 0x0808, 0x1723: 0x0808, + 0x1724: 0x0c08, 0x1725: 0x3308, 0x1726: 0x3308, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0040, + 0x172a: 0x0040, 0x172b: 0x0a18, 0x172c: 0x0a18, 0x172d: 0x0a18, 0x172e: 0x0a18, 0x172f: 0x0c18, + 0x1730: 0x0818, 0x1731: 0x0818, 0x1732: 0x0818, 0x1733: 0x0818, 0x1734: 0x0818, 0x1735: 0x0818, + 0x1736: 0x0818, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040, + 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, + // Block 0x5d, offset 0x1740 + 0x1740: 0x0a08, 0x1741: 0x0c08, 0x1742: 0x0a08, 0x1743: 0x0c08, 0x1744: 0x0c08, 0x1745: 0x0c08, + 0x1746: 0x0a08, 0x1747: 0x0a08, 0x1748: 0x0a08, 0x1749: 0x0c08, 0x174a: 0x0a08, 0x174b: 0x0a08, + 0x174c: 0x0c08, 0x174d: 0x0a08, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0a08, 0x1751: 0x0c08, + 0x1752: 0x0040, 0x1753: 0x0040, 0x1754: 0x0040, 0x1755: 0x0040, 0x1756: 0x0040, 0x1757: 0x0040, + 0x1758: 0x0040, 0x1759: 0x0818, 0x175a: 0x0818, 0x175b: 0x0818, 0x175c: 0x0818, 0x175d: 0x0040, + 0x175e: 0x0040, 0x175f: 0x0040, 0x1760: 0x0040, 0x1761: 0x0040, 0x1762: 0x0040, 0x1763: 0x0040, + 0x1764: 0x0040, 0x1765: 0x0040, 0x1766: 0x0040, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0c18, + 0x176a: 0x0c18, 0x176b: 0x0c18, 0x176c: 0x0c18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0818, + 0x1770: 0x0040, 0x1771: 0x0040, 0x1772: 0x0040, 0x1773: 0x0040, 0x1774: 0x0040, 0x1775: 0x0040, + 0x1776: 0x0040, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, + 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, + // Block 0x5e, offset 0x1780 + 0x1780: 0x3308, 0x1781: 0x3308, 0x1782: 0x3008, 0x1783: 0x3008, 0x1784: 0x0040, 0x1785: 0x0008, + 0x1786: 0x0008, 0x1787: 0x0008, 0x1788: 0x0008, 0x1789: 0x0008, 0x178a: 0x0008, 0x178b: 0x0008, + 0x178c: 0x0008, 0x178d: 0x0040, 0x178e: 0x0040, 0x178f: 0x0008, 0x1790: 0x0008, 0x1791: 0x0040, + 0x1792: 0x0040, 0x1793: 0x0008, 0x1794: 0x0008, 0x1795: 0x0008, 0x1796: 0x0008, 0x1797: 0x0008, + 0x1798: 0x0008, 0x1799: 0x0008, 0x179a: 0x0008, 0x179b: 0x0008, 0x179c: 0x0008, 0x179d: 0x0008, + 0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x0008, 0x17a3: 0x0008, + 0x17a4: 0x0008, 0x17a5: 0x0008, 0x17a6: 0x0008, 0x17a7: 0x0008, 0x17a8: 0x0008, 0x17a9: 0x0040, + 0x17aa: 0x0008, 0x17ab: 0x0008, 0x17ac: 0x0008, 0x17ad: 0x0008, 0x17ae: 0x0008, 0x17af: 0x0008, + 0x17b0: 0x0008, 0x17b1: 0x0040, 0x17b2: 0x0008, 0x17b3: 0x0008, 0x17b4: 0x0040, 0x17b5: 0x0008, + 0x17b6: 0x0008, 0x17b7: 0x0008, 0x17b8: 0x0008, 0x17b9: 0x0008, 0x17ba: 0x0040, 0x17bb: 0x0040, + 0x17bc: 0x3308, 0x17bd: 0x0008, 0x17be: 0x3008, 0x17bf: 0x3008, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x3308, 0x17c1: 0x3008, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x3008, 0x17c5: 0x0040, + 0x17c6: 0x0040, 0x17c7: 0x3008, 0x17c8: 0x3008, 0x17c9: 0x0040, 0x17ca: 0x0040, 0x17cb: 0x3008, + 0x17cc: 0x3008, 0x17cd: 0x3808, 0x17ce: 0x0040, 0x17cf: 0x0040, 0x17d0: 0x0008, 0x17d1: 0x0040, + 0x17d2: 0x0040, 0x17d3: 0x0040, 0x17d4: 0x0040, 0x17d5: 0x0040, 0x17d6: 0x0040, 0x17d7: 0x3008, + 0x17d8: 0x0040, 0x17d9: 0x0040, 0x17da: 0x0040, 0x17db: 0x0040, 0x17dc: 0x0040, 0x17dd: 0x0008, + 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x3008, 0x17e3: 0x3008, + 0x17e4: 0x0040, 0x17e5: 0x0040, 0x17e6: 0x3308, 0x17e7: 0x3308, 0x17e8: 0x3308, 0x17e9: 0x3308, + 0x17ea: 0x3308, 0x17eb: 0x3308, 0x17ec: 0x3308, 0x17ed: 0x0040, 0x17ee: 0x0040, 0x17ef: 0x0040, + 0x17f0: 0x3308, 0x17f1: 0x3308, 0x17f2: 0x3308, 0x17f3: 0x3308, 0x17f4: 0x3308, 0x17f5: 0x0040, + 0x17f6: 0x0040, 0x17f7: 0x0040, 0x17f8: 0x0040, 0x17f9: 0x0040, 0x17fa: 0x0040, 0x17fb: 0x0040, + 0x17fc: 0x0040, 0x17fd: 0x0040, 0x17fe: 0x0040, 0x17ff: 0x0040, + // Block 0x60, offset 0x1800 + 0x1800: 0x0039, 0x1801: 0x0ee9, 0x1802: 0x1159, 0x1803: 0x0ef9, 0x1804: 0x0f09, 0x1805: 0x1199, + 0x1806: 0x0f31, 0x1807: 0x0249, 0x1808: 0x0f41, 0x1809: 0x0259, 0x180a: 0x0f51, 0x180b: 0x0359, + 0x180c: 0x0f61, 0x180d: 0x0f71, 0x180e: 0x00d9, 0x180f: 0x0f99, 0x1810: 0x2039, 0x1811: 0x0269, + 0x1812: 0x01d9, 0x1813: 0x0fa9, 0x1814: 0x0fb9, 0x1815: 0x1089, 0x1816: 0x0279, 0x1817: 0x0369, + 0x1818: 0x0289, 0x1819: 0x13d1, 0x181a: 0x0039, 0x181b: 0x0ee9, 0x181c: 0x1159, 0x181d: 0x0ef9, + 0x181e: 0x0f09, 0x181f: 0x1199, 0x1820: 0x0f31, 0x1821: 0x0249, 0x1822: 0x0f41, 0x1823: 0x0259, + 0x1824: 0x0f51, 0x1825: 0x0359, 0x1826: 0x0f61, 0x1827: 0x0f71, 0x1828: 0x00d9, 0x1829: 0x0f99, + 0x182a: 0x2039, 0x182b: 0x0269, 0x182c: 0x01d9, 0x182d: 0x0fa9, 0x182e: 0x0fb9, 0x182f: 0x1089, + 0x1830: 0x0279, 0x1831: 0x0369, 0x1832: 0x0289, 0x1833: 0x13d1, 0x1834: 0x0039, 0x1835: 0x0ee9, + 0x1836: 0x1159, 0x1837: 0x0ef9, 0x1838: 0x0f09, 0x1839: 0x1199, 0x183a: 0x0f31, 0x183b: 0x0249, + 0x183c: 0x0f41, 0x183d: 0x0259, 0x183e: 0x0f51, 0x183f: 0x0359, + // Block 0x61, offset 0x1840 + 0x1840: 0x0f61, 0x1841: 0x0f71, 0x1842: 0x00d9, 0x1843: 0x0f99, 0x1844: 0x2039, 0x1845: 0x0269, + 0x1846: 0x01d9, 0x1847: 0x0fa9, 0x1848: 0x0fb9, 0x1849: 0x1089, 0x184a: 0x0279, 0x184b: 0x0369, + 0x184c: 0x0289, 0x184d: 0x13d1, 0x184e: 0x0039, 0x184f: 0x0ee9, 0x1850: 0x1159, 0x1851: 0x0ef9, + 0x1852: 0x0f09, 0x1853: 0x1199, 0x1854: 0x0f31, 0x1855: 0x0040, 0x1856: 0x0f41, 0x1857: 0x0259, + 0x1858: 0x0f51, 0x1859: 0x0359, 0x185a: 0x0f61, 0x185b: 0x0f71, 0x185c: 0x00d9, 0x185d: 0x0f99, + 0x185e: 0x2039, 0x185f: 0x0269, 0x1860: 0x01d9, 0x1861: 0x0fa9, 0x1862: 0x0fb9, 0x1863: 0x1089, + 0x1864: 0x0279, 0x1865: 0x0369, 0x1866: 0x0289, 0x1867: 0x13d1, 0x1868: 0x0039, 0x1869: 0x0ee9, + 0x186a: 0x1159, 0x186b: 0x0ef9, 0x186c: 0x0f09, 0x186d: 0x1199, 0x186e: 0x0f31, 0x186f: 0x0249, + 0x1870: 0x0f41, 0x1871: 0x0259, 0x1872: 0x0f51, 0x1873: 0x0359, 0x1874: 0x0f61, 0x1875: 0x0f71, + 0x1876: 0x00d9, 0x1877: 0x0f99, 0x1878: 0x2039, 0x1879: 0x0269, 0x187a: 0x01d9, 0x187b: 0x0fa9, + 0x187c: 0x0fb9, 0x187d: 0x1089, 0x187e: 0x0279, 0x187f: 0x0369, + // Block 0x62, offset 0x1880 + 0x1880: 0x0289, 0x1881: 0x13d1, 0x1882: 0x0039, 0x1883: 0x0ee9, 0x1884: 0x1159, 0x1885: 0x0ef9, + 0x1886: 0x0f09, 0x1887: 0x1199, 0x1888: 0x0f31, 0x1889: 0x0249, 0x188a: 0x0f41, 0x188b: 0x0259, + 0x188c: 0x0f51, 0x188d: 0x0359, 0x188e: 0x0f61, 0x188f: 0x0f71, 0x1890: 0x00d9, 0x1891: 0x0f99, + 0x1892: 0x2039, 0x1893: 0x0269, 0x1894: 0x01d9, 0x1895: 0x0fa9, 0x1896: 0x0fb9, 0x1897: 0x1089, + 0x1898: 0x0279, 0x1899: 0x0369, 0x189a: 0x0289, 0x189b: 0x13d1, 0x189c: 0x0039, 0x189d: 0x0040, + 0x189e: 0x1159, 0x189f: 0x0ef9, 0x18a0: 0x0040, 0x18a1: 0x0040, 0x18a2: 0x0f31, 0x18a3: 0x0040, + 0x18a4: 0x0040, 0x18a5: 0x0259, 0x18a6: 0x0f51, 0x18a7: 0x0040, 0x18a8: 0x0040, 0x18a9: 0x0f71, + 0x18aa: 0x00d9, 0x18ab: 0x0f99, 0x18ac: 0x2039, 0x18ad: 0x0040, 0x18ae: 0x01d9, 0x18af: 0x0fa9, + 0x18b0: 0x0fb9, 0x18b1: 0x1089, 0x18b2: 0x0279, 0x18b3: 0x0369, 0x18b4: 0x0289, 0x18b5: 0x13d1, + 0x18b6: 0x0039, 0x18b7: 0x0ee9, 0x18b8: 0x1159, 0x18b9: 0x0ef9, 0x18ba: 0x0040, 0x18bb: 0x1199, + 0x18bc: 0x0040, 0x18bd: 0x0249, 0x18be: 0x0f41, 0x18bf: 0x0259, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0f51, 0x18c1: 0x0359, 0x18c2: 0x0f61, 0x18c3: 0x0f71, 0x18c4: 0x0040, 0x18c5: 0x0f99, + 0x18c6: 0x2039, 0x18c7: 0x0269, 0x18c8: 0x01d9, 0x18c9: 0x0fa9, 0x18ca: 0x0fb9, 0x18cb: 0x1089, + 0x18cc: 0x0279, 0x18cd: 0x0369, 0x18ce: 0x0289, 0x18cf: 0x13d1, 0x18d0: 0x0039, 0x18d1: 0x0ee9, + 0x18d2: 0x1159, 0x18d3: 0x0ef9, 0x18d4: 0x0f09, 0x18d5: 0x1199, 0x18d6: 0x0f31, 0x18d7: 0x0249, + 0x18d8: 0x0f41, 0x18d9: 0x0259, 0x18da: 0x0f51, 0x18db: 0x0359, 0x18dc: 0x0f61, 0x18dd: 0x0f71, + 0x18de: 0x00d9, 0x18df: 0x0f99, 0x18e0: 0x2039, 0x18e1: 0x0269, 0x18e2: 0x01d9, 0x18e3: 0x0fa9, + 0x18e4: 0x0fb9, 0x18e5: 0x1089, 0x18e6: 0x0279, 0x18e7: 0x0369, 0x18e8: 0x0289, 0x18e9: 0x13d1, + 0x18ea: 0x0039, 0x18eb: 0x0ee9, 0x18ec: 0x1159, 0x18ed: 0x0ef9, 0x18ee: 0x0f09, 0x18ef: 0x1199, + 0x18f0: 0x0f31, 0x18f1: 0x0249, 0x18f2: 0x0f41, 0x18f3: 0x0259, 0x18f4: 0x0f51, 0x18f5: 0x0359, + 0x18f6: 0x0f61, 0x18f7: 0x0f71, 0x18f8: 0x00d9, 0x18f9: 0x0f99, 0x18fa: 0x2039, 0x18fb: 0x0269, + 0x18fc: 0x01d9, 0x18fd: 0x0fa9, 0x18fe: 0x0fb9, 0x18ff: 0x1089, + // Block 0x64, offset 0x1900 + 0x1900: 0x0279, 0x1901: 0x0369, 0x1902: 0x0289, 0x1903: 0x13d1, 0x1904: 0x0039, 0x1905: 0x0ee9, + 0x1906: 0x0040, 0x1907: 0x0ef9, 0x1908: 0x0f09, 0x1909: 0x1199, 0x190a: 0x0f31, 0x190b: 0x0040, + 0x190c: 0x0040, 0x190d: 0x0259, 0x190e: 0x0f51, 0x190f: 0x0359, 0x1910: 0x0f61, 0x1911: 0x0f71, + 0x1912: 0x00d9, 0x1913: 0x0f99, 0x1914: 0x2039, 0x1915: 0x0040, 0x1916: 0x01d9, 0x1917: 0x0fa9, + 0x1918: 0x0fb9, 0x1919: 0x1089, 0x191a: 0x0279, 0x191b: 0x0369, 0x191c: 0x0289, 0x191d: 0x0040, + 0x191e: 0x0039, 0x191f: 0x0ee9, 0x1920: 0x1159, 0x1921: 0x0ef9, 0x1922: 0x0f09, 0x1923: 0x1199, + 0x1924: 0x0f31, 0x1925: 0x0249, 0x1926: 0x0f41, 0x1927: 0x0259, 0x1928: 0x0f51, 0x1929: 0x0359, + 0x192a: 0x0f61, 0x192b: 0x0f71, 0x192c: 0x00d9, 0x192d: 0x0f99, 0x192e: 0x2039, 0x192f: 0x0269, + 0x1930: 0x01d9, 0x1931: 0x0fa9, 0x1932: 0x0fb9, 0x1933: 0x1089, 0x1934: 0x0279, 0x1935: 0x0369, + 0x1936: 0x0289, 0x1937: 0x13d1, 0x1938: 0x0039, 0x1939: 0x0ee9, 0x193a: 0x0040, 0x193b: 0x0ef9, + 0x193c: 0x0f09, 0x193d: 0x1199, 0x193e: 0x0f31, 0x193f: 0x0040, + // Block 0x65, offset 0x1940 + 0x1940: 0x0f41, 0x1941: 0x0259, 0x1942: 0x0f51, 0x1943: 0x0359, 0x1944: 0x0f61, 0x1945: 0x0040, + 0x1946: 0x00d9, 0x1947: 0x0040, 0x1948: 0x0040, 0x1949: 0x0040, 0x194a: 0x01d9, 0x194b: 0x0fa9, + 0x194c: 0x0fb9, 0x194d: 0x1089, 0x194e: 0x0279, 0x194f: 0x0369, 0x1950: 0x0289, 0x1951: 0x0040, + 0x1952: 0x0039, 0x1953: 0x0ee9, 0x1954: 0x1159, 0x1955: 0x0ef9, 0x1956: 0x0f09, 0x1957: 0x1199, + 0x1958: 0x0f31, 0x1959: 0x0249, 0x195a: 0x0f41, 0x195b: 0x0259, 0x195c: 0x0f51, 0x195d: 0x0359, + 0x195e: 0x0f61, 0x195f: 0x0f71, 0x1960: 0x00d9, 0x1961: 0x0f99, 0x1962: 0x2039, 0x1963: 0x0269, + 0x1964: 0x01d9, 0x1965: 0x0fa9, 0x1966: 0x0fb9, 0x1967: 0x1089, 0x1968: 0x0279, 0x1969: 0x0369, + 0x196a: 0x0289, 0x196b: 0x13d1, 0x196c: 0x0039, 0x196d: 0x0ee9, 0x196e: 0x1159, 0x196f: 0x0ef9, + 0x1970: 0x0f09, 0x1971: 0x1199, 0x1972: 0x0f31, 0x1973: 0x0249, 0x1974: 0x0f41, 0x1975: 0x0259, + 0x1976: 0x0f51, 0x1977: 0x0359, 0x1978: 0x0f61, 0x1979: 0x0f71, 0x197a: 0x00d9, 0x197b: 0x0f99, + 0x197c: 0x2039, 0x197d: 0x0269, 0x197e: 0x01d9, 0x197f: 0x0fa9, + // Block 0x66, offset 0x1980 + 0x1980: 0x0fb9, 0x1981: 0x1089, 0x1982: 0x0279, 0x1983: 0x0369, 0x1984: 0x0289, 0x1985: 0x13d1, + 0x1986: 0x0039, 0x1987: 0x0ee9, 0x1988: 0x1159, 0x1989: 0x0ef9, 0x198a: 0x0f09, 0x198b: 0x1199, + 0x198c: 0x0f31, 0x198d: 0x0249, 0x198e: 0x0f41, 0x198f: 0x0259, 0x1990: 0x0f51, 0x1991: 0x0359, + 0x1992: 0x0f61, 0x1993: 0x0f71, 0x1994: 0x00d9, 0x1995: 0x0f99, 0x1996: 0x2039, 0x1997: 0x0269, + 0x1998: 0x01d9, 0x1999: 0x0fa9, 0x199a: 0x0fb9, 0x199b: 0x1089, 0x199c: 0x0279, 0x199d: 0x0369, + 0x199e: 0x0289, 0x199f: 0x13d1, 0x19a0: 0x0039, 0x19a1: 0x0ee9, 0x19a2: 0x1159, 0x19a3: 0x0ef9, + 0x19a4: 0x0f09, 0x19a5: 0x1199, 0x19a6: 0x0f31, 0x19a7: 0x0249, 0x19a8: 0x0f41, 0x19a9: 0x0259, + 0x19aa: 0x0f51, 0x19ab: 0x0359, 0x19ac: 0x0f61, 0x19ad: 0x0f71, 0x19ae: 0x00d9, 0x19af: 0x0f99, + 0x19b0: 0x2039, 0x19b1: 0x0269, 0x19b2: 0x01d9, 0x19b3: 0x0fa9, 0x19b4: 0x0fb9, 0x19b5: 0x1089, + 0x19b6: 0x0279, 0x19b7: 0x0369, 0x19b8: 0x0289, 0x19b9: 0x13d1, 0x19ba: 0x0039, 0x19bb: 0x0ee9, + 0x19bc: 0x1159, 0x19bd: 0x0ef9, 0x19be: 0x0f09, 0x19bf: 0x1199, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x0f31, 0x19c1: 0x0249, 0x19c2: 0x0f41, 0x19c3: 0x0259, 0x19c4: 0x0f51, 0x19c5: 0x0359, + 0x19c6: 0x0f61, 0x19c7: 0x0f71, 0x19c8: 0x00d9, 0x19c9: 0x0f99, 0x19ca: 0x2039, 0x19cb: 0x0269, + 0x19cc: 0x01d9, 0x19cd: 0x0fa9, 0x19ce: 0x0fb9, 0x19cf: 0x1089, 0x19d0: 0x0279, 0x19d1: 0x0369, + 0x19d2: 0x0289, 0x19d3: 0x13d1, 0x19d4: 0x0039, 0x19d5: 0x0ee9, 0x19d6: 0x1159, 0x19d7: 0x0ef9, + 0x19d8: 0x0f09, 0x19d9: 0x1199, 0x19da: 0x0f31, 0x19db: 0x0249, 0x19dc: 0x0f41, 0x19dd: 0x0259, + 0x19de: 0x0f51, 0x19df: 0x0359, 0x19e0: 0x0f61, 0x19e1: 0x0f71, 0x19e2: 0x00d9, 0x19e3: 0x0f99, + 0x19e4: 0x2039, 0x19e5: 0x0269, 0x19e6: 0x01d9, 0x19e7: 0x0fa9, 0x19e8: 0x0fb9, 0x19e9: 0x1089, + 0x19ea: 0x0279, 0x19eb: 0x0369, 0x19ec: 0x0289, 0x19ed: 0x13d1, 0x19ee: 0x0039, 0x19ef: 0x0ee9, + 0x19f0: 0x1159, 0x19f1: 0x0ef9, 0x19f2: 0x0f09, 0x19f3: 0x1199, 0x19f4: 0x0f31, 0x19f5: 0x0249, + 0x19f6: 0x0f41, 0x19f7: 0x0259, 0x19f8: 0x0f51, 0x19f9: 0x0359, 0x19fa: 0x0f61, 0x19fb: 0x0f71, + 0x19fc: 0x00d9, 0x19fd: 0x0f99, 0x19fe: 0x2039, 0x19ff: 0x0269, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x01d9, 0x1a01: 0x0fa9, 0x1a02: 0x0fb9, 0x1a03: 0x1089, 0x1a04: 0x0279, 0x1a05: 0x0369, + 0x1a06: 0x0289, 0x1a07: 0x13d1, 0x1a08: 0x0039, 0x1a09: 0x0ee9, 0x1a0a: 0x1159, 0x1a0b: 0x0ef9, + 0x1a0c: 0x0f09, 0x1a0d: 0x1199, 0x1a0e: 0x0f31, 0x1a0f: 0x0249, 0x1a10: 0x0f41, 0x1a11: 0x0259, + 0x1a12: 0x0f51, 0x1a13: 0x0359, 0x1a14: 0x0f61, 0x1a15: 0x0f71, 0x1a16: 0x00d9, 0x1a17: 0x0f99, + 0x1a18: 0x2039, 0x1a19: 0x0269, 0x1a1a: 0x01d9, 0x1a1b: 0x0fa9, 0x1a1c: 0x0fb9, 0x1a1d: 0x1089, + 0x1a1e: 0x0279, 0x1a1f: 0x0369, 0x1a20: 0x0289, 0x1a21: 0x13d1, 0x1a22: 0x0039, 0x1a23: 0x0ee9, + 0x1a24: 0x1159, 0x1a25: 0x0ef9, 0x1a26: 0x0f09, 0x1a27: 0x1199, 0x1a28: 0x0f31, 0x1a29: 0x0249, + 0x1a2a: 0x0f41, 0x1a2b: 0x0259, 0x1a2c: 0x0f51, 0x1a2d: 0x0359, 0x1a2e: 0x0f61, 0x1a2f: 0x0f71, + 0x1a30: 0x00d9, 0x1a31: 0x0f99, 0x1a32: 0x2039, 0x1a33: 0x0269, 0x1a34: 0x01d9, 0x1a35: 0x0fa9, + 0x1a36: 0x0fb9, 0x1a37: 0x1089, 0x1a38: 0x0279, 0x1a39: 0x0369, 0x1a3a: 0x0289, 0x1a3b: 0x13d1, + 0x1a3c: 0x0039, 0x1a3d: 0x0ee9, 0x1a3e: 0x1159, 0x1a3f: 0x0ef9, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x0f09, 0x1a41: 0x1199, 0x1a42: 0x0f31, 0x1a43: 0x0249, 0x1a44: 0x0f41, 0x1a45: 0x0259, + 0x1a46: 0x0f51, 0x1a47: 0x0359, 0x1a48: 0x0f61, 0x1a49: 0x0f71, 0x1a4a: 0x00d9, 0x1a4b: 0x0f99, + 0x1a4c: 0x2039, 0x1a4d: 0x0269, 0x1a4e: 0x01d9, 0x1a4f: 0x0fa9, 0x1a50: 0x0fb9, 0x1a51: 0x1089, + 0x1a52: 0x0279, 0x1a53: 0x0369, 0x1a54: 0x0289, 0x1a55: 0x13d1, 0x1a56: 0x0039, 0x1a57: 0x0ee9, + 0x1a58: 0x1159, 0x1a59: 0x0ef9, 0x1a5a: 0x0f09, 0x1a5b: 0x1199, 0x1a5c: 0x0f31, 0x1a5d: 0x0249, + 0x1a5e: 0x0f41, 0x1a5f: 0x0259, 0x1a60: 0x0f51, 0x1a61: 0x0359, 0x1a62: 0x0f61, 0x1a63: 0x0f71, + 0x1a64: 0x00d9, 0x1a65: 0x0f99, 0x1a66: 0x2039, 0x1a67: 0x0269, 0x1a68: 0x01d9, 0x1a69: 0x0fa9, + 0x1a6a: 0x0fb9, 0x1a6b: 0x1089, 0x1a6c: 0x0279, 0x1a6d: 0x0369, 0x1a6e: 0x0289, 0x1a6f: 0x13d1, + 0x1a70: 0x0039, 0x1a71: 0x0ee9, 0x1a72: 0x1159, 0x1a73: 0x0ef9, 0x1a74: 0x0f09, 0x1a75: 0x1199, + 0x1a76: 0x0f31, 0x1a77: 0x0249, 0x1a78: 0x0f41, 0x1a79: 0x0259, 0x1a7a: 0x0f51, 0x1a7b: 0x0359, + 0x1a7c: 0x0f61, 0x1a7d: 0x0f71, 0x1a7e: 0x00d9, 0x1a7f: 0x0f99, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x2039, 0x1a81: 0x0269, 0x1a82: 0x01d9, 0x1a83: 0x0fa9, 0x1a84: 0x0fb9, 0x1a85: 0x1089, + 0x1a86: 0x0279, 0x1a87: 0x0369, 0x1a88: 0x0289, 0x1a89: 0x13d1, 0x1a8a: 0x0039, 0x1a8b: 0x0ee9, + 0x1a8c: 0x1159, 0x1a8d: 0x0ef9, 0x1a8e: 0x0f09, 0x1a8f: 0x1199, 0x1a90: 0x0f31, 0x1a91: 0x0249, + 0x1a92: 0x0f41, 0x1a93: 0x0259, 0x1a94: 0x0f51, 0x1a95: 0x0359, 0x1a96: 0x0f61, 0x1a97: 0x0f71, + 0x1a98: 0x00d9, 0x1a99: 0x0f99, 0x1a9a: 0x2039, 0x1a9b: 0x0269, 0x1a9c: 0x01d9, 0x1a9d: 0x0fa9, + 0x1a9e: 0x0fb9, 0x1a9f: 0x1089, 0x1aa0: 0x0279, 0x1aa1: 0x0369, 0x1aa2: 0x0289, 0x1aa3: 0x13d1, + 0x1aa4: 0xba81, 0x1aa5: 0xba99, 0x1aa6: 0x0040, 0x1aa7: 0x0040, 0x1aa8: 0xbab1, 0x1aa9: 0x1099, + 0x1aaa: 0x10b1, 0x1aab: 0x10c9, 0x1aac: 0xbac9, 0x1aad: 0xbae1, 0x1aae: 0xbaf9, 0x1aaf: 0x1429, + 0x1ab0: 0x1a31, 0x1ab1: 0xbb11, 0x1ab2: 0xbb29, 0x1ab3: 0xbb41, 0x1ab4: 0xbb59, 0x1ab5: 0xbb71, + 0x1ab6: 0xbb89, 0x1ab7: 0x2109, 0x1ab8: 0x1111, 0x1ab9: 0x1429, 0x1aba: 0xbba1, 0x1abb: 0xbbb9, + 0x1abc: 0xbbd1, 0x1abd: 0x10e1, 0x1abe: 0x10f9, 0x1abf: 0xbbe9, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x2079, 0x1ac1: 0xbc01, 0x1ac2: 0xbab1, 0x1ac3: 0x1099, 0x1ac4: 0x10b1, 0x1ac5: 0x10c9, + 0x1ac6: 0xbac9, 0x1ac7: 0xbae1, 0x1ac8: 0xbaf9, 0x1ac9: 0x1429, 0x1aca: 0x1a31, 0x1acb: 0xbb11, + 0x1acc: 0xbb29, 0x1acd: 0xbb41, 0x1ace: 0xbb59, 0x1acf: 0xbb71, 0x1ad0: 0xbb89, 0x1ad1: 0x2109, + 0x1ad2: 0x1111, 0x1ad3: 0xbba1, 0x1ad4: 0xbba1, 0x1ad5: 0xbbb9, 0x1ad6: 0xbbd1, 0x1ad7: 0x10e1, + 0x1ad8: 0x10f9, 0x1ad9: 0xbbe9, 0x1ada: 0x2079, 0x1adb: 0xbc21, 0x1adc: 0xbac9, 0x1add: 0x1429, + 0x1ade: 0xbb11, 0x1adf: 0x10e1, 0x1ae0: 0x1111, 0x1ae1: 0x2109, 0x1ae2: 0xbab1, 0x1ae3: 0x1099, + 0x1ae4: 0x10b1, 0x1ae5: 0x10c9, 0x1ae6: 0xbac9, 0x1ae7: 0xbae1, 0x1ae8: 0xbaf9, 0x1ae9: 0x1429, + 0x1aea: 0x1a31, 0x1aeb: 0xbb11, 0x1aec: 0xbb29, 0x1aed: 0xbb41, 0x1aee: 0xbb59, 0x1aef: 0xbb71, + 0x1af0: 0xbb89, 0x1af1: 0x2109, 0x1af2: 0x1111, 0x1af3: 0x1429, 0x1af4: 0xbba1, 0x1af5: 0xbbb9, + 0x1af6: 0xbbd1, 0x1af7: 0x10e1, 0x1af8: 0x10f9, 0x1af9: 0xbbe9, 0x1afa: 0x2079, 0x1afb: 0xbc01, + 0x1afc: 0xbab1, 0x1afd: 0x1099, 0x1afe: 0x10b1, 0x1aff: 0x10c9, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0xbac9, 0x1b01: 0xbae1, 0x1b02: 0xbaf9, 0x1b03: 0x1429, 0x1b04: 0x1a31, 0x1b05: 0xbb11, + 0x1b06: 0xbb29, 0x1b07: 0xbb41, 0x1b08: 0xbb59, 0x1b09: 0xbb71, 0x1b0a: 0xbb89, 0x1b0b: 0x2109, + 0x1b0c: 0x1111, 0x1b0d: 0xbba1, 0x1b0e: 0xbba1, 0x1b0f: 0xbbb9, 0x1b10: 0xbbd1, 0x1b11: 0x10e1, + 0x1b12: 0x10f9, 0x1b13: 0xbbe9, 0x1b14: 0x2079, 0x1b15: 0xbc21, 0x1b16: 0xbac9, 0x1b17: 0x1429, + 0x1b18: 0xbb11, 0x1b19: 0x10e1, 0x1b1a: 0x1111, 0x1b1b: 0x2109, 0x1b1c: 0xbab1, 0x1b1d: 0x1099, + 0x1b1e: 0x10b1, 0x1b1f: 0x10c9, 0x1b20: 0xbac9, 0x1b21: 0xbae1, 0x1b22: 0xbaf9, 0x1b23: 0x1429, + 0x1b24: 0x1a31, 0x1b25: 0xbb11, 0x1b26: 0xbb29, 0x1b27: 0xbb41, 0x1b28: 0xbb59, 0x1b29: 0xbb71, + 0x1b2a: 0xbb89, 0x1b2b: 0x2109, 0x1b2c: 0x1111, 0x1b2d: 0x1429, 0x1b2e: 0xbba1, 0x1b2f: 0xbbb9, + 0x1b30: 0xbbd1, 0x1b31: 0x10e1, 0x1b32: 0x10f9, 0x1b33: 0xbbe9, 0x1b34: 0x2079, 0x1b35: 0xbc01, + 0x1b36: 0xbab1, 0x1b37: 0x1099, 0x1b38: 0x10b1, 0x1b39: 0x10c9, 0x1b3a: 0xbac9, 0x1b3b: 0xbae1, + 0x1b3c: 0xbaf9, 0x1b3d: 0x1429, 0x1b3e: 0x1a31, 0x1b3f: 0xbb11, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0xbb29, 0x1b41: 0xbb41, 0x1b42: 0xbb59, 0x1b43: 0xbb71, 0x1b44: 0xbb89, 0x1b45: 0x2109, + 0x1b46: 0x1111, 0x1b47: 0xbba1, 0x1b48: 0xbba1, 0x1b49: 0xbbb9, 0x1b4a: 0xbbd1, 0x1b4b: 0x10e1, + 0x1b4c: 0x10f9, 0x1b4d: 0xbbe9, 0x1b4e: 0x2079, 0x1b4f: 0xbc21, 0x1b50: 0xbac9, 0x1b51: 0x1429, + 0x1b52: 0xbb11, 0x1b53: 0x10e1, 0x1b54: 0x1111, 0x1b55: 0x2109, 0x1b56: 0xbab1, 0x1b57: 0x1099, + 0x1b58: 0x10b1, 0x1b59: 0x10c9, 0x1b5a: 0xbac9, 0x1b5b: 0xbae1, 0x1b5c: 0xbaf9, 0x1b5d: 0x1429, + 0x1b5e: 0x1a31, 0x1b5f: 0xbb11, 0x1b60: 0xbb29, 0x1b61: 0xbb41, 0x1b62: 0xbb59, 0x1b63: 0xbb71, + 0x1b64: 0xbb89, 0x1b65: 0x2109, 0x1b66: 0x1111, 0x1b67: 0x1429, 0x1b68: 0xbba1, 0x1b69: 0xbbb9, + 0x1b6a: 0xbbd1, 0x1b6b: 0x10e1, 0x1b6c: 0x10f9, 0x1b6d: 0xbbe9, 0x1b6e: 0x2079, 0x1b6f: 0xbc01, + 0x1b70: 0xbab1, 0x1b71: 0x1099, 0x1b72: 0x10b1, 0x1b73: 0x10c9, 0x1b74: 0xbac9, 0x1b75: 0xbae1, + 0x1b76: 0xbaf9, 0x1b77: 0x1429, 0x1b78: 0x1a31, 0x1b79: 0xbb11, 0x1b7a: 0xbb29, 0x1b7b: 0xbb41, + 0x1b7c: 0xbb59, 0x1b7d: 0xbb71, 0x1b7e: 0xbb89, 0x1b7f: 0x2109, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x1111, 0x1b81: 0xbba1, 0x1b82: 0xbba1, 0x1b83: 0xbbb9, 0x1b84: 0xbbd1, 0x1b85: 0x10e1, + 0x1b86: 0x10f9, 0x1b87: 0xbbe9, 0x1b88: 0x2079, 0x1b89: 0xbc21, 0x1b8a: 0xbac9, 0x1b8b: 0x1429, + 0x1b8c: 0xbb11, 0x1b8d: 0x10e1, 0x1b8e: 0x1111, 0x1b8f: 0x2109, 0x1b90: 0xbab1, 0x1b91: 0x1099, + 0x1b92: 0x10b1, 0x1b93: 0x10c9, 0x1b94: 0xbac9, 0x1b95: 0xbae1, 0x1b96: 0xbaf9, 0x1b97: 0x1429, + 0x1b98: 0x1a31, 0x1b99: 0xbb11, 0x1b9a: 0xbb29, 0x1b9b: 0xbb41, 0x1b9c: 0xbb59, 0x1b9d: 0xbb71, + 0x1b9e: 0xbb89, 0x1b9f: 0x2109, 0x1ba0: 0x1111, 0x1ba1: 0x1429, 0x1ba2: 0xbba1, 0x1ba3: 0xbbb9, + 0x1ba4: 0xbbd1, 0x1ba5: 0x10e1, 0x1ba6: 0x10f9, 0x1ba7: 0xbbe9, 0x1ba8: 0x2079, 0x1ba9: 0xbc01, + 0x1baa: 0xbab1, 0x1bab: 0x1099, 0x1bac: 0x10b1, 0x1bad: 0x10c9, 0x1bae: 0xbac9, 0x1baf: 0xbae1, + 0x1bb0: 0xbaf9, 0x1bb1: 0x1429, 0x1bb2: 0x1a31, 0x1bb3: 0xbb11, 0x1bb4: 0xbb29, 0x1bb5: 0xbb41, + 0x1bb6: 0xbb59, 0x1bb7: 0xbb71, 0x1bb8: 0xbb89, 0x1bb9: 0x2109, 0x1bba: 0x1111, 0x1bbb: 0xbba1, + 0x1bbc: 0xbba1, 0x1bbd: 0xbbb9, 0x1bbe: 0xbbd1, 0x1bbf: 0x10e1, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x10f9, 0x1bc1: 0xbbe9, 0x1bc2: 0x2079, 0x1bc3: 0xbc21, 0x1bc4: 0xbac9, 0x1bc5: 0x1429, + 0x1bc6: 0xbb11, 0x1bc7: 0x10e1, 0x1bc8: 0x1111, 0x1bc9: 0x2109, 0x1bca: 0xbc41, 0x1bcb: 0xbc41, + 0x1bcc: 0x0040, 0x1bcd: 0x0040, 0x1bce: 0x1f41, 0x1bcf: 0x00c9, 0x1bd0: 0x0069, 0x1bd1: 0x0079, + 0x1bd2: 0x1f51, 0x1bd3: 0x1f61, 0x1bd4: 0x1f71, 0x1bd5: 0x1f81, 0x1bd6: 0x1f91, 0x1bd7: 0x1fa1, + 0x1bd8: 0x1f41, 0x1bd9: 0x00c9, 0x1bda: 0x0069, 0x1bdb: 0x0079, 0x1bdc: 0x1f51, 0x1bdd: 0x1f61, + 0x1bde: 0x1f71, 0x1bdf: 0x1f81, 0x1be0: 0x1f91, 0x1be1: 0x1fa1, 0x1be2: 0x1f41, 0x1be3: 0x00c9, + 0x1be4: 0x0069, 0x1be5: 0x0079, 0x1be6: 0x1f51, 0x1be7: 0x1f61, 0x1be8: 0x1f71, 0x1be9: 0x1f81, + 0x1bea: 0x1f91, 0x1beb: 0x1fa1, 0x1bec: 0x1f41, 0x1bed: 0x00c9, 0x1bee: 0x0069, 0x1bef: 0x0079, + 0x1bf0: 0x1f51, 0x1bf1: 0x1f61, 0x1bf2: 0x1f71, 0x1bf3: 0x1f81, 0x1bf4: 0x1f91, 0x1bf5: 0x1fa1, + 0x1bf6: 0x1f41, 0x1bf7: 0x00c9, 0x1bf8: 0x0069, 0x1bf9: 0x0079, 0x1bfa: 0x1f51, 0x1bfb: 0x1f61, + 0x1bfc: 0x1f71, 0x1bfd: 0x1f81, 0x1bfe: 0x1f91, 0x1bff: 0x1fa1, + // Block 0x70, offset 0x1c00 + 0x1c00: 0xe115, 0x1c01: 0xe115, 0x1c02: 0xe135, 0x1c03: 0xe135, 0x1c04: 0xe115, 0x1c05: 0xe115, + 0x1c06: 0xe175, 0x1c07: 0xe175, 0x1c08: 0xe115, 0x1c09: 0xe115, 0x1c0a: 0xe135, 0x1c0b: 0xe135, + 0x1c0c: 0xe115, 0x1c0d: 0xe115, 0x1c0e: 0xe1f5, 0x1c0f: 0xe1f5, 0x1c10: 0xe115, 0x1c11: 0xe115, + 0x1c12: 0xe135, 0x1c13: 0xe135, 0x1c14: 0xe115, 0x1c15: 0xe115, 0x1c16: 0xe175, 0x1c17: 0xe175, + 0x1c18: 0xe115, 0x1c19: 0xe115, 0x1c1a: 0xe135, 0x1c1b: 0xe135, 0x1c1c: 0xe115, 0x1c1d: 0xe115, + 0x1c1e: 0x8b05, 0x1c1f: 0x8b05, 0x1c20: 0x04b5, 0x1c21: 0x04b5, 0x1c22: 0x0a08, 0x1c23: 0x0a08, + 0x1c24: 0x0a08, 0x1c25: 0x0a08, 0x1c26: 0x0a08, 0x1c27: 0x0a08, 0x1c28: 0x0a08, 0x1c29: 0x0a08, + 0x1c2a: 0x0a08, 0x1c2b: 0x0a08, 0x1c2c: 0x0a08, 0x1c2d: 0x0a08, 0x1c2e: 0x0a08, 0x1c2f: 0x0a08, + 0x1c30: 0x0a08, 0x1c31: 0x0a08, 0x1c32: 0x0a08, 0x1c33: 0x0a08, 0x1c34: 0x0a08, 0x1c35: 0x0a08, + 0x1c36: 0x0a08, 0x1c37: 0x0a08, 0x1c38: 0x0a08, 0x1c39: 0x0a08, 0x1c3a: 0x0a08, 0x1c3b: 0x0a08, + 0x1c3c: 0x0a08, 0x1c3d: 0x0a08, 0x1c3e: 0x0a08, 0x1c3f: 0x0a08, + // Block 0x71, offset 0x1c40 + 0x1c40: 0xb189, 0x1c41: 0xb1a1, 0x1c42: 0xb201, 0x1c43: 0xb249, 0x1c44: 0x0040, 0x1c45: 0xb411, + 0x1c46: 0xb291, 0x1c47: 0xb219, 0x1c48: 0xb309, 0x1c49: 0xb429, 0x1c4a: 0xb399, 0x1c4b: 0xb3b1, + 0x1c4c: 0xb3c9, 0x1c4d: 0xb3e1, 0x1c4e: 0xb2a9, 0x1c4f: 0xb339, 0x1c50: 0xb369, 0x1c51: 0xb2d9, + 0x1c52: 0xb381, 0x1c53: 0xb279, 0x1c54: 0xb2c1, 0x1c55: 0xb1d1, 0x1c56: 0xb1e9, 0x1c57: 0xb231, + 0x1c58: 0xb261, 0x1c59: 0xb2f1, 0x1c5a: 0xb321, 0x1c5b: 0xb351, 0x1c5c: 0xbc59, 0x1c5d: 0x7949, + 0x1c5e: 0xbc71, 0x1c5f: 0xbc89, 0x1c60: 0x0040, 0x1c61: 0xb1a1, 0x1c62: 0xb201, 0x1c63: 0x0040, + 0x1c64: 0xb3f9, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0xb219, 0x1c68: 0x0040, 0x1c69: 0xb429, + 0x1c6a: 0xb399, 0x1c6b: 0xb3b1, 0x1c6c: 0xb3c9, 0x1c6d: 0xb3e1, 0x1c6e: 0xb2a9, 0x1c6f: 0xb339, + 0x1c70: 0xb369, 0x1c71: 0xb2d9, 0x1c72: 0xb381, 0x1c73: 0x0040, 0x1c74: 0xb2c1, 0x1c75: 0xb1d1, + 0x1c76: 0xb1e9, 0x1c77: 0xb231, 0x1c78: 0x0040, 0x1c79: 0xb2f1, 0x1c7a: 0x0040, 0x1c7b: 0xb351, + 0x1c7c: 0x0040, 0x1c7d: 0x0040, 0x1c7e: 0x0040, 0x1c7f: 0x0040, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x0040, 0x1c81: 0x0040, 0x1c82: 0xb201, 0x1c83: 0x0040, 0x1c84: 0x0040, 0x1c85: 0x0040, + 0x1c86: 0x0040, 0x1c87: 0xb219, 0x1c88: 0x0040, 0x1c89: 0xb429, 0x1c8a: 0x0040, 0x1c8b: 0xb3b1, + 0x1c8c: 0x0040, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0x0040, 0x1c91: 0xb2d9, + 0x1c92: 0xb381, 0x1c93: 0x0040, 0x1c94: 0xb2c1, 0x1c95: 0x0040, 0x1c96: 0x0040, 0x1c97: 0xb231, + 0x1c98: 0x0040, 0x1c99: 0xb2f1, 0x1c9a: 0x0040, 0x1c9b: 0xb351, 0x1c9c: 0x0040, 0x1c9d: 0x7949, + 0x1c9e: 0x0040, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, + 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0xb309, 0x1ca9: 0xb429, + 0x1caa: 0xb399, 0x1cab: 0x0040, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, + 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, + 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0xb321, 0x1cbb: 0xb351, + 0x1cbc: 0xbc59, 0x1cbd: 0x0040, 0x1cbe: 0xbc71, 0x1cbf: 0x0040, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0xb189, 0x1cc1: 0xb1a1, 0x1cc2: 0xb201, 0x1cc3: 0xb249, 0x1cc4: 0xb3f9, 0x1cc5: 0xb411, + 0x1cc6: 0xb291, 0x1cc7: 0xb219, 0x1cc8: 0xb309, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, + 0x1ccc: 0xb3c9, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0xb369, 0x1cd1: 0xb2d9, + 0x1cd2: 0xb381, 0x1cd3: 0xb279, 0x1cd4: 0xb2c1, 0x1cd5: 0xb1d1, 0x1cd6: 0xb1e9, 0x1cd7: 0xb231, + 0x1cd8: 0xb261, 0x1cd9: 0xb2f1, 0x1cda: 0xb321, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x0040, + 0x1cde: 0x0040, 0x1cdf: 0x0040, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0xb249, + 0x1ce4: 0x0040, 0x1ce5: 0xb411, 0x1ce6: 0xb291, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, + 0x1cea: 0x0040, 0x1ceb: 0xb3b1, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, + 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0xb279, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, + 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0xb261, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, + 0x1cfc: 0x0040, 0x1cfd: 0x0040, 0x1cfe: 0x0040, 0x1cff: 0x0040, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x0040, 0x1d01: 0xbca2, 0x1d02: 0xbcba, 0x1d03: 0xbcd2, 0x1d04: 0xbcea, 0x1d05: 0xbd02, + 0x1d06: 0xbd1a, 0x1d07: 0xbd32, 0x1d08: 0xbd4a, 0x1d09: 0xbd62, 0x1d0a: 0xbd7a, 0x1d0b: 0x0018, + 0x1d0c: 0x0018, 0x1d0d: 0x0040, 0x1d0e: 0x0040, 0x1d0f: 0x0040, 0x1d10: 0xbd92, 0x1d11: 0xbdb2, + 0x1d12: 0xbdd2, 0x1d13: 0xbdf2, 0x1d14: 0xbe12, 0x1d15: 0xbe32, 0x1d16: 0xbe52, 0x1d17: 0xbe72, + 0x1d18: 0xbe92, 0x1d19: 0xbeb2, 0x1d1a: 0xbed2, 0x1d1b: 0xbef2, 0x1d1c: 0xbf12, 0x1d1d: 0xbf32, + 0x1d1e: 0xbf52, 0x1d1f: 0xbf72, 0x1d20: 0xbf92, 0x1d21: 0xbfb2, 0x1d22: 0xbfd2, 0x1d23: 0xbff2, + 0x1d24: 0xc012, 0x1d25: 0xc032, 0x1d26: 0xc052, 0x1d27: 0xc072, 0x1d28: 0xc092, 0x1d29: 0xc0b2, + 0x1d2a: 0xc0d1, 0x1d2b: 0x1159, 0x1d2c: 0x0269, 0x1d2d: 0x6671, 0x1d2e: 0xc111, 0x1d2f: 0x0040, + 0x1d30: 0x0039, 0x1d31: 0x0ee9, 0x1d32: 0x1159, 0x1d33: 0x0ef9, 0x1d34: 0x0f09, 0x1d35: 0x1199, + 0x1d36: 0x0f31, 0x1d37: 0x0249, 0x1d38: 0x0f41, 0x1d39: 0x0259, 0x1d3a: 0x0f51, 0x1d3b: 0x0359, + 0x1d3c: 0x0f61, 0x1d3d: 0x0f71, 0x1d3e: 0x00d9, 0x1d3f: 0x0f99, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x2039, 0x1d41: 0x0269, 0x1d42: 0x01d9, 0x1d43: 0x0fa9, 0x1d44: 0x0fb9, 0x1d45: 0x1089, + 0x1d46: 0x0279, 0x1d47: 0x0369, 0x1d48: 0x0289, 0x1d49: 0x13d1, 0x1d4a: 0xc129, 0x1d4b: 0x65b1, + 0x1d4c: 0xc141, 0x1d4d: 0x1441, 0x1d4e: 0xc159, 0x1d4f: 0xc179, 0x1d50: 0x0018, 0x1d51: 0x0018, + 0x1d52: 0x0018, 0x1d53: 0x0018, 0x1d54: 0x0018, 0x1d55: 0x0018, 0x1d56: 0x0018, 0x1d57: 0x0018, + 0x1d58: 0x0018, 0x1d59: 0x0018, 0x1d5a: 0x0018, 0x1d5b: 0x0018, 0x1d5c: 0x0018, 0x1d5d: 0x0018, + 0x1d5e: 0x0018, 0x1d5f: 0x0018, 0x1d60: 0x0018, 0x1d61: 0x0018, 0x1d62: 0x0018, 0x1d63: 0x0018, + 0x1d64: 0x0018, 0x1d65: 0x0018, 0x1d66: 0x0018, 0x1d67: 0x0018, 0x1d68: 0x0018, 0x1d69: 0x0018, + 0x1d6a: 0xc191, 0x1d6b: 0xc1a9, 0x1d6c: 0x0040, 0x1d6d: 0x0040, 0x1d6e: 0x0040, 0x1d6f: 0x0040, + 0x1d70: 0x0018, 0x1d71: 0x0018, 0x1d72: 0x0018, 0x1d73: 0x0018, 0x1d74: 0x0018, 0x1d75: 0x0018, + 0x1d76: 0x0018, 0x1d77: 0x0018, 0x1d78: 0x0018, 0x1d79: 0x0018, 0x1d7a: 0x0018, 0x1d7b: 0x0018, + 0x1d7c: 0x0018, 0x1d7d: 0x0018, 0x1d7e: 0x0018, 0x1d7f: 0x0018, + // Block 0x76, offset 0x1d80 + 0x1d80: 0xc1d9, 0x1d81: 0xc211, 0x1d82: 0xc249, 0x1d83: 0x0040, 0x1d84: 0x0040, 0x1d85: 0x0040, + 0x1d86: 0x0040, 0x1d87: 0x0040, 0x1d88: 0x0040, 0x1d89: 0x0040, 0x1d8a: 0x0040, 0x1d8b: 0x0040, + 0x1d8c: 0x0040, 0x1d8d: 0x0040, 0x1d8e: 0x0040, 0x1d8f: 0x0040, 0x1d90: 0xc269, 0x1d91: 0xc289, + 0x1d92: 0xc2a9, 0x1d93: 0xc2c9, 0x1d94: 0xc2e9, 0x1d95: 0xc309, 0x1d96: 0xc329, 0x1d97: 0xc349, + 0x1d98: 0xc369, 0x1d99: 0xc389, 0x1d9a: 0xc3a9, 0x1d9b: 0xc3c9, 0x1d9c: 0xc3e9, 0x1d9d: 0xc409, + 0x1d9e: 0xc429, 0x1d9f: 0xc449, 0x1da0: 0xc469, 0x1da1: 0xc489, 0x1da2: 0xc4a9, 0x1da3: 0xc4c9, + 0x1da4: 0xc4e9, 0x1da5: 0xc509, 0x1da6: 0xc529, 0x1da7: 0xc549, 0x1da8: 0xc569, 0x1da9: 0xc589, + 0x1daa: 0xc5a9, 0x1dab: 0xc5c9, 0x1dac: 0xc5e9, 0x1dad: 0xc609, 0x1dae: 0xc629, 0x1daf: 0xc649, + 0x1db0: 0xc669, 0x1db1: 0xc689, 0x1db2: 0xc6a9, 0x1db3: 0xc6c9, 0x1db4: 0xc6e9, 0x1db5: 0xc709, + 0x1db6: 0xc729, 0x1db7: 0xc749, 0x1db8: 0xc769, 0x1db9: 0xc789, 0x1dba: 0xc7a9, 0x1dbb: 0xc7c9, + 0x1dbc: 0x0040, 0x1dbd: 0x0040, 0x1dbe: 0x0040, 0x1dbf: 0x0040, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0xcaf9, 0x1dc1: 0xcb19, 0x1dc2: 0xcb39, 0x1dc3: 0x8b1d, 0x1dc4: 0xcb59, 0x1dc5: 0xcb79, + 0x1dc6: 0xcb99, 0x1dc7: 0xcbb9, 0x1dc8: 0xcbd9, 0x1dc9: 0xcbf9, 0x1dca: 0xcc19, 0x1dcb: 0xcc39, + 0x1dcc: 0xcc59, 0x1dcd: 0x8b3d, 0x1dce: 0xcc79, 0x1dcf: 0xcc99, 0x1dd0: 0xccb9, 0x1dd1: 0xccd9, + 0x1dd2: 0x8b5d, 0x1dd3: 0xccf9, 0x1dd4: 0xcd19, 0x1dd5: 0xc429, 0x1dd6: 0x8b7d, 0x1dd7: 0xcd39, + 0x1dd8: 0xcd59, 0x1dd9: 0xcd79, 0x1dda: 0xcd99, 0x1ddb: 0xcdb9, 0x1ddc: 0x8b9d, 0x1ddd: 0xcdd9, + 0x1dde: 0xcdf9, 0x1ddf: 0xce19, 0x1de0: 0xce39, 0x1de1: 0xce59, 0x1de2: 0xc789, 0x1de3: 0xce79, + 0x1de4: 0xce99, 0x1de5: 0xceb9, 0x1de6: 0xced9, 0x1de7: 0xcef9, 0x1de8: 0xcf19, 0x1de9: 0xcf39, + 0x1dea: 0xcf59, 0x1deb: 0xcf79, 0x1dec: 0xcf99, 0x1ded: 0xcfb9, 0x1dee: 0xcfd9, 0x1def: 0xcff9, + 0x1df0: 0xd019, 0x1df1: 0xd039, 0x1df2: 0xd039, 0x1df3: 0xd039, 0x1df4: 0x8bbd, 0x1df5: 0xd059, + 0x1df6: 0xd079, 0x1df7: 0xd099, 0x1df8: 0x8bdd, 0x1df9: 0xd0b9, 0x1dfa: 0xd0d9, 0x1dfb: 0xd0f9, + 0x1dfc: 0xd119, 0x1dfd: 0xd139, 0x1dfe: 0xd159, 0x1dff: 0xd179, + // Block 0x78, offset 0x1e00 + 0x1e00: 0xd199, 0x1e01: 0xd1b9, 0x1e02: 0xd1d9, 0x1e03: 0xd1f9, 0x1e04: 0xd219, 0x1e05: 0xd239, + 0x1e06: 0xd239, 0x1e07: 0xd259, 0x1e08: 0xd279, 0x1e09: 0xd299, 0x1e0a: 0xd2b9, 0x1e0b: 0xd2d9, + 0x1e0c: 0xd2f9, 0x1e0d: 0xd319, 0x1e0e: 0xd339, 0x1e0f: 0xd359, 0x1e10: 0xd379, 0x1e11: 0xd399, + 0x1e12: 0xd3b9, 0x1e13: 0xd3d9, 0x1e14: 0xd3f9, 0x1e15: 0xd419, 0x1e16: 0xd439, 0x1e17: 0xd459, + 0x1e18: 0xd479, 0x1e19: 0x8bfd, 0x1e1a: 0xd499, 0x1e1b: 0xd4b9, 0x1e1c: 0xd4d9, 0x1e1d: 0xc309, + 0x1e1e: 0xd4f9, 0x1e1f: 0xd519, 0x1e20: 0x8c1d, 0x1e21: 0x8c3d, 0x1e22: 0xd539, 0x1e23: 0xd559, + 0x1e24: 0xd579, 0x1e25: 0xd599, 0x1e26: 0xd5b9, 0x1e27: 0xd5d9, 0x1e28: 0x2040, 0x1e29: 0xd5f9, + 0x1e2a: 0xd619, 0x1e2b: 0xd619, 0x1e2c: 0x8c5d, 0x1e2d: 0xd639, 0x1e2e: 0xd659, 0x1e2f: 0xd679, + 0x1e30: 0xd699, 0x1e31: 0x8c7d, 0x1e32: 0xd6b9, 0x1e33: 0xd6d9, 0x1e34: 0x2040, 0x1e35: 0xd6f9, + 0x1e36: 0xd719, 0x1e37: 0xd739, 0x1e38: 0xd759, 0x1e39: 0xd779, 0x1e3a: 0xd799, 0x1e3b: 0x8c9d, + 0x1e3c: 0xd7b9, 0x1e3d: 0x8cbd, 0x1e3e: 0xd7d9, 0x1e3f: 0xd7f9, + // Block 0x79, offset 0x1e40 + 0x1e40: 0xd819, 0x1e41: 0xd839, 0x1e42: 0xd859, 0x1e43: 0xd879, 0x1e44: 0xd899, 0x1e45: 0xd8b9, + 0x1e46: 0xd8d9, 0x1e47: 0xd8f9, 0x1e48: 0xd919, 0x1e49: 0x8cdd, 0x1e4a: 0xd939, 0x1e4b: 0xd959, + 0x1e4c: 0xd979, 0x1e4d: 0xd999, 0x1e4e: 0xd9b9, 0x1e4f: 0x8cfd, 0x1e50: 0xd9d9, 0x1e51: 0x8d1d, + 0x1e52: 0x8d3d, 0x1e53: 0xd9f9, 0x1e54: 0xda19, 0x1e55: 0xda19, 0x1e56: 0xda39, 0x1e57: 0x8d5d, + 0x1e58: 0x8d7d, 0x1e59: 0xda59, 0x1e5a: 0xda79, 0x1e5b: 0xda99, 0x1e5c: 0xdab9, 0x1e5d: 0xdad9, + 0x1e5e: 0xdaf9, 0x1e5f: 0xdb19, 0x1e60: 0xdb39, 0x1e61: 0xdb59, 0x1e62: 0xdb79, 0x1e63: 0xdb99, + 0x1e64: 0x8d9d, 0x1e65: 0xdbb9, 0x1e66: 0xdbd9, 0x1e67: 0xdbf9, 0x1e68: 0xdc19, 0x1e69: 0xdbf9, + 0x1e6a: 0xdc39, 0x1e6b: 0xdc59, 0x1e6c: 0xdc79, 0x1e6d: 0xdc99, 0x1e6e: 0xdcb9, 0x1e6f: 0xdcd9, + 0x1e70: 0xdcf9, 0x1e71: 0xdd19, 0x1e72: 0xdd39, 0x1e73: 0xdd59, 0x1e74: 0xdd79, 0x1e75: 0xdd99, + 0x1e76: 0xddb9, 0x1e77: 0xddd9, 0x1e78: 0x8dbd, 0x1e79: 0xddf9, 0x1e7a: 0xde19, 0x1e7b: 0xde39, + 0x1e7c: 0xde59, 0x1e7d: 0xde79, 0x1e7e: 0x8ddd, 0x1e7f: 0xde99, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0xe599, 0x1e81: 0xe5b9, 0x1e82: 0xe5d9, 0x1e83: 0xe5f9, 0x1e84: 0xe619, 0x1e85: 0xe639, + 0x1e86: 0x8efd, 0x1e87: 0xe659, 0x1e88: 0xe679, 0x1e89: 0xe699, 0x1e8a: 0xe6b9, 0x1e8b: 0xe6d9, + 0x1e8c: 0xe6f9, 0x1e8d: 0x8f1d, 0x1e8e: 0xe719, 0x1e8f: 0xe739, 0x1e90: 0x8f3d, 0x1e91: 0x8f5d, + 0x1e92: 0xe759, 0x1e93: 0xe779, 0x1e94: 0xe799, 0x1e95: 0xe7b9, 0x1e96: 0xe7d9, 0x1e97: 0xe7f9, + 0x1e98: 0xe819, 0x1e99: 0xe839, 0x1e9a: 0xe859, 0x1e9b: 0x8f7d, 0x1e9c: 0xe879, 0x1e9d: 0x8f9d, + 0x1e9e: 0xe899, 0x1e9f: 0x2040, 0x1ea0: 0xe8b9, 0x1ea1: 0xe8d9, 0x1ea2: 0xe8f9, 0x1ea3: 0x8fbd, + 0x1ea4: 0xe919, 0x1ea5: 0xe939, 0x1ea6: 0x8fdd, 0x1ea7: 0x8ffd, 0x1ea8: 0xe959, 0x1ea9: 0xe979, + 0x1eaa: 0xe999, 0x1eab: 0xe9b9, 0x1eac: 0xe9d9, 0x1ead: 0xe9d9, 0x1eae: 0xe9f9, 0x1eaf: 0xea19, + 0x1eb0: 0xea39, 0x1eb1: 0xea59, 0x1eb2: 0xea79, 0x1eb3: 0xea99, 0x1eb4: 0xeab9, 0x1eb5: 0x901d, + 0x1eb6: 0xead9, 0x1eb7: 0x903d, 0x1eb8: 0xeaf9, 0x1eb9: 0x905d, 0x1eba: 0xeb19, 0x1ebb: 0x907d, + 0x1ebc: 0x909d, 0x1ebd: 0x90bd, 0x1ebe: 0xeb39, 0x1ebf: 0xeb59, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xeb79, 0x1ec1: 0x90dd, 0x1ec2: 0x90fd, 0x1ec3: 0x911d, 0x1ec4: 0x913d, 0x1ec5: 0xeb99, + 0x1ec6: 0xebb9, 0x1ec7: 0xebb9, 0x1ec8: 0xebd9, 0x1ec9: 0xebf9, 0x1eca: 0xec19, 0x1ecb: 0xec39, + 0x1ecc: 0xec59, 0x1ecd: 0x915d, 0x1ece: 0xec79, 0x1ecf: 0xec99, 0x1ed0: 0xecb9, 0x1ed1: 0xecd9, + 0x1ed2: 0x917d, 0x1ed3: 0xecf9, 0x1ed4: 0x919d, 0x1ed5: 0x91bd, 0x1ed6: 0xed19, 0x1ed7: 0xed39, + 0x1ed8: 0xed59, 0x1ed9: 0xed79, 0x1eda: 0xed99, 0x1edb: 0xedb9, 0x1edc: 0x91dd, 0x1edd: 0x91fd, + 0x1ede: 0x921d, 0x1edf: 0x2040, 0x1ee0: 0xedd9, 0x1ee1: 0x923d, 0x1ee2: 0xedf9, 0x1ee3: 0xee19, + 0x1ee4: 0xee39, 0x1ee5: 0x925d, 0x1ee6: 0xee59, 0x1ee7: 0xee79, 0x1ee8: 0xee99, 0x1ee9: 0xeeb9, + 0x1eea: 0xeed9, 0x1eeb: 0x927d, 0x1eec: 0xeef9, 0x1eed: 0xef19, 0x1eee: 0xef39, 0x1eef: 0xef59, + 0x1ef0: 0xef79, 0x1ef1: 0xef99, 0x1ef2: 0x929d, 0x1ef3: 0x92bd, 0x1ef4: 0xefb9, 0x1ef5: 0x92dd, + 0x1ef6: 0xefd9, 0x1ef7: 0x92fd, 0x1ef8: 0xeff9, 0x1ef9: 0xf019, 0x1efa: 0xf039, 0x1efb: 0x931d, + 0x1efc: 0x933d, 0x1efd: 0xf059, 0x1efe: 0x935d, 0x1eff: 0xf079, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0xf6b9, 0x1f01: 0xf6d9, 0x1f02: 0xf6f9, 0x1f03: 0xf719, 0x1f04: 0xf739, 0x1f05: 0x951d, + 0x1f06: 0xf759, 0x1f07: 0xf779, 0x1f08: 0xf799, 0x1f09: 0xf7b9, 0x1f0a: 0xf7d9, 0x1f0b: 0x953d, + 0x1f0c: 0x955d, 0x1f0d: 0xf7f9, 0x1f0e: 0xf819, 0x1f0f: 0xf839, 0x1f10: 0xf859, 0x1f11: 0xf879, + 0x1f12: 0xf899, 0x1f13: 0x957d, 0x1f14: 0xf8b9, 0x1f15: 0xf8d9, 0x1f16: 0xf8f9, 0x1f17: 0xf919, + 0x1f18: 0x959d, 0x1f19: 0x95bd, 0x1f1a: 0xf939, 0x1f1b: 0xf959, 0x1f1c: 0xf979, 0x1f1d: 0x95dd, + 0x1f1e: 0xf999, 0x1f1f: 0xf9b9, 0x1f20: 0x6815, 0x1f21: 0x95fd, 0x1f22: 0xf9d9, 0x1f23: 0xf9f9, + 0x1f24: 0xfa19, 0x1f25: 0x961d, 0x1f26: 0xfa39, 0x1f27: 0xfa59, 0x1f28: 0xfa79, 0x1f29: 0xfa99, + 0x1f2a: 0xfab9, 0x1f2b: 0xfad9, 0x1f2c: 0xfaf9, 0x1f2d: 0x963d, 0x1f2e: 0xfb19, 0x1f2f: 0xfb39, + 0x1f30: 0xfb59, 0x1f31: 0x965d, 0x1f32: 0xfb79, 0x1f33: 0xfb99, 0x1f34: 0xfbb9, 0x1f35: 0xfbd9, + 0x1f36: 0x7b35, 0x1f37: 0x967d, 0x1f38: 0xfbf9, 0x1f39: 0xfc19, 0x1f3a: 0xfc39, 0x1f3b: 0x969d, + 0x1f3c: 0xfc59, 0x1f3d: 0x96bd, 0x1f3e: 0xfc79, 0x1f3f: 0xfc79, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xfc99, 0x1f41: 0x96dd, 0x1f42: 0xfcb9, 0x1f43: 0xfcd9, 0x1f44: 0xfcf9, 0x1f45: 0xfd19, + 0x1f46: 0xfd39, 0x1f47: 0xfd59, 0x1f48: 0xfd79, 0x1f49: 0x96fd, 0x1f4a: 0xfd99, 0x1f4b: 0xfdb9, + 0x1f4c: 0xfdd9, 0x1f4d: 0xfdf9, 0x1f4e: 0xfe19, 0x1f4f: 0xfe39, 0x1f50: 0x971d, 0x1f51: 0xfe59, + 0x1f52: 0x973d, 0x1f53: 0x975d, 0x1f54: 0x977d, 0x1f55: 0xfe79, 0x1f56: 0xfe99, 0x1f57: 0xfeb9, + 0x1f58: 0xfed9, 0x1f59: 0xfef9, 0x1f5a: 0xff19, 0x1f5b: 0xff39, 0x1f5c: 0xff59, 0x1f5d: 0x979d, + 0x1f5e: 0x0040, 0x1f5f: 0x0040, 0x1f60: 0x0040, 0x1f61: 0x0040, 0x1f62: 0x0040, 0x1f63: 0x0040, + 0x1f64: 0x0040, 0x1f65: 0x0040, 0x1f66: 0x0040, 0x1f67: 0x0040, 0x1f68: 0x0040, 0x1f69: 0x0040, + 0x1f6a: 0x0040, 0x1f6b: 0x0040, 0x1f6c: 0x0040, 0x1f6d: 0x0040, 0x1f6e: 0x0040, 0x1f6f: 0x0040, + 0x1f70: 0x0040, 0x1f71: 0x0040, 0x1f72: 0x0040, 0x1f73: 0x0040, 0x1f74: 0x0040, 0x1f75: 0x0040, + 0x1f76: 0x0040, 0x1f77: 0x0040, 0x1f78: 0x0040, 0x1f79: 0x0040, 0x1f7a: 0x0040, 0x1f7b: 0x0040, + 0x1f7c: 0x0040, 0x1f7d: 0x0040, 0x1f7e: 0x0040, 0x1f7f: 0x0040, +} + +// idnaIndex: 35 blocks, 2240 entries, 4480 bytes +// Block 0 is the zero block. +var idnaIndex = [2240]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x7c, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7d, 0xca: 0x7e, 0xcb: 0x07, 0xcc: 0x7f, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x80, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x81, 0xd6: 0x82, 0xd7: 0x83, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x84, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x85, 0xde: 0x86, 0xdf: 0x87, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, + 0xf0: 0x1c, 0xf1: 0x1d, 0xf2: 0x1d, 0xf3: 0x1f, 0xf4: 0x20, + // Block 0x4, offset 0x100 + 0x120: 0x88, 0x121: 0x89, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x13, 0x126: 0x14, 0x127: 0x15, + 0x128: 0x16, 0x129: 0x17, 0x12a: 0x18, 0x12b: 0x19, 0x12c: 0x1a, 0x12d: 0x1b, 0x12e: 0x1c, 0x12f: 0x8d, + 0x130: 0x8e, 0x131: 0x1d, 0x132: 0x1e, 0x133: 0x1f, 0x134: 0x8f, 0x135: 0x20, 0x136: 0x90, 0x137: 0x91, + 0x138: 0x92, 0x139: 0x93, 0x13a: 0x21, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x22, 0x13e: 0x23, 0x13f: 0x96, + // Block 0x5, offset 0x140 + 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, + 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, + 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, + 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, + 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, + 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, + 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x24, 0x175: 0x25, 0x176: 0x26, 0x177: 0xc3, + 0x178: 0x27, 0x179: 0x27, 0x17a: 0x28, 0x17b: 0x27, 0x17c: 0xc4, 0x17d: 0x29, 0x17e: 0x2a, 0x17f: 0x2b, + // Block 0x6, offset 0x180 + 0x180: 0x2c, 0x181: 0x2d, 0x182: 0x2e, 0x183: 0xc5, 0x184: 0x2f, 0x185: 0x30, 0x186: 0xc6, 0x187: 0x9b, + 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0xca, + 0x190: 0xcb, 0x191: 0x31, 0x192: 0x32, 0x193: 0x33, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, + 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, + 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, + 0x1a8: 0xcc, 0x1a9: 0xcd, 0x1aa: 0x9b, 0x1ab: 0xce, 0x1ac: 0x9b, 0x1ad: 0xcf, 0x1ae: 0xd0, 0x1af: 0xd1, + 0x1b0: 0xd2, 0x1b1: 0x34, 0x1b2: 0x27, 0x1b3: 0x35, 0x1b4: 0xd3, 0x1b5: 0xd4, 0x1b6: 0xd5, 0x1b7: 0xd6, + 0x1b8: 0xd7, 0x1b9: 0xd8, 0x1ba: 0xd9, 0x1bb: 0xda, 0x1bc: 0xdb, 0x1bd: 0xdc, 0x1be: 0xdd, 0x1bf: 0x36, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x37, 0x1c1: 0xde, 0x1c2: 0xdf, 0x1c3: 0xe0, 0x1c4: 0xe1, 0x1c5: 0x38, 0x1c6: 0x39, 0x1c7: 0xe2, + 0x1c8: 0xe3, 0x1c9: 0x3a, 0x1ca: 0x3b, 0x1cb: 0x3c, 0x1cc: 0x3d, 0x1cd: 0x3e, 0x1ce: 0x3f, 0x1cf: 0x40, + 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, + 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, + 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, + 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, + 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, + 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, + // Block 0x8, offset 0x200 + 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, + 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, + 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, + 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, + 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, + 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, + 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, + 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, + // Block 0x9, offset 0x240 + 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, + 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, + 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, + 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, + 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, + 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, + 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, + 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, + // Block 0xa, offset 0x280 + 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, + 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, + 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, + 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, + 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, + 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, + 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, + 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe4, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, + 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, + 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe5, 0x2d3: 0xe6, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, + 0x2d8: 0xe7, 0x2d9: 0x41, 0x2da: 0x42, 0x2db: 0xe8, 0x2dc: 0x43, 0x2dd: 0x44, 0x2de: 0x45, 0x2df: 0xe9, + 0x2e0: 0xea, 0x2e1: 0xeb, 0x2e2: 0xec, 0x2e3: 0xed, 0x2e4: 0xee, 0x2e5: 0xef, 0x2e6: 0xf0, 0x2e7: 0xf1, + 0x2e8: 0xf2, 0x2e9: 0xf3, 0x2ea: 0xf4, 0x2eb: 0xf5, 0x2ec: 0xf6, 0x2ed: 0xf7, 0x2ee: 0xf8, 0x2ef: 0xf9, + 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, + 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, + // Block 0xc, offset 0x300 + 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, + 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, + 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, + 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xfa, 0x31f: 0xfb, + // Block 0xd, offset 0x340 + 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, + 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, + 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, + 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, + 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, + 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, + 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, + 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, + // Block 0xe, offset 0x380 + 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, + 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, + 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, + 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, + 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfc, 0x3a5: 0xfd, 0x3a6: 0xfe, 0x3a7: 0xff, + 0x3a8: 0x46, 0x3a9: 0x100, 0x3aa: 0x101, 0x3ab: 0x47, 0x3ac: 0x48, 0x3ad: 0x49, 0x3ae: 0x4a, 0x3af: 0x4b, + 0x3b0: 0x102, 0x3b1: 0x4c, 0x3b2: 0x4d, 0x3b3: 0x4e, 0x3b4: 0x4f, 0x3b5: 0x50, 0x3b6: 0x103, 0x3b7: 0x51, + 0x3b8: 0x52, 0x3b9: 0x53, 0x3ba: 0x54, 0x3bb: 0x55, 0x3bc: 0x56, 0x3bd: 0x57, 0x3be: 0x58, 0x3bf: 0x59, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x104, 0x3c1: 0x105, 0x3c2: 0x9f, 0x3c3: 0x106, 0x3c4: 0x107, 0x3c5: 0x9b, 0x3c6: 0x108, 0x3c7: 0x109, + 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x10a, 0x3cb: 0x10b, 0x3cc: 0x10c, 0x3cd: 0x10d, 0x3ce: 0x10e, 0x3cf: 0x10f, + 0x3d0: 0x110, 0x3d1: 0x9f, 0x3d2: 0x111, 0x3d3: 0x112, 0x3d4: 0x113, 0x3d5: 0x114, 0x3d6: 0xba, 0x3d7: 0xba, + 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x115, 0x3dd: 0x116, 0x3de: 0xba, 0x3df: 0xba, + 0x3e0: 0x117, 0x3e1: 0x118, 0x3e2: 0x119, 0x3e3: 0x11a, 0x3e4: 0x11b, 0x3e5: 0xba, 0x3e6: 0x11c, 0x3e7: 0x11d, + 0x3e8: 0x11e, 0x3e9: 0x11f, 0x3ea: 0x120, 0x3eb: 0x5a, 0x3ec: 0x121, 0x3ed: 0x122, 0x3ee: 0x5b, 0x3ef: 0xba, + 0x3f0: 0x123, 0x3f1: 0x124, 0x3f2: 0x125, 0x3f3: 0x126, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, + 0x3f8: 0xba, 0x3f9: 0x127, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba, + // Block 0x10, offset 0x400 + 0x400: 0x128, 0x401: 0x129, 0x402: 0x12a, 0x403: 0x12b, 0x404: 0x12c, 0x405: 0x12d, 0x406: 0x12e, 0x407: 0x12f, + 0x408: 0x130, 0x409: 0xba, 0x40a: 0x131, 0x40b: 0x132, 0x40c: 0x5c, 0x40d: 0x5d, 0x40e: 0xba, 0x40f: 0xba, + 0x410: 0x133, 0x411: 0x134, 0x412: 0x135, 0x413: 0x136, 0x414: 0xba, 0x415: 0xba, 0x416: 0x137, 0x417: 0x138, + 0x418: 0x139, 0x419: 0x13a, 0x41a: 0x13b, 0x41b: 0x13c, 0x41c: 0x13d, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, + 0x420: 0xba, 0x421: 0xba, 0x422: 0x13e, 0x423: 0x13f, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba, + 0x428: 0xba, 0x429: 0xba, 0x42a: 0xba, 0x42b: 0x140, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, + 0x430: 0x141, 0x431: 0x142, 0x432: 0x143, 0x433: 0xba, 0x434: 0xba, 0x435: 0xba, 0x436: 0xba, 0x437: 0xba, + 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba, + // Block 0x11, offset 0x440 + 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, + 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x144, 0x44f: 0xba, + 0x450: 0x9b, 0x451: 0x145, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x146, 0x456: 0xba, 0x457: 0xba, + 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, + 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, + 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, + 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, + 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, + // Block 0x12, offset 0x480 + 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, + 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, + 0x490: 0x147, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, + 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, + 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, + 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, + 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, + 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, + // Block 0x13, offset 0x4c0 + 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, + 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, + 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, + 0x4d8: 0x9f, 0x4d9: 0x148, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, + 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, + 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, + 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, + 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, + // Block 0x14, offset 0x500 + 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, + 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, + 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, + 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, + 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, + 0x528: 0x140, 0x529: 0x149, 0x52a: 0xba, 0x52b: 0x14a, 0x52c: 0x14b, 0x52d: 0x14c, 0x52e: 0x14d, 0x52f: 0xba, + 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, + 0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x14e, 0x53e: 0x14f, 0x53f: 0x150, + // Block 0x15, offset 0x540 + 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, + 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, + 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, + 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x151, + 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, + 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x152, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, + 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, + 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, + // Block 0x16, offset 0x580 + 0x580: 0x153, 0x581: 0xba, 0x582: 0xba, 0x583: 0xba, 0x584: 0xba, 0x585: 0xba, 0x586: 0xba, 0x587: 0xba, + 0x588: 0xba, 0x589: 0xba, 0x58a: 0xba, 0x58b: 0xba, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, + 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, + 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, + 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, + 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, + 0x5b0: 0x9f, 0x5b1: 0x154, 0x5b2: 0x155, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, + 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x156, 0x5c4: 0x157, 0x5c5: 0x158, 0x5c6: 0x159, 0x5c7: 0x15a, + 0x5c8: 0x9b, 0x5c9: 0x15b, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x15c, 0x5ce: 0xba, 0x5cf: 0xba, + 0x5d0: 0x5e, 0x5d1: 0x5f, 0x5d2: 0x60, 0x5d3: 0x61, 0x5d4: 0x62, 0x5d5: 0x63, 0x5d6: 0x64, 0x5d7: 0x65, + 0x5d8: 0x66, 0x5d9: 0x67, 0x5da: 0x68, 0x5db: 0x69, 0x5dc: 0x6a, 0x5dd: 0x6b, 0x5de: 0x6c, 0x5df: 0x6d, + 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, + 0x5e8: 0x15d, 0x5e9: 0x15e, 0x5ea: 0x15f, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, + 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, + 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, + // Block 0x18, offset 0x600 + 0x600: 0x160, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba, + 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, + 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, + 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, + 0x620: 0x123, 0x621: 0x123, 0x622: 0x123, 0x623: 0x161, 0x624: 0x6e, 0x625: 0x162, 0x626: 0xba, 0x627: 0xba, + 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, + 0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, + 0x638: 0x6f, 0x639: 0x70, 0x63a: 0x71, 0x63b: 0x163, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, + // Block 0x19, offset 0x640 + 0x640: 0x164, 0x641: 0x9b, 0x642: 0x165, 0x643: 0x166, 0x644: 0x72, 0x645: 0x73, 0x646: 0x167, 0x647: 0x168, + 0x648: 0x74, 0x649: 0x169, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, + 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, + 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x16a, 0x65c: 0x9b, 0x65d: 0x16b, 0x65e: 0x9b, 0x65f: 0x16c, + 0x660: 0x16d, 0x661: 0x16e, 0x662: 0x16f, 0x663: 0xba, 0x664: 0x170, 0x665: 0x171, 0x666: 0x172, 0x667: 0x173, + 0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, + 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, + 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, + // Block 0x1a, offset 0x680 + 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, + 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, + 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, + 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x174, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, + 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, + 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, + 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, + 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, + 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, + 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, + 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x175, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, + 0x6e0: 0x176, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, + 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, + 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, + 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, + // Block 0x1c, offset 0x700 + 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, + 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, + 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, + 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, + 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, + 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, + 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, + 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x177, 0x73b: 0xba, 0x73c: 0xba, 0x73d: 0xba, 0x73e: 0xba, 0x73f: 0xba, + // Block 0x1d, offset 0x740 + 0x740: 0xba, 0x741: 0xba, 0x742: 0xba, 0x743: 0xba, 0x744: 0xba, 0x745: 0xba, 0x746: 0xba, 0x747: 0xba, + 0x748: 0xba, 0x749: 0xba, 0x74a: 0xba, 0x74b: 0xba, 0x74c: 0xba, 0x74d: 0xba, 0x74e: 0xba, 0x74f: 0xba, + 0x750: 0xba, 0x751: 0xba, 0x752: 0xba, 0x753: 0xba, 0x754: 0xba, 0x755: 0xba, 0x756: 0xba, 0x757: 0xba, + 0x758: 0xba, 0x759: 0xba, 0x75a: 0xba, 0x75b: 0xba, 0x75c: 0xba, 0x75d: 0xba, 0x75e: 0xba, 0x75f: 0xba, + 0x760: 0x75, 0x761: 0x76, 0x762: 0x77, 0x763: 0x178, 0x764: 0x78, 0x765: 0x79, 0x766: 0x179, 0x767: 0x7a, + 0x768: 0x7b, 0x769: 0xba, 0x76a: 0xba, 0x76b: 0xba, 0x76c: 0xba, 0x76d: 0xba, 0x76e: 0xba, 0x76f: 0xba, + 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, + 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, + // Block 0x1e, offset 0x780 + 0x790: 0x0d, 0x791: 0x0e, 0x792: 0x0f, 0x793: 0x10, 0x794: 0x11, 0x795: 0x0b, 0x796: 0x12, 0x797: 0x07, + 0x798: 0x13, 0x799: 0x0b, 0x79a: 0x0b, 0x79b: 0x14, 0x79c: 0x0b, 0x79d: 0x15, 0x79e: 0x16, 0x79f: 0x17, + 0x7a0: 0x07, 0x7a1: 0x07, 0x7a2: 0x07, 0x7a3: 0x07, 0x7a4: 0x07, 0x7a5: 0x07, 0x7a6: 0x07, 0x7a7: 0x07, + 0x7a8: 0x07, 0x7a9: 0x07, 0x7aa: 0x18, 0x7ab: 0x19, 0x7ac: 0x1a, 0x7ad: 0x0b, 0x7ae: 0x0b, 0x7af: 0x1b, + 0x7b0: 0x0b, 0x7b1: 0x0b, 0x7b2: 0x0b, 0x7b3: 0x0b, 0x7b4: 0x0b, 0x7b5: 0x0b, 0x7b6: 0x0b, 0x7b7: 0x0b, + 0x7b8: 0x0b, 0x7b9: 0x0b, 0x7ba: 0x0b, 0x7bb: 0x0b, 0x7bc: 0x0b, 0x7bd: 0x0b, 0x7be: 0x0b, 0x7bf: 0x0b, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x0b, 0x7c1: 0x0b, 0x7c2: 0x0b, 0x7c3: 0x0b, 0x7c4: 0x0b, 0x7c5: 0x0b, 0x7c6: 0x0b, 0x7c7: 0x0b, + 0x7c8: 0x0b, 0x7c9: 0x0b, 0x7ca: 0x0b, 0x7cb: 0x0b, 0x7cc: 0x0b, 0x7cd: 0x0b, 0x7ce: 0x0b, 0x7cf: 0x0b, + 0x7d0: 0x0b, 0x7d1: 0x0b, 0x7d2: 0x0b, 0x7d3: 0x0b, 0x7d4: 0x0b, 0x7d5: 0x0b, 0x7d6: 0x0b, 0x7d7: 0x0b, + 0x7d8: 0x0b, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x0b, 0x7dc: 0x0b, 0x7dd: 0x0b, 0x7de: 0x0b, 0x7df: 0x0b, + 0x7e0: 0x0b, 0x7e1: 0x0b, 0x7e2: 0x0b, 0x7e3: 0x0b, 0x7e4: 0x0b, 0x7e5: 0x0b, 0x7e6: 0x0b, 0x7e7: 0x0b, + 0x7e8: 0x0b, 0x7e9: 0x0b, 0x7ea: 0x0b, 0x7eb: 0x0b, 0x7ec: 0x0b, 0x7ed: 0x0b, 0x7ee: 0x0b, 0x7ef: 0x0b, + 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, + 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, + // Block 0x20, offset 0x800 + 0x800: 0x17a, 0x801: 0x17b, 0x802: 0xba, 0x803: 0xba, 0x804: 0x17c, 0x805: 0x17c, 0x806: 0x17c, 0x807: 0x17d, + 0x808: 0xba, 0x809: 0xba, 0x80a: 0xba, 0x80b: 0xba, 0x80c: 0xba, 0x80d: 0xba, 0x80e: 0xba, 0x80f: 0xba, + 0x810: 0xba, 0x811: 0xba, 0x812: 0xba, 0x813: 0xba, 0x814: 0xba, 0x815: 0xba, 0x816: 0xba, 0x817: 0xba, + 0x818: 0xba, 0x819: 0xba, 0x81a: 0xba, 0x81b: 0xba, 0x81c: 0xba, 0x81d: 0xba, 0x81e: 0xba, 0x81f: 0xba, + 0x820: 0xba, 0x821: 0xba, 0x822: 0xba, 0x823: 0xba, 0x824: 0xba, 0x825: 0xba, 0x826: 0xba, 0x827: 0xba, + 0x828: 0xba, 0x829: 0xba, 0x82a: 0xba, 0x82b: 0xba, 0x82c: 0xba, 0x82d: 0xba, 0x82e: 0xba, 0x82f: 0xba, + 0x830: 0xba, 0x831: 0xba, 0x832: 0xba, 0x833: 0xba, 0x834: 0xba, 0x835: 0xba, 0x836: 0xba, 0x837: 0xba, + 0x838: 0xba, 0x839: 0xba, 0x83a: 0xba, 0x83b: 0xba, 0x83c: 0xba, 0x83d: 0xba, 0x83e: 0xba, 0x83f: 0xba, + // Block 0x21, offset 0x840 + 0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b, + 0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b, + 0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b, + 0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b, + 0x860: 0x1e, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b, + 0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b, + 0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b, + 0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b, + // Block 0x22, offset 0x880 + 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, + 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, +} + +// idnaSparseOffset: 258 entries, 516 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x93, 0x98, 0xa1, 0xb1, 0xbf, 0xcc, 0xd8, 0xe9, 0xf3, 0xfa, 0x107, 0x118, 0x11f, 0x12a, 0x139, 0x147, 0x151, 0x153, 0x158, 0x15b, 0x15e, 0x160, 0x16c, 0x177, 0x17f, 0x185, 0x18b, 0x190, 0x195, 0x198, 0x19c, 0x1a2, 0x1a7, 0x1b3, 0x1bd, 0x1c3, 0x1d4, 0x1de, 0x1e1, 0x1e9, 0x1ec, 0x1f9, 0x201, 0x205, 0x20c, 0x214, 0x224, 0x230, 0x232, 0x23c, 0x248, 0x254, 0x260, 0x268, 0x26d, 0x277, 0x288, 0x28c, 0x297, 0x29b, 0x2a4, 0x2ac, 0x2b2, 0x2b7, 0x2ba, 0x2bd, 0x2c1, 0x2c7, 0x2cb, 0x2cf, 0x2d5, 0x2dc, 0x2e2, 0x2ea, 0x2f1, 0x2fc, 0x306, 0x30a, 0x30d, 0x313, 0x317, 0x319, 0x31c, 0x31e, 0x321, 0x32b, 0x32e, 0x33d, 0x341, 0x346, 0x349, 0x34d, 0x352, 0x357, 0x35d, 0x363, 0x372, 0x378, 0x37c, 0x38b, 0x390, 0x398, 0x3a2, 0x3ad, 0x3b5, 0x3c6, 0x3cf, 0x3df, 0x3ec, 0x3f6, 0x3fb, 0x408, 0x40c, 0x411, 0x413, 0x417, 0x419, 0x41d, 0x426, 0x42c, 0x430, 0x440, 0x44a, 0x44f, 0x452, 0x458, 0x45f, 0x464, 0x468, 0x46e, 0x473, 0x47c, 0x481, 0x487, 0x48e, 0x495, 0x49c, 0x4a0, 0x4a5, 0x4a8, 0x4ad, 0x4b9, 0x4bf, 0x4c4, 0x4cb, 0x4d3, 0x4d8, 0x4dc, 0x4ec, 0x4f3, 0x4f7, 0x4fb, 0x502, 0x504, 0x507, 0x50a, 0x50e, 0x512, 0x518, 0x521, 0x52d, 0x534, 0x53d, 0x545, 0x54c, 0x55a, 0x567, 0x574, 0x57d, 0x581, 0x58f, 0x597, 0x5a2, 0x5ab, 0x5b1, 0x5b9, 0x5c2, 0x5cc, 0x5cf, 0x5db, 0x5de, 0x5e3, 0x5e6, 0x5f0, 0x5f9, 0x605, 0x608, 0x60d, 0x610, 0x613, 0x616, 0x61d, 0x624, 0x628, 0x633, 0x636, 0x63c, 0x641, 0x645, 0x648, 0x64b, 0x64e, 0x653, 0x65d, 0x660, 0x664, 0x673, 0x67f, 0x683, 0x688, 0x68d, 0x691, 0x696, 0x69f, 0x6aa, 0x6b0, 0x6b8, 0x6bc, 0x6c0, 0x6c6, 0x6cc, 0x6d1, 0x6d4, 0x6e2, 0x6e9, 0x6ec, 0x6ef, 0x6f3, 0x6f9, 0x6fe, 0x708, 0x70d, 0x710, 0x713, 0x716, 0x719, 0x71d, 0x720, 0x730, 0x741, 0x746, 0x748, 0x74a} + +// idnaSparseValues: 1869 entries, 7476 bytes +var idnaSparseValues = [1869]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x07}, + {value: 0xe105, lo: 0x80, hi: 0x96}, + {value: 0x0018, lo: 0x97, hi: 0x97}, + {value: 0xe105, lo: 0x98, hi: 0x9e}, + {value: 0x001f, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbf}, + // Block 0x1, offset 0x8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0xe01d, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0335, lo: 0x83, hi: 0x83}, + {value: 0x034d, lo: 0x84, hi: 0x84}, + {value: 0x0365, lo: 0x85, hi: 0x85}, + {value: 0xe00d, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0xe00d, lo: 0x88, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x89}, + {value: 0xe00d, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe00d, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0x8d}, + {value: 0xe00d, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0xbf}, + // Block 0x2, offset 0x19 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0249, lo: 0xb0, hi: 0xb0}, + {value: 0x037d, lo: 0xb1, hi: 0xb1}, + {value: 0x0259, lo: 0xb2, hi: 0xb2}, + {value: 0x0269, lo: 0xb3, hi: 0xb3}, + {value: 0x034d, lo: 0xb4, hi: 0xb4}, + {value: 0x0395, lo: 0xb5, hi: 0xb5}, + {value: 0xe1bd, lo: 0xb6, hi: 0xb6}, + {value: 0x0279, lo: 0xb7, hi: 0xb7}, + {value: 0x0289, lo: 0xb8, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbf}, + // Block 0x3, offset 0x25 + {value: 0x0000, lo: 0x01}, + {value: 0x3308, lo: 0x80, hi: 0xbf}, + // Block 0x4, offset 0x27 + {value: 0x0000, lo: 0x04}, + {value: 0x03f5, lo: 0x80, hi: 0x8f}, + {value: 0xe105, lo: 0x90, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x5, offset 0x2c + {value: 0x0000, lo: 0x07}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x0545, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x0008, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x6, offset 0x34 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0401, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x88}, + {value: 0x0018, lo: 0x89, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x7, offset 0x3f + {value: 0x0000, lo: 0x0b}, + {value: 0x0818, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x82}, + {value: 0x0818, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x85}, + {value: 0x0818, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0808, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x8, offset 0x4b + {value: 0x0000, lo: 0x03}, + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0c08, lo: 0x88, hi: 0x99}, + {value: 0x0a08, lo: 0x9a, hi: 0xbf}, + // Block 0x9, offset 0x4f + {value: 0x0000, lo: 0x0e}, + {value: 0x3308, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0c08, lo: 0x8d, hi: 0x8d}, + {value: 0x0a08, lo: 0x8e, hi: 0x98}, + {value: 0x0c08, lo: 0x99, hi: 0x9b}, + {value: 0x0a08, lo: 0x9c, hi: 0xaa}, + {value: 0x0c08, lo: 0xab, hi: 0xac}, + {value: 0x0a08, lo: 0xad, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xb5, hi: 0xb7}, + {value: 0x0c08, lo: 0xb8, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbf}, + // Block 0xa, offset 0x5e + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xb, offset 0x63 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0xc, offset 0x6b + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x99}, + {value: 0x0808, lo: 0x9a, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa3}, + {value: 0x0808, lo: 0xa4, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa7}, + {value: 0x0808, lo: 0xa8, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0818, lo: 0xb0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd, offset 0x77 + {value: 0x0000, lo: 0x0d}, + {value: 0x0c08, lo: 0x80, hi: 0x80}, + {value: 0x0a08, lo: 0x81, hi: 0x85}, + {value: 0x0c08, lo: 0x86, hi: 0x87}, + {value: 0x0a08, lo: 0x88, hi: 0x88}, + {value: 0x0c08, lo: 0x89, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0x93}, + {value: 0x0c08, lo: 0x94, hi: 0x94}, + {value: 0x0a08, lo: 0x95, hi: 0x95}, + {value: 0x0808, lo: 0x96, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xe, offset 0x85 + {value: 0x0000, lo: 0x0d}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0a08, lo: 0xa0, hi: 0xa9}, + {value: 0x0c08, lo: 0xaa, hi: 0xac}, + {value: 0x0808, lo: 0xad, hi: 0xad}, + {value: 0x0c08, lo: 0xae, hi: 0xae}, + {value: 0x0a08, lo: 0xaf, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb2}, + {value: 0x0a08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0a08, lo: 0xb6, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xf, offset 0x93 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa1}, + {value: 0x0840, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xbf}, + // Block 0x10, offset 0x98 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x11, offset 0xa1 + {value: 0x0000, lo: 0x0f}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x85}, + {value: 0x3008, lo: 0x86, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8c}, + {value: 0x3b08, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x12, offset 0xb1 + {value: 0x0000, lo: 0x0d}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x13, offset 0xbf + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x14, offset 0xcc + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x15, offset 0xd8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x89}, + {value: 0x3b08, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x3008, lo: 0x98, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x16, offset 0xe9 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb2}, + {value: 0x08f1, lo: 0xb3, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb9}, + {value: 0x3b08, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0x17, offset 0xf3 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x8e}, + {value: 0x0018, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0xbf}, + // Block 0x18, offset 0xfa + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0961, lo: 0x9c, hi: 0x9c}, + {value: 0x0999, lo: 0x9d, hi: 0x9d}, + {value: 0x0008, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x19, offset 0x107 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe03d, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x1a, offset 0x118 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0x1b, offset 0x11f + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x1c, offset 0x12a + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xa1}, + {value: 0x3008, lo: 0xa2, hi: 0xa4}, + {value: 0x0008, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xbf}, + // Block 0x1d, offset 0x139 + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x8c}, + {value: 0x3308, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x3008, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x1e, offset 0x147 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x86}, + {value: 0x055d, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8c}, + {value: 0x055d, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0xe105, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0x1f, offset 0x151 + {value: 0x0000, lo: 0x01}, + {value: 0x0018, lo: 0x80, hi: 0xbf}, + // Block 0x20, offset 0x153 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa0}, + {value: 0x2018, lo: 0xa1, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x21, offset 0x158 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa7}, + {value: 0x2018, lo: 0xa8, hi: 0xbf}, + // Block 0x22, offset 0x15b + {value: 0x0000, lo: 0x02}, + {value: 0x2018, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0xbf}, + // Block 0x23, offset 0x15e + {value: 0x0000, lo: 0x01}, + {value: 0x0008, lo: 0x80, hi: 0xbf}, + // Block 0x24, offset 0x160 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x25, offset 0x16c + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x26, offset 0x177 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x27, offset 0x17f + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x28, offset 0x185 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x29, offset 0x18b + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2a, offset 0x190 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x2b, offset 0x195 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x2c, offset 0x198 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xbf}, + // Block 0x2d, offset 0x19c + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2e, offset 0x1a2 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x2f, offset 0x1a7 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x3b08, lo: 0x94, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x30, offset 0x1b3 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x31, offset 0x1bd + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xb3}, + {value: 0x3340, lo: 0xb4, hi: 0xb5}, + {value: 0x3008, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x32, offset 0x1c3 + {value: 0x0000, lo: 0x10}, + {value: 0x3008, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x91}, + {value: 0x3b08, lo: 0x92, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0x93}, + {value: 0x0018, lo: 0x94, hi: 0x96}, + {value: 0x0008, lo: 0x97, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x33, offset 0x1d4 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x86}, + {value: 0x0218, lo: 0x87, hi: 0x87}, + {value: 0x0018, lo: 0x88, hi: 0x8a}, + {value: 0x33c0, lo: 0x8b, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0208, lo: 0xa0, hi: 0xbf}, + // Block 0x34, offset 0x1de + {value: 0x0000, lo: 0x02}, + {value: 0x0208, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x35, offset 0x1e1 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0208, lo: 0x87, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xa9}, + {value: 0x0208, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x36, offset 0x1e9 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0x37, offset 0x1ec + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x38, offset 0x1f9 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x39, offset 0x201 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x3a, offset 0x205 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0028, lo: 0x9a, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xbf}, + // Block 0x3b, offset 0x20c + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x3308, lo: 0x97, hi: 0x98}, + {value: 0x3008, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x3c, offset 0x214 + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x94}, + {value: 0x3008, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xac}, + {value: 0x3008, lo: 0xad, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x224 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xbd}, + {value: 0x3318, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x3e, offset 0x230 + {value: 0x0000, lo: 0x01}, + {value: 0x0040, lo: 0x80, hi: 0xbf}, + // Block 0x3f, offset 0x232 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3008, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x40, offset 0x23c + {value: 0x0000, lo: 0x0b}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x3808, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x41, offset 0x248 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3808, lo: 0xaa, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xbf}, + // Block 0x42, offset 0x254 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3008, lo: 0xaa, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3808, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x43, offset 0x260 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x3008, lo: 0xa4, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbf}, + // Block 0x44, offset 0x268 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x45, offset 0x26d + {value: 0x0000, lo: 0x09}, + {value: 0x0e29, lo: 0x80, hi: 0x80}, + {value: 0x0e41, lo: 0x81, hi: 0x81}, + {value: 0x0e59, lo: 0x82, hi: 0x82}, + {value: 0x0e71, lo: 0x83, hi: 0x83}, + {value: 0x0e89, lo: 0x84, hi: 0x85}, + {value: 0x0ea1, lo: 0x86, hi: 0x86}, + {value: 0x0eb9, lo: 0x87, hi: 0x87}, + {value: 0x057d, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0x46, offset 0x277 + {value: 0x0000, lo: 0x10}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x92}, + {value: 0x0018, lo: 0x93, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa8}, + {value: 0x0008, lo: 0xa9, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x47, offset 0x288 + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0x48, offset 0x28c + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x87}, + {value: 0xe045, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0xe045, lo: 0x98, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0xe045, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbf}, + // Block 0x49, offset 0x297 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x3318, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbf}, + // Block 0x4a, offset 0x29b + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x24c1, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x4b, offset 0x2a4 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x24f1, lo: 0xac, hi: 0xac}, + {value: 0x2529, lo: 0xad, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xae}, + {value: 0x2579, lo: 0xaf, hi: 0xaf}, + {value: 0x25b1, lo: 0xb0, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0x4c, offset 0x2ac + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x9f}, + {value: 0x0080, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xad}, + {value: 0x0080, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x4d, offset 0x2b2 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa8}, + {value: 0x09c5, lo: 0xa9, hi: 0xa9}, + {value: 0x09e5, lo: 0xaa, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xbf}, + // Block 0x4e, offset 0x2b7 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x4f, offset 0x2ba + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0x50, offset 0x2bd + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x28c1, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x51, offset 0x2c1 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0e66, lo: 0xb4, hi: 0xb4}, + {value: 0x292a, lo: 0xb5, hi: 0xb5}, + {value: 0x0e86, lo: 0xb6, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x52, offset 0x2c7 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x9b}, + {value: 0x2941, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0xbf}, + // Block 0x53, offset 0x2cb + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x54, offset 0x2cf + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0018, lo: 0xbd, hi: 0xbf}, + // Block 0x55, offset 0x2d5 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0xab}, + {value: 0x0018, lo: 0xac, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x56, offset 0x2dc + {value: 0x0000, lo: 0x05}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x03f5, lo: 0x90, hi: 0x9f}, + {value: 0x0ea5, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x57, offset 0x2e2 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x58, offset 0x2ea + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xae}, + {value: 0xe075, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0x59, offset 0x2f1 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x5a, offset 0x2fc + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xbf}, + // Block 0x5b, offset 0x306 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x5c, offset 0x30a + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0xbf}, + // Block 0x5d, offset 0x30d + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9e}, + {value: 0x0edd, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x5e, offset 0x313 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb2}, + {value: 0x0efd, lo: 0xb3, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x5f, offset 0x317 + {value: 0x0020, lo: 0x01}, + {value: 0x0f1d, lo: 0x80, hi: 0xbf}, + // Block 0x60, offset 0x319 + {value: 0x0020, lo: 0x02}, + {value: 0x171d, lo: 0x80, hi: 0x8f}, + {value: 0x18fd, lo: 0x90, hi: 0xbf}, + // Block 0x61, offset 0x31c + {value: 0x0020, lo: 0x01}, + {value: 0x1efd, lo: 0x80, hi: 0xbf}, + // Block 0x62, offset 0x31e + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x63, offset 0x321 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9a}, + {value: 0x29e2, lo: 0x9b, hi: 0x9b}, + {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9e}, + {value: 0x2a31, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x64, offset 0x32b + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbe}, + {value: 0x2a69, lo: 0xbf, hi: 0xbf}, + // Block 0x65, offset 0x32e + {value: 0x0000, lo: 0x0e}, + {value: 0x0040, lo: 0x80, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xb0}, + {value: 0x2a1d, lo: 0xb1, hi: 0xb1}, + {value: 0x2a3d, lo: 0xb2, hi: 0xb2}, + {value: 0x2a5d, lo: 0xb3, hi: 0xb3}, + {value: 0x2a7d, lo: 0xb4, hi: 0xb4}, + {value: 0x2a5d, lo: 0xb5, hi: 0xb5}, + {value: 0x2a9d, lo: 0xb6, hi: 0xb6}, + {value: 0x2abd, lo: 0xb7, hi: 0xb7}, + {value: 0x2add, lo: 0xb8, hi: 0xb9}, + {value: 0x2afd, lo: 0xba, hi: 0xbb}, + {value: 0x2b1d, lo: 0xbc, hi: 0xbd}, + {value: 0x2afd, lo: 0xbe, hi: 0xbf}, + // Block 0x66, offset 0x33d + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x67, offset 0x341 + {value: 0x0030, lo: 0x04}, + {value: 0x2aa2, lo: 0x80, hi: 0x9d}, + {value: 0x305a, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x30a2, lo: 0xa0, hi: 0xbf}, + // Block 0x68, offset 0x346 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x69, offset 0x349 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x6a, offset 0x34d + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x6b, offset 0x352 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0x6c, offset 0x357 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb1}, + {value: 0x0018, lo: 0xb2, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6d, offset 0x35d + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0xb6}, + {value: 0x0008, lo: 0xb7, hi: 0xb7}, + {value: 0x2009, lo: 0xb8, hi: 0xb8}, + {value: 0x6e89, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xbf}, + // Block 0x6e, offset 0x363 + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x3308, lo: 0x8b, hi: 0x8b}, + {value: 0x0008, lo: 0x8c, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x6f, offset 0x372 + {value: 0x0000, lo: 0x05}, + {value: 0x0208, lo: 0x80, hi: 0xb1}, + {value: 0x0108, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x70, offset 0x378 + {value: 0x0000, lo: 0x03}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xbf}, + // Block 0x71, offset 0x37c + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0008, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x72, offset 0x38b + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x73, offset 0x390 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x91}, + {value: 0x3008, lo: 0x92, hi: 0x92}, + {value: 0x3808, lo: 0x93, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x74, offset 0x398 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb9}, + {value: 0x3008, lo: 0xba, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x75, offset 0x3a2 + {value: 0x0000, lo: 0x0a}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x76, offset 0x3ad + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x77, offset 0x3b5 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8c}, + {value: 0x3008, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbd}, + {value: 0x0008, lo: 0xbe, hi: 0xbf}, + // Block 0x78, offset 0x3c6 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x79, offset 0x3cf + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x9a}, + {value: 0x0008, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3b08, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x7a, offset 0x3df + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x90}, + {value: 0x0008, lo: 0x91, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x7b, offset 0x3ec + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x4465, lo: 0x9c, hi: 0x9c}, + {value: 0x447d, lo: 0x9d, hi: 0x9d}, + {value: 0x2971, lo: 0x9e, hi: 0x9e}, + {value: 0xe06d, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xaf}, + {value: 0x4495, lo: 0xb0, hi: 0xbf}, + // Block 0x7c, offset 0x3f6 + {value: 0x0000, lo: 0x04}, + {value: 0x44b5, lo: 0x80, hi: 0x8f}, + {value: 0x44d5, lo: 0x90, hi: 0x9f}, + {value: 0x44f5, lo: 0xa0, hi: 0xaf}, + {value: 0x44d5, lo: 0xb0, hi: 0xbf}, + // Block 0x7d, offset 0x3fb + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3b08, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x7e, offset 0x408 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x7f, offset 0x40c + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x80, offset 0x411 + {value: 0x0020, lo: 0x01}, + {value: 0x4515, lo: 0x80, hi: 0xbf}, + // Block 0x81, offset 0x413 + {value: 0x0020, lo: 0x03}, + {value: 0x4d15, lo: 0x80, hi: 0x94}, + {value: 0x4ad5, lo: 0x95, hi: 0x95}, + {value: 0x4fb5, lo: 0x96, hi: 0xbf}, + // Block 0x82, offset 0x417 + {value: 0x0020, lo: 0x01}, + {value: 0x54f5, lo: 0x80, hi: 0xbf}, + // Block 0x83, offset 0x419 + {value: 0x0020, lo: 0x03}, + {value: 0x5cf5, lo: 0x80, hi: 0x84}, + {value: 0x5655, lo: 0x85, hi: 0x85}, + {value: 0x5d95, lo: 0x86, hi: 0xbf}, + // Block 0x84, offset 0x41d + {value: 0x0020, lo: 0x08}, + {value: 0x6b55, lo: 0x80, hi: 0x8f}, + {value: 0x6d15, lo: 0x90, hi: 0x90}, + {value: 0x6d55, lo: 0x91, hi: 0xab}, + {value: 0x6ea1, lo: 0xac, hi: 0xac}, + {value: 0x70b5, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x70d5, lo: 0xb0, hi: 0xbf}, + // Block 0x85, offset 0x426 + {value: 0x0020, lo: 0x05}, + {value: 0x72d5, lo: 0x80, hi: 0xad}, + {value: 0x6535, lo: 0xae, hi: 0xae}, + {value: 0x7895, lo: 0xaf, hi: 0xb5}, + {value: 0x6f55, lo: 0xb6, hi: 0xb6}, + {value: 0x7975, lo: 0xb7, hi: 0xbf}, + // Block 0x86, offset 0x42c + {value: 0x0028, lo: 0x03}, + {value: 0x7c21, lo: 0x80, hi: 0x82}, + {value: 0x7be1, lo: 0x83, hi: 0x83}, + {value: 0x7c99, lo: 0x84, hi: 0xbf}, + // Block 0x87, offset 0x430 + {value: 0x0038, lo: 0x0f}, + {value: 0x9db1, lo: 0x80, hi: 0x83}, + {value: 0x9e59, lo: 0x84, hi: 0x85}, + {value: 0x9e91, lo: 0x86, hi: 0x87}, + {value: 0x9ec9, lo: 0x88, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0xa089, lo: 0x92, hi: 0x97}, + {value: 0xa1a1, lo: 0x98, hi: 0x9c}, + {value: 0xa281, lo: 0x9d, hi: 0xb3}, + {value: 0x9d41, lo: 0xb4, hi: 0xb4}, + {value: 0x9db1, lo: 0xb5, hi: 0xb5}, + {value: 0xa789, lo: 0xb6, hi: 0xbb}, + {value: 0xa869, lo: 0xbc, hi: 0xbc}, + {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, + {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, + // Block 0x88, offset 0x440 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0008, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x89, offset 0x44a + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0x8a, offset 0x44f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x8b, offset 0x452 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x8c, offset 0x458 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x8d, offset 0x45f + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x8e, offset 0x464 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x8f, offset 0x468 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x90, offset 0x46e + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x91, offset 0x473 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x92, offset 0x47c + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x93, offset 0x481 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x94, offset 0x487 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x97}, + {value: 0x8ad5, lo: 0x98, hi: 0x9f}, + {value: 0x8aed, lo: 0xa0, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xbf}, + // Block 0x95, offset 0x48e + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x8aed, lo: 0xb0, hi: 0xb7}, + {value: 0x8ad5, lo: 0xb8, hi: 0xbf}, + // Block 0x96, offset 0x495 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x97, offset 0x49c + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x98, offset 0x4a0 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xae}, + {value: 0x0018, lo: 0xaf, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x99, offset 0x4a5 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x9a, offset 0x4a8 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xbf}, + // Block 0x9b, offset 0x4ad + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0808, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0808, lo: 0x8a, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb6}, + {value: 0x0808, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbb}, + {value: 0x0808, lo: 0xbc, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x0808, lo: 0xbf, hi: 0xbf}, + // Block 0x9c, offset 0x4b9 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x96}, + {value: 0x0818, lo: 0x97, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0818, lo: 0xb7, hi: 0xbf}, + // Block 0x9d, offset 0x4bf + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa6}, + {value: 0x0818, lo: 0xa7, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x9e, offset 0x4c4 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x0818, lo: 0xbb, hi: 0xbf}, + // Block 0x9f, offset 0x4cb + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0818, lo: 0x96, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbe}, + {value: 0x0818, lo: 0xbf, hi: 0xbf}, + // Block 0xa0, offset 0x4d3 + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbb}, + {value: 0x0818, lo: 0xbc, hi: 0xbd}, + {value: 0x0808, lo: 0xbe, hi: 0xbf}, + // Block 0xa1, offset 0x4d8 + {value: 0x0000, lo: 0x03}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0xa2, offset 0x4dc + {value: 0x0000, lo: 0x0f}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x94}, + {value: 0x0808, lo: 0x95, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x98}, + {value: 0x0808, lo: 0x99, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xa3, offset 0x4ec + {value: 0x0000, lo: 0x06}, + {value: 0x0818, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0818, lo: 0x90, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xbc}, + {value: 0x0818, lo: 0xbd, hi: 0xbf}, + // Block 0xa4, offset 0x4f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xa5, offset 0x4f7 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb8}, + {value: 0x0018, lo: 0xb9, hi: 0xbf}, + // Block 0xa6, offset 0x4fb + {value: 0x0000, lo: 0x06}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0818, lo: 0x98, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb7}, + {value: 0x0818, lo: 0xb8, hi: 0xbf}, + // Block 0xa7, offset 0x502 + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa8, offset 0x504 + {value: 0x0000, lo: 0x02}, + {value: 0x0808, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xa9, offset 0x507 + {value: 0x0000, lo: 0x02}, + {value: 0x03dd, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xaa, offset 0x50a + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xab, offset 0x50e + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xac, offset 0x512 + {value: 0x0000, lo: 0x05}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xad, offset 0x518 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x91}, + {value: 0x0018, lo: 0x92, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xae, offset 0x521 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbc}, + {value: 0x0340, lo: 0xbd, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0xaf, offset 0x52d + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb0, offset 0x534 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb2}, + {value: 0x3b08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xbf}, + // Block 0xb1, offset 0x53d + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xb2, offset 0x545 + {value: 0x0000, lo: 0x06}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xbe}, + {value: 0x3008, lo: 0xbf, hi: 0xbf}, + // Block 0xb3, offset 0x54c + {value: 0x0000, lo: 0x0d}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xb4, offset 0x55a + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3808, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xb5, offset 0x567 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0008, lo: 0x9f, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xb6, offset 0x574 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x3308, lo: 0x9f, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa9}, + {value: 0x3b08, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb7, offset 0x57d + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xb8, offset 0x581 + {value: 0x0000, lo: 0x0d}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xb9, offset 0x58f + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xba, offset 0x597 + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x85}, + {value: 0x0018, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xbb, offset 0x5a2 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbc, offset 0x5ab + {value: 0x0000, lo: 0x05}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9b}, + {value: 0x3308, lo: 0x9c, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xbd, offset 0x5b1 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbe, offset 0x5b9 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xbf, offset 0x5c2 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb5}, + {value: 0x3808, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0xc0, offset 0x5cc + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0xc1, offset 0x5cf + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0xc2, offset 0x5db + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xbf}, + // Block 0xc3, offset 0x5de + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0xc4, offset 0x5e3 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xc5, offset 0x5e6 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xc6, offset 0x5f0 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xbf}, + // Block 0xc7, offset 0x5f9 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xaa, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xc8, offset 0x605 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xc9, offset 0x608 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xca, offset 0x60d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0xbf}, + // Block 0xcb, offset 0x610 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xbf}, + // Block 0xcc, offset 0x613 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xbf}, + // Block 0xcd, offset 0x616 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xce, offset 0x61d + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xcf, offset 0x624 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0xd0, offset 0x628 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0xd1, offset 0x633 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xd2, offset 0x636 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3008, lo: 0x91, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd3, offset 0x63c + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xd4, offset 0x641 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0xd5, offset 0x645 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xd6, offset 0x648 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xd7, offset 0x64b + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0xbf}, + // Block 0xd8, offset 0x64e + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0xd9, offset 0x653 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x03c0, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xbf}, + // Block 0xda, offset 0x65d + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xdb, offset 0x660 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xbf}, + // Block 0xdc, offset 0x664 + {value: 0x0000, lo: 0x0e}, + {value: 0x0018, lo: 0x80, hi: 0x9d}, + {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, + {value: 0xb601, lo: 0x9f, hi: 0x9f}, + {value: 0xb649, lo: 0xa0, hi: 0xa0}, + {value: 0xb6b1, lo: 0xa1, hi: 0xa1}, + {value: 0xb719, lo: 0xa2, hi: 0xa2}, + {value: 0xb781, lo: 0xa3, hi: 0xa3}, + {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, + {value: 0x3018, lo: 0xa5, hi: 0xa6}, + {value: 0x3318, lo: 0xa7, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xac}, + {value: 0x3018, lo: 0xad, hi: 0xb2}, + {value: 0x0340, lo: 0xb3, hi: 0xba}, + {value: 0x3318, lo: 0xbb, hi: 0xbf}, + // Block 0xdd, offset 0x673 + {value: 0x0000, lo: 0x0b}, + {value: 0x3318, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0x84}, + {value: 0x3318, lo: 0x85, hi: 0x8b}, + {value: 0x0018, lo: 0x8c, hi: 0xa9}, + {value: 0x3318, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xba}, + {value: 0xb851, lo: 0xbb, hi: 0xbb}, + {value: 0xb899, lo: 0xbc, hi: 0xbc}, + {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, + {value: 0xb949, lo: 0xbe, hi: 0xbe}, + {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, + // Block 0xde, offset 0x67f + {value: 0x0000, lo: 0x03}, + {value: 0xba19, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xbf}, + // Block 0xdf, offset 0x683 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x3318, lo: 0x82, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0xbf}, + // Block 0xe0, offset 0x688 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe1, offset 0x68d + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xe2, offset 0x691 + {value: 0x0000, lo: 0x04}, + {value: 0x3308, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0xe3, offset 0x696 + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x3308, lo: 0xa1, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xe4, offset 0x69f + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0xe5, offset 0x6aa + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x86}, + {value: 0x0818, lo: 0x87, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xe6, offset 0x6b0 + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xe7, offset 0x6b8 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe8, offset 0x6bc + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0xe9, offset 0x6c0 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0xea, offset 0x6c6 + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xeb, offset 0x6cc + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0xc1c1, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xec, offset 0x6d1 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xbf}, + // Block 0xed, offset 0x6d4 + {value: 0x0000, lo: 0x0d}, + {value: 0xc7e9, lo: 0x80, hi: 0x80}, + {value: 0xc839, lo: 0x81, hi: 0x81}, + {value: 0xc889, lo: 0x82, hi: 0x82}, + {value: 0xc8d9, lo: 0x83, hi: 0x83}, + {value: 0xc929, lo: 0x84, hi: 0x84}, + {value: 0xc979, lo: 0x85, hi: 0x85}, + {value: 0xc9c9, lo: 0x86, hi: 0x86}, + {value: 0xca19, lo: 0x87, hi: 0x87}, + {value: 0xca69, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0xcab9, lo: 0x90, hi: 0x90}, + {value: 0xcad9, lo: 0x91, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0xbf}, + // Block 0xee, offset 0x6e2 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x92}, + {value: 0x0040, lo: 0x93, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xef, offset 0x6e9 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0xf0, offset 0x6ec + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0xbf}, + // Block 0xf1, offset 0x6ef + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0xf2, offset 0x6f3 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0xf3, offset 0x6f9 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0xf4, offset 0x6fe + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb2}, + {value: 0x0018, lo: 0xb3, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xf5, offset 0x708 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xf6, offset 0x70d + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0xbf}, + // Block 0xf7, offset 0x710 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0xbf}, + // Block 0xf8, offset 0x713 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xf9, offset 0x716 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xfa, offset 0x719 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0xfb, offset 0x71d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xbf}, + // Block 0xfc, offset 0x720 + {value: 0x0020, lo: 0x0f}, + {value: 0xdeb9, lo: 0x80, hi: 0x89}, + {value: 0x8dfd, lo: 0x8a, hi: 0x8a}, + {value: 0xdff9, lo: 0x8b, hi: 0x9c}, + {value: 0x8e1d, lo: 0x9d, hi: 0x9d}, + {value: 0xe239, lo: 0x9e, hi: 0xa2}, + {value: 0x8e3d, lo: 0xa3, hi: 0xa3}, + {value: 0xe2d9, lo: 0xa4, hi: 0xab}, + {value: 0x7ed5, lo: 0xac, hi: 0xac}, + {value: 0xe3d9, lo: 0xad, hi: 0xaf}, + {value: 0x8e5d, lo: 0xb0, hi: 0xb0}, + {value: 0xe439, lo: 0xb1, hi: 0xb6}, + {value: 0x8e7d, lo: 0xb7, hi: 0xb9}, + {value: 0xe4f9, lo: 0xba, hi: 0xba}, + {value: 0x8edd, lo: 0xbb, hi: 0xbb}, + {value: 0xe519, lo: 0xbc, hi: 0xbf}, + // Block 0xfd, offset 0x730 + {value: 0x0020, lo: 0x10}, + {value: 0x937d, lo: 0x80, hi: 0x80}, + {value: 0xf099, lo: 0x81, hi: 0x86}, + {value: 0x939d, lo: 0x87, hi: 0x8a}, + {value: 0xd9f9, lo: 0x8b, hi: 0x8b}, + {value: 0xf159, lo: 0x8c, hi: 0x96}, + {value: 0x941d, lo: 0x97, hi: 0x97}, + {value: 0xf2b9, lo: 0x98, hi: 0xa3}, + {value: 0x943d, lo: 0xa4, hi: 0xa6}, + {value: 0xf439, lo: 0xa7, hi: 0xaa}, + {value: 0x949d, lo: 0xab, hi: 0xab}, + {value: 0xf4b9, lo: 0xac, hi: 0xac}, + {value: 0x94bd, lo: 0xad, hi: 0xad}, + {value: 0xf4d9, lo: 0xae, hi: 0xaf}, + {value: 0x94dd, lo: 0xb0, hi: 0xb1}, + {value: 0xf519, lo: 0xb2, hi: 0xbe}, + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0xfe, offset 0x741 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0340, lo: 0x81, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x9f}, + {value: 0x0340, lo: 0xa0, hi: 0xbf}, + // Block 0xff, offset 0x746 + {value: 0x0000, lo: 0x01}, + {value: 0x0340, lo: 0x80, hi: 0xbf}, + // Block 0x100, offset 0x748 + {value: 0x0000, lo: 0x01}, + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x101, offset 0x74a + {value: 0x0000, lo: 0x02}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, +} + +// Total table size 41662 bytes (40KiB); checksum: 355A58A4 diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go index 43711c67d6ae..3ebf6f2daa30 100644 --- a/vendor/golang.org/x/net/trace/trace.go +++ b/vendor/golang.org/x/net/trace/trace.go @@ -86,6 +86,12 @@ import ( // FOR DEBUGGING ONLY. This will slow down the program. var DebugUseAfterFinish = false +// HTTP ServeMux paths. +const ( + debugRequestsPath = "/debug/requests" + debugEventsPath = "/debug/events" +) + // AuthRequest determines whether a specific request is permitted to load the // /debug/requests or /debug/events pages. // @@ -112,8 +118,8 @@ var AuthRequest = func(req *http.Request) (any, sensitive bool) { } func init() { - _, pat := http.DefaultServeMux.Handler(&http.Request{URL: &url.URL{Path: "/debug/requests"}}) - if pat != "" { + _, pat := http.DefaultServeMux.Handler(&http.Request{URL: &url.URL{Path: debugRequestsPath}}) + if pat == debugRequestsPath { panic("/debug/requests is already registered. You may have two independent copies of " + "golang.org/x/net/trace in your binary, trying to maintain separate state. This may " + "involve a vendored copy of golang.org/x/net/trace.") @@ -121,8 +127,8 @@ func init() { // TODO(jbd): Serve Traces from /debug/traces in the future? // There is no requirement for a request to be present to have traces. - http.HandleFunc("/debug/requests", Traces) - http.HandleFunc("/debug/events", Events) + http.HandleFunc(debugRequestsPath, Traces) + http.HandleFunc(debugEventsPath, Events) } // NewContext returns a copy of the parent context diff --git a/vendor/golang.org/x/oauth2/.travis.yml b/vendor/golang.org/x/oauth2/.travis.yml new file mode 100644 index 000000000000..fa139db22519 --- /dev/null +++ b/vendor/golang.org/x/oauth2/.travis.yml @@ -0,0 +1,13 @@ +language: go + +go: + - tip + +install: + - export GOPATH="$HOME/gopath" + - mkdir -p "$GOPATH/src/golang.org/x" + - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/golang.org/x/oauth2" + - go get -v -t -d golang.org/x/oauth2/... + +script: + - go test -v golang.org/x/oauth2/... diff --git a/vendor/golang.org/x/sync/AUTHORS b/vendor/golang.org/x/oauth2/AUTHORS similarity index 100% rename from vendor/golang.org/x/sync/AUTHORS rename to vendor/golang.org/x/oauth2/AUTHORS diff --git a/vendor/golang.org/x/oauth2/CONTRIBUTING.md b/vendor/golang.org/x/oauth2/CONTRIBUTING.md new file mode 100644 index 000000000000..dfbed62cf546 --- /dev/null +++ b/vendor/golang.org/x/oauth2/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# Contributing to Go + +Go is an open source project. + +It is the work of hundreds of contributors. We appreciate your help! + +## Filing issues + +When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions: + +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? + +General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. +The gophers there will answer or ask you to file an issue if you've tripped over a bug. + +## Contributing code + +Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) +before sending patches. + +Unless otherwise noted, the Go source files are distributed under +the BSD-style license found in the LICENSE file. diff --git a/vendor/golang.org/x/sync/CONTRIBUTORS b/vendor/golang.org/x/oauth2/CONTRIBUTORS similarity index 100% rename from vendor/golang.org/x/sync/CONTRIBUTORS rename to vendor/golang.org/x/oauth2/CONTRIBUTORS diff --git a/vendor/golang.org/x/sync/LICENSE b/vendor/golang.org/x/oauth2/LICENSE similarity index 100% rename from vendor/golang.org/x/sync/LICENSE rename to vendor/golang.org/x/oauth2/LICENSE diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md new file mode 100644 index 000000000000..0f443e6934d9 --- /dev/null +++ b/vendor/golang.org/x/oauth2/README.md @@ -0,0 +1,35 @@ +# OAuth2 for Go + +[![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2) +[![GoDoc](https://godoc.org/golang.org/x/oauth2?status.svg)](https://godoc.org/golang.org/x/oauth2) + +oauth2 package contains a client implementation for OAuth 2.0 spec. + +## Installation + +~~~~ +go get golang.org/x/oauth2 +~~~~ + +Or you can manually git clone the repository to +`$(go env GOPATH)/src/golang.org/x/oauth2`. + +See godoc for further documentation and examples. + +* [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2) +* [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google) + +## Policy for new packages + +We no longer accept new provider-specific packages in this repo. For +defining provider endpoints and provider-specific OAuth2 behavior, we +encourage you to create packages elsewhere. We'll keep the existing +packages for compatibility. + +## Report Issues / Send Patches + +This repository uses Gerrit for code changes. To learn how to submit changes to +this repository, see https://golang.org/doc/contribute.html. + +The main issue tracker for the oauth2 repository is located at +https://github.com/golang/oauth2/issues. diff --git a/vendor/golang.org/x/oauth2/go.mod b/vendor/golang.org/x/oauth2/go.mod new file mode 100644 index 000000000000..b3457815528f --- /dev/null +++ b/vendor/golang.org/x/oauth2/go.mod @@ -0,0 +1,10 @@ +module golang.org/x/oauth2 + +go 1.11 + +require ( + cloud.google.com/go v0.34.0 + golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e + golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect + google.golang.org/appengine v1.4.0 +) diff --git a/vendor/golang.org/x/oauth2/go.sum b/vendor/golang.org/x/oauth2/go.sum new file mode 100644 index 000000000000..6f0079b0d7f9 --- /dev/null +++ b/vendor/golang.org/x/oauth2/go.sum @@ -0,0 +1,12 @@ +cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/vendor/golang.org/x/oauth2/google/appengine.go b/vendor/golang.org/x/oauth2/google/appengine.go new file mode 100644 index 000000000000..feb1157b15b4 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/appengine.go @@ -0,0 +1,38 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "context" + "time" + + "golang.org/x/oauth2" +) + +// Set at init time by appengine_gen1.go. If nil, we're not on App Engine standard first generation (<= Go 1.9) or App Engine flexible. +var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error) + +// Set at init time by appengine_gen1.go. If nil, we're not on App Engine standard first generation (<= Go 1.9) or App Engine flexible. +var appengineAppIDFunc func(c context.Context) string + +// AppEngineTokenSource returns a token source that fetches tokens from either +// the current application's service account or from the metadata server, +// depending on the App Engine environment. See below for environment-specific +// details. If you are implementing a 3-legged OAuth 2.0 flow on App Engine that +// involves user accounts, see oauth2.Config instead. +// +// First generation App Engine runtimes (<= Go 1.9): +// AppEngineTokenSource returns a token source that fetches tokens issued to the +// current App Engine application's service account. The provided context must have +// come from appengine.NewContext. +// +// Second generation App Engine runtimes (>= Go 1.11) and App Engine flexible: +// AppEngineTokenSource is DEPRECATED on second generation runtimes and on the +// flexible environment. It delegates to ComputeTokenSource, and the provided +// context and scopes are not used. Please use DefaultTokenSource (or ComputeTokenSource, +// which DefaultTokenSource will use in this case) instead. +func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { + return appEngineTokenSource(ctx, scope...) +} diff --git a/vendor/golang.org/x/oauth2/google/appengine_gen1.go b/vendor/golang.org/x/oauth2/google/appengine_gen1.go new file mode 100644 index 000000000000..83dacac320a9 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/appengine_gen1.go @@ -0,0 +1,77 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build appengine + +// This file applies to App Engine first generation runtimes (<= Go 1.9). + +package google + +import ( + "context" + "sort" + "strings" + "sync" + + "golang.org/x/oauth2" + "google.golang.org/appengine" +) + +func init() { + appengineTokenFunc = appengine.AccessToken + appengineAppIDFunc = appengine.AppID +} + +// See comment on AppEngineTokenSource in appengine.go. +func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { + scopes := append([]string{}, scope...) + sort.Strings(scopes) + return &gaeTokenSource{ + ctx: ctx, + scopes: scopes, + key: strings.Join(scopes, " "), + } +} + +// aeTokens helps the fetched tokens to be reused until their expiration. +var ( + aeTokensMu sync.Mutex + aeTokens = make(map[string]*tokenLock) // key is space-separated scopes +) + +type tokenLock struct { + mu sync.Mutex // guards t; held while fetching or updating t + t *oauth2.Token +} + +type gaeTokenSource struct { + ctx context.Context + scopes []string + key string // to aeTokens map; space-separated scopes +} + +func (ts *gaeTokenSource) Token() (*oauth2.Token, error) { + aeTokensMu.Lock() + tok, ok := aeTokens[ts.key] + if !ok { + tok = &tokenLock{} + aeTokens[ts.key] = tok + } + aeTokensMu.Unlock() + + tok.mu.Lock() + defer tok.mu.Unlock() + if tok.t.Valid() { + return tok.t, nil + } + access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...) + if err != nil { + return nil, err + } + tok.t = &oauth2.Token{ + AccessToken: access, + Expiry: exp, + } + return tok.t, nil +} diff --git a/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go b/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go new file mode 100644 index 000000000000..04c2c2216af5 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go @@ -0,0 +1,27 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !appengine + +// This file applies to App Engine second generation runtimes (>= Go 1.11) and App Engine flexible. + +package google + +import ( + "context" + "log" + "sync" + + "golang.org/x/oauth2" +) + +var logOnce sync.Once // only spam about deprecation once + +// See comment on AppEngineTokenSource in appengine.go. +func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { + logOnce.Do(func() { + log.Print("google: AppEngineTokenSource is deprecated on App Engine standard second generation runtimes (>= Go 1.11) and App Engine flexible. Please use DefaultTokenSource or ComputeTokenSource.") + }) + return ComputeTokenSource("") +} diff --git a/vendor/golang.org/x/oauth2/google/default.go b/vendor/golang.org/x/oauth2/google/default.go new file mode 100644 index 000000000000..5087d845fe14 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/default.go @@ -0,0 +1,155 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "runtime" + + "cloud.google.com/go/compute/metadata" + "golang.org/x/oauth2" +) + +// Credentials holds Google credentials, including "Application Default Credentials". +// For more details, see: +// https://developers.google.com/accounts/docs/application-default-credentials +type Credentials struct { + ProjectID string // may be empty + TokenSource oauth2.TokenSource + + // JSON contains the raw bytes from a JSON credentials file. + // This field may be nil if authentication is provided by the + // environment and not with a credentials file, e.g. when code is + // running on Google Cloud Platform. + JSON []byte +} + +// DefaultCredentials is the old name of Credentials. +// +// Deprecated: use Credentials instead. +type DefaultCredentials = Credentials + +// DefaultClient returns an HTTP Client that uses the +// DefaultTokenSource to obtain authentication credentials. +func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) { + ts, err := DefaultTokenSource(ctx, scope...) + if err != nil { + return nil, err + } + return oauth2.NewClient(ctx, ts), nil +} + +// DefaultTokenSource returns the token source for +// "Application Default Credentials". +// It is a shortcut for FindDefaultCredentials(ctx, scope).TokenSource. +func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) { + creds, err := FindDefaultCredentials(ctx, scope...) + if err != nil { + return nil, err + } + return creds.TokenSource, nil +} + +// FindDefaultCredentials searches for "Application Default Credentials". +// +// It looks for credentials in the following places, +// preferring the first location found: +// +// 1. A JSON file whose path is specified by the +// GOOGLE_APPLICATION_CREDENTIALS environment variable. +// 2. A JSON file in a location known to the gcloud command-line tool. +// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json. +// On other systems, $HOME/.config/gcloud/application_default_credentials.json. +// 3. On Google App Engine standard first generation runtimes (<= Go 1.9) it uses +// the appengine.AccessToken function. +// 4. On Google Compute Engine, Google App Engine standard second generation runtimes +// (>= Go 1.11), and Google App Engine flexible environment, it fetches +// credentials from the metadata server. +// (In this final case any provided scopes are ignored.) +func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) { + // First, try the environment variable. + const envVar = "GOOGLE_APPLICATION_CREDENTIALS" + if filename := os.Getenv(envVar); filename != "" { + creds, err := readCredentialsFile(ctx, filename, scopes) + if err != nil { + return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err) + } + return creds, nil + } + + // Second, try a well-known file. + filename := wellKnownFile() + if creds, err := readCredentialsFile(ctx, filename, scopes); err == nil { + return creds, nil + } else if !os.IsNotExist(err) { + return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err) + } + + // Third, if we're on a Google App Engine standard first generation runtime (<= Go 1.9) + // use those credentials. App Engine standard second generation runtimes (>= Go 1.11) + // and App Engine flexible use ComputeTokenSource and the metadata server. + if appengineTokenFunc != nil { + return &DefaultCredentials{ + ProjectID: appengineAppIDFunc(ctx), + TokenSource: AppEngineTokenSource(ctx, scopes...), + }, nil + } + + // Fourth, if we're on Google Compute Engine, an App Engine standard second generation runtime, + // or App Engine flexible, use the metadata server. + if metadata.OnGCE() { + id, _ := metadata.ProjectID() + return &DefaultCredentials{ + ProjectID: id, + TokenSource: ComputeTokenSource(""), + }, nil + } + + // None are found; return helpful error. + const url = "https://developers.google.com/accounts/docs/application-default-credentials" + return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url) +} + +// CredentialsFromJSON obtains Google credentials from a JSON value. The JSON can +// represent either a Google Developers Console client_credentials.json file (as in +// ConfigFromJSON) or a Google Developers service account key file (as in +// JWTConfigFromJSON). +func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error) { + var f credentialsFile + if err := json.Unmarshal(jsonData, &f); err != nil { + return nil, err + } + ts, err := f.tokenSource(ctx, append([]string(nil), scopes...)) + if err != nil { + return nil, err + } + return &DefaultCredentials{ + ProjectID: f.ProjectID, + TokenSource: ts, + JSON: jsonData, + }, nil +} + +func wellKnownFile() string { + const f = "application_default_credentials.json" + if runtime.GOOS == "windows" { + return filepath.Join(os.Getenv("APPDATA"), "gcloud", f) + } + return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f) +} + +func readCredentialsFile(ctx context.Context, filename string, scopes []string) (*DefaultCredentials, error) { + b, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + return CredentialsFromJSON(ctx, b, scopes...) +} diff --git a/vendor/golang.org/x/oauth2/google/doc.go b/vendor/golang.org/x/oauth2/google/doc.go new file mode 100644 index 000000000000..73be629033d3 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/doc.go @@ -0,0 +1,40 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package google provides support for making OAuth2 authorized and authenticated +// HTTP requests to Google APIs. It supports the Web server flow, client-side +// credentials, service accounts, Google Compute Engine service accounts, and Google +// App Engine service accounts. +// +// A brief overview of the package follows. For more information, please read +// https://developers.google.com/accounts/docs/OAuth2 +// and +// https://developers.google.com/accounts/docs/application-default-credentials. +// +// OAuth2 Configs +// +// Two functions in this package return golang.org/x/oauth2.Config values from Google credential +// data. Google supports two JSON formats for OAuth2 credentials: one is handled by ConfigFromJSON, +// the other by JWTConfigFromJSON. The returned Config can be used to obtain a TokenSource or +// create an http.Client. +// +// +// Credentials +// +// The Credentials type represents Google credentials, including Application Default +// Credentials. +// +// Use FindDefaultCredentials to obtain Application Default Credentials. +// FindDefaultCredentials looks in some well-known places for a credentials file, and +// will call AppEngineTokenSource or ComputeTokenSource as needed. +// +// DefaultClient and DefaultTokenSource are convenience methods. They first call FindDefaultCredentials, +// then use the credentials to construct an http.Client or an oauth2.TokenSource. +// +// Use CredentialsFromJSON to obtain credentials from either of the two JSON formats +// described in OAuth2 Configs, above. The TokenSource in the returned value is the +// same as the one obtained from the oauth2.Config returned from ConfigFromJSON or +// JWTConfigFromJSON, but the Credentials may contain additional information +// that is useful is some circumstances. +package google // import "golang.org/x/oauth2/google" diff --git a/vendor/golang.org/x/oauth2/google/google.go b/vendor/golang.org/x/oauth2/google/google.go new file mode 100644 index 000000000000..df8e87d74a3a --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/google.go @@ -0,0 +1,193 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + "cloud.google.com/go/compute/metadata" + "golang.org/x/oauth2" + "golang.org/x/oauth2/jwt" +) + +// Endpoint is Google's OAuth 2.0 endpoint. +var Endpoint = oauth2.Endpoint{ + AuthURL: "https://accounts.google.com/o/oauth2/auth", + TokenURL: "https://oauth2.googleapis.com/token", + AuthStyle: oauth2.AuthStyleInParams, +} + +// JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow. +const JWTTokenURL = "https://oauth2.googleapis.com/token" + +// ConfigFromJSON uses a Google Developers Console client_credentials.json +// file to construct a config. +// client_credentials.json can be downloaded from +// https://console.developers.google.com, under "Credentials". Download the Web +// application credentials in the JSON format and provide the contents of the +// file as jsonKey. +func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) { + type cred struct { + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RedirectURIs []string `json:"redirect_uris"` + AuthURI string `json:"auth_uri"` + TokenURI string `json:"token_uri"` + } + var j struct { + Web *cred `json:"web"` + Installed *cred `json:"installed"` + } + if err := json.Unmarshal(jsonKey, &j); err != nil { + return nil, err + } + var c *cred + switch { + case j.Web != nil: + c = j.Web + case j.Installed != nil: + c = j.Installed + default: + return nil, fmt.Errorf("oauth2/google: no credentials found") + } + if len(c.RedirectURIs) < 1 { + return nil, errors.New("oauth2/google: missing redirect URL in the client_credentials.json") + } + return &oauth2.Config{ + ClientID: c.ClientID, + ClientSecret: c.ClientSecret, + RedirectURL: c.RedirectURIs[0], + Scopes: scope, + Endpoint: oauth2.Endpoint{ + AuthURL: c.AuthURI, + TokenURL: c.TokenURI, + }, + }, nil +} + +// JWTConfigFromJSON uses a Google Developers service account JSON key file to read +// the credentials that authorize and authenticate the requests. +// Create a service account on "Credentials" for your project at +// https://console.developers.google.com to download a JSON key file. +func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) { + var f credentialsFile + if err := json.Unmarshal(jsonKey, &f); err != nil { + return nil, err + } + if f.Type != serviceAccountKey { + return nil, fmt.Errorf("google: read JWT from JSON credentials: 'type' field is %q (expected %q)", f.Type, serviceAccountKey) + } + scope = append([]string(nil), scope...) // copy + return f.jwtConfig(scope), nil +} + +// JSON key file types. +const ( + serviceAccountKey = "service_account" + userCredentialsKey = "authorized_user" +) + +// credentialsFile is the unmarshalled representation of a credentials file. +type credentialsFile struct { + Type string `json:"type"` // serviceAccountKey or userCredentialsKey + + // Service Account fields + ClientEmail string `json:"client_email"` + PrivateKeyID string `json:"private_key_id"` + PrivateKey string `json:"private_key"` + TokenURL string `json:"token_uri"` + ProjectID string `json:"project_id"` + + // User Credential fields + // (These typically come from gcloud auth.) + ClientSecret string `json:"client_secret"` + ClientID string `json:"client_id"` + RefreshToken string `json:"refresh_token"` +} + +func (f *credentialsFile) jwtConfig(scopes []string) *jwt.Config { + cfg := &jwt.Config{ + Email: f.ClientEmail, + PrivateKey: []byte(f.PrivateKey), + PrivateKeyID: f.PrivateKeyID, + Scopes: scopes, + TokenURL: f.TokenURL, + } + if cfg.TokenURL == "" { + cfg.TokenURL = JWTTokenURL + } + return cfg +} + +func (f *credentialsFile) tokenSource(ctx context.Context, scopes []string) (oauth2.TokenSource, error) { + switch f.Type { + case serviceAccountKey: + cfg := f.jwtConfig(scopes) + return cfg.TokenSource(ctx), nil + case userCredentialsKey: + cfg := &oauth2.Config{ + ClientID: f.ClientID, + ClientSecret: f.ClientSecret, + Scopes: scopes, + Endpoint: Endpoint, + } + tok := &oauth2.Token{RefreshToken: f.RefreshToken} + return cfg.TokenSource(ctx, tok), nil + case "": + return nil, errors.New("missing 'type' field in credentials") + default: + return nil, fmt.Errorf("unknown credential type: %q", f.Type) + } +} + +// ComputeTokenSource returns a token source that fetches access tokens +// from Google Compute Engine (GCE)'s metadata server. It's only valid to use +// this token source if your program is running on a GCE instance. +// If no account is specified, "default" is used. +// Further information about retrieving access tokens from the GCE metadata +// server can be found at https://cloud.google.com/compute/docs/authentication. +func ComputeTokenSource(account string) oauth2.TokenSource { + return oauth2.ReuseTokenSource(nil, computeSource{account: account}) +} + +type computeSource struct { + account string +} + +func (cs computeSource) Token() (*oauth2.Token, error) { + if !metadata.OnGCE() { + return nil, errors.New("oauth2/google: can't get a token from the metadata service; not running on GCE") + } + acct := cs.account + if acct == "" { + acct = "default" + } + tokenJSON, err := metadata.Get("instance/service-accounts/" + acct + "/token") + if err != nil { + return nil, err + } + var res struct { + AccessToken string `json:"access_token"` + ExpiresInSec int `json:"expires_in"` + TokenType string `json:"token_type"` + } + err = json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res) + if err != nil { + return nil, fmt.Errorf("oauth2/google: invalid token JSON from metadata: %v", err) + } + if res.ExpiresInSec == 0 || res.AccessToken == "" { + return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata") + } + return &oauth2.Token{ + AccessToken: res.AccessToken, + TokenType: res.TokenType, + Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second), + }, nil +} diff --git a/vendor/golang.org/x/oauth2/google/jwt.go b/vendor/golang.org/x/oauth2/google/jwt.go new file mode 100644 index 000000000000..b0fdb3a888ac --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/jwt.go @@ -0,0 +1,74 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "crypto/rsa" + "fmt" + "time" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/internal" + "golang.org/x/oauth2/jws" +) + +// JWTAccessTokenSourceFromJSON uses a Google Developers service account JSON +// key file to read the credentials that authorize and authenticate the +// requests, and returns a TokenSource that does not use any OAuth2 flow but +// instead creates a JWT and sends that as the access token. +// The audience is typically a URL that specifies the scope of the credentials. +// +// Note that this is not a standard OAuth flow, but rather an +// optimization supported by a few Google services. +// Unless you know otherwise, you should use JWTConfigFromJSON instead. +func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error) { + cfg, err := JWTConfigFromJSON(jsonKey) + if err != nil { + return nil, fmt.Errorf("google: could not parse JSON key: %v", err) + } + pk, err := internal.ParseKey(cfg.PrivateKey) + if err != nil { + return nil, fmt.Errorf("google: could not parse key: %v", err) + } + ts := &jwtAccessTokenSource{ + email: cfg.Email, + audience: audience, + pk: pk, + pkID: cfg.PrivateKeyID, + } + tok, err := ts.Token() + if err != nil { + return nil, err + } + return oauth2.ReuseTokenSource(tok, ts), nil +} + +type jwtAccessTokenSource struct { + email, audience string + pk *rsa.PrivateKey + pkID string +} + +func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) { + iat := time.Now() + exp := iat.Add(time.Hour) + cs := &jws.ClaimSet{ + Iss: ts.email, + Sub: ts.email, + Aud: ts.audience, + Iat: iat.Unix(), + Exp: exp.Unix(), + } + hdr := &jws.Header{ + Algorithm: "RS256", + Typ: "JWT", + KeyID: string(ts.pkID), + } + msg, err := jws.Encode(hdr, cs, ts.pk) + if err != nil { + return nil, fmt.Errorf("google: could not encode JWT: %v", err) + } + return &oauth2.Token{AccessToken: msg, TokenType: "Bearer", Expiry: exp}, nil +} diff --git a/vendor/golang.org/x/oauth2/google/sdk.go b/vendor/golang.org/x/oauth2/google/sdk.go new file mode 100644 index 000000000000..456224bc7896 --- /dev/null +++ b/vendor/golang.org/x/oauth2/google/sdk.go @@ -0,0 +1,201 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package google + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "os" + "os/user" + "path/filepath" + "runtime" + "strings" + "time" + + "golang.org/x/oauth2" +) + +type sdkCredentials struct { + Data []struct { + Credential struct { + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + TokenExpiry *time.Time `json:"token_expiry"` + } `json:"credential"` + Key struct { + Account string `json:"account"` + Scope string `json:"scope"` + } `json:"key"` + } +} + +// An SDKConfig provides access to tokens from an account already +// authorized via the Google Cloud SDK. +type SDKConfig struct { + conf oauth2.Config + initialToken *oauth2.Token +} + +// NewSDKConfig creates an SDKConfig for the given Google Cloud SDK +// account. If account is empty, the account currently active in +// Google Cloud SDK properties is used. +// Google Cloud SDK credentials must be created by running `gcloud auth` +// before using this function. +// The Google Cloud SDK is available at https://cloud.google.com/sdk/. +func NewSDKConfig(account string) (*SDKConfig, error) { + configPath, err := sdkConfigPath() + if err != nil { + return nil, fmt.Errorf("oauth2/google: error getting SDK config path: %v", err) + } + credentialsPath := filepath.Join(configPath, "credentials") + f, err := os.Open(credentialsPath) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to load SDK credentials: %v", err) + } + defer f.Close() + + var c sdkCredentials + if err := json.NewDecoder(f).Decode(&c); err != nil { + return nil, fmt.Errorf("oauth2/google: failed to decode SDK credentials from %q: %v", credentialsPath, err) + } + if len(c.Data) == 0 { + return nil, fmt.Errorf("oauth2/google: no credentials found in %q, run `gcloud auth login` to create one", credentialsPath) + } + if account == "" { + propertiesPath := filepath.Join(configPath, "properties") + f, err := os.Open(propertiesPath) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to load SDK properties: %v", err) + } + defer f.Close() + ini, err := parseINI(f) + if err != nil { + return nil, fmt.Errorf("oauth2/google: failed to parse SDK properties %q: %v", propertiesPath, err) + } + core, ok := ini["core"] + if !ok { + return nil, fmt.Errorf("oauth2/google: failed to find [core] section in %v", ini) + } + active, ok := core["account"] + if !ok { + return nil, fmt.Errorf("oauth2/google: failed to find %q attribute in %v", "account", core) + } + account = active + } + + for _, d := range c.Data { + if account == "" || d.Key.Account == account { + if d.Credential.AccessToken == "" && d.Credential.RefreshToken == "" { + return nil, fmt.Errorf("oauth2/google: no token available for account %q", account) + } + var expiry time.Time + if d.Credential.TokenExpiry != nil { + expiry = *d.Credential.TokenExpiry + } + return &SDKConfig{ + conf: oauth2.Config{ + ClientID: d.Credential.ClientID, + ClientSecret: d.Credential.ClientSecret, + Scopes: strings.Split(d.Key.Scope, " "), + Endpoint: Endpoint, + RedirectURL: "oob", + }, + initialToken: &oauth2.Token{ + AccessToken: d.Credential.AccessToken, + RefreshToken: d.Credential.RefreshToken, + Expiry: expiry, + }, + }, nil + } + } + return nil, fmt.Errorf("oauth2/google: no such credentials for account %q", account) +} + +// Client returns an HTTP client using Google Cloud SDK credentials to +// authorize requests. The token will auto-refresh as necessary. The +// underlying http.RoundTripper will be obtained using the provided +// context. The returned client and its Transport should not be +// modified. +func (c *SDKConfig) Client(ctx context.Context) *http.Client { + return &http.Client{ + Transport: &oauth2.Transport{ + Source: c.TokenSource(ctx), + }, + } +} + +// TokenSource returns an oauth2.TokenSource that retrieve tokens from +// Google Cloud SDK credentials using the provided context. +// It will returns the current access token stored in the credentials, +// and refresh it when it expires, but it won't update the credentials +// with the new access token. +func (c *SDKConfig) TokenSource(ctx context.Context) oauth2.TokenSource { + return c.conf.TokenSource(ctx, c.initialToken) +} + +// Scopes are the OAuth 2.0 scopes the current account is authorized for. +func (c *SDKConfig) Scopes() []string { + return c.conf.Scopes +} + +func parseINI(ini io.Reader) (map[string]map[string]string, error) { + result := map[string]map[string]string{ + "": {}, // root section + } + scanner := bufio.NewScanner(ini) + currentSection := "" + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if strings.HasPrefix(line, ";") { + // comment. + continue + } + if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { + currentSection = strings.TrimSpace(line[1 : len(line)-1]) + result[currentSection] = map[string]string{} + continue + } + parts := strings.SplitN(line, "=", 2) + if len(parts) == 2 && parts[0] != "" { + result[currentSection][strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1]) + } + } + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("error scanning ini: %v", err) + } + return result, nil +} + +// sdkConfigPath tries to guess where the gcloud config is located. +// It can be overridden during tests. +var sdkConfigPath = func() (string, error) { + if runtime.GOOS == "windows" { + return filepath.Join(os.Getenv("APPDATA"), "gcloud"), nil + } + homeDir := guessUnixHomeDir() + if homeDir == "" { + return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty") + } + return filepath.Join(homeDir, ".config", "gcloud"), nil +} + +func guessUnixHomeDir() string { + // Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470 + if v := os.Getenv("HOME"); v != "" { + return v + } + // Else, fall back to user.Current: + if u, err := user.Current(); err == nil { + return u.HomeDir + } + return "" +} diff --git a/vendor/golang.org/x/oauth2/internal/client_appengine.go b/vendor/golang.org/x/oauth2/internal/client_appengine.go new file mode 100644 index 000000000000..7434871880a7 --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/client_appengine.go @@ -0,0 +1,13 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build appengine + +package internal + +import "google.golang.org/appengine/urlfetch" + +func init() { + appengineClientHook = urlfetch.Client +} diff --git a/vendor/golang.org/x/oauth2/internal/doc.go b/vendor/golang.org/x/oauth2/internal/doc.go new file mode 100644 index 000000000000..03265e888af4 --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/doc.go @@ -0,0 +1,6 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package internal contains support packages for oauth2 package. +package internal diff --git a/vendor/golang.org/x/oauth2/internal/oauth2.go b/vendor/golang.org/x/oauth2/internal/oauth2.go new file mode 100644 index 000000000000..c0ab196cf461 --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/oauth2.go @@ -0,0 +1,37 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "fmt" +) + +// ParseKey converts the binary contents of a private key file +// to an *rsa.PrivateKey. It detects whether the private key is in a +// PEM container or not. If so, it extracts the the private key +// from PEM container before conversion. It only supports PEM +// containers with no passphrase. +func ParseKey(key []byte) (*rsa.PrivateKey, error) { + block, _ := pem.Decode(key) + if block != nil { + key = block.Bytes + } + parsedKey, err := x509.ParsePKCS8PrivateKey(key) + if err != nil { + parsedKey, err = x509.ParsePKCS1PrivateKey(key) + if err != nil { + return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8; parse error: %v", err) + } + } + parsed, ok := parsedKey.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("private key is invalid") + } + return parsed, nil +} diff --git a/vendor/golang.org/x/oauth2/internal/token.go b/vendor/golang.org/x/oauth2/internal/token.go new file mode 100644 index 000000000000..83f7847e49ac --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/token.go @@ -0,0 +1,304 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "math" + "mime" + "net/http" + "net/url" + "strconv" + "strings" + "sync" + "time" + + "golang.org/x/net/context/ctxhttp" +) + +// Token represents the credentials used to authorize +// the requests to access protected resources on the OAuth 2.0 +// provider's backend. +// +// This type is a mirror of oauth2.Token and exists to break +// an otherwise-circular dependency. Other internal packages +// should convert this Token into an oauth2.Token before use. +type Token struct { + // AccessToken is the token that authorizes and authenticates + // the requests. + AccessToken string + + // TokenType is the type of token. + // The Type method returns either this or "Bearer", the default. + TokenType string + + // RefreshToken is a token that's used by the application + // (as opposed to the user) to refresh the access token + // if it expires. + RefreshToken string + + // Expiry is the optional expiration time of the access token. + // + // If zero, TokenSource implementations will reuse the same + // token forever and RefreshToken or equivalent + // mechanisms for that TokenSource will not be used. + Expiry time.Time + + // Raw optionally contains extra metadata from the server + // when updating a token. + Raw interface{} +} + +// tokenJSON is the struct representing the HTTP response from OAuth2 +// providers returning a token in JSON form. +type tokenJSON struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + RefreshToken string `json:"refresh_token"` + ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number + Expires expirationTime `json:"expires"` // broken Facebook spelling of expires_in +} + +func (e *tokenJSON) expiry() (t time.Time) { + if v := e.ExpiresIn; v != 0 { + return time.Now().Add(time.Duration(v) * time.Second) + } + if v := e.Expires; v != 0 { + return time.Now().Add(time.Duration(v) * time.Second) + } + return +} + +type expirationTime int32 + +func (e *expirationTime) UnmarshalJSON(b []byte) error { + if len(b) == 0 || string(b) == "null" { + return nil + } + var n json.Number + err := json.Unmarshal(b, &n) + if err != nil { + return err + } + i, err := n.Int64() + if err != nil { + return err + } + if i > math.MaxInt32 { + i = math.MaxInt32 + } + *e = expirationTime(i) + return nil +} + +// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op. +// +// Deprecated: this function no longer does anything. Caller code that +// wants to avoid potential extra HTTP requests made during +// auto-probing of the provider's auth style should set +// Endpoint.AuthStyle. +func RegisterBrokenAuthHeaderProvider(tokenURL string) {} + +// AuthStyle is a copy of the golang.org/x/oauth2 package's AuthStyle type. +type AuthStyle int + +const ( + AuthStyleUnknown AuthStyle = 0 + AuthStyleInParams AuthStyle = 1 + AuthStyleInHeader AuthStyle = 2 +) + +// authStyleCache is the set of tokenURLs we've successfully used via +// RetrieveToken and which style auth we ended up using. +// It's called a cache, but it doesn't (yet?) shrink. It's expected that +// the set of OAuth2 servers a program contacts over time is fixed and +// small. +var authStyleCache struct { + sync.Mutex + m map[string]AuthStyle // keyed by tokenURL +} + +// ResetAuthCache resets the global authentication style cache used +// for AuthStyleUnknown token requests. +func ResetAuthCache() { + authStyleCache.Lock() + defer authStyleCache.Unlock() + authStyleCache.m = nil +} + +// lookupAuthStyle reports which auth style we last used with tokenURL +// when calling RetrieveToken and whether we have ever done so. +func lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) { + authStyleCache.Lock() + defer authStyleCache.Unlock() + style, ok = authStyleCache.m[tokenURL] + return +} + +// setAuthStyle adds an entry to authStyleCache, documented above. +func setAuthStyle(tokenURL string, v AuthStyle) { + authStyleCache.Lock() + defer authStyleCache.Unlock() + if authStyleCache.m == nil { + authStyleCache.m = make(map[string]AuthStyle) + } + authStyleCache.m[tokenURL] = v +} + +// newTokenRequest returns a new *http.Request to retrieve a new token +// from tokenURL using the provided clientID, clientSecret, and POST +// body parameters. +// +// inParams is whether the clientID & clientSecret should be encoded +// as the POST body. An 'inParams' value of true means to send it in +// the POST body (along with any values in v); false means to send it +// in the Authorization header. +func newTokenRequest(tokenURL, clientID, clientSecret string, v url.Values, authStyle AuthStyle) (*http.Request, error) { + if authStyle == AuthStyleInParams { + v = cloneURLValues(v) + if clientID != "" { + v.Set("client_id", clientID) + } + if clientSecret != "" { + v.Set("client_secret", clientSecret) + } + } + req, err := http.NewRequest("POST", tokenURL, strings.NewReader(v.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + if authStyle == AuthStyleInHeader { + req.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret)) + } + return req, nil +} + +func cloneURLValues(v url.Values) url.Values { + v2 := make(url.Values, len(v)) + for k, vv := range v { + v2[k] = append([]string(nil), vv...) + } + return v2 +} + +func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle) (*Token, error) { + needsAuthStyleProbe := authStyle == 0 + if needsAuthStyleProbe { + if style, ok := lookupAuthStyle(tokenURL); ok { + authStyle = style + needsAuthStyleProbe = false + } else { + authStyle = AuthStyleInHeader // the first way we'll try + } + } + req, err := newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle) + if err != nil { + return nil, err + } + token, err := doTokenRoundTrip(ctx, req) + if err != nil && needsAuthStyleProbe { + // If we get an error, assume the server wants the + // clientID & clientSecret in a different form. + // See https://code.google.com/p/goauth2/issues/detail?id=31 for background. + // In summary: + // - Reddit only accepts client secret in the Authorization header + // - Dropbox accepts either it in URL param or Auth header, but not both. + // - Google only accepts URL param (not spec compliant?), not Auth header + // - Stripe only accepts client secret in Auth header with Bearer method, not Basic + // + // We used to maintain a big table in this code of all the sites and which way + // they went, but maintaining it didn't scale & got annoying. + // So just try both ways. + authStyle = AuthStyleInParams // the second way we'll try + req, _ = newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle) + token, err = doTokenRoundTrip(ctx, req) + } + if needsAuthStyleProbe && err == nil { + setAuthStyle(tokenURL, authStyle) + } + // Don't overwrite `RefreshToken` with an empty value + // if this was a token refreshing request. + if token != nil && token.RefreshToken == "" { + token.RefreshToken = v.Get("refresh_token") + } + return token, err +} + +func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) { + r, err := ctxhttp.Do(ctx, ContextClient(ctx), req) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20)) + r.Body.Close() + if err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + if code := r.StatusCode; code < 200 || code > 299 { + return nil, &RetrieveError{ + Response: r, + Body: body, + } + } + + var token *Token + content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type")) + switch content { + case "application/x-www-form-urlencoded", "text/plain": + vals, err := url.ParseQuery(string(body)) + if err != nil { + return nil, err + } + token = &Token{ + AccessToken: vals.Get("access_token"), + TokenType: vals.Get("token_type"), + RefreshToken: vals.Get("refresh_token"), + Raw: vals, + } + e := vals.Get("expires_in") + if e == "" || e == "null" { + // TODO(jbd): Facebook's OAuth2 implementation is broken and + // returns expires_in field in expires. Remove the fallback to expires, + // when Facebook fixes their implementation. + e = vals.Get("expires") + } + expires, _ := strconv.Atoi(e) + if expires != 0 { + token.Expiry = time.Now().Add(time.Duration(expires) * time.Second) + } + default: + var tj tokenJSON + if err = json.Unmarshal(body, &tj); err != nil { + return nil, err + } + token = &Token{ + AccessToken: tj.AccessToken, + TokenType: tj.TokenType, + RefreshToken: tj.RefreshToken, + Expiry: tj.expiry(), + Raw: make(map[string]interface{}), + } + json.Unmarshal(body, &token.Raw) // no error checks for optional fields + } + if token.AccessToken == "" { + return nil, errors.New("oauth2: server response missing access_token") + } + return token, nil +} + +type RetrieveError struct { + Response *http.Response + Body []byte +} + +func (r *RetrieveError) Error() string { + return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body) +} diff --git a/vendor/golang.org/x/oauth2/internal/transport.go b/vendor/golang.org/x/oauth2/internal/transport.go new file mode 100644 index 000000000000..572074a637dd --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/transport.go @@ -0,0 +1,33 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal + +import ( + "context" + "net/http" +) + +// HTTPClient is the context key to use with golang.org/x/net/context's +// WithValue function to associate an *http.Client value with a context. +var HTTPClient ContextKey + +// ContextKey is just an empty struct. It exists so HTTPClient can be +// an immutable public variable with a unique type. It's immutable +// because nobody else can create a ContextKey, being unexported. +type ContextKey struct{} + +var appengineClientHook func(context.Context) *http.Client + +func ContextClient(ctx context.Context) *http.Client { + if ctx != nil { + if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok { + return hc + } + } + if appengineClientHook != nil { + return appengineClientHook(ctx) + } + return http.DefaultClient +} diff --git a/vendor/golang.org/x/oauth2/jws/jws.go b/vendor/golang.org/x/oauth2/jws/jws.go new file mode 100644 index 000000000000..683d2d271a30 --- /dev/null +++ b/vendor/golang.org/x/oauth2/jws/jws.go @@ -0,0 +1,182 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package jws provides a partial implementation +// of JSON Web Signature encoding and decoding. +// It exists to support the golang.org/x/oauth2 package. +// +// See RFC 7515. +// +// Deprecated: this package is not intended for public use and might be +// removed in the future. It exists for internal use only. +// Please switch to another JWS package or copy this package into your own +// source tree. +package jws // import "golang.org/x/oauth2/jws" + +import ( + "bytes" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "strings" + "time" +) + +// ClaimSet contains information about the JWT signature including the +// permissions being requested (scopes), the target of the token, the issuer, +// the time the token was issued, and the lifetime of the token. +type ClaimSet struct { + Iss string `json:"iss"` // email address of the client_id of the application making the access token request + Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests + Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional). + Exp int64 `json:"exp"` // the expiration time of the assertion (seconds since Unix epoch) + Iat int64 `json:"iat"` // the time the assertion was issued (seconds since Unix epoch) + Typ string `json:"typ,omitempty"` // token type (Optional). + + // Email for which the application is requesting delegated access (Optional). + Sub string `json:"sub,omitempty"` + + // The old name of Sub. Client keeps setting Prn to be + // complaint with legacy OAuth 2.0 providers. (Optional) + Prn string `json:"prn,omitempty"` + + // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3 + // This array is marshalled using custom code (see (c *ClaimSet) encode()). + PrivateClaims map[string]interface{} `json:"-"` +} + +func (c *ClaimSet) encode() (string, error) { + // Reverting time back for machines whose time is not perfectly in sync. + // If client machine's time is in the future according + // to Google servers, an access token will not be issued. + now := time.Now().Add(-10 * time.Second) + if c.Iat == 0 { + c.Iat = now.Unix() + } + if c.Exp == 0 { + c.Exp = now.Add(time.Hour).Unix() + } + if c.Exp < c.Iat { + return "", fmt.Errorf("jws: invalid Exp = %v; must be later than Iat = %v", c.Exp, c.Iat) + } + + b, err := json.Marshal(c) + if err != nil { + return "", err + } + + if len(c.PrivateClaims) == 0 { + return base64.RawURLEncoding.EncodeToString(b), nil + } + + // Marshal private claim set and then append it to b. + prv, err := json.Marshal(c.PrivateClaims) + if err != nil { + return "", fmt.Errorf("jws: invalid map of private claims %v", c.PrivateClaims) + } + + // Concatenate public and private claim JSON objects. + if !bytes.HasSuffix(b, []byte{'}'}) { + return "", fmt.Errorf("jws: invalid JSON %s", b) + } + if !bytes.HasPrefix(prv, []byte{'{'}) { + return "", fmt.Errorf("jws: invalid JSON %s", prv) + } + b[len(b)-1] = ',' // Replace closing curly brace with a comma. + b = append(b, prv[1:]...) // Append private claims. + return base64.RawURLEncoding.EncodeToString(b), nil +} + +// Header represents the header for the signed JWS payloads. +type Header struct { + // The algorithm used for signature. + Algorithm string `json:"alg"` + + // Represents the token type. + Typ string `json:"typ"` + + // The optional hint of which key is being used. + KeyID string `json:"kid,omitempty"` +} + +func (h *Header) encode() (string, error) { + b, err := json.Marshal(h) + if err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(b), nil +} + +// Decode decodes a claim set from a JWS payload. +func Decode(payload string) (*ClaimSet, error) { + // decode returned id token to get expiry + s := strings.Split(payload, ".") + if len(s) < 2 { + // TODO(jbd): Provide more context about the error. + return nil, errors.New("jws: invalid token received") + } + decoded, err := base64.RawURLEncoding.DecodeString(s[1]) + if err != nil { + return nil, err + } + c := &ClaimSet{} + err = json.NewDecoder(bytes.NewBuffer(decoded)).Decode(c) + return c, err +} + +// Signer returns a signature for the given data. +type Signer func(data []byte) (sig []byte, err error) + +// EncodeWithSigner encodes a header and claim set with the provided signer. +func EncodeWithSigner(header *Header, c *ClaimSet, sg Signer) (string, error) { + head, err := header.encode() + if err != nil { + return "", err + } + cs, err := c.encode() + if err != nil { + return "", err + } + ss := fmt.Sprintf("%s.%s", head, cs) + sig, err := sg([]byte(ss)) + if err != nil { + return "", err + } + return fmt.Sprintf("%s.%s", ss, base64.RawURLEncoding.EncodeToString(sig)), nil +} + +// Encode encodes a signed JWS with provided header and claim set. +// This invokes EncodeWithSigner using crypto/rsa.SignPKCS1v15 with the given RSA private key. +func Encode(header *Header, c *ClaimSet, key *rsa.PrivateKey) (string, error) { + sg := func(data []byte) (sig []byte, err error) { + h := sha256.New() + h.Write(data) + return rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil)) + } + return EncodeWithSigner(header, c, sg) +} + +// Verify tests whether the provided JWT token's signature was produced by the private key +// associated with the supplied public key. +func Verify(token string, key *rsa.PublicKey) error { + parts := strings.Split(token, ".") + if len(parts) != 3 { + return errors.New("jws: invalid token received, token must have 3 parts") + } + + signedContent := parts[0] + "." + parts[1] + signatureString, err := base64.RawURLEncoding.DecodeString(parts[2]) + if err != nil { + return err + } + + h := sha256.New() + h.Write([]byte(signedContent)) + return rsa.VerifyPKCS1v15(key, crypto.SHA256, h.Sum(nil), []byte(signatureString)) +} diff --git a/vendor/golang.org/x/oauth2/jwt/jwt.go b/vendor/golang.org/x/oauth2/jwt/jwt.go new file mode 100644 index 000000000000..99f3e0a32c8a --- /dev/null +++ b/vendor/golang.org/x/oauth2/jwt/jwt.go @@ -0,0 +1,170 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package jwt implements the OAuth 2.0 JSON Web Token flow, commonly +// known as "two-legged OAuth 2.0". +// +// See: https://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12 +package jwt + +import ( + "context" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strings" + "time" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/internal" + "golang.org/x/oauth2/jws" +) + +var ( + defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" + defaultHeader = &jws.Header{Algorithm: "RS256", Typ: "JWT"} +) + +// Config is the configuration for using JWT to fetch tokens, +// commonly known as "two-legged OAuth 2.0". +type Config struct { + // Email is the OAuth client identifier used when communicating with + // the configured OAuth provider. + Email string + + // PrivateKey contains the contents of an RSA private key or the + // contents of a PEM file that contains a private key. The provided + // private key is used to sign JWT payloads. + // PEM containers with a passphrase are not supported. + // Use the following command to convert a PKCS 12 file into a PEM. + // + // $ openssl pkcs12 -in key.p12 -out key.pem -nodes + // + PrivateKey []byte + + // PrivateKeyID contains an optional hint indicating which key is being + // used. + PrivateKeyID string + + // Subject is the optional user to impersonate. + Subject string + + // Scopes optionally specifies a list of requested permission scopes. + Scopes []string + + // TokenURL is the endpoint required to complete the 2-legged JWT flow. + TokenURL string + + // Expires optionally specifies how long the token is valid for. + Expires time.Duration + + // Audience optionally specifies the intended audience of the + // request. If empty, the value of TokenURL is used as the + // intended audience. + Audience string +} + +// TokenSource returns a JWT TokenSource using the configuration +// in c and the HTTP client from the provided context. +func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource { + return oauth2.ReuseTokenSource(nil, jwtSource{ctx, c}) +} + +// Client returns an HTTP client wrapping the context's +// HTTP transport and adding Authorization headers with tokens +// obtained from c. +// +// The returned client and its Transport should not be modified. +func (c *Config) Client(ctx context.Context) *http.Client { + return oauth2.NewClient(ctx, c.TokenSource(ctx)) +} + +// jwtSource is a source that always does a signed JWT request for a token. +// It should typically be wrapped with a reuseTokenSource. +type jwtSource struct { + ctx context.Context + conf *Config +} + +func (js jwtSource) Token() (*oauth2.Token, error) { + pk, err := internal.ParseKey(js.conf.PrivateKey) + if err != nil { + return nil, err + } + hc := oauth2.NewClient(js.ctx, nil) + claimSet := &jws.ClaimSet{ + Iss: js.conf.Email, + Scope: strings.Join(js.conf.Scopes, " "), + Aud: js.conf.TokenURL, + } + if subject := js.conf.Subject; subject != "" { + claimSet.Sub = subject + // prn is the old name of sub. Keep setting it + // to be compatible with legacy OAuth 2.0 providers. + claimSet.Prn = subject + } + if t := js.conf.Expires; t > 0 { + claimSet.Exp = time.Now().Add(t).Unix() + } + if aud := js.conf.Audience; aud != "" { + claimSet.Aud = aud + } + h := *defaultHeader + h.KeyID = js.conf.PrivateKeyID + payload, err := jws.Encode(&h, claimSet, pk) + if err != nil { + return nil, err + } + v := url.Values{} + v.Set("grant_type", defaultGrantType) + v.Set("assertion", payload) + resp, err := hc.PostForm(js.conf.TokenURL, v) + if err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + if c := resp.StatusCode; c < 200 || c > 299 { + return nil, &oauth2.RetrieveError{ + Response: resp, + Body: body, + } + } + // tokenRes is the JSON response body. + var tokenRes struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + IDToken string `json:"id_token"` + ExpiresIn int64 `json:"expires_in"` // relative seconds from now + } + if err := json.Unmarshal(body, &tokenRes); err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + token := &oauth2.Token{ + AccessToken: tokenRes.AccessToken, + TokenType: tokenRes.TokenType, + } + raw := make(map[string]interface{}) + json.Unmarshal(body, &raw) // no error checks for optional fields + token = token.WithExtra(raw) + + if secs := tokenRes.ExpiresIn; secs > 0 { + token.Expiry = time.Now().Add(time.Duration(secs) * time.Second) + } + if v := tokenRes.IDToken; v != "" { + // decode returned id token to get expiry + claimSet, err := jws.Decode(v) + if err != nil { + return nil, fmt.Errorf("oauth2: error decoding JWT token: %v", err) + } + token.Expiry = time.Unix(claimSet.Exp, 0) + } + return token, nil +} diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go new file mode 100644 index 000000000000..428283f0b010 --- /dev/null +++ b/vendor/golang.org/x/oauth2/oauth2.go @@ -0,0 +1,381 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package oauth2 provides support for making +// OAuth2 authorized and authenticated HTTP requests, +// as specified in RFC 6749. +// It can additionally grant authorization with Bearer JWT. +package oauth2 // import "golang.org/x/oauth2" + +import ( + "bytes" + "context" + "errors" + "net/http" + "net/url" + "strings" + "sync" + + "golang.org/x/oauth2/internal" +) + +// NoContext is the default context you should supply if not using +// your own context.Context (see https://golang.org/x/net/context). +// +// Deprecated: Use context.Background() or context.TODO() instead. +var NoContext = context.TODO() + +// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op. +// +// Deprecated: this function no longer does anything. Caller code that +// wants to avoid potential extra HTTP requests made during +// auto-probing of the provider's auth style should set +// Endpoint.AuthStyle. +func RegisterBrokenAuthHeaderProvider(tokenURL string) {} + +// Config describes a typical 3-legged OAuth2 flow, with both the +// client application information and the server's endpoint URLs. +// For the client credentials 2-legged OAuth2 flow, see the clientcredentials +// package (https://golang.org/x/oauth2/clientcredentials). +type Config struct { + // ClientID is the application's ID. + ClientID string + + // ClientSecret is the application's secret. + ClientSecret string + + // Endpoint contains the resource server's token endpoint + // URLs. These are constants specific to each server and are + // often available via site-specific packages, such as + // google.Endpoint or github.Endpoint. + Endpoint Endpoint + + // RedirectURL is the URL to redirect users going through + // the OAuth flow, after the resource owner's URLs. + RedirectURL string + + // Scope specifies optional requested permissions. + Scopes []string +} + +// A TokenSource is anything that can return a token. +type TokenSource interface { + // Token returns a token or an error. + // Token must be safe for concurrent use by multiple goroutines. + // The returned Token must not be modified. + Token() (*Token, error) +} + +// Endpoint represents an OAuth 2.0 provider's authorization and token +// endpoint URLs. +type Endpoint struct { + AuthURL string + TokenURL string + + // AuthStyle optionally specifies how the endpoint wants the + // client ID & client secret sent. The zero value means to + // auto-detect. + AuthStyle AuthStyle +} + +// AuthStyle represents how requests for tokens are authenticated +// to the server. +type AuthStyle int + +const ( + // AuthStyleAutoDetect means to auto-detect which authentication + // style the provider wants by trying both ways and caching + // the successful way for the future. + AuthStyleAutoDetect AuthStyle = 0 + + // AuthStyleInParams sends the "client_id" and "client_secret" + // in the POST body as application/x-www-form-urlencoded parameters. + AuthStyleInParams AuthStyle = 1 + + // AuthStyleInHeader sends the client_id and client_password + // using HTTP Basic Authorization. This is an optional style + // described in the OAuth2 RFC 6749 section 2.3.1. + AuthStyleInHeader AuthStyle = 2 +) + +var ( + // AccessTypeOnline and AccessTypeOffline are options passed + // to the Options.AuthCodeURL method. They modify the + // "access_type" field that gets sent in the URL returned by + // AuthCodeURL. + // + // Online is the default if neither is specified. If your + // application needs to refresh access tokens when the user + // is not present at the browser, then use offline. This will + // result in your application obtaining a refresh token the + // first time your application exchanges an authorization + // code for a user. + AccessTypeOnline AuthCodeOption = SetAuthURLParam("access_type", "online") + AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline") + + // ApprovalForce forces the users to view the consent dialog + // and confirm the permissions request at the URL returned + // from AuthCodeURL, even if they've already done so. + ApprovalForce AuthCodeOption = SetAuthURLParam("approval_prompt", "force") +) + +// An AuthCodeOption is passed to Config.AuthCodeURL. +type AuthCodeOption interface { + setValue(url.Values) +} + +type setParam struct{ k, v string } + +func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) } + +// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters +// to a provider's authorization endpoint. +func SetAuthURLParam(key, value string) AuthCodeOption { + return setParam{key, value} +} + +// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page +// that asks for permissions for the required scopes explicitly. +// +// State is a token to protect the user from CSRF attacks. You must +// always provide a non-empty string and validate that it matches the +// the state query parameter on your redirect callback. +// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info. +// +// Opts may include AccessTypeOnline or AccessTypeOffline, as well +// as ApprovalForce. +// It can also be used to pass the PKCE challenge. +// See https://www.oauth.com/oauth2-servers/pkce/ for more info. +func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string { + var buf bytes.Buffer + buf.WriteString(c.Endpoint.AuthURL) + v := url.Values{ + "response_type": {"code"}, + "client_id": {c.ClientID}, + } + if c.RedirectURL != "" { + v.Set("redirect_uri", c.RedirectURL) + } + if len(c.Scopes) > 0 { + v.Set("scope", strings.Join(c.Scopes, " ")) + } + if state != "" { + // TODO(light): Docs say never to omit state; don't allow empty. + v.Set("state", state) + } + for _, opt := range opts { + opt.setValue(v) + } + if strings.Contains(c.Endpoint.AuthURL, "?") { + buf.WriteByte('&') + } else { + buf.WriteByte('?') + } + buf.WriteString(v.Encode()) + return buf.String() +} + +// PasswordCredentialsToken converts a resource owner username and password +// pair into a token. +// +// Per the RFC, this grant type should only be used "when there is a high +// degree of trust between the resource owner and the client (e.g., the client +// is part of the device operating system or a highly privileged application), +// and when other authorization grant types are not available." +// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info. +// +// The provided context optionally controls which HTTP client is used. See the HTTPClient variable. +func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) { + v := url.Values{ + "grant_type": {"password"}, + "username": {username}, + "password": {password}, + } + if len(c.Scopes) > 0 { + v.Set("scope", strings.Join(c.Scopes, " ")) + } + return retrieveToken(ctx, c, v) +} + +// Exchange converts an authorization code into a token. +// +// It is used after a resource provider redirects the user back +// to the Redirect URI (the URL obtained from AuthCodeURL). +// +// The provided context optionally controls which HTTP client is used. See the HTTPClient variable. +// +// The code will be in the *http.Request.FormValue("code"). Before +// calling Exchange, be sure to validate FormValue("state"). +// +// Opts may include the PKCE verifier code if previously used in AuthCodeURL. +// See https://www.oauth.com/oauth2-servers/pkce/ for more info. +func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOption) (*Token, error) { + v := url.Values{ + "grant_type": {"authorization_code"}, + "code": {code}, + } + if c.RedirectURL != "" { + v.Set("redirect_uri", c.RedirectURL) + } + for _, opt := range opts { + opt.setValue(v) + } + return retrieveToken(ctx, c, v) +} + +// Client returns an HTTP client using the provided token. +// The token will auto-refresh as necessary. The underlying +// HTTP transport will be obtained using the provided context. +// The returned client and its Transport should not be modified. +func (c *Config) Client(ctx context.Context, t *Token) *http.Client { + return NewClient(ctx, c.TokenSource(ctx, t)) +} + +// TokenSource returns a TokenSource that returns t until t expires, +// automatically refreshing it as necessary using the provided context. +// +// Most users will use Config.Client instead. +func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource { + tkr := &tokenRefresher{ + ctx: ctx, + conf: c, + } + if t != nil { + tkr.refreshToken = t.RefreshToken + } + return &reuseTokenSource{ + t: t, + new: tkr, + } +} + +// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token" +// HTTP requests to renew a token using a RefreshToken. +type tokenRefresher struct { + ctx context.Context // used to get HTTP requests + conf *Config + refreshToken string +} + +// WARNING: Token is not safe for concurrent access, as it +// updates the tokenRefresher's refreshToken field. +// Within this package, it is used by reuseTokenSource which +// synchronizes calls to this method with its own mutex. +func (tf *tokenRefresher) Token() (*Token, error) { + if tf.refreshToken == "" { + return nil, errors.New("oauth2: token expired and refresh token is not set") + } + + tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{ + "grant_type": {"refresh_token"}, + "refresh_token": {tf.refreshToken}, + }) + + if err != nil { + return nil, err + } + if tf.refreshToken != tk.RefreshToken { + tf.refreshToken = tk.RefreshToken + } + return tk, err +} + +// reuseTokenSource is a TokenSource that holds a single token in memory +// and validates its expiry before each call to retrieve it with +// Token. If it's expired, it will be auto-refreshed using the +// new TokenSource. +type reuseTokenSource struct { + new TokenSource // called when t is expired. + + mu sync.Mutex // guards t + t *Token +} + +// Token returns the current token if it's still valid, else will +// refresh the current token (using r.Context for HTTP client +// information) and return the new one. +func (s *reuseTokenSource) Token() (*Token, error) { + s.mu.Lock() + defer s.mu.Unlock() + if s.t.Valid() { + return s.t, nil + } + t, err := s.new.Token() + if err != nil { + return nil, err + } + s.t = t + return t, nil +} + +// StaticTokenSource returns a TokenSource that always returns the same token. +// Because the provided token t is never refreshed, StaticTokenSource is only +// useful for tokens that never expire. +func StaticTokenSource(t *Token) TokenSource { + return staticTokenSource{t} +} + +// staticTokenSource is a TokenSource that always returns the same Token. +type staticTokenSource struct { + t *Token +} + +func (s staticTokenSource) Token() (*Token, error) { + return s.t, nil +} + +// HTTPClient is the context key to use with golang.org/x/net/context's +// WithValue function to associate an *http.Client value with a context. +var HTTPClient internal.ContextKey + +// NewClient creates an *http.Client from a Context and TokenSource. +// The returned client is not valid beyond the lifetime of the context. +// +// Note that if a custom *http.Client is provided via the Context it +// is used only for token acquisition and is not used to configure the +// *http.Client returned from NewClient. +// +// As a special case, if src is nil, a non-OAuth2 client is returned +// using the provided context. This exists to support related OAuth2 +// packages. +func NewClient(ctx context.Context, src TokenSource) *http.Client { + if src == nil { + return internal.ContextClient(ctx) + } + return &http.Client{ + Transport: &Transport{ + Base: internal.ContextClient(ctx).Transport, + Source: ReuseTokenSource(nil, src), + }, + } +} + +// ReuseTokenSource returns a TokenSource which repeatedly returns the +// same token as long as it's valid, starting with t. +// When its cached token is invalid, a new token is obtained from src. +// +// ReuseTokenSource is typically used to reuse tokens from a cache +// (such as a file on disk) between runs of a program, rather than +// obtaining new tokens unnecessarily. +// +// The initial token t may be nil, in which case the TokenSource is +// wrapped in a caching version if it isn't one already. This also +// means it's always safe to wrap ReuseTokenSource around any other +// TokenSource without adverse effects. +func ReuseTokenSource(t *Token, src TokenSource) TokenSource { + // Don't wrap a reuseTokenSource in itself. That would work, + // but cause an unnecessary number of mutex operations. + // Just build the equivalent one. + if rt, ok := src.(*reuseTokenSource); ok { + if t == nil { + // Just use it directly. + return rt + } + src = rt.new + } + return &reuseTokenSource{ + t: t, + new: src, + } +} diff --git a/vendor/golang.org/x/oauth2/token.go b/vendor/golang.org/x/oauth2/token.go new file mode 100644 index 000000000000..822720341af1 --- /dev/null +++ b/vendor/golang.org/x/oauth2/token.go @@ -0,0 +1,178 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2 + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "golang.org/x/oauth2/internal" +) + +// expiryDelta determines how earlier a token should be considered +// expired than its actual expiration time. It is used to avoid late +// expirations due to client-server time mismatches. +const expiryDelta = 10 * time.Second + +// Token represents the credentials used to authorize +// the requests to access protected resources on the OAuth 2.0 +// provider's backend. +// +// Most users of this package should not access fields of Token +// directly. They're exported mostly for use by related packages +// implementing derivative OAuth2 flows. +type Token struct { + // AccessToken is the token that authorizes and authenticates + // the requests. + AccessToken string `json:"access_token"` + + // TokenType is the type of token. + // The Type method returns either this or "Bearer", the default. + TokenType string `json:"token_type,omitempty"` + + // RefreshToken is a token that's used by the application + // (as opposed to the user) to refresh the access token + // if it expires. + RefreshToken string `json:"refresh_token,omitempty"` + + // Expiry is the optional expiration time of the access token. + // + // If zero, TokenSource implementations will reuse the same + // token forever and RefreshToken or equivalent + // mechanisms for that TokenSource will not be used. + Expiry time.Time `json:"expiry,omitempty"` + + // raw optionally contains extra metadata from the server + // when updating a token. + raw interface{} +} + +// Type returns t.TokenType if non-empty, else "Bearer". +func (t *Token) Type() string { + if strings.EqualFold(t.TokenType, "bearer") { + return "Bearer" + } + if strings.EqualFold(t.TokenType, "mac") { + return "MAC" + } + if strings.EqualFold(t.TokenType, "basic") { + return "Basic" + } + if t.TokenType != "" { + return t.TokenType + } + return "Bearer" +} + +// SetAuthHeader sets the Authorization header to r using the access +// token in t. +// +// This method is unnecessary when using Transport or an HTTP Client +// returned by this package. +func (t *Token) SetAuthHeader(r *http.Request) { + r.Header.Set("Authorization", t.Type()+" "+t.AccessToken) +} + +// WithExtra returns a new Token that's a clone of t, but using the +// provided raw extra map. This is only intended for use by packages +// implementing derivative OAuth2 flows. +func (t *Token) WithExtra(extra interface{}) *Token { + t2 := new(Token) + *t2 = *t + t2.raw = extra + return t2 +} + +// Extra returns an extra field. +// Extra fields are key-value pairs returned by the server as a +// part of the token retrieval response. +func (t *Token) Extra(key string) interface{} { + if raw, ok := t.raw.(map[string]interface{}); ok { + return raw[key] + } + + vals, ok := t.raw.(url.Values) + if !ok { + return nil + } + + v := vals.Get(key) + switch s := strings.TrimSpace(v); strings.Count(s, ".") { + case 0: // Contains no "."; try to parse as int + if i, err := strconv.ParseInt(s, 10, 64); err == nil { + return i + } + case 1: // Contains a single "."; try to parse as float + if f, err := strconv.ParseFloat(s, 64); err == nil { + return f + } + } + + return v +} + +// timeNow is time.Now but pulled out as a variable for tests. +var timeNow = time.Now + +// expired reports whether the token is expired. +// t must be non-nil. +func (t *Token) expired() bool { + if t.Expiry.IsZero() { + return false + } + return t.Expiry.Round(0).Add(-expiryDelta).Before(timeNow()) +} + +// Valid reports whether t is non-nil, has an AccessToken, and is not expired. +func (t *Token) Valid() bool { + return t != nil && t.AccessToken != "" && !t.expired() +} + +// tokenFromInternal maps an *internal.Token struct into +// a *Token struct. +func tokenFromInternal(t *internal.Token) *Token { + if t == nil { + return nil + } + return &Token{ + AccessToken: t.AccessToken, + TokenType: t.TokenType, + RefreshToken: t.RefreshToken, + Expiry: t.Expiry, + raw: t.Raw, + } +} + +// retrieveToken takes a *Config and uses that to retrieve an *internal.Token. +// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along +// with an error.. +func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) { + tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle)) + if err != nil { + if rErr, ok := err.(*internal.RetrieveError); ok { + return nil, (*RetrieveError)(rErr) + } + return nil, err + } + return tokenFromInternal(tk), nil +} + +// RetrieveError is the error returned when the token endpoint returns a +// non-2XX HTTP status code. +type RetrieveError struct { + Response *http.Response + // Body is the body that was consumed by reading Response.Body. + // It may be truncated. + Body []byte +} + +func (r *RetrieveError) Error() string { + return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body) +} diff --git a/vendor/golang.org/x/oauth2/transport.go b/vendor/golang.org/x/oauth2/transport.go new file mode 100644 index 000000000000..aa0d34f1e0ea --- /dev/null +++ b/vendor/golang.org/x/oauth2/transport.go @@ -0,0 +1,144 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2 + +import ( + "errors" + "io" + "net/http" + "sync" +) + +// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests, +// wrapping a base RoundTripper and adding an Authorization header +// with a token from the supplied Sources. +// +// Transport is a low-level mechanism. Most code will use the +// higher-level Config.Client method instead. +type Transport struct { + // Source supplies the token to add to outgoing requests' + // Authorization headers. + Source TokenSource + + // Base is the base RoundTripper used to make HTTP requests. + // If nil, http.DefaultTransport is used. + Base http.RoundTripper + + mu sync.Mutex // guards modReq + modReq map[*http.Request]*http.Request // original -> modified +} + +// RoundTrip authorizes and authenticates the request with an +// access token from Transport's Source. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { + reqBodyClosed := false + if req.Body != nil { + defer func() { + if !reqBodyClosed { + req.Body.Close() + } + }() + } + + if t.Source == nil { + return nil, errors.New("oauth2: Transport's Source is nil") + } + token, err := t.Source.Token() + if err != nil { + return nil, err + } + + req2 := cloneRequest(req) // per RoundTripper contract + token.SetAuthHeader(req2) + t.setModReq(req, req2) + res, err := t.base().RoundTrip(req2) + + // req.Body is assumed to have been closed by the base RoundTripper. + reqBodyClosed = true + + if err != nil { + t.setModReq(req, nil) + return nil, err + } + res.Body = &onEOFReader{ + rc: res.Body, + fn: func() { t.setModReq(req, nil) }, + } + return res, nil +} + +// CancelRequest cancels an in-flight request by closing its connection. +func (t *Transport) CancelRequest(req *http.Request) { + type canceler interface { + CancelRequest(*http.Request) + } + if cr, ok := t.base().(canceler); ok { + t.mu.Lock() + modReq := t.modReq[req] + delete(t.modReq, req) + t.mu.Unlock() + cr.CancelRequest(modReq) + } +} + +func (t *Transport) base() http.RoundTripper { + if t.Base != nil { + return t.Base + } + return http.DefaultTransport +} + +func (t *Transport) setModReq(orig, mod *http.Request) { + t.mu.Lock() + defer t.mu.Unlock() + if t.modReq == nil { + t.modReq = make(map[*http.Request]*http.Request) + } + if mod == nil { + delete(t.modReq, orig) + } else { + t.modReq[orig] = mod + } +} + +// cloneRequest returns a clone of the provided *http.Request. +// The clone is a shallow copy of the struct and its Header map. +func cloneRequest(r *http.Request) *http.Request { + // shallow copy of the struct + r2 := new(http.Request) + *r2 = *r + // deep copy of the Header + r2.Header = make(http.Header, len(r.Header)) + for k, s := range r.Header { + r2.Header[k] = append([]string(nil), s...) + } + return r2 +} + +type onEOFReader struct { + rc io.ReadCloser + fn func() +} + +func (r *onEOFReader) Read(p []byte) (n int, err error) { + n, err = r.rc.Read(p) + if err == io.EOF { + r.runFunc() + } + return +} + +func (r *onEOFReader) Close() error { + err := r.rc.Close() + r.runFunc() + return err +} + +func (r *onEOFReader) runFunc() { + if fn := r.fn; fn != nil { + fn() + r.fn = nil + } +} diff --git a/vendor/golang.org/x/sync/PATENTS b/vendor/golang.org/x/sync/PATENTS deleted file mode 100644 index 733099041f84..000000000000 --- a/vendor/golang.org/x/sync/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google 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, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/sync/semaphore/semaphore.go b/vendor/golang.org/x/sync/semaphore/semaphore.go deleted file mode 100644 index ac53e733e795..000000000000 --- a/vendor/golang.org/x/sync/semaphore/semaphore.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package semaphore provides a weighted semaphore implementation. -package semaphore // import "golang.org/x/sync/semaphore" - -import ( - "container/list" - "context" - "sync" -) - -type waiter struct { - n int64 - ready chan<- struct{} // Closed when semaphore acquired. -} - -// NewWeighted creates a new weighted semaphore with the given -// maximum combined weight for concurrent access. -func NewWeighted(n int64) *Weighted { - w := &Weighted{size: n} - return w -} - -// Weighted provides a way to bound concurrent access to a resource. -// The callers can request access with a given weight. -type Weighted struct { - size int64 - cur int64 - mu sync.Mutex - waiters list.List -} - -// Acquire acquires the semaphore with a weight of n, blocking until resources -// are available or ctx is done. On success, returns nil. On failure, returns -// ctx.Err() and leaves the semaphore unchanged. -// -// If ctx is already done, Acquire may still succeed without blocking. -func (s *Weighted) Acquire(ctx context.Context, n int64) error { - s.mu.Lock() - if s.size-s.cur >= n && s.waiters.Len() == 0 { - s.cur += n - s.mu.Unlock() - return nil - } - - if n > s.size { - // Don't make other Acquire calls block on one that's doomed to fail. - s.mu.Unlock() - <-ctx.Done() - return ctx.Err() - } - - ready := make(chan struct{}) - w := waiter{n: n, ready: ready} - elem := s.waiters.PushBack(w) - s.mu.Unlock() - - select { - case <-ctx.Done(): - err := ctx.Err() - s.mu.Lock() - select { - case <-ready: - // Acquired the semaphore after we were canceled. Rather than trying to - // fix up the queue, just pretend we didn't notice the cancelation. - err = nil - default: - s.waiters.Remove(elem) - } - s.mu.Unlock() - return err - - case <-ready: - return nil - } -} - -// TryAcquire acquires the semaphore with a weight of n without blocking. -// On success, returns true. On failure, returns false and leaves the semaphore unchanged. -func (s *Weighted) TryAcquire(n int64) bool { - s.mu.Lock() - success := s.size-s.cur >= n && s.waiters.Len() == 0 - if success { - s.cur += n - } - s.mu.Unlock() - return success -} - -// Release releases the semaphore with a weight of n. -func (s *Weighted) Release(n int64) { - s.mu.Lock() - s.cur -= n - if s.cur < 0 { - s.mu.Unlock() - panic("semaphore: bad release") - } - for { - next := s.waiters.Front() - if next == nil { - break // No more waiters blocked. - } - - w := next.Value.(waiter) - if s.size-s.cur < w.n { - // Not enough tokens for the next waiter. We could keep going (to try to - // find a waiter with a smaller request), but under load that could cause - // starvation for large requests; instead, we leave all remaining waiters - // blocked. - // - // Consider a semaphore used as a read-write lock, with N tokens, N - // readers, and one writer. Each reader can Acquire(1) to obtain a read - // lock. The writer can Acquire(N) to obtain a write lock, excluding all - // of the readers. If we allow the readers to jump ahead in the queue, - // the writer will starve — there is always one token available for every - // reader. - break - } - - s.cur += w.n - s.waiters.Remove(next) - close(w.ready) - } - s.mu.Unlock() -} diff --git a/vendor/golang.org/x/sys/cpu/byteorder.go b/vendor/golang.org/x/sys/cpu/byteorder.go new file mode 100644 index 000000000000..da6b9e4363d4 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/byteorder.go @@ -0,0 +1,30 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +import ( + "encoding/binary" + "runtime" +) + +// hostByteOrder returns binary.LittleEndian on little-endian machines and +// binary.BigEndian on big-endian machines. +func hostByteOrder() binary.ByteOrder { + switch runtime.GOARCH { + case "386", "amd64", "amd64p32", + "arm", "arm64", + "mipsle", "mips64le", "mips64p32le", + "ppc64le", + "riscv", "riscv64": + return binary.LittleEndian + case "armbe", "arm64be", + "mips", "mips64", "mips64p32", + "ppc", "ppc64", + "s390", "s390x", + "sparc", "sparc64": + return binary.BigEndian + } + panic("unknown architecture") +} diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go new file mode 100644 index 000000000000..679e78c2cefe --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -0,0 +1,126 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cpu implements processor feature detection for +// various CPU architectures. +package cpu + +// Initialized reports whether the CPU features were initialized. +// +// For some GOOS/GOARCH combinations initialization of the CPU features depends +// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm +// Initialized will report false if reading the file fails. +var Initialized bool + +// CacheLinePad is used to pad structs to avoid false sharing. +type CacheLinePad struct{ _ [cacheLineSize]byte } + +// X86 contains the supported CPU features of the +// current X86/AMD64 platform. If the current platform +// is not X86/AMD64 then all feature flags are false. +// +// X86 is padded to avoid false sharing. Further the HasAVX +// and HasAVX2 are only set if the OS supports XMM and YMM +// registers in addition to the CPUID feature bit being set. +var X86 struct { + _ CacheLinePad + HasAES bool // AES hardware implementation (AES NI) + HasADX bool // Multi-precision add-carry instruction extensions + HasAVX bool // Advanced vector extension + HasAVX2 bool // Advanced vector extension 2 + HasBMI1 bool // Bit manipulation instruction set 1 + HasBMI2 bool // Bit manipulation instruction set 2 + HasERMS bool // Enhanced REP for MOVSB and STOSB + HasFMA bool // Fused-multiply-add instructions + HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers. + HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM + HasPOPCNT bool // Hamming weight instruction POPCNT. + HasRDRAND bool // RDRAND instruction (on-chip random number generator) + HasRDSEED bool // RDSEED instruction (on-chip random number generator) + HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64) + HasSSE3 bool // Streaming SIMD extension 3 + HasSSSE3 bool // Supplemental streaming SIMD extension 3 + HasSSE41 bool // Streaming SIMD extension 4 and 4.1 + HasSSE42 bool // Streaming SIMD extension 4 and 4.2 + _ CacheLinePad +} + +// ARM64 contains the supported CPU features of the +// current ARMv8(aarch64) platform. If the current platform +// is not arm64 then all feature flags are false. +var ARM64 struct { + _ CacheLinePad + HasFP bool // Floating-point instruction set (always available) + HasASIMD bool // Advanced SIMD (always available) + HasEVTSTRM bool // Event stream support + HasAES bool // AES hardware implementation + HasPMULL bool // Polynomial multiplication instruction set + HasSHA1 bool // SHA1 hardware implementation + HasSHA2 bool // SHA2 hardware implementation + HasCRC32 bool // CRC32 hardware implementation + HasATOMICS bool // Atomic memory operation instruction set + HasFPHP bool // Half precision floating-point instruction set + HasASIMDHP bool // Advanced SIMD half precision instruction set + HasCPUID bool // CPUID identification scheme registers + HasASIMDRDM bool // Rounding double multiply add/subtract instruction set + HasJSCVT bool // Javascript conversion from floating-point to integer + HasFCMA bool // Floating-point multiplication and addition of complex numbers + HasLRCPC bool // Release Consistent processor consistent support + HasDCPOP bool // Persistent memory support + HasSHA3 bool // SHA3 hardware implementation + HasSM3 bool // SM3 hardware implementation + HasSM4 bool // SM4 hardware implementation + HasASIMDDP bool // Advanced SIMD double precision instruction set + HasSHA512 bool // SHA512 hardware implementation + HasSVE bool // Scalable Vector Extensions + HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32 + _ CacheLinePad +} + +// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms. +// If the current platform is not ppc64/ppc64le then all feature flags are false. +// +// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00, +// since there are no optional categories. There are some exceptions that also +// require kernel support to work (DARN, SCV), so there are feature bits for +// those as well. The minimum processor requirement is POWER8 (ISA 2.07). +// The struct is padded to avoid false sharing. +var PPC64 struct { + _ CacheLinePad + HasDARN bool // Hardware random number generator (requires kernel enablement) + HasSCV bool // Syscall vectored (requires kernel enablement) + IsPOWER8 bool // ISA v2.07 (POWER8) + IsPOWER9 bool // ISA v3.00 (POWER9) + _ CacheLinePad +} + +// S390X contains the supported CPU features of the current IBM Z +// (s390x) platform. If the current platform is not IBM Z then all +// feature flags are false. +// +// S390X is padded to avoid false sharing. Further HasVX is only set +// if the OS supports vector registers in addition to the STFLE +// feature bit being set. +var S390X struct { + _ CacheLinePad + HasZARCH bool // z/Architecture mode is active [mandatory] + HasSTFLE bool // store facility list extended + HasLDISP bool // long (20-bit) displacements + HasEIMM bool // 32-bit immediates + HasDFP bool // decimal floating point + HasETF3EH bool // ETF-3 enhanced + HasMSA bool // message security assist (CPACF) + HasAES bool // KM-AES{128,192,256} functions + HasAESCBC bool // KMC-AES{128,192,256} functions + HasAESCTR bool // KMCTR-AES{128,192,256} functions + HasAESGCM bool // KMA-GCM-AES{128,192,256} functions + HasGHASH bool // KIMD-GHASH function + HasSHA1 bool // K{I,L}MD-SHA-1 functions + HasSHA256 bool // K{I,L}MD-SHA-256 functions + HasSHA512 bool // K{I,L}MD-SHA-512 functions + HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions + HasVX bool // vector facility + HasVXE bool // vector-enhancements facility 1 + _ CacheLinePad +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_aix_ppc64.go b/vendor/golang.org/x/sys/cpu/cpu_aix_ppc64.go new file mode 100644 index 000000000000..d8c26a048d73 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_aix_ppc64.go @@ -0,0 +1,30 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix,ppc64 + +package cpu + +import "golang.org/x/sys/unix" + +const cacheLineSize = 128 + +const ( + // getsystemcfg constants + _SC_IMPL = 2 + _IMPL_POWER8 = 0x10000 + _IMPL_POWER9 = 0x20000 +) + +func init() { + impl := unix.Getsystemcfg(_SC_IMPL) + if impl&_IMPL_POWER8 != 0 { + PPC64.IsPOWER8 = true + } + if impl&_IMPL_POWER9 != 0 { + PPC64.IsPOWER9 = true + } + + Initialized = true +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm.go b/vendor/golang.org/x/sys/cpu/cpu_arm.go new file mode 100644 index 000000000000..7f2348b7d4b6 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_arm.go @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +const cacheLineSize = 32 + +func doinit() {} diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go new file mode 100644 index 000000000000..568bcd031aa4 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go @@ -0,0 +1,21 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +package cpu + +// haveAsmFunctions reports whether the other functions in this file can +// be safely called. +func haveAsmFunctions() bool { return true } + +// The following feature detection functions are defined in cpu_s390x.s. +// They are likely to be expensive to call so the results should be cached. +func stfle() facilityList +func kmQuery() queryResult +func kmcQuery() queryResult +func kmctrQuery() queryResult +func kmaQuery() queryResult +func kimdQuery() queryResult +func klmdQuery() queryResult diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go new file mode 100644 index 000000000000..f7cb46971cb0 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go @@ -0,0 +1,16 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build 386 amd64 amd64p32 +// +build !gccgo + +package cpu + +// cpuid is implemented in cpu_x86.s for gc compiler +// and in cpu_gccgo.c for gccgo. +func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) + +// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler +// and in cpu_gccgo.c for gccgo. +func xgetbv() (eax, edx uint32) diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo.c b/vendor/golang.org/x/sys/cpu/cpu_gccgo.c new file mode 100644 index 000000000000..e363c7d13197 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo.c @@ -0,0 +1,43 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build 386 amd64 amd64p32 +// +build gccgo + +#include <cpuid.h> +#include <stdint.h> + +// Need to wrap __get_cpuid_count because it's declared as static. +int +gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf, + uint32_t *eax, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx) +{ + return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx); +} + +// xgetbv reads the contents of an XCR (Extended Control Register) +// specified in the ECX register into registers EDX:EAX. +// Currently, the only supported value for XCR is 0. +// +// TODO: Replace with a better alternative: +// +// #include <xsaveintrin.h> +// +// #pragma GCC target("xsave") +// +// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) { +// unsigned long long x = _xgetbv(0); +// *eax = x & 0xffffffff; +// *edx = (x >> 32) & 0xffffffff; +// } +// +// Note that _xgetbv is defined starting with GCC 8. +void +gccgoXgetbv(uint32_t *eax, uint32_t *edx) +{ + __asm(" xorl %%ecx, %%ecx\n" + " xgetbv" + : "=a"(*eax), "=d"(*edx)); +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo.go new file mode 100644 index 000000000000..ba49b91bd398 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build 386 amd64 amd64p32 +// +build gccgo + +package cpu + +//extern gccgoGetCpuidCount +func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32) + +func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) { + var a, b, c, d uint32 + gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d) + return a, b, c, d +} + +//extern gccgoXgetbv +func gccgoXgetbv(eax, edx *uint32) + +func xgetbv() (eax, edx uint32) { + var a, d uint32 + gccgoXgetbv(&a, &d) + return a, d +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go new file mode 100644 index 000000000000..aa986f77825f --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go @@ -0,0 +1,22 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gccgo + +package cpu + +// haveAsmFunctions reports whether the other functions in this file can +// be safely called. +func haveAsmFunctions() bool { return false } + +// TODO(mundaym): the following feature detection functions are currently +// stubs. See https://golang.org/cl/162887 for how to fix this. +// They are likely to be expensive to call so the results should be cached. +func stfle() facilityList { panic("not implemented for gccgo") } +func kmQuery() queryResult { panic("not implemented for gccgo") } +func kmcQuery() queryResult { panic("not implemented for gccgo") } +func kmctrQuery() queryResult { panic("not implemented for gccgo") } +func kmaQuery() queryResult { panic("not implemented for gccgo") } +func kimdQuery() queryResult { panic("not implemented for gccgo") } +func klmdQuery() queryResult { panic("not implemented for gccgo") } diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux.go b/vendor/golang.org/x/sys/cpu/cpu_linux.go new file mode 100644 index 000000000000..76b5f507fafe --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_linux.go @@ -0,0 +1,59 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !amd64,!amd64p32,!386 + +package cpu + +import ( + "io/ioutil" +) + +const ( + _AT_HWCAP = 16 + _AT_HWCAP2 = 26 + + procAuxv = "/proc/self/auxv" + + uintSize = int(32 << (^uint(0) >> 63)) +) + +// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2 +// These are initialized in cpu_$GOARCH.go +// and should not be changed after they are initialized. +var hwCap uint +var hwCap2 uint + +func init() { + buf, err := ioutil.ReadFile(procAuxv) + if err != nil { + // e.g. on android /proc/self/auxv is not accessible, so silently + // ignore the error and leave Initialized = false + return + } + + bo := hostByteOrder() + for len(buf) >= 2*(uintSize/8) { + var tag, val uint + switch uintSize { + case 32: + tag = uint(bo.Uint32(buf[0:])) + val = uint(bo.Uint32(buf[4:])) + buf = buf[8:] + case 64: + tag = uint(bo.Uint64(buf[0:])) + val = uint(bo.Uint64(buf[8:])) + buf = buf[16:] + } + switch tag { + case _AT_HWCAP: + hwCap = val + case _AT_HWCAP2: + hwCap2 = val + } + } + doinit() + + Initialized = true +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go new file mode 100644 index 000000000000..fa7fb1bd7b2a --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go @@ -0,0 +1,67 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +const cacheLineSize = 64 + +// HWCAP/HWCAP2 bits. These are exposed by Linux. +const ( + hwcap_FP = 1 << 0 + hwcap_ASIMD = 1 << 1 + hwcap_EVTSTRM = 1 << 2 + hwcap_AES = 1 << 3 + hwcap_PMULL = 1 << 4 + hwcap_SHA1 = 1 << 5 + hwcap_SHA2 = 1 << 6 + hwcap_CRC32 = 1 << 7 + hwcap_ATOMICS = 1 << 8 + hwcap_FPHP = 1 << 9 + hwcap_ASIMDHP = 1 << 10 + hwcap_CPUID = 1 << 11 + hwcap_ASIMDRDM = 1 << 12 + hwcap_JSCVT = 1 << 13 + hwcap_FCMA = 1 << 14 + hwcap_LRCPC = 1 << 15 + hwcap_DCPOP = 1 << 16 + hwcap_SHA3 = 1 << 17 + hwcap_SM3 = 1 << 18 + hwcap_SM4 = 1 << 19 + hwcap_ASIMDDP = 1 << 20 + hwcap_SHA512 = 1 << 21 + hwcap_SVE = 1 << 22 + hwcap_ASIMDFHM = 1 << 23 +) + +func doinit() { + // HWCAP feature bits + ARM64.HasFP = isSet(hwCap, hwcap_FP) + ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD) + ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM) + ARM64.HasAES = isSet(hwCap, hwcap_AES) + ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL) + ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1) + ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2) + ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32) + ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS) + ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP) + ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP) + ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID) + ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM) + ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT) + ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA) + ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC) + ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP) + ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3) + ARM64.HasSM3 = isSet(hwCap, hwcap_SM3) + ARM64.HasSM4 = isSet(hwCap, hwcap_SM4) + ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP) + ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512) + ARM64.HasSVE = isSet(hwCap, hwcap_SVE) + ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM) +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go b/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go new file mode 100644 index 000000000000..6c8d975d40af --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go @@ -0,0 +1,33 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux +// +build ppc64 ppc64le + +package cpu + +const cacheLineSize = 128 + +// HWCAP/HWCAP2 bits. These are exposed by the kernel. +const ( + // ISA Level + _PPC_FEATURE2_ARCH_2_07 = 0x80000000 + _PPC_FEATURE2_ARCH_3_00 = 0x00800000 + + // CPU features + _PPC_FEATURE2_DARN = 0x00200000 + _PPC_FEATURE2_SCV = 0x00100000 +) + +func doinit() { + // HWCAP2 feature bits + PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07) + PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00) + PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN) + PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV) +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go new file mode 100644 index 000000000000..d579eaef4043 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go @@ -0,0 +1,161 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +const cacheLineSize = 256 + +const ( + // bit mask values from /usr/include/bits/hwcap.h + hwcap_ZARCH = 2 + hwcap_STFLE = 4 + hwcap_MSA = 8 + hwcap_LDISP = 16 + hwcap_EIMM = 32 + hwcap_DFP = 64 + hwcap_ETF3EH = 256 + hwcap_VX = 2048 + hwcap_VXE = 8192 +) + +// bitIsSet reports whether the bit at index is set. The bit index +// is in big endian order, so bit index 0 is the leftmost bit. +func bitIsSet(bits []uint64, index uint) bool { + return bits[index/64]&((1<<63)>>(index%64)) != 0 +} + +// function is the code for the named cryptographic function. +type function uint8 + +const ( + // KM{,A,C,CTR} function codes + aes128 function = 18 // AES-128 + aes192 function = 19 // AES-192 + aes256 function = 20 // AES-256 + + // K{I,L}MD function codes + sha1 function = 1 // SHA-1 + sha256 function = 2 // SHA-256 + sha512 function = 3 // SHA-512 + sha3_224 function = 32 // SHA3-224 + sha3_256 function = 33 // SHA3-256 + sha3_384 function = 34 // SHA3-384 + sha3_512 function = 35 // SHA3-512 + shake128 function = 36 // SHAKE-128 + shake256 function = 37 // SHAKE-256 + + // KLMD function codes + ghash function = 65 // GHASH +) + +// queryResult contains the result of a Query function +// call. Bits are numbered in big endian order so the +// leftmost bit (the MSB) is at index 0. +type queryResult struct { + bits [2]uint64 +} + +// Has reports whether the given functions are present. +func (q *queryResult) Has(fns ...function) bool { + if len(fns) == 0 { + panic("no function codes provided") + } + for _, f := range fns { + if !bitIsSet(q.bits[:], uint(f)) { + return false + } + } + return true +} + +// facility is a bit index for the named facility. +type facility uint8 + +const ( + // cryptography facilities + msa4 facility = 77 // message-security-assist extension 4 + msa8 facility = 146 // message-security-assist extension 8 +) + +// facilityList contains the result of an STFLE call. +// Bits are numbered in big endian order so the +// leftmost bit (the MSB) is at index 0. +type facilityList struct { + bits [4]uint64 +} + +// Has reports whether the given facilities are present. +func (s *facilityList) Has(fs ...facility) bool { + if len(fs) == 0 { + panic("no facility bits provided") + } + for _, f := range fs { + if !bitIsSet(s.bits[:], uint(f)) { + return false + } + } + return true +} + +func doinit() { + // test HWCAP bit vector + has := func(featureMask uint) bool { + return hwCap&featureMask == featureMask + } + + // mandatory + S390X.HasZARCH = has(hwcap_ZARCH) + + // optional + S390X.HasSTFLE = has(hwcap_STFLE) + S390X.HasLDISP = has(hwcap_LDISP) + S390X.HasEIMM = has(hwcap_EIMM) + S390X.HasETF3EH = has(hwcap_ETF3EH) + S390X.HasDFP = has(hwcap_DFP) + S390X.HasMSA = has(hwcap_MSA) + S390X.HasVX = has(hwcap_VX) + if S390X.HasVX { + S390X.HasVXE = has(hwcap_VXE) + } + + // We need implementations of stfle, km and so on + // to detect cryptographic features. + if !haveAsmFunctions() { + return + } + + // optional cryptographic functions + if S390X.HasMSA { + aes := []function{aes128, aes192, aes256} + + // cipher message + km, kmc := kmQuery(), kmcQuery() + S390X.HasAES = km.Has(aes...) + S390X.HasAESCBC = kmc.Has(aes...) + if S390X.HasSTFLE { + facilities := stfle() + if facilities.Has(msa4) { + kmctr := kmctrQuery() + S390X.HasAESCTR = kmctr.Has(aes...) + } + if facilities.Has(msa8) { + kma := kmaQuery() + S390X.HasAESGCM = kma.Has(aes...) + } + } + + // compute message digest + kimd := kimdQuery() // intermediate (no padding) + klmd := klmdQuery() // last (padding) + S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) + S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) + S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) + S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist + sha3 := []function{ + sha3_224, sha3_256, sha3_384, sha3_512, + shake128, shake256, + } + S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) + } +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_mips64x.go b/vendor/golang.org/x/sys/cpu/cpu_mips64x.go new file mode 100644 index 000000000000..f55e0c82c73a --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_mips64x.go @@ -0,0 +1,11 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips64 mips64le + +package cpu + +const cacheLineSize = 32 + +func doinit() {} diff --git a/vendor/golang.org/x/sys/cpu/cpu_mipsx.go b/vendor/golang.org/x/sys/cpu/cpu_mipsx.go new file mode 100644 index 000000000000..cda87b1a1b19 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_mipsx.go @@ -0,0 +1,11 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips mipsle + +package cpu + +const cacheLineSize = 32 + +func doinit() {} diff --git a/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go new file mode 100644 index 000000000000..dd1e76dc921a --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go @@ -0,0 +1,11 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !linux,arm64 + +package cpu + +const cacheLineSize = 64 + +func doinit() {} diff --git a/vendor/golang.org/x/sys/cpu/cpu_s390x.s b/vendor/golang.org/x/sys/cpu/cpu_s390x.s new file mode 100644 index 000000000000..e5037d92e061 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_s390x.s @@ -0,0 +1,57 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +// func stfle() facilityList +TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32 + MOVD $ret+0(FP), R1 + MOVD $3, R0 // last doubleword index to store + XC $32, (R1), (R1) // clear 4 doublewords (32 bytes) + WORD $0xb2b01000 // store facility list extended (STFLE) + RET + +// func kmQuery() queryResult +TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KM-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + WORD $0xB92E0024 // cipher message (KM) + RET + +// func kmcQuery() queryResult +TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KMC-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + WORD $0xB92F0024 // cipher message with chaining (KMC) + RET + +// func kmctrQuery() queryResult +TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KMCTR-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + WORD $0xB92D4024 // cipher message with counter (KMCTR) + RET + +// func kmaQuery() queryResult +TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KMA-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + WORD $0xb9296024 // cipher message with authentication (KMA) + RET + +// func kimdQuery() queryResult +TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KIMD-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + WORD $0xB93E0024 // compute intermediate message digest (KIMD) + RET + +// func klmdQuery() queryResult +TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KLMD-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + WORD $0xB93F0024 // compute last message digest (KLMD) + RET diff --git a/vendor/golang.org/x/sys/cpu/cpu_wasm.go b/vendor/golang.org/x/sys/cpu/cpu_wasm.go new file mode 100644 index 000000000000..bd9bbda0c082 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_wasm.go @@ -0,0 +1,15 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build wasm + +package cpu + +// We're compiling the cpu package for an unknown (software-abstracted) CPU. +// Make CacheLinePad an empty struct and hope that the usual struct alignment +// rules are good enough. + +const cacheLineSize = 0 + +func doinit() {} diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.go b/vendor/golang.org/x/sys/cpu/cpu_x86.go new file mode 100644 index 000000000000..d70d317f5a4c --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_x86.go @@ -0,0 +1,59 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build 386 amd64 amd64p32 + +package cpu + +const cacheLineSize = 64 + +func init() { + Initialized = true + + maxID, _, _, _ := cpuid(0, 0) + + if maxID < 1 { + return + } + + _, _, ecx1, edx1 := cpuid(1, 0) + X86.HasSSE2 = isSet(26, edx1) + + X86.HasSSE3 = isSet(0, ecx1) + X86.HasPCLMULQDQ = isSet(1, ecx1) + X86.HasSSSE3 = isSet(9, ecx1) + X86.HasFMA = isSet(12, ecx1) + X86.HasSSE41 = isSet(19, ecx1) + X86.HasSSE42 = isSet(20, ecx1) + X86.HasPOPCNT = isSet(23, ecx1) + X86.HasAES = isSet(25, ecx1) + X86.HasOSXSAVE = isSet(27, ecx1) + X86.HasRDRAND = isSet(30, ecx1) + + osSupportsAVX := false + // For XGETBV, OSXSAVE bit is required and sufficient. + if X86.HasOSXSAVE { + eax, _ := xgetbv() + // Check if XMM and YMM registers have OS support. + osSupportsAVX = isSet(1, eax) && isSet(2, eax) + } + + X86.HasAVX = isSet(28, ecx1) && osSupportsAVX + + if maxID < 7 { + return + } + + _, ebx7, _, _ := cpuid(7, 0) + X86.HasBMI1 = isSet(3, ebx7) + X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX + X86.HasBMI2 = isSet(8, ebx7) + X86.HasERMS = isSet(9, ebx7) + X86.HasRDSEED = isSet(18, ebx7) + X86.HasADX = isSet(19, ebx7) +} + +func isSet(bitpos uint, value uint32) bool { + return value&(1<<bitpos) != 0 +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.s b/vendor/golang.org/x/sys/cpu/cpu_x86.s new file mode 100644 index 000000000000..47f084128cc3 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_x86.s @@ -0,0 +1,27 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build 386 amd64 amd64p32 +// +build !gccgo + +#include "textflag.h" + +// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) +TEXT ·cpuid(SB), NOSPLIT, $0-24 + MOVL eaxArg+0(FP), AX + MOVL ecxArg+4(FP), CX + CPUID + MOVL AX, eax+8(FP) + MOVL BX, ebx+12(FP) + MOVL CX, ecx+16(FP) + MOVL DX, edx+20(FP) + RET + +// func xgetbv() (eax, edx uint32) +TEXT ·xgetbv(SB),NOSPLIT,$0-8 + MOVL $0, CX + XGETBV + MOVL AX, eax+0(FP) + MOVL DX, edx+4(FP) + RET diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md index 2bf415fb1cff..eb2f78ae295b 100644 --- a/vendor/golang.org/x/sys/unix/README.md +++ b/vendor/golang.org/x/sys/unix/README.md @@ -32,7 +32,7 @@ To build the files for your current OS and architecture, make sure GOOS and GOARCH are set correctly and run `mkall.sh`. This will generate the files for your specific system. Running `mkall.sh -n` shows the commands that will be run. -Requirements: bash, perl, go +Requirements: bash, go ### New Build System (currently for `GOOS == "linux"`) @@ -52,14 +52,14 @@ system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will then generate all of the files for all of the GOOS/GOARCH pairs in the new build system. Running `mkall.sh -n` shows the commands that will be run. -Requirements: bash, perl, go, docker +Requirements: bash, go, docker ## Component files This section describes the various files used in the code generation process. It also contains instructions on how to modify these files to add a new architecture/OS or to add additional syscalls, types, or constants. Note that -if you are using the new build system, the scripts cannot be called normally. +if you are using the new build system, the scripts/programs cannot be called normally. They must be called from within the docker container. ### asm files @@ -81,8 +81,8 @@ each GOOS/GOARCH pair. ### mksysnum -Mksysnum is a script located at `${GOOS}/mksysnum.pl` (or `mksysnum_${GOOS}.pl` -for the old system). This script takes in a list of header files containing the +Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go` +for the old system). This program takes in a list of header files containing the syscall number declarations and parses them to produce the corresponding list of Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated constants. @@ -92,14 +92,14 @@ new installation of the target OS (or updating the source checkouts for the new build system). However, depending on the OS, you make need to update the parsing in mksysnum. -### mksyscall.pl +### mksyscall.go The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are hand-written Go files which implement system calls (for unix, the specific OS, or the specific OS/Architecture pair respectively) that need special handling and list `//sys` comments giving prototypes for ones that can be generated. -The mksyscall.pl script takes the `//sys` and `//sysnb` comments and converts +The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts them into syscalls. This requires the name of the prototype in the comment to match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function prototype can be exported (capitalized) or not. @@ -160,7 +160,7 @@ signal numbers, and constants. Generated by `mkerrors.sh` (see above). ### `zsyscall_${GOOS}_${GOARCH}.go` A file containing all the generated syscalls for a specific GOOS and GOARCH. -Generated by `mksyscall.pl` (see above). +Generated by `mksyscall.go` (see above). ### `zsysnum_${GOOS}_${GOARCH}.go` diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s new file mode 100644 index 000000000000..d9318cbf034d --- /dev/null +++ b/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s @@ -0,0 +1,29 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +// +// System call support for ARM64, FreeBSD +// + +// Just jump to package syscall's implementation for all these functions. +// The runtime may know about them. + +TEXT ·Syscall(SB),NOSPLIT,$0-56 + JMP syscall·Syscall(SB) + +TEXT ·Syscall6(SB),NOSPLIT,$0-80 + JMP syscall·Syscall6(SB) + +TEXT ·Syscall9(SB),NOSPLIT,$0-104 + JMP syscall·Syscall9(SB) + +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + JMP syscall·RawSyscall(SB) + +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s new file mode 100644 index 000000000000..6f98ba5a370a --- /dev/null +++ b/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s @@ -0,0 +1,29 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +// +// System call support for ARM64, NetBSD +// + +// Just jump to package syscall's implementation for all these functions. +// The runtime may know about them. + +TEXT ·Syscall(SB),NOSPLIT,$0-56 + B syscall·Syscall(SB) + +TEXT ·Syscall6(SB),NOSPLIT,$0-80 + B syscall·Syscall6(SB) + +TEXT ·Syscall9(SB),NOSPLIT,$0-104 + B syscall·Syscall9(SB) + +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + B syscall·RawSyscall(SB) + +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + B syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s new file mode 100644 index 000000000000..0cedea3d39d8 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s @@ -0,0 +1,29 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +// +// System call support for arm64, OpenBSD +// + +// Just jump to package syscall's implementation for all these functions. +// The runtime may know about them. + +TEXT ·Syscall(SB),NOSPLIT,$0-56 + JMP syscall·Syscall(SB) + +TEXT ·Syscall6(SB),NOSPLIT,$0-80 + JMP syscall·Syscall6(SB) + +TEXT ·Syscall9(SB),NOSPLIT,$0-104 + JMP syscall·Syscall9(SB) + +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + JMP syscall·RawSyscall(SB) + +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/fcntl.go b/vendor/golang.org/x/sys/unix/fcntl.go index 9379ba9cef77..39c03f1ef135 100644 --- a/vendor/golang.org/x/sys/unix/fcntl.go +++ b/vendor/golang.org/x/sys/unix/fcntl.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd +// +build dragonfly freebsd linux netbsd openbsd package unix diff --git a/vendor/golang.org/x/sys/unix/fcntl_darwin.go b/vendor/golang.org/x/sys/unix/fcntl_darwin.go new file mode 100644 index 000000000000..5868a4a47b45 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/fcntl_darwin.go @@ -0,0 +1,18 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +import "unsafe" + +// FcntlInt performs a fcntl syscall on fd with the provided command and argument. +func FcntlInt(fd uintptr, cmd, arg int) (int, error) { + return fcntl(int(fd), cmd, arg) +} + +// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. +func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { + _, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk)))) + return err +} diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index b21f0118e1de..80d00707bb0d 100644 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -62,110 +62,130 @@ _* | *_ | _) ;; aix_ppc) mkerrors="$mkerrors -maix32" - mksyscall="./mksyscall_aix_ppc.pl -aix" + mksyscall="go run mksyscall_aix_ppc.go -aix" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; aix_ppc64) mkerrors="$mkerrors -maix64" - mksyscall="./mksyscall_aix_ppc64.pl -aix" + mksyscall="go run mksyscall_aix_ppc64.go -aix" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; darwin_386) mkerrors="$mkerrors -m32" mksyscall="go run mksyscall.go -l32" - mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" + mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" mkasm="go run mkasm_darwin.go" ;; darwin_amd64) mkerrors="$mkerrors -m64" - mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" + mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" mkasm="go run mkasm_darwin.go" ;; darwin_arm) mkerrors="$mkerrors" mksyscall="go run mksyscall.go -l32" - mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" + mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" mkasm="go run mkasm_darwin.go" ;; darwin_arm64) mkerrors="$mkerrors -m64" - mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" + mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" mkasm="go run mkasm_darwin.go" ;; dragonfly_amd64) mkerrors="$mkerrors -m64" mksyscall="go run mksyscall.go -dragonfly" - mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl" + mksysnum="go run mksysnum.go 'https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master'" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; freebsd_386) mkerrors="$mkerrors -m32" mksyscall="go run mksyscall.go -l32" - mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl" + mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; freebsd_amd64) mkerrors="$mkerrors -m64" - mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl" + mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; freebsd_arm) mkerrors="$mkerrors" mksyscall="go run mksyscall.go -l32 -arm" - mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl" + mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'" # Let the type of C char be signed for making the bare syscall # API consistent across platforms. mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" ;; +freebsd_arm64) + mkerrors="$mkerrors -m64" + mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'" + mktypes="GOARCH=$GOARCH go tool cgo -godefs" + ;; netbsd_386) mkerrors="$mkerrors -m32" mksyscall="go run mksyscall.go -l32 -netbsd" - mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl" + mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; netbsd_amd64) mkerrors="$mkerrors -m64" mksyscall="go run mksyscall.go -netbsd" - mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl" + mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; netbsd_arm) mkerrors="$mkerrors" mksyscall="go run mksyscall.go -l32 -netbsd -arm" - mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl" + mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'" # Let the type of C char be signed for making the bare syscall # API consistent across platforms. mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" ;; +netbsd_arm64) + mkerrors="$mkerrors -m64" + mksyscall="go run mksyscall.go -netbsd" + mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'" + mktypes="GOARCH=$GOARCH go tool cgo -godefs" + ;; openbsd_386) mkerrors="$mkerrors -m32" mksyscall="go run mksyscall.go -l32 -openbsd" - mksysctl="./mksysctl_openbsd.pl" - mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" + mksysctl="go run mksysctl_openbsd.go" + mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; openbsd_amd64) mkerrors="$mkerrors -m64" mksyscall="go run mksyscall.go -openbsd" - mksysctl="./mksysctl_openbsd.pl" - mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" + mksysctl="go run mksysctl_openbsd.go" + mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; openbsd_arm) mkerrors="$mkerrors" mksyscall="go run mksyscall.go -l32 -openbsd -arm" - mksysctl="./mksysctl_openbsd.pl" - mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" + mksysctl="go run mksysctl_openbsd.go" + mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'" + # Let the type of C char be signed for making the bare syscall + # API consistent across platforms. + mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" + ;; +openbsd_arm64) + mkerrors="$mkerrors -m64" + mksyscall="go run mksyscall.go -openbsd" + mksysctl="go run mksysctl_openbsd.go" + mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'" # Let the type of C char be signed for making the bare syscall # API consistent across platforms. mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" ;; solaris_amd64) - mksyscall="./mksyscall_solaris.pl" + mksyscall="go run mksyscall_solaris.go" mkerrors="$mkerrors -m64" mksysnum= mktypes="GOARCH=$GOARCH go tool cgo -godefs" @@ -202,8 +222,6 @@ esac esac if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi - if [ -n "$mktypes" ]; then - echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; + if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi - fi ) | $run diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 178077f47b46..b3c33c2c324b 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -179,8 +179,10 @@ struct ltchars { #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> +#include <sys/signalfd.h> #include <sys/socket.h> #include <sys/xattr.h> +#include <linux/errqueue.h> #include <linux/if.h> #include <linux/if_alg.h> #include <linux/if_arp.h> @@ -190,6 +192,7 @@ struct ltchars { #include <linux/if_packet.h> #include <linux/if_addr.h> #include <linux/falloc.h> +#include <linux/fanotify.h> #include <linux/filter.h> #include <linux/fs.h> #include <linux/kexec.h> @@ -219,6 +222,7 @@ struct ltchars { #include <linux/hdreg.h> #include <linux/rtc.h> #include <linux/if_xdp.h> +#include <linux/cryptouser.h> #include <mtd/ubi-user.h> #include <net/route.h> @@ -257,16 +261,6 @@ struct ltchars { #define FS_KEY_DESC_PREFIX "fscrypt:" #define FS_KEY_DESC_PREFIX_SIZE 8 #define FS_MAX_KEY_SIZE 64 - -// XDP socket constants do not appear to be picked up otherwise. -// Copied from samples/bpf/xdpsock_user.c. -#ifndef SOL_XDP -#define SOL_XDP 283 -#endif - -#ifndef AF_XDP -#define AF_XDP 44 -#endif ' includes_NetBSD=' @@ -453,7 +447,7 @@ ccflags="$@" $2 !~ "MNT_BITS" && $2 ~ /^(MS|MNT|UMOUNT)_/ || $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || - $2 ~ /^(O|F|E?FD|NAME|S|PTRACE|PT)_/ || + $2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT)_/ || $2 ~ /^KEXEC_/ || $2 ~ /^LINUX_REBOOT_CMD_/ || $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || @@ -474,12 +468,13 @@ ccflags="$@" $2 ~ /^CLONE_[A-Z_]+/ || $2 !~ /^(BPF_TIMEVAL)$/ && $2 ~ /^(BPF|DLT)_/ || - $2 ~ /^CLOCK_/ || + $2 ~ /^(CLOCK|TIMER)_/ || $2 ~ /^CAN_/ || $2 ~ /^CAP_/ || $2 ~ /^ALG_/ || $2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ || $2 ~ /^GRND_/ || + $2 ~ /^RND/ || $2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ || $2 ~ /^KEYCTL_/ || $2 ~ /^PERF_EVENT_IOC_/ || @@ -505,9 +500,11 @@ ccflags="$@" $2 ~ /^NFN/ || $2 ~ /^XDP_/ || $2 ~ /^(HDIO|WIN|SMART)_/ || + $2 ~ /^CRYPTO_/ || $2 !~ "WMESGLEN" && $2 ~ /^W[A-Z0-9]+$/ || $2 ~/^PPPIOC/ || + $2 ~ /^FAN_|FANOTIFY_/ || $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^__WCOREFLAG$/ {next} $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} diff --git a/vendor/golang.org/x/sys/unix/mksyscall.go b/vendor/golang.org/x/sys/unix/mksyscall.go index 890652ca836a..e4af9424e978 100644 --- a/vendor/golang.org/x/sys/unix/mksyscall.go +++ b/vendor/golang.org/x/sys/unix/mksyscall.go @@ -88,6 +88,10 @@ func parseParam(p string) Param { func main() { // Get the OS and architecture (using GOARCH_TARGET if it exists) goos := os.Getenv("GOOS") + if goos == "" { + fmt.Fprintln(os.Stderr, "GOOS not defined in environment") + os.Exit(1) + } goarch := os.Getenv("GOARCH_TARGET") if goarch == "" { goarch = os.Getenv("GOARCH") @@ -149,6 +153,11 @@ func main() { } funct, inps, outps, sysname := f[2], f[3], f[4], f[5] + // ClockGettime doesn't have a syscall number on Darwin, only generate libc wrappers. + if goos == "darwin" && !libc && funct == "ClockGettime" { + continue + } + // Split argument lists on comma. in := parseParamList(inps) out := parseParamList(outps) @@ -224,7 +233,7 @@ func main() { } else { args = append(args, fmt.Sprintf("uintptr(%s)", p.Name)) } - } else if p.Type == "int64" && endianness != "" { + } else if (p.Type == "int64" || p.Type == "uint64") && endianness != "" { if len(args)%2 == 1 && *arm { // arm abi specifies 64-bit argument uses // (even, odd) pair diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.go b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.go new file mode 100644 index 000000000000..3be3cdfc3b6e --- /dev/null +++ b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.go @@ -0,0 +1,415 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +/* +This program reads a file containing function prototypes +(like syscall_aix.go) and generates system call bodies. +The prototypes are marked by lines beginning with "//sys" +and read like func declarations if //sys is replaced by func, but: + * The parameter lists must give a name for each argument. + This includes return parameters. + * The parameter lists must give a type for each argument: + the (x, y, z int) shorthand is not allowed. + * If the return parameter is an error number, it must be named err. + * If go func name needs to be different than its libc name, + * or the function is not in libc, name could be specified + * at the end, after "=" sign, like + //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt +*/ +package main + +import ( + "bufio" + "flag" + "fmt" + "os" + "regexp" + "strings" +) + +var ( + b32 = flag.Bool("b32", false, "32bit big-endian") + l32 = flag.Bool("l32", false, "32bit little-endian") + aix = flag.Bool("aix", false, "aix") + tags = flag.String("tags", "", "build tags") +) + +// cmdLine returns this programs's commandline arguments +func cmdLine() string { + return "go run mksyscall_aix_ppc.go " + strings.Join(os.Args[1:], " ") +} + +// buildTags returns build tags +func buildTags() string { + return *tags +} + +// Param is function parameter +type Param struct { + Name string + Type string +} + +// usage prints the program usage +func usage() { + fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc.go [-b32 | -l32] [-tags x,y] [file ...]\n") + os.Exit(1) +} + +// parseParamList parses parameter list and returns a slice of parameters +func parseParamList(list string) []string { + list = strings.TrimSpace(list) + if list == "" { + return []string{} + } + return regexp.MustCompile(`\s*,\s*`).Split(list, -1) +} + +// parseParam splits a parameter into name and type +func parseParam(p string) Param { + ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p) + if ps == nil { + fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p) + os.Exit(1) + } + return Param{ps[1], ps[2]} +} + +func main() { + flag.Usage = usage + flag.Parse() + if len(flag.Args()) <= 0 { + fmt.Fprintf(os.Stderr, "no files to parse provided\n") + usage() + } + + endianness := "" + if *b32 { + endianness = "big-endian" + } else if *l32 { + endianness = "little-endian" + } + + pack := "" + text := "" + cExtern := "/*\n#include <stdint.h>\n#include <stddef.h>\n" + for _, path := range flag.Args() { + file, err := os.Open(path) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + s := bufio.NewScanner(file) + for s.Scan() { + t := s.Text() + t = strings.TrimSpace(t) + t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `) + if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" { + pack = p[1] + } + nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t) + if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil { + continue + } + + // Line must be of the form + // func Open(path string, mode int, perm int) (fd int, err error) + // Split into name, in params, out params. + f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t) + if f == nil { + fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t) + os.Exit(1) + } + funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6] + + // Split argument lists on comma. + in := parseParamList(inps) + out := parseParamList(outps) + + inps = strings.Join(in, ", ") + outps = strings.Join(out, ", ") + + // Try in vain to keep people from editing this file. + // The theory is that they jump into the middle of the file + // without reading the header. + text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n" + + // Check if value return, err return available + errvar := "" + retvar := "" + rettype := "" + for _, param := range out { + p := parseParam(param) + if p.Type == "error" { + errvar = p.Name + } else { + retvar = p.Name + rettype = p.Type + } + } + + // System call name. + if sysname == "" { + sysname = funct + } + sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`) + sysname = strings.ToLower(sysname) // All libc functions are lowercase. + + cRettype := "" + if rettype == "unsafe.Pointer" { + cRettype = "uintptr_t" + } else if rettype == "uintptr" { + cRettype = "uintptr_t" + } else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil { + cRettype = "uintptr_t" + } else if rettype == "int" { + cRettype = "int" + } else if rettype == "int32" { + cRettype = "int" + } else if rettype == "int64" { + cRettype = "long long" + } else if rettype == "uint32" { + cRettype = "unsigned int" + } else if rettype == "uint64" { + cRettype = "unsigned long long" + } else { + cRettype = "int" + } + if sysname == "exit" { + cRettype = "void" + } + + // Change p.Types to c + var cIn []string + for _, param := range in { + p := parseParam(param) + if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil { + cIn = append(cIn, "uintptr_t") + } else if p.Type == "string" { + cIn = append(cIn, "uintptr_t") + } else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil { + cIn = append(cIn, "uintptr_t", "size_t") + } else if p.Type == "unsafe.Pointer" { + cIn = append(cIn, "uintptr_t") + } else if p.Type == "uintptr" { + cIn = append(cIn, "uintptr_t") + } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil { + cIn = append(cIn, "uintptr_t") + } else if p.Type == "int" { + cIn = append(cIn, "int") + } else if p.Type == "int32" { + cIn = append(cIn, "int") + } else if p.Type == "int64" { + cIn = append(cIn, "long long") + } else if p.Type == "uint32" { + cIn = append(cIn, "unsigned int") + } else if p.Type == "uint64" { + cIn = append(cIn, "unsigned long long") + } else { + cIn = append(cIn, "int") + } + } + + if funct != "fcntl" && funct != "FcntlInt" && funct != "readlen" && funct != "writelen" { + if sysname == "select" { + // select is a keyword of Go. Its name is + // changed to c_select. + cExtern += "#define c_select select\n" + } + // Imports of system calls from libc + cExtern += fmt.Sprintf("%s %s", cRettype, sysname) + cIn := strings.Join(cIn, ", ") + cExtern += fmt.Sprintf("(%s);\n", cIn) + } + + // So file name. + if *aix { + if modname == "" { + modname = "libc.a/shr_64.o" + } else { + fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct) + os.Exit(1) + } + } + + strconvfunc := "C.CString" + + // Go function header. + if outps != "" { + outps = fmt.Sprintf(" (%s)", outps) + } + if text != "" { + text += "\n" + } + + text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps) + + // Prepare arguments to Syscall. + var args []string + n := 0 + argN := 0 + for _, param := range in { + p := parseParam(param) + if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil { + args = append(args, "C.uintptr_t(uintptr(unsafe.Pointer("+p.Name+")))") + } else if p.Type == "string" && errvar != "" { + text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name) + args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n)) + n++ + } else if p.Type == "string" { + fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n") + text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name) + args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n)) + n++ + } else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil { + // Convert slice into pointer, length. + // Have to be careful not to take address of &a[0] if len == 0: + // pass nil in that case. + text += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1]) + text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name) + args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(unsafe.Pointer(_p%d)))", n)) + n++ + text += fmt.Sprintf("\tvar _p%d int\n", n) + text += fmt.Sprintf("\t_p%d = len(%s)\n", n, p.Name) + args = append(args, fmt.Sprintf("C.size_t(_p%d)", n)) + n++ + } else if p.Type == "int64" && endianness != "" { + if endianness == "big-endian" { + args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name)) + } else { + args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name)) + } + n++ + } else if p.Type == "bool" { + text += fmt.Sprintf("\tvar _p%d uint32\n", n) + text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n) + args = append(args, fmt.Sprintf("_p%d", n)) + } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil { + args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name)) + } else if p.Type == "unsafe.Pointer" { + args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name)) + } else if p.Type == "int" { + if (argN == 2) && ((funct == "readlen") || (funct == "writelen")) { + args = append(args, fmt.Sprintf("C.size_t(%s)", p.Name)) + } else if argN == 0 && funct == "fcntl" { + args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name)) + } else if (argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt")) { + args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name)) + } else { + args = append(args, fmt.Sprintf("C.int(%s)", p.Name)) + } + } else if p.Type == "int32" { + args = append(args, fmt.Sprintf("C.int(%s)", p.Name)) + } else if p.Type == "int64" { + args = append(args, fmt.Sprintf("C.longlong(%s)", p.Name)) + } else if p.Type == "uint32" { + args = append(args, fmt.Sprintf("C.uint(%s)", p.Name)) + } else if p.Type == "uint64" { + args = append(args, fmt.Sprintf("C.ulonglong(%s)", p.Name)) + } else if p.Type == "uintptr" { + args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name)) + } else { + args = append(args, fmt.Sprintf("C.int(%s)", p.Name)) + } + argN++ + } + + // Actual call. + arglist := strings.Join(args, ", ") + call := "" + if sysname == "exit" { + if errvar != "" { + call += "er :=" + } else { + call += "" + } + } else if errvar != "" { + call += "r0,er :=" + } else if retvar != "" { + call += "r0,_ :=" + } else { + call += "" + } + if sysname == "select" { + // select is a keyword of Go. Its name is + // changed to c_select. + call += fmt.Sprintf("C.c_%s(%s)", sysname, arglist) + } else { + call += fmt.Sprintf("C.%s(%s)", sysname, arglist) + } + + // Assign return values. + body := "" + for i := 0; i < len(out); i++ { + p := parseParam(out[i]) + reg := "" + if p.Name == "err" { + reg = "e1" + } else { + reg = "r0" + } + if reg != "e1" { + body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg) + } + } + + // verify return + if sysname != "exit" && errvar != "" { + if regexp.MustCompile(`^uintptr`).FindStringSubmatch(cRettype) != nil { + body += "\tif (uintptr(r0) ==^uintptr(0) && er != nil) {\n" + body += fmt.Sprintf("\t\t%s = er\n", errvar) + body += "\t}\n" + } else { + body += "\tif (r0 ==-1 && er != nil) {\n" + body += fmt.Sprintf("\t\t%s = er\n", errvar) + body += "\t}\n" + } + } else if errvar != "" { + body += "\tif (er != nil) {\n" + body += fmt.Sprintf("\t\t%s = er\n", errvar) + body += "\t}\n" + } + + text += fmt.Sprintf("\t%s\n", call) + text += body + + text += "\treturn\n" + text += "}\n" + } + if err := s.Err(); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + file.Close() + } + imp := "" + if pack != "unix" { + imp = "import \"golang.org/x/sys/unix\"\n" + + } + fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, cExtern, imp, text) +} + +const srcTemplate = `// %s +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build %s + +package %s + + +%s +*/ +import "C" +import ( + "unsafe" +) + + +%s + +%s +` diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl deleted file mode 100644 index c44de8d310ef..000000000000 --- a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.pl +++ /dev/null @@ -1,384 +0,0 @@ -#!/usr/bin/env perl -# Copyright 2018 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -# This program reads a file containing function prototypes -# (like syscall_aix.go) and generates system call bodies. -# The prototypes are marked by lines beginning with "//sys" -# and read like func declarations if //sys is replaced by func, but: -# * The parameter lists must give a name for each argument. -# This includes return parameters. -# * The parameter lists must give a type for each argument: -# the (x, y, z int) shorthand is not allowed. -# * If the return parameter is an error number, it must be named err. -# * If go func name needs to be different than its libc name, -# * or the function is not in libc, name could be specified -# * at the end, after "=" sign, like -# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt - -use strict; - -my $cmdline = "mksyscall_aix_ppc.pl " . join(' ', @ARGV); -my $errors = 0; -my $_32bit = ""; -my $tags = ""; # build tags -my $aix = 0; -my $solaris = 0; - -binmode STDOUT; - -if($ARGV[0] eq "-b32") { - $_32bit = "big-endian"; - shift; -} elsif($ARGV[0] eq "-l32") { - $_32bit = "little-endian"; - shift; -} -if($ARGV[0] eq "-aix") { - $aix = 1; - shift; -} -if($ARGV[0] eq "-tags") { - shift; - $tags = $ARGV[0]; - shift; -} - -if($ARGV[0] =~ /^-/) { - print STDERR "usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n"; - exit 1; -} - -sub parseparamlist($) { - my ($list) = @_; - $list =~ s/^\s*//; - $list =~ s/\s*$//; - if($list eq "") { - return (); - } - return split(/\s*,\s*/, $list); -} - -sub parseparam($) { - my ($p) = @_; - if($p !~ /^(\S*) (\S*)$/) { - print STDERR "$ARGV:$.: malformed parameter: $p\n"; - $errors = 1; - return ("xx", "int"); - } - return ($1, $2); -} - -my $package = ""; -my $text = ""; -my $c_extern = "/*\n#include <stdint.h>\n#include <stddef.h>\n"; -my @vars = (); -while(<>) { - chomp; - s/\s+/ /g; - s/^\s+//; - s/\s+$//; - $package = $1 if !$package && /^package (\S+)$/; - my $nonblock = /^\/\/sysnb /; - next if !/^\/\/sys / && !$nonblock; - - # Line must be of the form - # func Open(path string, mode int, perm int) (fd int, err error) - # Split into name, in params, out params. - if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) { - print STDERR "$ARGV:$.: malformed //sys declaration\n"; - $errors = 1; - next; - } - my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6); - - # Split argument lists on comma. - my @in = parseparamlist($in); - my @out = parseparamlist($out); - - $in = join(', ', @in); - $out = join(', ', @out); - - # Try in vain to keep people from editing this file. - # The theory is that they jump into the middle of the file - # without reading the header. - $text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; - - # Check if value return, err return available - my $errvar = ""; - my $retvar = ""; - my $rettype = ""; - foreach my $p (@out) { - my ($name, $type) = parseparam($p); - if($type eq "error") { - $errvar = $name; - } else { - $retvar = $name; - $rettype = $type; - } - } - - # System call name. - #if($func ne "fcntl") { - - if($sysname eq "") { - $sysname = "$func"; - } - - $sysname =~ s/([a-z])([A-Z])/${1}_$2/g; - $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. - - my $C_rettype = ""; - if($rettype eq "unsafe.Pointer") { - $C_rettype = "uintptr_t"; - } elsif($rettype eq "uintptr") { - $C_rettype = "uintptr_t"; - } elsif($rettype =~ /^_/) { - $C_rettype = "uintptr_t"; - } elsif($rettype eq "int") { - $C_rettype = "int"; - } elsif($rettype eq "int32") { - $C_rettype = "int"; - } elsif($rettype eq "int64") { - $C_rettype = "long long"; - } elsif($rettype eq "uint32") { - $C_rettype = "unsigned int"; - } elsif($rettype eq "uint64") { - $C_rettype = "unsigned long long"; - } else { - $C_rettype = "int"; - } - if($sysname eq "exit") { - $C_rettype = "void"; - } - - # Change types to c - my @c_in = (); - foreach my $p (@in) { - my ($name, $type) = parseparam($p); - if($type =~ /^\*/) { - push @c_in, "uintptr_t"; - } elsif($type eq "string") { - push @c_in, "uintptr_t"; - } elsif($type =~ /^\[\](.*)/) { - push @c_in, "uintptr_t", "size_t"; - } elsif($type eq "unsafe.Pointer") { - push @c_in, "uintptr_t"; - } elsif($type eq "uintptr") { - push @c_in, "uintptr_t"; - } elsif($type =~ /^_/) { - push @c_in, "uintptr_t"; - } elsif($type eq "int") { - push @c_in, "int"; - } elsif($type eq "int32") { - push @c_in, "int"; - } elsif($type eq "int64") { - push @c_in, "long long"; - } elsif($type eq "uint32") { - push @c_in, "unsigned int"; - } elsif($type eq "uint64") { - push @c_in, "unsigned long long"; - } else { - push @c_in, "int"; - } - } - - if ($func ne "fcntl" && $func ne "FcntlInt" && $func ne "readlen" && $func ne "writelen") { - # Imports of system calls from libc - $c_extern .= "$C_rettype $sysname"; - my $c_in = join(', ', @c_in); - $c_extern .= "($c_in);\n"; - } - - # So file name. - if($aix) { - if($modname eq "") { - $modname = "libc.a/shr_64.o"; - } else { - print STDERR "$func: only syscall using libc are available\n"; - $errors = 1; - next; - } - } - - my $strconvfunc = "C.CString"; - my $strconvtype = "*byte"; - - # Go function header. - if($out ne "") { - $out = " ($out)"; - } - if($text ne "") { - $text .= "\n" - } - - $text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ; - - # Prepare arguments to call. - my @args = (); - my $n = 0; - my $arg_n = 0; - foreach my $p (@in) { - my ($name, $type) = parseparam($p); - if($type =~ /^\*/) { - push @args, "C.uintptr_t(uintptr(unsafe.Pointer($name)))"; - } elsif($type eq "string" && $errvar ne "") { - $text .= "\t_p$n := uintptr(unsafe.Pointer($strconvfunc($name)))\n"; - push @args, "C.uintptr_t(_p$n)"; - $n++; - } elsif($type eq "string") { - print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; - $text .= "\t_p$n := uintptr(unsafe.Pointer($strconvfunc($name)))\n"; - push @args, "C.uintptr_t(_p$n)"; - $n++; - } elsif($type =~ /^\[\](.*)/) { - # Convert slice into pointer, length. - # Have to be careful not to take address of &a[0] if len == 0: - # pass nil in that case. - $text .= "\tvar _p$n *$1\n"; - $text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n"; - push @args, "C.uintptr_t(uintptr(unsafe.Pointer(_p$n)))"; - $n++; - $text .= "\tvar _p$n int\n"; - $text .= "\t_p$n = len($name)\n"; - push @args, "C.size_t(_p$n)"; - $n++; - } elsif($type eq "int64" && $_32bit ne "") { - if($_32bit eq "big-endian") { - push @args, "uintptr($name >> 32)", "uintptr($name)"; - } else { - push @args, "uintptr($name)", "uintptr($name >> 32)"; - } - $n++; - } elsif($type eq "bool") { - $text .= "\tvar _p$n uint32\n"; - $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n"; - push @args, "_p$n"; - $n++; - } elsif($type =~ /^_/) { - push @args, "C.uintptr_t(uintptr($name))"; - } elsif($type eq "unsafe.Pointer") { - push @args, "C.uintptr_t(uintptr($name))"; - } elsif($type eq "int") { - if (($arg_n == 2) && (($func eq "readlen") || ($func eq "writelen"))) { - push @args, "C.size_t($name)"; - } elsif ($arg_n == 0 && $func eq "fcntl") { - push @args, "C.uintptr_t($name)"; - } elsif (($arg_n == 2) && (($func eq "fcntl") || ($func eq "FcntlInt"))) { - push @args, "C.uintptr_t($name)"; - } else { - push @args, "C.int($name)"; - } - } elsif($type eq "int32") { - push @args, "C.int($name)"; - } elsif($type eq "int64") { - push @args, "C.longlong($name)"; - } elsif($type eq "uint32") { - push @args, "C.uint($name)"; - } elsif($type eq "uint64") { - push @args, "C.ulonglong($name)"; - } elsif($type eq "uintptr") { - push @args, "C.uintptr_t($name)"; - } else { - push @args, "C.int($name)"; - } - $arg_n++; - } - my $nargs = @args; - - - # Determine which form to use; pad args with zeros. - if ($nonblock) { - } - - my $args = join(', ', @args); - my $call = ""; - if ($sysname eq "exit") { - if ($errvar ne "") { - $call .= "er :="; - } else { - $call .= ""; - } - } elsif ($errvar ne "") { - $call .= "r0,er :="; - } elsif ($retvar ne "") { - $call .= "r0,_ :="; - } else { - $call .= "" - } - $call .= "C.$sysname($args)"; - - # Assign return values. - my $body = ""; - my $failexpr = ""; - - for(my $i=0; $i<@out; $i++) { - my $p = $out[$i]; - my ($name, $type) = parseparam($p); - my $reg = ""; - if($name eq "err") { - $reg = "e1"; - } else { - $reg = "r0"; - } - if($reg ne "e1" ) { - $body .= "\t$name = $type($reg)\n"; - } - } - - # verify return - if ($sysname ne "exit" && $errvar ne "") { - if ($C_rettype =~ /^uintptr/) { - $body .= "\tif \(uintptr\(r0\) ==\^uintptr\(0\) && er != nil\) {\n"; - $body .= "\t\t$errvar = er\n"; - $body .= "\t}\n"; - } else { - $body .= "\tif \(r0 ==-1 && er != nil\) {\n"; - $body .= "\t\t$errvar = er\n"; - $body .= "\t}\n"; - } - } elsif ($errvar ne "") { - $body .= "\tif \(er != nil\) {\n"; - $body .= "\t\t$errvar = er\n"; - $body .= "\t}\n"; - } - - $text .= "\t$call\n"; - $text .= $body; - - $text .= "\treturn\n"; - $text .= "}\n"; -} - -if($errors) { - exit 1; -} - -print <<EOF; -// $cmdline -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $tags - -package $package - - -$c_extern -*/ -import "C" -import ( - "unsafe" -) - - -EOF - -print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; - -chomp($_=<<EOF); - -$text -EOF -print $_; -exit 0; diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.go b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.go new file mode 100644 index 000000000000..c960099517af --- /dev/null +++ b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.go @@ -0,0 +1,614 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +/* +This program reads a file containing function prototypes +(like syscall_aix.go) and generates system call bodies. +The prototypes are marked by lines beginning with "//sys" +and read like func declarations if //sys is replaced by func, but: + * The parameter lists must give a name for each argument. + This includes return parameters. + * The parameter lists must give a type for each argument: + the (x, y, z int) shorthand is not allowed. + * If the return parameter is an error number, it must be named err. + * If go func name needs to be different than its libc name, + * or the function is not in libc, name could be specified + * at the end, after "=" sign, like + //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt + + +This program will generate three files and handle both gc and gccgo implementation: + - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation) + - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6 + - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type. + + The generated code looks like this + +zsyscall_aix_ppc64.go +func asyscall(...) (n int, err error) { + // Pointer Creation + r1, e1 := callasyscall(...) + // Type Conversion + // Error Handler + return +} + +zsyscall_aix_ppc64_gc.go +//go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o" +//go:linkname libc_asyscall libc_asyscall +var asyscall syscallFunc + +func callasyscall(...) (r1 uintptr, e1 Errno) { + r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... ) + return +} + +zsyscall_aix_ppc64_ggcgo.go + +// int asyscall(...) + +import "C" + +func callasyscall(...) (r1 uintptr, e1 Errno) { + r1 = uintptr(C.asyscall(...)) + e1 = syscall.GetErrno() + return +} +*/ + +package main + +import ( + "bufio" + "flag" + "fmt" + "io/ioutil" + "os" + "regexp" + "strings" +) + +var ( + b32 = flag.Bool("b32", false, "32bit big-endian") + l32 = flag.Bool("l32", false, "32bit little-endian") + aix = flag.Bool("aix", false, "aix") + tags = flag.String("tags", "", "build tags") +) + +// cmdLine returns this programs's commandline arguments +func cmdLine() string { + return "go run mksyscall_aix_ppc64.go " + strings.Join(os.Args[1:], " ") +} + +// buildTags returns build tags +func buildTags() string { + return *tags +} + +// Param is function parameter +type Param struct { + Name string + Type string +} + +// usage prints the program usage +func usage() { + fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc64.go [-b32 | -l32] [-tags x,y] [file ...]\n") + os.Exit(1) +} + +// parseParamList parses parameter list and returns a slice of parameters +func parseParamList(list string) []string { + list = strings.TrimSpace(list) + if list == "" { + return []string{} + } + return regexp.MustCompile(`\s*,\s*`).Split(list, -1) +} + +// parseParam splits a parameter into name and type +func parseParam(p string) Param { + ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p) + if ps == nil { + fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p) + os.Exit(1) + } + return Param{ps[1], ps[2]} +} + +func main() { + flag.Usage = usage + flag.Parse() + if len(flag.Args()) <= 0 { + fmt.Fprintf(os.Stderr, "no files to parse provided\n") + usage() + } + + endianness := "" + if *b32 { + endianness = "big-endian" + } else if *l32 { + endianness = "little-endian" + } + + pack := "" + // GCCGO + textgccgo := "" + cExtern := "/*\n#include <stdint.h>\n" + // GC + textgc := "" + dynimports := "" + linknames := "" + var vars []string + // COMMON + textcommon := "" + for _, path := range flag.Args() { + file, err := os.Open(path) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + s := bufio.NewScanner(file) + for s.Scan() { + t := s.Text() + t = strings.TrimSpace(t) + t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `) + if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" { + pack = p[1] + } + nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t) + if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil { + continue + } + + // Line must be of the form + // func Open(path string, mode int, perm int) (fd int, err error) + // Split into name, in params, out params. + f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t) + if f == nil { + fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t) + os.Exit(1) + } + funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6] + + // Split argument lists on comma. + in := parseParamList(inps) + out := parseParamList(outps) + + inps = strings.Join(in, ", ") + outps = strings.Join(out, ", ") + + if sysname == "" { + sysname = funct + } + + onlyCommon := false + if funct == "readlen" || funct == "writelen" || funct == "FcntlInt" || funct == "FcntlFlock" { + // This function call another syscall which is already implemented. + // Therefore, the gc and gccgo part must not be generated. + onlyCommon = true + } + + // Try in vain to keep people from editing this file. + // The theory is that they jump into the middle of the file + // without reading the header. + + textcommon += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n" + if !onlyCommon { + textgccgo += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n" + textgc += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n" + } + + // Check if value return, err return available + errvar := "" + rettype := "" + for _, param := range out { + p := parseParam(param) + if p.Type == "error" { + errvar = p.Name + } else { + rettype = p.Type + } + } + + sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`) + sysname = strings.ToLower(sysname) // All libc functions are lowercase. + + // GCCGO Prototype return type + cRettype := "" + if rettype == "unsafe.Pointer" { + cRettype = "uintptr_t" + } else if rettype == "uintptr" { + cRettype = "uintptr_t" + } else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil { + cRettype = "uintptr_t" + } else if rettype == "int" { + cRettype = "int" + } else if rettype == "int32" { + cRettype = "int" + } else if rettype == "int64" { + cRettype = "long long" + } else if rettype == "uint32" { + cRettype = "unsigned int" + } else if rettype == "uint64" { + cRettype = "unsigned long long" + } else { + cRettype = "int" + } + if sysname == "exit" { + cRettype = "void" + } + + // GCCGO Prototype arguments type + var cIn []string + for i, param := range in { + p := parseParam(param) + if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil { + cIn = append(cIn, "uintptr_t") + } else if p.Type == "string" { + cIn = append(cIn, "uintptr_t") + } else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil { + cIn = append(cIn, "uintptr_t", "size_t") + } else if p.Type == "unsafe.Pointer" { + cIn = append(cIn, "uintptr_t") + } else if p.Type == "uintptr" { + cIn = append(cIn, "uintptr_t") + } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil { + cIn = append(cIn, "uintptr_t") + } else if p.Type == "int" { + if (i == 0 || i == 2) && funct == "fcntl" { + // These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock + cIn = append(cIn, "uintptr_t") + } else { + cIn = append(cIn, "int") + } + + } else if p.Type == "int32" { + cIn = append(cIn, "int") + } else if p.Type == "int64" { + cIn = append(cIn, "long long") + } else if p.Type == "uint32" { + cIn = append(cIn, "unsigned int") + } else if p.Type == "uint64" { + cIn = append(cIn, "unsigned long long") + } else { + cIn = append(cIn, "int") + } + } + + if !onlyCommon { + // GCCGO Prototype Generation + // Imports of system calls from libc + if sysname == "select" { + // select is a keyword of Go. Its name is + // changed to c_select. + cExtern += "#define c_select select\n" + } + cExtern += fmt.Sprintf("%s %s", cRettype, sysname) + cIn := strings.Join(cIn, ", ") + cExtern += fmt.Sprintf("(%s);\n", cIn) + } + // GC Library name + if modname == "" { + modname = "libc.a/shr_64.o" + } else { + fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct) + os.Exit(1) + } + sysvarname := fmt.Sprintf("libc_%s", sysname) + + if !onlyCommon { + // GC Runtime import of function to allow cross-platform builds. + dynimports += fmt.Sprintf("//go:cgo_import_dynamic %s %s \"%s\"\n", sysvarname, sysname, modname) + // GC Link symbol to proc address variable. + linknames += fmt.Sprintf("//go:linkname %s %s\n", sysvarname, sysvarname) + // GC Library proc address variable. + vars = append(vars, sysvarname) + } + + strconvfunc := "BytePtrFromString" + strconvtype := "*byte" + + // Go function header. + if outps != "" { + outps = fmt.Sprintf(" (%s)", outps) + } + if textcommon != "" { + textcommon += "\n" + } + + textcommon += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps) + + // Prepare arguments tocall. + var argscommon []string // Arguments in the common part + var argscall []string // Arguments for call prototype + var argsgc []string // Arguments for gc call (with syscall6) + var argsgccgo []string // Arguments for gccgo call (with C.name_of_syscall) + n := 0 + argN := 0 + for _, param := range in { + p := parseParam(param) + if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil { + argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.Name)) + argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name)) + argsgc = append(argsgc, p.Name) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name)) + } else if p.Type == "string" && errvar != "" { + textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype) + textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name) + textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar) + + argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n)) + argscall = append(argscall, fmt.Sprintf("_p%d uintptr ", n)) + argsgc = append(argsgc, fmt.Sprintf("_p%d", n)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n)) + n++ + } else if p.Type == "string" { + fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n") + textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype) + textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name) + textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar) + + argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n)) + argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n)) + argsgc = append(argsgc, fmt.Sprintf("_p%d", n)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n)) + n++ + } else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil { + // Convert slice into pointer, length. + // Have to be careful not to take address of &a[0] if len == 0: + // pass nil in that case. + textcommon += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1]) + textcommon += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name) + argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("len(%s)", p.Name)) + argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n), fmt.Sprintf("_lenp%d int", n)) + argsgc = append(argsgc, fmt.Sprintf("_p%d", n), fmt.Sprintf("uintptr(_lenp%d)", n)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n), fmt.Sprintf("C.size_t(_lenp%d)", n)) + n++ + } else if p.Type == "int64" && endianness != "" { + fmt.Fprintf(os.Stderr, path+":"+funct+" uses int64 with 32 bits mode. Case not yet implemented\n") + } else if p.Type == "bool" { + fmt.Fprintf(os.Stderr, path+":"+funct+" uses bool. Case not yet implemented\n") + } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil || p.Type == "unsafe.Pointer" { + argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name)) + argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name)) + argsgc = append(argsgc, p.Name) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name)) + } else if p.Type == "int" { + if (argN == 0 || argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt") || (funct == "FcntlFlock")) { + // These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock + argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name)) + argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name)) + argsgc = append(argsgc, p.Name) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name)) + + } else { + argscommon = append(argscommon, p.Name) + argscall = append(argscall, fmt.Sprintf("%s int", p.Name)) + argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name)) + } + } else if p.Type == "int32" { + argscommon = append(argscommon, p.Name) + argscall = append(argscall, fmt.Sprintf("%s int32", p.Name)) + argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name)) + } else if p.Type == "int64" { + argscommon = append(argscommon, p.Name) + argscall = append(argscall, fmt.Sprintf("%s int64", p.Name)) + argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.longlong(%s)", p.Name)) + } else if p.Type == "uint32" { + argscommon = append(argscommon, p.Name) + argscall = append(argscall, fmt.Sprintf("%s uint32", p.Name)) + argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.uint(%s)", p.Name)) + } else if p.Type == "uint64" { + argscommon = append(argscommon, p.Name) + argscall = append(argscall, fmt.Sprintf("%s uint64", p.Name)) + argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.ulonglong(%s)", p.Name)) + } else if p.Type == "uintptr" { + argscommon = append(argscommon, p.Name) + argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name)) + argsgc = append(argsgc, p.Name) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name)) + } else { + argscommon = append(argscommon, fmt.Sprintf("int(%s)", p.Name)) + argscall = append(argscall, fmt.Sprintf("%s int", p.Name)) + argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name)) + argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name)) + } + argN++ + } + nargs := len(argsgc) + + // COMMON function generation + argscommonlist := strings.Join(argscommon, ", ") + callcommon := fmt.Sprintf("call%s(%s)", sysname, argscommonlist) + ret := []string{"_", "_"} + body := "" + doErrno := false + for i := 0; i < len(out); i++ { + p := parseParam(out[i]) + reg := "" + if p.Name == "err" { + reg = "e1" + ret[1] = reg + doErrno = true + } else { + reg = "r0" + ret[0] = reg + } + if p.Type == "bool" { + reg = fmt.Sprintf("%s != 0", reg) + } + if reg != "e1" { + body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg) + } + } + if ret[0] == "_" && ret[1] == "_" { + textcommon += fmt.Sprintf("\t%s\n", callcommon) + } else { + textcommon += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], callcommon) + } + textcommon += body + + if doErrno { + textcommon += "\tif e1 != 0 {\n" + textcommon += "\t\terr = errnoErr(e1)\n" + textcommon += "\t}\n" + } + textcommon += "\treturn\n" + textcommon += "}\n" + + if onlyCommon { + continue + } + + // CALL Prototype + callProto := fmt.Sprintf("func call%s(%s) (r1 uintptr, e1 Errno) {\n", sysname, strings.Join(argscall, ", ")) + + // GC function generation + asm := "syscall6" + if nonblock != nil { + asm = "rawSyscall6" + } + + if len(argsgc) <= 6 { + for len(argsgc) < 6 { + argsgc = append(argsgc, "0") + } + } else { + fmt.Fprintf(os.Stderr, "%s: too many arguments to system call", funct) + os.Exit(1) + } + argsgclist := strings.Join(argsgc, ", ") + callgc := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, argsgclist) + + textgc += callProto + textgc += fmt.Sprintf("\tr1, _, e1 = %s\n", callgc) + textgc += "\treturn\n}\n" + + // GCCGO function generation + argsgccgolist := strings.Join(argsgccgo, ", ") + var callgccgo string + if sysname == "select" { + // select is a keyword of Go. Its name is + // changed to c_select. + callgccgo = fmt.Sprintf("C.c_%s(%s)", sysname, argsgccgolist) + } else { + callgccgo = fmt.Sprintf("C.%s(%s)", sysname, argsgccgolist) + } + textgccgo += callProto + textgccgo += fmt.Sprintf("\tr1 = uintptr(%s)\n", callgccgo) + textgccgo += "\te1 = syscall.GetErrno()\n" + textgccgo += "\treturn\n}\n" + } + if err := s.Err(); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + file.Close() + } + imp := "" + if pack != "unix" { + imp = "import \"golang.org/x/sys/unix\"\n" + + } + + // Print zsyscall_aix_ppc64.go + err := ioutil.WriteFile("zsyscall_aix_ppc64.go", + []byte(fmt.Sprintf(srcTemplate1, cmdLine(), buildTags(), pack, imp, textcommon)), + 0644) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + // Print zsyscall_aix_ppc64_gc.go + vardecls := "\t" + strings.Join(vars, ",\n\t") + vardecls += " syscallFunc" + err = ioutil.WriteFile("zsyscall_aix_ppc64_gc.go", + []byte(fmt.Sprintf(srcTemplate2, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, textgc)), + 0644) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + // Print zsyscall_aix_ppc64_gccgo.go + err = ioutil.WriteFile("zsyscall_aix_ppc64_gccgo.go", + []byte(fmt.Sprintf(srcTemplate3, cmdLine(), buildTags(), pack, cExtern, imp, textgccgo)), + 0644) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } +} + +const srcTemplate1 = `// %s +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build %s + +package %s + +import ( + "unsafe" +) + + +%s + +%s +` +const srcTemplate2 = `// %s +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build %s +// +build !gccgo + +package %s + +import ( + "unsafe" +) +%s +%s +%s +type syscallFunc uintptr + +var ( +%s +) + +// Implemented in runtime/syscall_aix.go. +func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) +func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) + +%s +` +const srcTemplate3 = `// %s +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build %s +// +build gccgo + +package %s + +%s +*/ +import "C" +import ( + "syscall" +) + + +%s + +%s +` diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl deleted file mode 100644 index 53df26bb93ac..000000000000 --- a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.pl +++ /dev/null @@ -1,579 +0,0 @@ -#!/usr/bin/env perl -# Copyright 2018 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -# This program reads a file containing function prototypes -# (like syscall_aix.go) and generates system call bodies. -# The prototypes are marked by lines beginning with "//sys" -# and read like func declarations if //sys is replaced by func, but: -# * The parameter lists must give a name for each argument. -# This includes return parameters. -# * The parameter lists must give a type for each argument: -# the (x, y, z int) shorthand is not allowed. -# * If the return parameter is an error number, it must be named err. -# * If go func name needs to be different than its libc name, -# * or the function is not in libc, name could be specified -# * at the end, after "=" sign, like -# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt - -# This program will generate three files and handle both gc and gccgo implementation: -# - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation) -# - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6 -# - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type. - -# The generated code looks like this -# -# zsyscall_aix_ppc64.go -# func asyscall(...) (n int, err error) { -# // Pointer Creation -# r1, e1 := callasyscall(...) -# // Type Conversion -# // Error Handler -# return -# } -# -# zsyscall_aix_ppc64_gc.go -# //go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o" -# //go:linkname libc_asyscall libc_asyscall -# var asyscall syscallFunc -# -# func callasyscall(...) (r1 uintptr, e1 Errno) { -# r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... ) -# return -# } -# -# zsyscall_aix_ppc64_ggcgo.go -# /* -# int asyscall(...) -# -# */ -# import "C" -# -# func callasyscall(...) (r1 uintptr, e1 Errno) { -# r1 = uintptr(C.asyscall(...)) -# e1 = syscall.GetErrno() -# return -# } - - - -use strict; - -my $cmdline = "mksyscall_aix_ppc64.pl " . join(' ', @ARGV); -my $errors = 0; -my $_32bit = ""; -my $tags = ""; # build tags -my $aix = 0; -my $solaris = 0; - -binmode STDOUT; - -if($ARGV[0] eq "-b32") { - $_32bit = "big-endian"; - shift; -} elsif($ARGV[0] eq "-l32") { - $_32bit = "little-endian"; - shift; -} -if($ARGV[0] eq "-aix") { - $aix = 1; - shift; -} -if($ARGV[0] eq "-tags") { - shift; - $tags = $ARGV[0]; - shift; -} - -if($ARGV[0] =~ /^-/) { - print STDERR "usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n"; - exit 1; -} - -sub parseparamlist($) { - my ($list) = @_; - $list =~ s/^\s*//; - $list =~ s/\s*$//; - if($list eq "") { - return (); - } - return split(/\s*,\s*/, $list); -} - -sub parseparam($) { - my ($p) = @_; - if($p !~ /^(\S*) (\S*)$/) { - print STDERR "$ARGV:$.: malformed parameter: $p\n"; - $errors = 1; - return ("xx", "int"); - } - return ($1, $2); -} - -my $package = ""; -# GCCGO -my $textgccgo = ""; -my $c_extern = "/*\n#include <stdint.h>\n"; -# GC -my $textgc = ""; -my $dynimports = ""; -my $linknames = ""; -my @vars = (); -# COMMUN -my $textcommon = ""; - -while(<>) { - chomp; - s/\s+/ /g; - s/^\s+//; - s/\s+$//; - $package = $1 if !$package && /^package (\S+)$/; - my $nonblock = /^\/\/sysnb /; - next if !/^\/\/sys / && !$nonblock; - - # Line must be of the form - # func Open(path string, mode int, perm int) (fd int, err error) - # Split into name, in params, out params. - if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) { - print STDERR "$ARGV:$.: malformed //sys declaration\n"; - $errors = 1; - next; - } - my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6); - - # Split argument lists on comma. - my @in = parseparamlist($in); - my @out = parseparamlist($out); - - $in = join(', ', @in); - $out = join(', ', @out); - - if($sysname eq "") { - $sysname = "$func"; - } - - my $onlyCommon = 0; - if ($func eq "readlen" || $func eq "writelen" || $func eq "FcntlInt" || $func eq "FcntlFlock") { - # This function call another syscall which is already implemented. - # Therefore, the gc and gccgo part must not be generated. - $onlyCommon = 1 - } - - # Try in vain to keep people from editing this file. - # The theory is that they jump into the middle of the file - # without reading the header. - - $textcommon .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; - if (!$onlyCommon) { - $textgccgo .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; - $textgc .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; - } - - - # Check if value return, err return available - my $errvar = ""; - my $retvar = ""; - my $rettype = ""; - foreach my $p (@out) { - my ($name, $type) = parseparam($p); - if($type eq "error") { - $errvar = $name; - } else { - $retvar = $name; - $rettype = $type; - } - } - - - $sysname =~ s/([a-z])([A-Z])/${1}_$2/g; - $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. - - # GCCGO Prototype return type - my $C_rettype = ""; - if($rettype eq "unsafe.Pointer") { - $C_rettype = "uintptr_t"; - } elsif($rettype eq "uintptr") { - $C_rettype = "uintptr_t"; - } elsif($rettype =~ /^_/) { - $C_rettype = "uintptr_t"; - } elsif($rettype eq "int") { - $C_rettype = "int"; - } elsif($rettype eq "int32") { - $C_rettype = "int"; - } elsif($rettype eq "int64") { - $C_rettype = "long long"; - } elsif($rettype eq "uint32") { - $C_rettype = "unsigned int"; - } elsif($rettype eq "uint64") { - $C_rettype = "unsigned long long"; - } else { - $C_rettype = "int"; - } - if($sysname eq "exit") { - $C_rettype = "void"; - } - - # GCCGO Prototype arguments type - my @c_in = (); - foreach my $i (0 .. $#in) { - my ($name, $type) = parseparam($in[$i]); - if($type =~ /^\*/) { - push @c_in, "uintptr_t"; - } elsif($type eq "string") { - push @c_in, "uintptr_t"; - } elsif($type =~ /^\[\](.*)/) { - push @c_in, "uintptr_t", "size_t"; - } elsif($type eq "unsafe.Pointer") { - push @c_in, "uintptr_t"; - } elsif($type eq "uintptr") { - push @c_in, "uintptr_t"; - } elsif($type =~ /^_/) { - push @c_in, "uintptr_t"; - } elsif($type eq "int") { - if (($i == 0 || $i == 2) && $func eq "fcntl"){ - # These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock - push @c_in, "uintptr_t"; - } else { - push @c_in, "int"; - } - } elsif($type eq "int32") { - push @c_in, "int"; - } elsif($type eq "int64") { - push @c_in, "long long"; - } elsif($type eq "uint32") { - push @c_in, "unsigned int"; - } elsif($type eq "uint64") { - push @c_in, "unsigned long long"; - } else { - push @c_in, "int"; - } - } - - if (!$onlyCommon){ - # GCCGO Prototype Generation - # Imports of system calls from libc - $c_extern .= "$C_rettype $sysname"; - my $c_in = join(', ', @c_in); - $c_extern .= "($c_in);\n"; - } - - # GC Library name - if($modname eq "") { - $modname = "libc.a/shr_64.o"; - } else { - print STDERR "$func: only syscall using libc are available\n"; - $errors = 1; - next; - } - my $sysvarname = "libc_${sysname}"; - - if (!$onlyCommon){ - # GC Runtime import of function to allow cross-platform builds. - $dynimports .= "//go:cgo_import_dynamic ${sysvarname} ${sysname} \"$modname\"\n"; - # GC Link symbol to proc address variable. - $linknames .= "//go:linkname ${sysvarname} ${sysvarname}\n"; - # GC Library proc address variable. - push @vars, $sysvarname; - } - - my $strconvfunc ="BytePtrFromString"; - my $strconvtype = "*byte"; - - # Go function header. - if($out ne "") { - $out = " ($out)"; - } - if($textcommon ne "") { - $textcommon .= "\n" - } - - $textcommon .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ; - - # Prepare arguments to call. - my @argscommun = (); # Arguments in the commun part - my @argscall = (); # Arguments for call prototype - my @argsgc = (); # Arguments for gc call (with syscall6) - my @argsgccgo = (); # Arguments for gccgo call (with C.name_of_syscall) - my $n = 0; - my $arg_n = 0; - foreach my $p (@in) { - my ($name, $type) = parseparam($p); - if($type =~ /^\*/) { - push @argscommun, "uintptr(unsafe.Pointer($name))"; - push @argscall, "$name uintptr"; - push @argsgc, "$name"; - push @argsgccgo, "C.uintptr_t($name)"; - } elsif($type eq "string" && $errvar ne "") { - $textcommon .= "\tvar _p$n $strconvtype\n"; - $textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n"; - $textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; - - push @argscommun, "uintptr(unsafe.Pointer(_p$n))"; - push @argscall, "_p$n uintptr "; - push @argsgc, "_p$n"; - push @argsgccgo, "C.uintptr_t(_p$n)"; - $n++; - } elsif($type eq "string") { - print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; - $textcommon .= "\tvar _p$n $strconvtype\n"; - $textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n"; - $textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; - - push @argscommun, "uintptr(unsafe.Pointer(_p$n))"; - push @argscall, "_p$n uintptr"; - push @argsgc, "_p$n"; - push @argsgccgo, "C.uintptr_t(_p$n)"; - $n++; - } elsif($type =~ /^\[\](.*)/) { - # Convert slice into pointer, length. - # Have to be careful not to take address of &a[0] if len == 0: - # pass nil in that case. - $textcommon .= "\tvar _p$n *$1\n"; - $textcommon .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n"; - push @argscommun, "uintptr(unsafe.Pointer(_p$n))", "len($name)"; - push @argscall, "_p$n uintptr", "_lenp$n int"; - push @argsgc, "_p$n", "uintptr(_lenp$n)"; - push @argsgccgo, "C.uintptr_t(_p$n)", "C.size_t(_lenp$n)"; - $n++; - } elsif($type eq "int64" && $_32bit ne "") { - print STDERR "$ARGV:$.: $func uses int64 with 32 bits mode. Case not yet implemented\n"; - # if($_32bit eq "big-endian") { - # push @args, "uintptr($name >> 32)", "uintptr($name)"; - # } else { - # push @args, "uintptr($name)", "uintptr($name >> 32)"; - # } - # $n++; - } elsif($type eq "bool") { - print STDERR "$ARGV:$.: $func uses bool. Case not yet implemented\n"; - # $text .= "\tvar _p$n uint32\n"; - # $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n"; - # push @args, "_p$n"; - # $n++; - } elsif($type =~ /^_/ ||$type eq "unsafe.Pointer") { - push @argscommun, "uintptr($name)"; - push @argscall, "$name uintptr"; - push @argsgc, "$name"; - push @argsgccgo, "C.uintptr_t($name)"; - } elsif($type eq "int") { - if (($arg_n == 0 || $arg_n == 2) && ($func eq "fcntl" || $func eq "FcntlInt" || $func eq "FcntlFlock")) { - # These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock - push @argscommun, "uintptr($name)"; - push @argscall, "$name uintptr"; - push @argsgc, "$name"; - push @argsgccgo, "C.uintptr_t($name)"; - } else { - push @argscommun, "$name"; - push @argscall, "$name int"; - push @argsgc, "uintptr($name)"; - push @argsgccgo, "C.int($name)"; - } - } elsif($type eq "int32") { - push @argscommun, "$name"; - push @argscall, "$name int32"; - push @argsgc, "uintptr($name)"; - push @argsgccgo, "C.int($name)"; - } elsif($type eq "int64") { - push @argscommun, "$name"; - push @argscall, "$name int64"; - push @argsgc, "uintptr($name)"; - push @argsgccgo, "C.longlong($name)"; - } elsif($type eq "uint32") { - push @argscommun, "$name"; - push @argscall, "$name uint32"; - push @argsgc, "uintptr($name)"; - push @argsgccgo, "C.uint($name)"; - } elsif($type eq "uint64") { - push @argscommun, "$name"; - push @argscall, "$name uint64"; - push @argsgc, "uintptr($name)"; - push @argsgccgo, "C.ulonglong($name)"; - } elsif($type eq "uintptr") { - push @argscommun, "$name"; - push @argscall, "$name uintptr"; - push @argsgc, "$name"; - push @argsgccgo, "C.uintptr_t($name)"; - } else { - push @argscommun, "int($name)"; - push @argscall, "$name int"; - push @argsgc, "uintptr($name)"; - push @argsgccgo, "C.int($name)"; - } - $arg_n++; - } - my $nargs = @argsgc; - - # COMMUN function generation - my $argscommun = join(', ', @argscommun); - my $callcommun = "call$sysname($argscommun)"; - my @ret = ("_", "_"); - my $body = ""; - my $do_errno = 0; - for(my $i=0; $i<@out; $i++) { - my $p = $out[$i]; - my ($name, $type) = parseparam($p); - my $reg = ""; - if($name eq "err") { - $reg = "e1"; - $ret[1] = $reg; - $do_errno = 1; - } else { - $reg = "r0"; - $ret[0] = $reg; - } - if($type eq "bool") { - $reg = "$reg != 0"; - } - if($reg ne "e1") { - $body .= "\t$name = $type($reg)\n"; - } - } - if ($ret[0] eq "_" && $ret[1] eq "_") { - $textcommon .= "\t$callcommun\n"; - } else { - $textcommon .= "\t$ret[0], $ret[1] := $callcommun\n"; - } - $textcommon .= $body; - - if ($do_errno) { - $textcommon .= "\tif e1 != 0 {\n"; - $textcommon .= "\t\terr = errnoErr(e1)\n"; - $textcommon .= "\t}\n"; - } - $textcommon .= "\treturn\n"; - $textcommon .= "}\n"; - - if ($onlyCommon){ - next - } - # CALL Prototype - my $callProto = sprintf "func call%s(%s) (r1 uintptr, e1 Errno) {\n", $sysname, join(', ', @argscall); - - # GC function generation - my $asm = "syscall6"; - if ($nonblock) { - $asm = "rawSyscall6"; - } - - if(@argsgc <= 6) { - while(@argsgc < 6) { - push @argsgc, "0"; - } - } else { - print STDERR "$ARGV:$.: too many arguments to system call\n"; - } - my $argsgc = join(', ', @argsgc); - my $callgc = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $argsgc)"; - - $textgc .= $callProto; - $textgc .= "\tr1, _, e1 = $callgc\n"; - $textgc .= "\treturn\n}\n"; - - # GCCGO function generation - my $argsgccgo = join(', ', @argsgccgo); - my $callgccgo = "C.$sysname($argsgccgo)"; - $textgccgo .= $callProto; - $textgccgo .= "\tr1 = uintptr($callgccgo)\n"; - $textgccgo .= "\te1 = syscall.GetErrno()\n"; - $textgccgo .= "\treturn\n}\n"; -} - -if($errors) { - exit 1; -} - -# Print zsyscall_aix_ppc64.go -open(my $fcommun, '>', 'zsyscall_aix_ppc64.go'); -my $tofcommun = <<EOF; -// $cmdline -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $tags - -package $package - -import ( - "unsafe" -) - -EOF - -$tofcommun .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; - -$tofcommun .=<<EOF; - -$textcommon -EOF -print $fcommun $tofcommun; - - -# Print zsyscall_aix_ppc64_gc.go -open(my $fgc, '>', 'zsyscall_aix_ppc64_gc.go'); -my $tofgc = <<EOF; -// $cmdline -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $tags -// +build !gccgo - -package $package - -import ( - "unsafe" -) - - -EOF - -$tofgc .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; - -my $vardecls = "\t" . join(",\n\t", @vars); -$vardecls .= " syscallFunc"; - -$tofgc .=<<EOF; -$dynimports -$linknames -type syscallFunc uintptr - -var ( -$vardecls -) - -// Implemented in runtime/syscall_aix.go. -func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) -func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) - -$textgc -EOF -print $fgc $tofgc; - -# Print zsyscall_aix_ppc64_gc.go -open(my $fgccgo, '>', 'zsyscall_aix_ppc64_gccgo.go'); -my $tofgccgo = <<EOF; -// $cmdline -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $tags -// +build gccgo - -package $package - - -$c_extern -*/ -import "C" -import ( - "syscall" -) - - -EOF - -$tofgccgo .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; - -$tofgccgo .=<<EOF; - -$textgccgo -EOF -print $fgccgo $tofgccgo; -exit 0; diff --git a/vendor/golang.org/x/sys/unix/mksyscall_solaris.go b/vendor/golang.org/x/sys/unix/mksyscall_solaris.go new file mode 100644 index 000000000000..3d864738b695 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/mksyscall_solaris.go @@ -0,0 +1,335 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +/* + This program reads a file containing function prototypes + (like syscall_solaris.go) and generates system call bodies. + The prototypes are marked by lines beginning with "//sys" + and read like func declarations if //sys is replaced by func, but: + * The parameter lists must give a name for each argument. + This includes return parameters. + * The parameter lists must give a type for each argument: + the (x, y, z int) shorthand is not allowed. + * If the return parameter is an error number, it must be named err. + * If go func name needs to be different than its libc name, + * or the function is not in libc, name could be specified + * at the end, after "=" sign, like + //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt +*/ + +package main + +import ( + "bufio" + "flag" + "fmt" + "os" + "regexp" + "strings" +) + +var ( + b32 = flag.Bool("b32", false, "32bit big-endian") + l32 = flag.Bool("l32", false, "32bit little-endian") + tags = flag.String("tags", "", "build tags") +) + +// cmdLine returns this programs's commandline arguments +func cmdLine() string { + return "go run mksyscall_solaris.go " + strings.Join(os.Args[1:], " ") +} + +// buildTags returns build tags +func buildTags() string { + return *tags +} + +// Param is function parameter +type Param struct { + Name string + Type string +} + +// usage prints the program usage +func usage() { + fmt.Fprintf(os.Stderr, "usage: go run mksyscall_solaris.go [-b32 | -l32] [-tags x,y] [file ...]\n") + os.Exit(1) +} + +// parseParamList parses parameter list and returns a slice of parameters +func parseParamList(list string) []string { + list = strings.TrimSpace(list) + if list == "" { + return []string{} + } + return regexp.MustCompile(`\s*,\s*`).Split(list, -1) +} + +// parseParam splits a parameter into name and type +func parseParam(p string) Param { + ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p) + if ps == nil { + fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p) + os.Exit(1) + } + return Param{ps[1], ps[2]} +} + +func main() { + flag.Usage = usage + flag.Parse() + if len(flag.Args()) <= 0 { + fmt.Fprintf(os.Stderr, "no files to parse provided\n") + usage() + } + + endianness := "" + if *b32 { + endianness = "big-endian" + } else if *l32 { + endianness = "little-endian" + } + + pack := "" + text := "" + dynimports := "" + linknames := "" + var vars []string + for _, path := range flag.Args() { + file, err := os.Open(path) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + s := bufio.NewScanner(file) + for s.Scan() { + t := s.Text() + t = strings.TrimSpace(t) + t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `) + if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" { + pack = p[1] + } + nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t) + if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil { + continue + } + + // Line must be of the form + // func Open(path string, mode int, perm int) (fd int, err error) + // Split into name, in params, out params. + f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t) + if f == nil { + fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t) + os.Exit(1) + } + funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6] + + // Split argument lists on comma. + in := parseParamList(inps) + out := parseParamList(outps) + + inps = strings.Join(in, ", ") + outps = strings.Join(out, ", ") + + // Try in vain to keep people from editing this file. + // The theory is that they jump into the middle of the file + // without reading the header. + text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n" + + // So file name. + if modname == "" { + modname = "libc" + } + + // System call name. + if sysname == "" { + sysname = funct + } + + // System call pointer variable name. + sysvarname := fmt.Sprintf("proc%s", sysname) + + strconvfunc := "BytePtrFromString" + strconvtype := "*byte" + + sysname = strings.ToLower(sysname) // All libc functions are lowercase. + + // Runtime import of function to allow cross-platform builds. + dynimports += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"%s.so\"\n", sysname, sysname, modname) + // Link symbol to proc address variable. + linknames += fmt.Sprintf("//go:linkname %s libc_%s\n", sysvarname, sysname) + // Library proc address variable. + vars = append(vars, sysvarname) + + // Go function header. + outlist := strings.Join(out, ", ") + if outlist != "" { + outlist = fmt.Sprintf(" (%s)", outlist) + } + if text != "" { + text += "\n" + } + text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outlist) + + // Check if err return available + errvar := "" + for _, param := range out { + p := parseParam(param) + if p.Type == "error" { + errvar = p.Name + continue + } + } + + // Prepare arguments to Syscall. + var args []string + n := 0 + for _, param := range in { + p := parseParam(param) + if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil { + args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))") + } else if p.Type == "string" && errvar != "" { + text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype) + text += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name) + text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar) + args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n)) + n++ + } else if p.Type == "string" { + fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n") + text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype) + text += fmt.Sprintf("\t_p%d, _ = %s(%s)\n", n, strconvfunc, p.Name) + args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n)) + n++ + } else if s := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); s != nil { + // Convert slice into pointer, length. + // Have to be careful not to take address of &a[0] if len == 0: + // pass nil in that case. + text += fmt.Sprintf("\tvar _p%d *%s\n", n, s[1]) + text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name) + args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("uintptr(len(%s))", p.Name)) + n++ + } else if p.Type == "int64" && endianness != "" { + if endianness == "big-endian" { + args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name)) + } else { + args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name)) + } + } else if p.Type == "bool" { + text += fmt.Sprintf("\tvar _p%d uint32\n", n) + text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n) + args = append(args, fmt.Sprintf("uintptr(_p%d)", n)) + n++ + } else { + args = append(args, fmt.Sprintf("uintptr(%s)", p.Name)) + } + } + nargs := len(args) + + // Determine which form to use; pad args with zeros. + asm := "sysvicall6" + if nonblock != nil { + asm = "rawSysvicall6" + } + if len(args) <= 6 { + for len(args) < 6 { + args = append(args, "0") + } + } else { + fmt.Fprintf(os.Stderr, "%s: too many arguments to system call\n", path) + os.Exit(1) + } + + // Actual call. + arglist := strings.Join(args, ", ") + call := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, arglist) + + // Assign return values. + body := "" + ret := []string{"_", "_", "_"} + doErrno := false + for i := 0; i < len(out); i++ { + p := parseParam(out[i]) + reg := "" + if p.Name == "err" { + reg = "e1" + ret[2] = reg + doErrno = true + } else { + reg = fmt.Sprintf("r%d", i) + ret[i] = reg + } + if p.Type == "bool" { + reg = fmt.Sprintf("%d != 0", reg) + } + if p.Type == "int64" && endianness != "" { + // 64-bit number in r1:r0 or r0:r1. + if i+2 > len(out) { + fmt.Fprintf(os.Stderr, "%s: not enough registers for int64 return\n", path) + os.Exit(1) + } + if endianness == "big-endian" { + reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1) + } else { + reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i) + } + ret[i] = fmt.Sprintf("r%d", i) + ret[i+1] = fmt.Sprintf("r%d", i+1) + } + if reg != "e1" { + body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg) + } + } + if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" { + text += fmt.Sprintf("\t%s\n", call) + } else { + text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call) + } + text += body + + if doErrno { + text += "\tif e1 != 0 {\n" + text += "\t\terr = e1\n" + text += "\t}\n" + } + text += "\treturn\n" + text += "}\n" + } + if err := s.Err(); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + file.Close() + } + imp := "" + if pack != "unix" { + imp = "import \"golang.org/x/sys/unix\"\n" + + } + vardecls := "\t" + strings.Join(vars, ",\n\t") + vardecls += " syscallFunc" + fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, text) +} + +const srcTemplate = `// %s +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build %s + +package %s + +import ( + "syscall" + "unsafe" +) +%s +%s +%s +var ( +%s +) + +%s +` diff --git a/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl b/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl deleted file mode 100644 index a354df5a6bfd..000000000000 --- a/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl +++ /dev/null @@ -1,294 +0,0 @@ -#!/usr/bin/env perl -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -# This program reads a file containing function prototypes -# (like syscall_solaris.go) and generates system call bodies. -# The prototypes are marked by lines beginning with "//sys" -# and read like func declarations if //sys is replaced by func, but: -# * The parameter lists must give a name for each argument. -# This includes return parameters. -# * The parameter lists must give a type for each argument: -# the (x, y, z int) shorthand is not allowed. -# * If the return parameter is an error number, it must be named err. -# * If go func name needs to be different than its libc name, -# * or the function is not in libc, name could be specified -# * at the end, after "=" sign, like -# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt - -use strict; - -my $cmdline = "mksyscall_solaris.pl " . join(' ', @ARGV); -my $errors = 0; -my $_32bit = ""; -my $tags = ""; # build tags - -binmode STDOUT; - -if($ARGV[0] eq "-b32") { - $_32bit = "big-endian"; - shift; -} elsif($ARGV[0] eq "-l32") { - $_32bit = "little-endian"; - shift; -} -if($ARGV[0] eq "-tags") { - shift; - $tags = $ARGV[0]; - shift; -} - -if($ARGV[0] =~ /^-/) { - print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [-tags x,y] [file ...]\n"; - exit 1; -} - -sub parseparamlist($) { - my ($list) = @_; - $list =~ s/^\s*//; - $list =~ s/\s*$//; - if($list eq "") { - return (); - } - return split(/\s*,\s*/, $list); -} - -sub parseparam($) { - my ($p) = @_; - if($p !~ /^(\S*) (\S*)$/) { - print STDERR "$ARGV:$.: malformed parameter: $p\n"; - $errors = 1; - return ("xx", "int"); - } - return ($1, $2); -} - -my $package = ""; -my $text = ""; -my $dynimports = ""; -my $linknames = ""; -my @vars = (); -while(<>) { - chomp; - s/\s+/ /g; - s/^\s+//; - s/\s+$//; - $package = $1 if !$package && /^package (\S+)$/; - my $nonblock = /^\/\/sysnb /; - next if !/^\/\/sys / && !$nonblock; - - # Line must be of the form - # func Open(path string, mode int, perm int) (fd int, err error) - # Split into name, in params, out params. - if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) { - print STDERR "$ARGV:$.: malformed //sys declaration\n"; - $errors = 1; - next; - } - my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6); - - # Split argument lists on comma. - my @in = parseparamlist($in); - my @out = parseparamlist($out); - - # Try in vain to keep people from editing this file. - # The theory is that they jump into the middle of the file - # without reading the header. - $text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; - - # So file name. - if($modname eq "") { - $modname = "libc"; - } - - # System call name. - if($sysname eq "") { - $sysname = "$func"; - } - - # System call pointer variable name. - my $sysvarname = "proc$sysname"; - - my $strconvfunc = "BytePtrFromString"; - my $strconvtype = "*byte"; - - $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. - - # Runtime import of function to allow cross-platform builds. - $dynimports .= "//go:cgo_import_dynamic libc_${sysname} ${sysname} \"$modname.so\"\n"; - # Link symbol to proc address variable. - $linknames .= "//go:linkname ${sysvarname} libc_${sysname}\n"; - # Library proc address variable. - push @vars, $sysvarname; - - # Go function header. - $out = join(', ', @out); - if($out ne "") { - $out = " ($out)"; - } - if($text ne "") { - $text .= "\n" - } - $text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out; - - # Check if err return available - my $errvar = ""; - foreach my $p (@out) { - my ($name, $type) = parseparam($p); - if($type eq "error") { - $errvar = $name; - last; - } - } - - # Prepare arguments to Syscall. - my @args = (); - my $n = 0; - foreach my $p (@in) { - my ($name, $type) = parseparam($p); - if($type =~ /^\*/) { - push @args, "uintptr(unsafe.Pointer($name))"; - } elsif($type eq "string" && $errvar ne "") { - $text .= "\tvar _p$n $strconvtype\n"; - $text .= "\t_p$n, $errvar = $strconvfunc($name)\n"; - $text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; - push @args, "uintptr(unsafe.Pointer(_p$n))"; - $n++; - } elsif($type eq "string") { - print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; - $text .= "\tvar _p$n $strconvtype\n"; - $text .= "\t_p$n, _ = $strconvfunc($name)\n"; - push @args, "uintptr(unsafe.Pointer(_p$n))"; - $n++; - } elsif($type =~ /^\[\](.*)/) { - # Convert slice into pointer, length. - # Have to be careful not to take address of &a[0] if len == 0: - # pass nil in that case. - $text .= "\tvar _p$n *$1\n"; - $text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n"; - push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))"; - $n++; - } elsif($type eq "int64" && $_32bit ne "") { - if($_32bit eq "big-endian") { - push @args, "uintptr($name >> 32)", "uintptr($name)"; - } else { - push @args, "uintptr($name)", "uintptr($name >> 32)"; - } - } elsif($type eq "bool") { - $text .= "\tvar _p$n uint32\n"; - $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n"; - push @args, "uintptr(_p$n)"; - $n++; - } else { - push @args, "uintptr($name)"; - } - } - my $nargs = @args; - - # Determine which form to use; pad args with zeros. - my $asm = "sysvicall6"; - if ($nonblock) { - $asm = "rawSysvicall6"; - } - if(@args <= 6) { - while(@args < 6) { - push @args, "0"; - } - } else { - print STDERR "$ARGV:$.: too many arguments to system call\n"; - } - - # Actual call. - my $args = join(', ', @args); - my $call = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $args)"; - - # Assign return values. - my $body = ""; - my $failexpr = ""; - my @ret = ("_", "_", "_"); - my @pout= (); - my $do_errno = 0; - for(my $i=0; $i<@out; $i++) { - my $p = $out[$i]; - my ($name, $type) = parseparam($p); - my $reg = ""; - if($name eq "err") { - $reg = "e1"; - $ret[2] = $reg; - $do_errno = 1; - } else { - $reg = sprintf("r%d", $i); - $ret[$i] = $reg; - } - if($type eq "bool") { - $reg = "$reg != 0"; - } - if($type eq "int64" && $_32bit ne "") { - # 64-bit number in r1:r0 or r0:r1. - if($i+2 > @out) { - print STDERR "$ARGV:$.: not enough registers for int64 return\n"; - } - if($_32bit eq "big-endian") { - $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1); - } else { - $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i); - } - $ret[$i] = sprintf("r%d", $i); - $ret[$i+1] = sprintf("r%d", $i+1); - } - if($reg ne "e1") { - $body .= "\t$name = $type($reg)\n"; - } - } - if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { - $text .= "\t$call\n"; - } else { - $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; - } - $text .= $body; - - if ($do_errno) { - $text .= "\tif e1 != 0 {\n"; - $text .= "\t\terr = e1\n"; - $text .= "\t}\n"; - } - $text .= "\treturn\n"; - $text .= "}\n"; -} - -if($errors) { - exit 1; -} - -print <<EOF; -// $cmdline -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $tags - -package $package - -import ( - "syscall" - "unsafe" -) -EOF - -print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; - -my $vardecls = "\t" . join(",\n\t", @vars); -$vardecls .= " syscallFunc"; - -chomp($_=<<EOF); - -$dynimports -$linknames -var ( -$vardecls -) - -$text -EOF -print $_; -exit 0; diff --git a/vendor/golang.org/x/sys/unix/mksysctl_openbsd.go b/vendor/golang.org/x/sys/unix/mksysctl_openbsd.go new file mode 100644 index 000000000000..b6b409909cc3 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/mksysctl_openbsd.go @@ -0,0 +1,355 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Parse the header files for OpenBSD and generate a Go usable sysctl MIB. +// +// Build a MIB with each entry being an array containing the level, type and +// a hash that will contain additional entries if the current entry is a node. +// We then walk this MIB and create a flattened sysctl name to OID hash. + +package main + +import ( + "bufio" + "fmt" + "os" + "path/filepath" + "regexp" + "sort" + "strings" +) + +var ( + goos, goarch string +) + +// cmdLine returns this programs's commandline arguments. +func cmdLine() string { + return "go run mksysctl_openbsd.go " + strings.Join(os.Args[1:], " ") +} + +// buildTags returns build tags. +func buildTags() string { + return fmt.Sprintf("%s,%s", goarch, goos) +} + +// reMatch performs regular expression match and stores the substring slice to value pointed by m. +func reMatch(re *regexp.Regexp, str string, m *[]string) bool { + *m = re.FindStringSubmatch(str) + if *m != nil { + return true + } + return false +} + +type nodeElement struct { + n int + t string + pE *map[string]nodeElement +} + +var ( + debugEnabled bool + mib map[string]nodeElement + node *map[string]nodeElement + nodeMap map[string]string + sysCtl []string +) + +var ( + ctlNames1RE = regexp.MustCompile(`^#define\s+(CTL_NAMES)\s+{`) + ctlNames2RE = regexp.MustCompile(`^#define\s+(CTL_(.*)_NAMES)\s+{`) + ctlNames3RE = regexp.MustCompile(`^#define\s+((.*)CTL_NAMES)\s+{`) + netInetRE = regexp.MustCompile(`^netinet/`) + netInet6RE = regexp.MustCompile(`^netinet6/`) + netRE = regexp.MustCompile(`^net/`) + bracesRE = regexp.MustCompile(`{.*}`) + ctlTypeRE = regexp.MustCompile(`{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}`) + fsNetKernRE = regexp.MustCompile(`^(fs|net|kern)_`) +) + +func debug(s string) { + if debugEnabled { + fmt.Fprintln(os.Stderr, s) + } +} + +// Walk the MIB and build a sysctl name to OID mapping. +func buildSysctl(pNode *map[string]nodeElement, name string, oid []int) { + lNode := pNode // local copy of pointer to node + var keys []string + for k := range *lNode { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, key := range keys { + nodename := name + if name != "" { + nodename += "." + } + nodename += key + + nodeoid := append(oid, (*pNode)[key].n) + + if (*pNode)[key].t == `CTLTYPE_NODE` { + if _, ok := nodeMap[nodename]; ok { + lNode = &mib + ctlName := nodeMap[nodename] + for _, part := range strings.Split(ctlName, ".") { + lNode = ((*lNode)[part]).pE + } + } else { + lNode = (*pNode)[key].pE + } + buildSysctl(lNode, nodename, nodeoid) + } else if (*pNode)[key].t != "" { + oidStr := []string{} + for j := range nodeoid { + oidStr = append(oidStr, fmt.Sprintf("%d", nodeoid[j])) + } + text := "\t{ \"" + nodename + "\", []_C_int{ " + strings.Join(oidStr, ", ") + " } }, \n" + sysCtl = append(sysCtl, text) + } + } +} + +func main() { + // Get the OS (using GOOS_TARGET if it exist) + goos = os.Getenv("GOOS_TARGET") + if goos == "" { + goos = os.Getenv("GOOS") + } + // Get the architecture (using GOARCH_TARGET if it exists) + goarch = os.Getenv("GOARCH_TARGET") + if goarch == "" { + goarch = os.Getenv("GOARCH") + } + // Check if GOOS and GOARCH environment variables are defined + if goarch == "" || goos == "" { + fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n") + os.Exit(1) + } + + mib = make(map[string]nodeElement) + headers := [...]string{ + `sys/sysctl.h`, + `sys/socket.h`, + `sys/tty.h`, + `sys/malloc.h`, + `sys/mount.h`, + `sys/namei.h`, + `sys/sem.h`, + `sys/shm.h`, + `sys/vmmeter.h`, + `uvm/uvmexp.h`, + `uvm/uvm_param.h`, + `uvm/uvm_swap_encrypt.h`, + `ddb/db_var.h`, + `net/if.h`, + `net/if_pfsync.h`, + `net/pipex.h`, + `netinet/in.h`, + `netinet/icmp_var.h`, + `netinet/igmp_var.h`, + `netinet/ip_ah.h`, + `netinet/ip_carp.h`, + `netinet/ip_divert.h`, + `netinet/ip_esp.h`, + `netinet/ip_ether.h`, + `netinet/ip_gre.h`, + `netinet/ip_ipcomp.h`, + `netinet/ip_ipip.h`, + `netinet/pim_var.h`, + `netinet/tcp_var.h`, + `netinet/udp_var.h`, + `netinet6/in6.h`, + `netinet6/ip6_divert.h`, + `netinet6/pim6_var.h`, + `netinet/icmp6.h`, + `netmpls/mpls.h`, + } + + ctls := [...]string{ + `kern`, + `vm`, + `fs`, + `net`, + //debug /* Special handling required */ + `hw`, + //machdep /* Arch specific */ + `user`, + `ddb`, + //vfs /* Special handling required */ + `fs.posix`, + `kern.forkstat`, + `kern.intrcnt`, + `kern.malloc`, + `kern.nchstats`, + `kern.seminfo`, + `kern.shminfo`, + `kern.timecounter`, + `kern.tty`, + `kern.watchdog`, + `net.bpf`, + `net.ifq`, + `net.inet`, + `net.inet.ah`, + `net.inet.carp`, + `net.inet.divert`, + `net.inet.esp`, + `net.inet.etherip`, + `net.inet.gre`, + `net.inet.icmp`, + `net.inet.igmp`, + `net.inet.ip`, + `net.inet.ip.ifq`, + `net.inet.ipcomp`, + `net.inet.ipip`, + `net.inet.mobileip`, + `net.inet.pfsync`, + `net.inet.pim`, + `net.inet.tcp`, + `net.inet.udp`, + `net.inet6`, + `net.inet6.divert`, + `net.inet6.ip6`, + `net.inet6.icmp6`, + `net.inet6.pim6`, + `net.inet6.tcp6`, + `net.inet6.udp6`, + `net.mpls`, + `net.mpls.ifq`, + `net.key`, + `net.pflow`, + `net.pfsync`, + `net.pipex`, + `net.rt`, + `vm.swapencrypt`, + //vfsgenctl /* Special handling required */ + } + + // Node name "fixups" + ctlMap := map[string]string{ + "ipproto": "net.inet", + "net.inet.ipproto": "net.inet", + "net.inet6.ipv6proto": "net.inet6", + "net.inet6.ipv6": "net.inet6.ip6", + "net.inet.icmpv6": "net.inet6.icmp6", + "net.inet6.divert6": "net.inet6.divert", + "net.inet6.tcp6": "net.inet.tcp", + "net.inet6.udp6": "net.inet.udp", + "mpls": "net.mpls", + "swpenc": "vm.swapencrypt", + } + + // Node mappings + nodeMap = map[string]string{ + "net.inet.ip.ifq": "net.ifq", + "net.inet.pfsync": "net.pfsync", + "net.mpls.ifq": "net.ifq", + } + + mCtls := make(map[string]bool) + for _, ctl := range ctls { + mCtls[ctl] = true + } + + for _, header := range headers { + debug("Processing " + header) + file, err := os.Open(filepath.Join("/usr/include", header)) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + os.Exit(1) + } + s := bufio.NewScanner(file) + for s.Scan() { + var sub []string + if reMatch(ctlNames1RE, s.Text(), &sub) || + reMatch(ctlNames2RE, s.Text(), &sub) || + reMatch(ctlNames3RE, s.Text(), &sub) { + if sub[1] == `CTL_NAMES` { + // Top level. + node = &mib + } else { + // Node. + nodename := strings.ToLower(sub[2]) + ctlName := "" + if reMatch(netInetRE, header, &sub) { + ctlName = "net.inet." + nodename + } else if reMatch(netInet6RE, header, &sub) { + ctlName = "net.inet6." + nodename + } else if reMatch(netRE, header, &sub) { + ctlName = "net." + nodename + } else { + ctlName = nodename + ctlName = fsNetKernRE.ReplaceAllString(ctlName, `$1.`) + } + + if val, ok := ctlMap[ctlName]; ok { + ctlName = val + } + if _, ok := mCtls[ctlName]; !ok { + debug("Ignoring " + ctlName + "...") + continue + } + + // Walk down from the top of the MIB. + node = &mib + for _, part := range strings.Split(ctlName, ".") { + if _, ok := (*node)[part]; !ok { + debug("Missing node " + part) + (*node)[part] = nodeElement{n: 0, t: "", pE: &map[string]nodeElement{}} + } + node = (*node)[part].pE + } + } + + // Populate current node with entries. + i := -1 + for !strings.HasPrefix(s.Text(), "}") { + s.Scan() + if reMatch(bracesRE, s.Text(), &sub) { + i++ + } + if !reMatch(ctlTypeRE, s.Text(), &sub) { + continue + } + (*node)[sub[1]] = nodeElement{n: i, t: sub[2], pE: &map[string]nodeElement{}} + } + } + } + err = s.Err() + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + os.Exit(1) + } + file.Close() + } + buildSysctl(&mib, "", []int{}) + + sort.Strings(sysCtl) + text := strings.Join(sysCtl, "") + + fmt.Printf(srcTemplate, cmdLine(), buildTags(), text) +} + +const srcTemplate = `// %s +// Code generated by the command above; DO NOT EDIT. + +// +build %s + +package unix + +type mibentry struct { + ctlname string + ctloid []_C_int +} + +var sysctlMib = []mibentry { +%s +} +` diff --git a/vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl b/vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl deleted file mode 100644 index 20632e14608e..000000000000 --- a/vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env perl - -# Copyright 2011 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -# -# Parse the header files for OpenBSD and generate a Go usable sysctl MIB. -# -# Build a MIB with each entry being an array containing the level, type and -# a hash that will contain additional entries if the current entry is a node. -# We then walk this MIB and create a flattened sysctl name to OID hash. -# - -use strict; - -if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { - print STDERR "GOARCH or GOOS not defined in environment\n"; - exit 1; -} - -my $debug = 0; -my %ctls = (); - -my @headers = qw ( - sys/sysctl.h - sys/socket.h - sys/tty.h - sys/malloc.h - sys/mount.h - sys/namei.h - sys/sem.h - sys/shm.h - sys/vmmeter.h - uvm/uvmexp.h - uvm/uvm_param.h - uvm/uvm_swap_encrypt.h - ddb/db_var.h - net/if.h - net/if_pfsync.h - net/pipex.h - netinet/in.h - netinet/icmp_var.h - netinet/igmp_var.h - netinet/ip_ah.h - netinet/ip_carp.h - netinet/ip_divert.h - netinet/ip_esp.h - netinet/ip_ether.h - netinet/ip_gre.h - netinet/ip_ipcomp.h - netinet/ip_ipip.h - netinet/pim_var.h - netinet/tcp_var.h - netinet/udp_var.h - netinet6/in6.h - netinet6/ip6_divert.h - netinet6/pim6_var.h - netinet/icmp6.h - netmpls/mpls.h -); - -my @ctls = qw ( - kern - vm - fs - net - #debug # Special handling required - hw - #machdep # Arch specific - user - ddb - #vfs # Special handling required - fs.posix - kern.forkstat - kern.intrcnt - kern.malloc - kern.nchstats - kern.seminfo - kern.shminfo - kern.timecounter - kern.tty - kern.watchdog - net.bpf - net.ifq - net.inet - net.inet.ah - net.inet.carp - net.inet.divert - net.inet.esp - net.inet.etherip - net.inet.gre - net.inet.icmp - net.inet.igmp - net.inet.ip - net.inet.ip.ifq - net.inet.ipcomp - net.inet.ipip - net.inet.mobileip - net.inet.pfsync - net.inet.pim - net.inet.tcp - net.inet.udp - net.inet6 - net.inet6.divert - net.inet6.ip6 - net.inet6.icmp6 - net.inet6.pim6 - net.inet6.tcp6 - net.inet6.udp6 - net.mpls - net.mpls.ifq - net.key - net.pflow - net.pfsync - net.pipex - net.rt - vm.swapencrypt - #vfsgenctl # Special handling required -); - -# Node name "fixups" -my %ctl_map = ( - "ipproto" => "net.inet", - "net.inet.ipproto" => "net.inet", - "net.inet6.ipv6proto" => "net.inet6", - "net.inet6.ipv6" => "net.inet6.ip6", - "net.inet.icmpv6" => "net.inet6.icmp6", - "net.inet6.divert6" => "net.inet6.divert", - "net.inet6.tcp6" => "net.inet.tcp", - "net.inet6.udp6" => "net.inet.udp", - "mpls" => "net.mpls", - "swpenc" => "vm.swapencrypt" -); - -# Node mappings -my %node_map = ( - "net.inet.ip.ifq" => "net.ifq", - "net.inet.pfsync" => "net.pfsync", - "net.mpls.ifq" => "net.ifq" -); - -my $ctlname; -my %mib = (); -my %sysctl = (); -my $node; - -sub debug() { - print STDERR "$_[0]\n" if $debug; -} - -# Walk the MIB and build a sysctl name to OID mapping. -sub build_sysctl() { - my ($node, $name, $oid) = @_; - my %node = %{$node}; - my @oid = @{$oid}; - - foreach my $key (sort keys %node) { - my @node = @{$node{$key}}; - my $nodename = $name.($name ne '' ? '.' : '').$key; - my @nodeoid = (@oid, $node[0]); - if ($node[1] eq 'CTLTYPE_NODE') { - if (exists $node_map{$nodename}) { - $node = \%mib; - $ctlname = $node_map{$nodename}; - foreach my $part (split /\./, $ctlname) { - $node = \%{@{$$node{$part}}[2]}; - } - } else { - $node = $node[2]; - } - &build_sysctl($node, $nodename, \@nodeoid); - } elsif ($node[1] ne '') { - $sysctl{$nodename} = \@nodeoid; - } - } -} - -foreach my $ctl (@ctls) { - $ctls{$ctl} = $ctl; -} - -# Build MIB -foreach my $header (@headers) { - &debug("Processing $header..."); - open HEADER, "/usr/include/$header" || - print STDERR "Failed to open $header\n"; - while (<HEADER>) { - if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ || - $_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ || - $_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) { - if ($1 eq 'CTL_NAMES') { - # Top level. - $node = \%mib; - } else { - # Node. - my $nodename = lc($2); - if ($header =~ /^netinet\//) { - $ctlname = "net.inet.$nodename"; - } elsif ($header =~ /^netinet6\//) { - $ctlname = "net.inet6.$nodename"; - } elsif ($header =~ /^net\//) { - $ctlname = "net.$nodename"; - } else { - $ctlname = "$nodename"; - $ctlname =~ s/^(fs|net|kern)_/$1\./; - } - if (exists $ctl_map{$ctlname}) { - $ctlname = $ctl_map{$ctlname}; - } - if (not exists $ctls{$ctlname}) { - &debug("Ignoring $ctlname..."); - next; - } - - # Walk down from the top of the MIB. - $node = \%mib; - foreach my $part (split /\./, $ctlname) { - if (not exists $$node{$part}) { - &debug("Missing node $part"); - $$node{$part} = [ 0, '', {} ]; - } - $node = \%{@{$$node{$part}}[2]}; - } - } - - # Populate current node with entries. - my $i = -1; - while (defined($_) && $_ !~ /^}/) { - $_ = <HEADER>; - $i++ if $_ =~ /{.*}/; - next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/; - $$node{$1} = [ $i, $2, {} ]; - } - } - } - close HEADER; -} - -&build_sysctl(\%mib, "", []); - -print <<EOF; -// mksysctl_openbsd.pl -// Code generated by the command above; DO NOT EDIT. - -// +build $ENV{'GOARCH'},$ENV{'GOOS'} - -package unix; - -type mibentry struct { - ctlname string - ctloid []_C_int -} - -var sysctlMib = []mibentry { -EOF - -foreach my $name (sort keys %sysctl) { - my @oid = @{$sysctl{$name}}; - print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n"; -} - -print <<EOF; -} -EOF diff --git a/vendor/golang.org/x/sys/unix/mksysnum.go b/vendor/golang.org/x/sys/unix/mksysnum.go new file mode 100644 index 000000000000..07f8960ff38c --- /dev/null +++ b/vendor/golang.org/x/sys/unix/mksysnum.go @@ -0,0 +1,190 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Generate system call table for DragonFly, NetBSD, +// FreeBSD, OpenBSD or Darwin from master list +// (for example, /usr/src/sys/kern/syscalls.master or +// sys/syscall.h). +package main + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "regexp" + "strings" +) + +var ( + goos, goarch string +) + +// cmdLine returns this programs's commandline arguments +func cmdLine() string { + return "go run mksysnum.go " + strings.Join(os.Args[1:], " ") +} + +// buildTags returns build tags +func buildTags() string { + return fmt.Sprintf("%s,%s", goarch, goos) +} + +func checkErr(err error) { + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + os.Exit(1) + } +} + +// source string and substring slice for regexp +type re struct { + str string // source string + sub []string // matched sub-string +} + +// Match performs regular expression match +func (r *re) Match(exp string) bool { + r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str) + if r.sub != nil { + return true + } + return false +} + +// fetchFile fetches a text file from URL +func fetchFile(URL string) io.Reader { + resp, err := http.Get(URL) + checkErr(err) + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + checkErr(err) + return strings.NewReader(string(body)) +} + +// readFile reads a text file from path +func readFile(path string) io.Reader { + file, err := os.Open(os.Args[1]) + checkErr(err) + return file +} + +func format(name, num, proto string) string { + name = strings.ToUpper(name) + // There are multiple entries for enosys and nosys, so comment them out. + nm := re{str: name} + if nm.Match(`^SYS_E?NOSYS$`) { + name = fmt.Sprintf("// %s", name) + } + if name == `SYS_SYS_EXIT` { + name = `SYS_EXIT` + } + return fmt.Sprintf(" %s = %s; // %s\n", name, num, proto) +} + +func main() { + // Get the OS (using GOOS_TARGET if it exist) + goos = os.Getenv("GOOS_TARGET") + if goos == "" { + goos = os.Getenv("GOOS") + } + // Get the architecture (using GOARCH_TARGET if it exists) + goarch = os.Getenv("GOARCH_TARGET") + if goarch == "" { + goarch = os.Getenv("GOARCH") + } + // Check if GOOS and GOARCH environment variables are defined + if goarch == "" || goos == "" { + fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n") + os.Exit(1) + } + + file := strings.TrimSpace(os.Args[1]) + var syscalls io.Reader + if strings.HasPrefix(file, "https://") || strings.HasPrefix(file, "http://") { + // Download syscalls.master file + syscalls = fetchFile(file) + } else { + syscalls = readFile(file) + } + + var text, line string + s := bufio.NewScanner(syscalls) + for s.Scan() { + t := re{str: line} + if t.Match(`^(.*)\\$`) { + // Handle continuation + line = t.sub[1] + line += strings.TrimLeft(s.Text(), " \t") + } else { + // New line + line = s.Text() + } + t = re{str: line} + if t.Match(`\\$`) { + continue + } + t = re{str: line} + + switch goos { + case "dragonfly": + if t.Match(`^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$`) { + num, proto := t.sub[1], t.sub[2] + name := fmt.Sprintf("SYS_%s", t.sub[3]) + text += format(name, num, proto) + } + case "freebsd": + if t.Match(`^([0-9]+)\s+\S+\s+(?:NO)?STD\s+({ \S+\s+(\w+).*)$`) { + num, proto := t.sub[1], t.sub[2] + name := fmt.Sprintf("SYS_%s", t.sub[3]) + text += format(name, num, proto) + } + case "openbsd": + if t.Match(`^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$`) { + num, proto, name := t.sub[1], t.sub[3], t.sub[4] + text += format(name, num, proto) + } + case "netbsd": + if t.Match(`^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$`) { + num, proto, compat := t.sub[1], t.sub[6], t.sub[8] + name := t.sub[7] + "_" + t.sub[9] + if t.sub[11] != "" { + name = t.sub[7] + "_" + t.sub[11] + } + name = strings.ToUpper(name) + if compat == "" || compat == "13" || compat == "30" || compat == "50" { + text += fmt.Sprintf(" %s = %s; // %s\n", name, num, proto) + } + } + case "darwin": + if t.Match(`^#define\s+SYS_(\w+)\s+([0-9]+)`) { + name, num := t.sub[1], t.sub[2] + name = strings.ToUpper(name) + text += fmt.Sprintf(" SYS_%s = %s;\n", name, num) + } + default: + fmt.Fprintf(os.Stderr, "unrecognized GOOS=%s\n", goos) + os.Exit(1) + + } + } + err := s.Err() + checkErr(err) + + fmt.Printf(template, cmdLine(), buildTags(), text) +} + +const template = `// %s +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build %s + +package unix + +const( +%s)` diff --git a/vendor/golang.org/x/sys/unix/mksysnum_darwin.pl b/vendor/golang.org/x/sys/unix/mksysnum_darwin.pl deleted file mode 100644 index 5453c53b1923..000000000000 --- a/vendor/golang.org/x/sys/unix/mksysnum_darwin.pl +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env perl -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. -# -# Generate system call table for Darwin from sys/syscall.h - -use strict; - -if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { - print STDERR "GOARCH or GOOS not defined in environment\n"; - exit 1; -} - -my $command = "mksysnum_darwin.pl " . join(' ', @ARGV); - -print <<EOF; -// $command -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $ENV{'GOARCH'},$ENV{'GOOS'} - -package unix - -const ( -EOF - -while(<>){ - if(/^#define\s+SYS_(\w+)\s+([0-9]+)/){ - my $name = $1; - my $num = $2; - $name =~ y/a-z/A-Z/; - print " SYS_$name = $num;" - } -} - -print <<EOF; -) -EOF diff --git a/vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl b/vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl deleted file mode 100644 index 6804f41216e7..000000000000 --- a/vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env perl -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. -# -# Generate system call table for DragonFly from master list -# (for example, /usr/src/sys/kern/syscalls.master). - -use strict; - -if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { - print STDERR "GOARCH or GOOS not defined in environment\n"; - exit 1; -} - -my $command = "mksysnum_dragonfly.pl " . join(' ', @ARGV); - -print <<EOF; -// $command -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $ENV{'GOARCH'},$ENV{'GOOS'} - -package unix - -const ( -EOF - -while(<>){ - if(/^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$/){ - my $num = $1; - my $proto = $2; - my $name = "SYS_$3"; - $name =~ y/a-z/A-Z/; - - # There are multiple entries for enosys and nosys, so comment them out. - if($name =~ /^SYS_E?NOSYS$/){ - $name = "// $name"; - } - if($name eq 'SYS_SYS_EXIT'){ - $name = 'SYS_EXIT'; - } - - print " $name = $num; // $proto\n"; - } -} - -print <<EOF; -) -EOF diff --git a/vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl b/vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl deleted file mode 100644 index 198993d0954d..000000000000 --- a/vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env perl -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. -# -# Generate system call table for FreeBSD from master list -# (for example, /usr/src/sys/kern/syscalls.master). - -use strict; - -if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { - print STDERR "GOARCH or GOOS not defined in environment\n"; - exit 1; -} - -my $command = "mksysnum_freebsd.pl " . join(' ', @ARGV); - -print <<EOF; -// $command -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $ENV{'GOARCH'},$ENV{'GOOS'} - -package unix - -const ( -EOF - -while(<>){ - if(/^([0-9]+)\s+\S+\s+(?:NO)?STD\s+({ \S+\s+(\w+).*)$/){ - my $num = $1; - my $proto = $2; - my $name = "SYS_$3"; - $name =~ y/a-z/A-Z/; - - # There are multiple entries for enosys and nosys, so comment them out. - if($name =~ /^SYS_E?NOSYS$/){ - $name = "// $name"; - } - if($name eq 'SYS_SYS_EXIT'){ - $name = 'SYS_EXIT'; - } - - print " $name = $num; // $proto\n"; - } -} - -print <<EOF; -) -EOF diff --git a/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl b/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl deleted file mode 100644 index 85988b140b9d..000000000000 --- a/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env perl -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. -# -# Generate system call table for OpenBSD from master list -# (for example, /usr/src/sys/kern/syscalls.master). - -use strict; - -if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { - print STDERR "GOARCH or GOOS not defined in environment\n"; - exit 1; -} - -my $command = "mksysnum_netbsd.pl " . join(' ', @ARGV); - -print <<EOF; -// $command -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $ENV{'GOARCH'},$ENV{'GOOS'} - -package unix - -const ( -EOF - -my $line = ''; -while(<>){ - if($line =~ /^(.*)\\$/) { - # Handle continuation - $line = $1; - $_ =~ s/^\s+//; - $line .= $_; - } else { - # New line - $line = $_; - } - next if $line =~ /\\$/; - if($line =~ /^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$/) { - my $num = $1; - my $proto = $6; - my $compat = $8; - my $name = "$7_$9"; - - $name = "$7_$11" if $11 ne ''; - $name =~ y/a-z/A-Z/; - - if($compat eq '' || $compat eq '13' || $compat eq '30' || $compat eq '50') { - print " $name = $num; // $proto\n"; - } - } -} - -print <<EOF; -) -EOF diff --git a/vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl b/vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl deleted file mode 100644 index 84edf60ca12d..000000000000 --- a/vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env perl -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. -# -# Generate system call table for OpenBSD from master list -# (for example, /usr/src/sys/kern/syscalls.master). - -use strict; - -if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { - print STDERR "GOARCH or GOOS not defined in environment\n"; - exit 1; -} - -my $command = "mksysnum_openbsd.pl " . join(' ', @ARGV); - -print <<EOF; -// $command -// Code generated by the command above; see README.md. DO NOT EDIT. - -// +build $ENV{'GOARCH'},$ENV{'GOOS'} - -package unix - -const ( -EOF - -while(<>){ - if(/^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$/){ - my $num = $1; - my $proto = $3; - my $name = $4; - $name =~ y/a-z/A-Z/; - - # There are multiple entries for enosys and nosys, so comment them out. - if($name =~ /^SYS_E?NOSYS$/){ - $name = "// $name"; - } - if($name eq 'SYS_SYS_EXIT'){ - $name = 'SYS_EXIT'; - } - - print " $name = $num; // $proto\n"; - } -} - -print <<EOF; -) -EOF diff --git a/vendor/golang.org/x/sys/unix/openbsd_pledge.go b/vendor/golang.org/x/sys/unix/openbsd_pledge.go deleted file mode 100644 index 230a36d2490a..000000000000 --- a/vendor/golang.org/x/sys/unix/openbsd_pledge.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build openbsd -// +build 386 amd64 arm - -package unix - -import ( - "errors" - "fmt" - "strconv" - "syscall" - "unsafe" -) - -// Pledge implements the pledge syscall. -// -// The pledge syscall does not accept execpromises on OpenBSD releases -// before 6.3. -// -// execpromises must be empty when Pledge is called on OpenBSD -// releases predating 6.3, otherwise an error will be returned. -// -// For more information see pledge(2). -func Pledge(promises, execpromises string) error { - maj, min, err := majmin() - if err != nil { - return err - } - - err = pledgeAvailable(maj, min, execpromises) - if err != nil { - return err - } - - pptr, err := syscall.BytePtrFromString(promises) - if err != nil { - return err - } - - // This variable will hold either a nil unsafe.Pointer or - // an unsafe.Pointer to a string (execpromises). - var expr unsafe.Pointer - - // If we're running on OpenBSD > 6.2, pass execpromises to the syscall. - if maj > 6 || (maj == 6 && min > 2) { - exptr, err := syscall.BytePtrFromString(execpromises) - if err != nil { - return err - } - expr = unsafe.Pointer(exptr) - } - - _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) - if e != 0 { - return e - } - - return nil -} - -// PledgePromises implements the pledge syscall. -// -// This changes the promises and leaves the execpromises untouched. -// -// For more information see pledge(2). -func PledgePromises(promises string) error { - maj, min, err := majmin() - if err != nil { - return err - } - - err = pledgeAvailable(maj, min, "") - if err != nil { - return err - } - - // This variable holds the execpromises and is always nil. - var expr unsafe.Pointer - - pptr, err := syscall.BytePtrFromString(promises) - if err != nil { - return err - } - - _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) - if e != 0 { - return e - } - - return nil -} - -// PledgeExecpromises implements the pledge syscall. -// -// This changes the execpromises and leaves the promises untouched. -// -// For more information see pledge(2). -func PledgeExecpromises(execpromises string) error { - maj, min, err := majmin() - if err != nil { - return err - } - - err = pledgeAvailable(maj, min, execpromises) - if err != nil { - return err - } - - // This variable holds the promises and is always nil. - var pptr unsafe.Pointer - - exptr, err := syscall.BytePtrFromString(execpromises) - if err != nil { - return err - } - - _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(pptr), uintptr(unsafe.Pointer(exptr)), 0) - if e != 0 { - return e - } - - return nil -} - -// majmin returns major and minor version number for an OpenBSD system. -func majmin() (major int, minor int, err error) { - var v Utsname - err = Uname(&v) - if err != nil { - return - } - - major, err = strconv.Atoi(string(v.Release[0])) - if err != nil { - err = errors.New("cannot parse major version number returned by uname") - return - } - - minor, err = strconv.Atoi(string(v.Release[2])) - if err != nil { - err = errors.New("cannot parse minor version number returned by uname") - return - } - - return -} - -// pledgeAvailable checks for availability of the pledge(2) syscall -// based on the running OpenBSD version. -func pledgeAvailable(maj, min int, execpromises string) error { - // If OpenBSD <= 5.9, pledge is not available. - if (maj == 5 && min != 9) || maj < 5 { - return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min) - } - - // If OpenBSD <= 6.2 and execpromises is not empty, - // return an error - execpromises is not available before 6.3 - if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" { - return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min) - } - - return nil -} diff --git a/vendor/golang.org/x/sys/unix/openbsd_unveil.go b/vendor/golang.org/x/sys/unix/openbsd_unveil.go deleted file mode 100644 index aebc2dc5768f..000000000000 --- a/vendor/golang.org/x/sys/unix/openbsd_unveil.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build openbsd - -package unix - -import ( - "syscall" - "unsafe" -) - -// Unveil implements the unveil syscall. -// For more information see unveil(2). -// Note that the special case of blocking further -// unveil calls is handled by UnveilBlock. -func Unveil(path string, flags string) error { - pathPtr, err := syscall.BytePtrFromString(path) - if err != nil { - return err - } - flagsPtr, err := syscall.BytePtrFromString(flags) - if err != nil { - return err - } - _, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(unsafe.Pointer(pathPtr)), uintptr(unsafe.Pointer(flagsPtr)), 0) - if e != 0 { - return e - } - return nil -} - -// UnveilBlock blocks future unveil calls. -// For more information see unveil(2). -func UnveilBlock() error { - // Both pointers must be nil. - var pathUnsafe, flagsUnsafe unsafe.Pointer - _, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(pathUnsafe), uintptr(flagsUnsafe), 0) - if e != 0 { - return e - } - return nil -} diff --git a/vendor/golang.org/x/sys/unix/pledge_openbsd.go b/vendor/golang.org/x/sys/unix/pledge_openbsd.go new file mode 100644 index 000000000000..eb48294b2742 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/pledge_openbsd.go @@ -0,0 +1,163 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +import ( + "errors" + "fmt" + "strconv" + "syscall" + "unsafe" +) + +// Pledge implements the pledge syscall. +// +// The pledge syscall does not accept execpromises on OpenBSD releases +// before 6.3. +// +// execpromises must be empty when Pledge is called on OpenBSD +// releases predating 6.3, otherwise an error will be returned. +// +// For more information see pledge(2). +func Pledge(promises, execpromises string) error { + maj, min, err := majmin() + if err != nil { + return err + } + + err = pledgeAvailable(maj, min, execpromises) + if err != nil { + return err + } + + pptr, err := syscall.BytePtrFromString(promises) + if err != nil { + return err + } + + // This variable will hold either a nil unsafe.Pointer or + // an unsafe.Pointer to a string (execpromises). + var expr unsafe.Pointer + + // If we're running on OpenBSD > 6.2, pass execpromises to the syscall. + if maj > 6 || (maj == 6 && min > 2) { + exptr, err := syscall.BytePtrFromString(execpromises) + if err != nil { + return err + } + expr = unsafe.Pointer(exptr) + } + + _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) + if e != 0 { + return e + } + + return nil +} + +// PledgePromises implements the pledge syscall. +// +// This changes the promises and leaves the execpromises untouched. +// +// For more information see pledge(2). +func PledgePromises(promises string) error { + maj, min, err := majmin() + if err != nil { + return err + } + + err = pledgeAvailable(maj, min, "") + if err != nil { + return err + } + + // This variable holds the execpromises and is always nil. + var expr unsafe.Pointer + + pptr, err := syscall.BytePtrFromString(promises) + if err != nil { + return err + } + + _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0) + if e != 0 { + return e + } + + return nil +} + +// PledgeExecpromises implements the pledge syscall. +// +// This changes the execpromises and leaves the promises untouched. +// +// For more information see pledge(2). +func PledgeExecpromises(execpromises string) error { + maj, min, err := majmin() + if err != nil { + return err + } + + err = pledgeAvailable(maj, min, execpromises) + if err != nil { + return err + } + + // This variable holds the promises and is always nil. + var pptr unsafe.Pointer + + exptr, err := syscall.BytePtrFromString(execpromises) + if err != nil { + return err + } + + _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(pptr), uintptr(unsafe.Pointer(exptr)), 0) + if e != 0 { + return e + } + + return nil +} + +// majmin returns major and minor version number for an OpenBSD system. +func majmin() (major int, minor int, err error) { + var v Utsname + err = Uname(&v) + if err != nil { + return + } + + major, err = strconv.Atoi(string(v.Release[0])) + if err != nil { + err = errors.New("cannot parse major version number returned by uname") + return + } + + minor, err = strconv.Atoi(string(v.Release[2])) + if err != nil { + err = errors.New("cannot parse minor version number returned by uname") + return + } + + return +} + +// pledgeAvailable checks for availability of the pledge(2) syscall +// based on the running OpenBSD version. +func pledgeAvailable(maj, min int, execpromises string) error { + // If OpenBSD <= 5.9, pledge is not available. + if (maj == 5 && min != 9) || maj < 5 { + return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min) + } + + // If OpenBSD <= 6.2 and execpromises is not empty, + // return an error - execpromises is not available before 6.3 + if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" { + return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min) + } + + return nil +} diff --git a/vendor/golang.org/x/sys/unix/sockcmsg_unix.go b/vendor/golang.org/x/sys/unix/sockcmsg_unix.go index 5f9ae233a7a6..062bcabab1b0 100644 --- a/vendor/golang.org/x/sys/unix/sockcmsg_unix.go +++ b/vendor/golang.org/x/sys/unix/sockcmsg_unix.go @@ -18,15 +18,18 @@ func cmsgAlignOf(salen int) int { salign := SizeofPtr switch runtime.GOOS { - case "darwin", "dragonfly", "solaris": - // NOTE: It seems like 64-bit Darwin, DragonFly BSD and - // Solaris kernels still require 32-bit aligned access to - // network subsystem. + case "aix": + // There is no alignment on AIX. + salign = 1 + case "darwin", "dragonfly", "solaris", "illumos": + // NOTE: It seems like 64-bit Darwin, DragonFly BSD, + // illumos, and Solaris kernels still require 32-bit + // aligned access to network subsystem. if SizeofPtr == 8 { salign = 4 } - case "openbsd": - // OpenBSD armv7 requires 64-bit alignment. + case "netbsd", "openbsd": + // NetBSD and OpenBSD armv7 require 64-bit alignment. if runtime.GOARCH == "arm" { salign = 8 } diff --git a/vendor/golang.org/x/sys/unix/syscall.go b/vendor/golang.org/x/sys/unix/syscall.go index 0d4b1d7a20e6..fd4ee8ebeb70 100644 --- a/vendor/golang.org/x/sys/unix/syscall.go +++ b/vendor/golang.org/x/sys/unix/syscall.go @@ -50,5 +50,4 @@ func BytePtrFromString(s string) (*byte, error) { } // Single-word zero for use when we need a valid pointer to 0 bytes. -// See mkunix.pl. var _zero uintptr diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index 1351a228b841..c1fb7bd16e9f 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -227,7 +227,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { // Some versions of AIX have a bug in getsockname (see IV78655). // We can't rely on sa.Len being set correctly. - n := SizeofSockaddrUnix - 3 // substract leading Family, Len, terminating NUL. + n := SizeofSockaddrUnix - 3 // subtract leading Family, Len, terminating NUL. for i := 0; i < n; i++ { if pp.Path[i] == 0 { n = i @@ -444,8 +444,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { //sysnb Times(tms *Tms) (ticks uintptr, err error) //sysnb Umask(mask int) (oldmask int) //sysnb Uname(buf *Utsname) (err error) -//TODO umount -// //sys Unmount(target string, flags int) (err error) = umount //sys Unlink(path string) (err error) //sys Unlinkat(dirfd int, path string, flags int) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error) @@ -470,8 +468,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { //sys Pause() (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64 -//TODO Select -// //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) +//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) //sysnb Setregid(rgid int, egid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error) @@ -493,8 +490,10 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) -//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) -//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) + +// In order to use msghdr structure with Control, Controllen, nrecvmsg and nsendmsg must be used. +//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = nrecvmsg +//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg //sys munmap(addr uintptr, length uintptr) (err error) @@ -545,3 +544,14 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { //sys gettimeofday(tv *Timeval, tzp *Timezone) (err error) //sysnb Time(t *Time_t) (tt Time_t, err error) //sys Utime(path string, buf *Utimbuf) (err error) + +//sys Getsystemcfg(label int) (n uint64) + +//sys umount(target string) (err error) +func Unmount(target string, flags int) (err error) { + if flags != 0 { + // AIX doesn't have any flags for umount. + return ENOSYS + } + return umount(target) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 04042e44b4a3..21200918927f 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -144,6 +144,23 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) ( //sys getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) +func SysctlClockinfo(name string) (*Clockinfo, error) { + mib, err := sysctlmib(name) + if err != nil { + return nil, err + } + + n := uintptr(SizeofClockinfo) + var ci Clockinfo + if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil { + return nil, err + } + if n != SizeofClockinfo { + return nil, EIO + } + return &ci, nil +} + //sysnb pipe() (r int, w int, err error) func Pipe(p []int) (err error) { @@ -416,6 +433,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Chmod(path string, mode uint32) (err error) //sys Chown(path string, uid int, gid int) (err error) //sys Chroot(path string) (err error) +//sys ClockGettime(clockid int32, time *Timespec) (err error) //sys Close(fd int) (err error) //sys Dup(fd int) (nfd int, err error) //sys Dup2(from int, to int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 891c94d7e26b..962eee304642 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -304,6 +304,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys read(fd int, p []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error) //sys Rename(from string, to string) (err error) +//sys Renameat(fromfd int, from string, tofd int, to string) (err error) //sys Revoke(path string) (err error) //sys Rmdir(path string) (err error) //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go new file mode 100644 index 000000000000..a318054878a9 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go @@ -0,0 +1,52 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build arm64,freebsd + +package unix + +import ( + "syscall" + "unsafe" +) + +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} +} + +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} +} + +func SetKevent(k *Kevent_t, fd, mode, flags int) { + k.Ident = uint64(fd) + k.Filter = int16(mode) + k.Flags = uint16(flags) +} + +func (iov *Iovec) SetLen(length int) { + iov.Len = uint64(length) +} + +func (msghdr *Msghdr) SetControllen(length int) { + msghdr.Controllen = uint32(length) +} + +func (cmsg *Cmsghdr) SetLen(length int) { + cmsg.Len = uint32(length) +} + +func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { + var writtenOut uint64 = 0 + _, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0) + + written = int(writtenOut) + + if e1 != 0 { + err = e1 + } + return +} + +func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 77604023335b..c302f01b2e94 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -14,6 +14,7 @@ package unix import ( "encoding/binary" "net" + "runtime" "syscall" "unsafe" ) @@ -38,6 +39,20 @@ func Creat(path string, mode uint32) (fd int, err error) { return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) } +//sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) +//sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) + +func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error) { + if pathname == "" { + return fanotifyMark(fd, flags, mask, dirFd, nil) + } + p, err := BytePtrFromString(pathname) + if err != nil { + return err + } + return fanotifyMark(fd, flags, mask, dirFd, p) +} + //sys fchmodat(dirfd int, path string, mode uint32) (err error) func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { @@ -80,6 +95,12 @@ func ioctlSetTermios(fd int, req uint, value *Termios) error { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } +func IoctlSetRTCTime(fd int, value *RTCTime) error { + err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) + runtime.KeepAlive(value) + return err +} + // IoctlGetInt performs an ioctl operation which gets an integer value // from fd, using the specified request number. func IoctlGetInt(fd int, req uint) (int, error) { @@ -100,6 +121,12 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { return &value, err } +func IoctlGetRTCTime(fd int) (*RTCTime, error) { + var value RTCTime + err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) + return &value, err +} + //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) func Link(oldpath string, newpath string) (err error) { @@ -977,10 +1004,50 @@ func GetsockoptString(fd, level, opt int) (string, error) { return string(buf[:vallen-1]), nil } +func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) { + var value TpacketStats + vallen := _Socklen(SizeofTpacketStats) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) + return &value, err +} + +func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) { + var value TpacketStatsV3 + vallen := _Socklen(SizeofTpacketStatsV3) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) + return &value, err +} + func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) } +func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error { + return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) +} + +// SetsockoptSockFprog attaches a classic BPF or an extended BPF program to a +// socket to filter incoming packets. See 'man 7 socket' for usage information. +func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error { + return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog)) +} + +func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error { + var p unsafe.Pointer + if len(filter) > 0 { + p = unsafe.Pointer(&filter[0]) + } + return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter)) +} + +func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error { + return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) +} + +func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error { + return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) +} + // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) // KeyctlInt calls keyctl commands in which each argument is an int. @@ -1381,6 +1448,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Chroot(path string) (err error) //sys ClockGetres(clockid int32, res *Timespec) (err error) //sys ClockGettime(clockid int32, time *Timespec) (err error) +//sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) //sys Close(fd int) (err error) //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys DeleteModule(name string, flags int) (err error) @@ -1441,7 +1509,6 @@ func Getpgrp() (pid int) { //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 //sys read(fd int, p []byte) (n int, err error) //sys Removexattr(path string, attr string) (err error) -//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) //sys Setdomainname(p []byte) (err error) @@ -1466,6 +1533,7 @@ func Setgid(uid int) (err error) { //sys Setpriority(which int, who int, prio int) (err error) //sys Setxattr(path string, attr string, data []byte, flags int) (err error) +//sys Signalfd(fd int, mask *Sigset_t, flags int) = SYS_SIGNALFD4 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) //sys Sync() //sys Syncfs(fd int) (err error) @@ -1594,6 +1662,82 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { return EACCES } +//sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT +//sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT + +// fileHandle is the argument to nameToHandleAt and openByHandleAt. We +// originally tried to generate it via unix/linux/types.go with "type +// fileHandle C.struct_file_handle" but that generated empty structs +// for mips64 and mips64le. Instead, hard code it for now (it's the +// same everywhere else) until the mips64 generator issue is fixed. +type fileHandle struct { + Bytes uint32 + Type int32 +} + +// FileHandle represents the C struct file_handle used by +// name_to_handle_at (see NameToHandleAt) and open_by_handle_at (see +// OpenByHandleAt). +type FileHandle struct { + *fileHandle +} + +// NewFileHandle constructs a FileHandle. +func NewFileHandle(handleType int32, handle []byte) FileHandle { + const hdrSize = unsafe.Sizeof(fileHandle{}) + buf := make([]byte, hdrSize+uintptr(len(handle))) + copy(buf[hdrSize:], handle) + fh := (*fileHandle)(unsafe.Pointer(&buf[0])) + fh.Type = handleType + fh.Bytes = uint32(len(handle)) + return FileHandle{fh} +} + +func (fh *FileHandle) Size() int { return int(fh.fileHandle.Bytes) } +func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type } +func (fh *FileHandle) Bytes() []byte { + n := fh.Size() + if n == 0 { + return nil + } + return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n] +} + +// NameToHandleAt wraps the name_to_handle_at system call; it obtains +// a handle for a path name. +func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) { + var mid _C_int + // Try first with a small buffer, assuming the handle will + // only be 32 bytes. + size := uint32(32 + unsafe.Sizeof(fileHandle{})) + didResize := false + for { + buf := make([]byte, size) + fh := (*fileHandle)(unsafe.Pointer(&buf[0])) + fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{})) + err = nameToHandleAt(dirfd, path, fh, &mid, flags) + if err == EOVERFLOW { + if didResize { + // We shouldn't need to resize more than once + return + } + didResize = true + size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{})) + continue + } + if err != nil { + return + } + return FileHandle{fh}, int(mid), nil + } +} + +// OpenByHandleAt wraps the open_by_handle_at system call; it opens a +// file via a handle as previously returned by NameToHandleAt. +func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) { + return openByHandleAt(mountFD, handle.fileHandle, flags) +} + /* * Unimplemented */ @@ -1682,7 +1826,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { // Shmdt // Shmget // Sigaltstack -// Signalfd // Swapoff // Swapon // Sysfs diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/vendor/golang.org/x/sys/unix/syscall_linux_386.go index 74bc098ce192..e2f8cf6e5ade 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_386.go @@ -68,6 +68,7 @@ func Pipe2(p []int, flags int) (err error) { //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys Setfsgid(gid int) (err error) = SYS_SETFSGID32 //sys Setfsuid(uid int) (err error) = SYS_SETFSUID32 diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go index 615f2918adac..87a30744d6c9 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go @@ -43,6 +43,7 @@ func Lstat(path string, stat *Stat_t) (err error) { //sys Pause() (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go index ad2bd2582f3b..3a3c37b4c8b6 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go @@ -19,12 +19,18 @@ func setTimeval(sec, usec int64) Timeval { return Timeval{Sec: int32(sec), Usec: int32(usec)} } +//sysnb pipe(p *[2]_C_int) (err error) + func Pipe(p []int) (err error) { if len(p) != 2 { return EINVAL } var pp [2]_C_int + // Try pipe2 first for Android O, then try pipe for kernel 2.6.23. err = pipe2(&pp, 0) + if err == ENOSYS { + err = pipe(&pp) + } p[0] = int(pp[0]) p[1] = int(pp[1]) return @@ -89,6 +95,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { //sys Listen(s int, n int) (err error) //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Pause() (err error) +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Setfsgid(gid int) (err error) = SYS_SETFSGID32 diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index fa5a9a6f6498..cb20b15d5d2b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -30,6 +30,7 @@ func EpollCreate(size int) (fd int, err error) { //sys Listen(s int, n int) (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { @@ -207,3 +208,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { } return ppoll(&fds[0], len(fds), ts, nil) } + +//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) + +func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { + cmdlineLen := len(cmdline) + if cmdlineLen > 0 { + // Account for the additional NULL byte added by + // BytePtrFromString in kexecFileLoad. The kexec_file_load + // syscall expects a NULL-terminated string. + cmdlineLen++ + } + return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go index ad991031c7e0..b3b21ec1e2b0 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go @@ -12,7 +12,6 @@ package unix //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) -//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -25,6 +24,7 @@ package unix //sys Pause() (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { @@ -148,6 +148,7 @@ type stat_t struct { } //sys fstat(fd int, st *stat_t) (err error) +//sys fstatat(dirfd int, path string, st *stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys lstat(path string, st *stat_t) (err error) //sys stat(path string, st *stat_t) (err error) @@ -158,6 +159,13 @@ func Fstat(fd int, s *Stat_t) (err error) { return } +func Fstatat(dirfd int, path string, s *Stat_t, flags int) (err error) { + st := &stat_t{} + err = fstatat(dirfd, path, st, flags) + fillStat_t(s, st) + return +} + func Lstat(path string, s *Stat_t) (err error) { st := &stat_t{} err = lstat(path, st) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go index 99e0e999a1af..5144d4e1330b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go @@ -28,6 +28,7 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, //sys Listen(s int, n int) (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys Setfsgid(gid int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go index 41451854bc01..0a100b66a3ab 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go @@ -30,6 +30,7 @@ package unix //sys Pause() (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go index 44aa1227a6c2..6230f6405200 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go @@ -207,3 +207,20 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { } return ppoll(&fds[0], len(fds), ts, nil) } + +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0) +} + +//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) + +func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { + cmdlineLen := len(cmdline) + if cmdlineLen > 0 { + // Account for the additional NULL byte added by + // BytePtrFromString in kexecFileLoad. The kexec_file_load + // syscall expects a NULL-terminated string. + cmdlineLen++ + } + return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go index f52f148f9ff3..f81dbdc9c831 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go @@ -30,6 +30,7 @@ import ( //sys Pause() (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go index 72e64187debf..b69565616fc0 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go @@ -26,6 +26,7 @@ package unix //sys Pause() (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 +//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go new file mode 100644 index 000000000000..f3434465a179 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go @@ -0,0 +1,33 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build arm64,netbsd + +package unix + +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} +} + +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} +} + +func SetKevent(k *Kevent_t, fd, mode, flags int) { + k.Ident = uint64(fd) + k.Filter = uint32(mode) + k.Flags = uint32(flags) +} + +func (iov *Iovec) SetLen(length int) { + iov.Len = uint64(length) +} + +func (msghdr *Msghdr) SetControllen(length int) { + msghdr.Controllen = uint32(length) +} + +func (cmsg *Cmsghdr) SetLen(length int) { + cmsg.Len = uint32(length) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go index 687999549c80..c8648ec02678 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -43,6 +43,23 @@ func nametomib(name string) (mib []_C_int, err error) { return nil, EINVAL } +func SysctlClockinfo(name string) (*Clockinfo, error) { + mib, err := sysctlmib(name) + if err != nil { + return nil, err + } + + n := uintptr(SizeofClockinfo) + var ci Clockinfo + if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil { + return nil, err + } + if n != SizeofClockinfo { + return nil, EIO + } + return &ci, nil +} + func SysctlUvmexp(name string) (*Uvmexp, error) { mib, err := sysctlmib(name) if err != nil { diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go new file mode 100644 index 000000000000..0fb39cf5eb12 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go @@ -0,0 +1,37 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build arm64,openbsd + +package unix + +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} +} + +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} +} + +func SetKevent(k *Kevent_t, fd, mode, flags int) { + k.Ident = uint64(fd) + k.Filter = int16(mode) + k.Flags = uint16(flags) +} + +func (iov *Iovec) SetLen(length int) { + iov.Len = uint64(length) +} + +func (msghdr *Msghdr) SetControllen(length int) { + msghdr.Controllen = uint32(length) +} + +func (cmsg *Cmsghdr) SetLen(length int) { + cmsg.Len = uint32(length) +} + +// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions +// of openbsd/amd64 the syscall is called sysctl instead of __sysctl. +const SYS___SYSCTL = SYS_SYSCTL diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 33583a22b67c..3de37566c6fd 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -28,6 +28,11 @@ var ( errENOENT error = syscall.ENOENT ) +var ( + signalNameMapOnce sync.Once + signalNameMap map[string]syscall.Signal +) + // errnoErr returns common boxed Errno values, to prevent // allocations at runtime. func errnoErr(e syscall.Errno) error { @@ -66,6 +71,19 @@ func SignalName(s syscall.Signal) string { return "" } +// SignalNum returns the syscall.Signal for signal named s, +// or 0 if a signal with such name is not found. +// The signal name should start with "SIG". +func SignalNum(s string) syscall.Signal { + signalNameMapOnce.Do(func() { + signalNameMap = make(map[string]syscall.Signal) + for _, signal := range signalList { + signalNameMap[signal.name] = signal.num + } + }) + return signalNameMap[s] +} + // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. func clen(n []byte) int { i := bytes.IndexByte(n, 0) @@ -276,6 +294,13 @@ func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) { return &tv, err } +func GetsockoptUint64(fd, level, opt int) (value uint64, err error) { + var n uint64 + vallen := _Socklen(8) + err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) + return n, err +} + func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { var rsa RawSockaddrAny var len _Socklen = SizeofSockaddrAny @@ -326,13 +351,21 @@ func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { } func SetsockoptString(fd, level, opt int, s string) (err error) { - return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s))) + var p unsafe.Pointer + if len(s) > 0 { + p = unsafe.Pointer(&[]byte(s)[0]) + } + return setsockopt(fd, level, opt, p, uintptr(len(s))) } func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) } +func SetsockoptUint64(fd, level, opt int, value uint64) (err error) { + return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8) +} + func Socket(domain, typ, proto int) (fd int, err error) { if domain == AF_INET6 && SocketDisableIPv6 { return -1, EAFNOSUPPORT @@ -377,3 +410,22 @@ func SetNonblock(fd int, nonblocking bool) (err error) { func Exec(argv0 string, argv []string, envv []string) error { return syscall.Exec(argv0, argv, envv) } + +// Lutimes sets the access and modification times tv on path. If path refers to +// a symlink, it is not dereferenced and the timestamps are set on the symlink. +// If tv is nil, the access and modification times are set to the current time. +// Otherwise tv must contain exactly 2 elements, with access time as the first +// element and modification time as the second element. +func Lutimes(path string, tv []Timeval) error { + if tv == nil { + return UtimesNanoAt(AT_FDCWD, path, nil, AT_SYMLINK_NOFOLLOW) + } + if len(tv) != 2 { + return EINVAL + } + ts := []Timespec{ + NsecToTimespec(TimevalToNsec(tv[0])), + NsecToTimespec(TimevalToNsec(tv[1])), + } + return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW) +} diff --git a/vendor/golang.org/x/sys/unix/types_darwin.go b/vendor/golang.org/x/sys/unix/types_darwin.go index 9fd2aaa6a224..155c2e692b45 100644 --- a/vendor/golang.org/x/sys/unix/types_darwin.go +++ b/vendor/golang.org/x/sys/unix/types_darwin.go @@ -275,3 +275,9 @@ const ( // uname type Utsname C.struct_utsname + +// Clockinfo + +const SizeofClockinfo = C.sizeof_struct_clockinfo + +type Clockinfo C.struct_clockinfo diff --git a/vendor/golang.org/x/sys/unix/types_openbsd.go b/vendor/golang.org/x/sys/unix/types_openbsd.go index 4e5e57f9a61a..8aafbe4469bf 100644 --- a/vendor/golang.org/x/sys/unix/types_openbsd.go +++ b/vendor/golang.org/x/sys/unix/types_openbsd.go @@ -274,3 +274,9 @@ type Utsname C.struct_utsname const SizeofUvmexp = C.sizeof_struct_uvmexp type Uvmexp C.struct_uvmexp + +// Clockinfo + +const SizeofClockinfo = C.sizeof_struct_clockinfo + +type Clockinfo C.struct_clockinfo diff --git a/vendor/golang.org/x/sys/unix/unveil_openbsd.go b/vendor/golang.org/x/sys/unix/unveil_openbsd.go new file mode 100644 index 000000000000..168d5ae77914 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/unveil_openbsd.go @@ -0,0 +1,42 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +import ( + "syscall" + "unsafe" +) + +// Unveil implements the unveil syscall. +// For more information see unveil(2). +// Note that the special case of blocking further +// unveil calls is handled by UnveilBlock. +func Unveil(path string, flags string) error { + pathPtr, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + flagsPtr, err := syscall.BytePtrFromString(flags) + if err != nil { + return err + } + _, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(unsafe.Pointer(pathPtr)), uintptr(unsafe.Pointer(flagsPtr)), 0) + if e != 0 { + return e + } + return nil +} + +// UnveilBlock blocks future unveil calls. +// For more information see unveil(2). +func UnveilBlock() error { + // Both pointers must be nil. + var pathUnsafe, flagsUnsafe unsafe.Pointer + _, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(pathUnsafe), uintptr(flagsUnsafe), 0) + if e != 0 { + return e + } + return nil +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go index 4b7b965027da..1def8a581265 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go @@ -926,6 +926,8 @@ const ( TCSETSF = 0x5404 TCSETSW = 0x5403 TCXONC = 0x540b + TIMER_ABSTIME = 0x3e7 + TIMER_MAX = 0x20 TIOC = 0x5400 TIOCCBRK = 0x2000747a TIOCCDTR = 0x20007478 diff --git a/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go index ed04fd1b77db..03187dea98f3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go @@ -3,7 +3,7 @@ // +build ppc64,aix -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -maix64 _const.go package unix @@ -926,6 +926,8 @@ const ( TCSETSF = 0x5404 TCSETSW = 0x5403 TCXONC = 0x540b + TIMER_ABSTIME = 0x3e7 + TIMER_MAX = 0x20 TIOC = 0x5400 TIOCCBRK = 0x2000747a TIOCCDTR = 0x20007478 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go new file mode 100644 index 000000000000..d4a192fefeee --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go @@ -0,0 +1,1794 @@ +// mkerrors.sh -m64 +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build arm64,freebsd + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs -- -m64 _const.go + +package unix + +import "syscall" + +const ( + AF_APPLETALK = 0x10 + AF_ARP = 0x23 + AF_ATM = 0x1e + AF_BLUETOOTH = 0x24 + AF_CCITT = 0xa + AF_CHAOS = 0x5 + AF_CNT = 0x15 + AF_COIP = 0x14 + AF_DATAKIT = 0x9 + AF_DECnet = 0xc + AF_DLI = 0xd + AF_E164 = 0x1a + AF_ECMA = 0x8 + AF_HYLINK = 0xf + AF_IEEE80211 = 0x25 + AF_IMPLINK = 0x3 + AF_INET = 0x2 + AF_INET6 = 0x1c + AF_INET6_SDP = 0x2a + AF_INET_SDP = 0x28 + AF_IPX = 0x17 + AF_ISDN = 0x1a + AF_ISO = 0x7 + AF_LAT = 0xe + AF_LINK = 0x12 + AF_LOCAL = 0x1 + AF_MAX = 0x2a + AF_NATM = 0x1d + AF_NETBIOS = 0x6 + AF_NETGRAPH = 0x20 + AF_OSI = 0x7 + AF_PUP = 0x4 + AF_ROUTE = 0x11 + AF_SCLUSTER = 0x22 + AF_SIP = 0x18 + AF_SLOW = 0x21 + AF_SNA = 0xb + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + AF_VENDOR00 = 0x27 + AF_VENDOR01 = 0x29 + AF_VENDOR02 = 0x2b + AF_VENDOR03 = 0x2d + AF_VENDOR04 = 0x2f + AF_VENDOR05 = 0x31 + AF_VENDOR06 = 0x33 + AF_VENDOR07 = 0x35 + AF_VENDOR08 = 0x37 + AF_VENDOR09 = 0x39 + AF_VENDOR10 = 0x3b + AF_VENDOR11 = 0x3d + AF_VENDOR12 = 0x3f + AF_VENDOR13 = 0x41 + AF_VENDOR14 = 0x43 + AF_VENDOR15 = 0x45 + AF_VENDOR16 = 0x47 + AF_VENDOR17 = 0x49 + AF_VENDOR18 = 0x4b + AF_VENDOR19 = 0x4d + AF_VENDOR20 = 0x4f + AF_VENDOR21 = 0x51 + AF_VENDOR22 = 0x53 + AF_VENDOR23 = 0x55 + AF_VENDOR24 = 0x57 + AF_VENDOR25 = 0x59 + AF_VENDOR26 = 0x5b + AF_VENDOR27 = 0x5d + AF_VENDOR28 = 0x5f + AF_VENDOR29 = 0x61 + AF_VENDOR30 = 0x63 + AF_VENDOR31 = 0x65 + AF_VENDOR32 = 0x67 + AF_VENDOR33 = 0x69 + AF_VENDOR34 = 0x6b + AF_VENDOR35 = 0x6d + AF_VENDOR36 = 0x6f + AF_VENDOR37 = 0x71 + AF_VENDOR38 = 0x73 + AF_VENDOR39 = 0x75 + AF_VENDOR40 = 0x77 + AF_VENDOR41 = 0x79 + AF_VENDOR42 = 0x7b + AF_VENDOR43 = 0x7d + AF_VENDOR44 = 0x7f + AF_VENDOR45 = 0x81 + AF_VENDOR46 = 0x83 + AF_VENDOR47 = 0x85 + ALTWERASE = 0x200 + B0 = 0x0 + B110 = 0x6e + B115200 = 0x1c200 + B1200 = 0x4b0 + B134 = 0x86 + B14400 = 0x3840 + B150 = 0x96 + B1800 = 0x708 + B19200 = 0x4b00 + B200 = 0xc8 + B230400 = 0x38400 + B2400 = 0x960 + B28800 = 0x7080 + B300 = 0x12c + B38400 = 0x9600 + B460800 = 0x70800 + B4800 = 0x12c0 + B50 = 0x32 + B57600 = 0xe100 + B600 = 0x258 + B7200 = 0x1c20 + B75 = 0x4b + B76800 = 0x12c00 + B921600 = 0xe1000 + B9600 = 0x2580 + BIOCFEEDBACK = 0x8004427c + BIOCFLUSH = 0x20004268 + BIOCGBLEN = 0x40044266 + BIOCGDIRECTION = 0x40044276 + BIOCGDLT = 0x4004426a + BIOCGDLTLIST = 0xc0104279 + BIOCGETBUFMODE = 0x4004427d + BIOCGETIF = 0x4020426b + BIOCGETZMAX = 0x4008427f + BIOCGHDRCMPLT = 0x40044274 + BIOCGRSIG = 0x40044272 + BIOCGRTIMEOUT = 0x4010426e + BIOCGSEESENT = 0x40044276 + BIOCGSTATS = 0x4008426f + BIOCGTSTAMP = 0x40044283 + BIOCIMMEDIATE = 0x80044270 + BIOCLOCK = 0x2000427a + BIOCPROMISC = 0x20004269 + BIOCROTZBUF = 0x40184280 + BIOCSBLEN = 0xc0044266 + BIOCSDIRECTION = 0x80044277 + BIOCSDLT = 0x80044278 + BIOCSETBUFMODE = 0x8004427e + BIOCSETF = 0x80104267 + BIOCSETFNR = 0x80104282 + BIOCSETIF = 0x8020426c + BIOCSETWF = 0x8010427b + BIOCSETZBUF = 0x80184281 + BIOCSHDRCMPLT = 0x80044275 + BIOCSRSIG = 0x80044273 + BIOCSRTIMEOUT = 0x8010426d + BIOCSSEESENT = 0x80044277 + BIOCSTSTAMP = 0x80044284 + BIOCVERSION = 0x40044271 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALIGNMENT = 0x8 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_BUFMODE_BUFFER = 0x1 + BPF_BUFMODE_ZBUF = 0x2 + BPF_DIV = 0x30 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXBUFSIZE = 0x80000 + BPF_MAXINSNS = 0x200 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINBUFSIZE = 0x20 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MOD = 0x90 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_OR = 0x40 + BPF_RELEASE = 0x30bb6 + BPF_RET = 0x6 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_T_BINTIME = 0x2 + BPF_T_BINTIME_FAST = 0x102 + BPF_T_BINTIME_MONOTONIC = 0x202 + BPF_T_BINTIME_MONOTONIC_FAST = 0x302 + BPF_T_FAST = 0x100 + BPF_T_FLAG_MASK = 0x300 + BPF_T_FORMAT_MASK = 0x3 + BPF_T_MICROTIME = 0x0 + BPF_T_MICROTIME_FAST = 0x100 + BPF_T_MICROTIME_MONOTONIC = 0x200 + BPF_T_MICROTIME_MONOTONIC_FAST = 0x300 + BPF_T_MONOTONIC = 0x200 + BPF_T_MONOTONIC_FAST = 0x300 + BPF_T_NANOTIME = 0x1 + BPF_T_NANOTIME_FAST = 0x101 + BPF_T_NANOTIME_MONOTONIC = 0x201 + BPF_T_NANOTIME_MONOTONIC_FAST = 0x301 + BPF_T_NONE = 0x3 + BPF_T_NORMAL = 0x0 + BPF_W = 0x0 + BPF_X = 0x8 + BPF_XOR = 0xa0 + BRKINT = 0x2 + CAP_ACCEPT = 0x200000020000000 + CAP_ACL_CHECK = 0x400000000010000 + CAP_ACL_DELETE = 0x400000000020000 + CAP_ACL_GET = 0x400000000040000 + CAP_ACL_SET = 0x400000000080000 + CAP_ALL0 = 0x20007ffffffffff + CAP_ALL1 = 0x4000000001fffff + CAP_BIND = 0x200000040000000 + CAP_BINDAT = 0x200008000000400 + CAP_CHFLAGSAT = 0x200000000001400 + CAP_CONNECT = 0x200000080000000 + CAP_CONNECTAT = 0x200010000000400 + CAP_CREATE = 0x200000000000040 + CAP_EVENT = 0x400000000000020 + CAP_EXTATTR_DELETE = 0x400000000001000 + CAP_EXTATTR_GET = 0x400000000002000 + CAP_EXTATTR_LIST = 0x400000000004000 + CAP_EXTATTR_SET = 0x400000000008000 + CAP_FCHDIR = 0x200000000000800 + CAP_FCHFLAGS = 0x200000000001000 + CAP_FCHMOD = 0x200000000002000 + CAP_FCHMODAT = 0x200000000002400 + CAP_FCHOWN = 0x200000000004000 + CAP_FCHOWNAT = 0x200000000004400 + CAP_FCNTL = 0x200000000008000 + CAP_FCNTL_ALL = 0x78 + CAP_FCNTL_GETFL = 0x8 + CAP_FCNTL_GETOWN = 0x20 + CAP_FCNTL_SETFL = 0x10 + CAP_FCNTL_SETOWN = 0x40 + CAP_FEXECVE = 0x200000000000080 + CAP_FLOCK = 0x200000000010000 + CAP_FPATHCONF = 0x200000000020000 + CAP_FSCK = 0x200000000040000 + CAP_FSTAT = 0x200000000080000 + CAP_FSTATAT = 0x200000000080400 + CAP_FSTATFS = 0x200000000100000 + CAP_FSYNC = 0x200000000000100 + CAP_FTRUNCATE = 0x200000000000200 + CAP_FUTIMES = 0x200000000200000 + CAP_FUTIMESAT = 0x200000000200400 + CAP_GETPEERNAME = 0x200000100000000 + CAP_GETSOCKNAME = 0x200000200000000 + CAP_GETSOCKOPT = 0x200000400000000 + CAP_IOCTL = 0x400000000000080 + CAP_IOCTLS_ALL = 0x7fffffffffffffff + CAP_KQUEUE = 0x400000000100040 + CAP_KQUEUE_CHANGE = 0x400000000100000 + CAP_KQUEUE_EVENT = 0x400000000000040 + CAP_LINKAT_SOURCE = 0x200020000000400 + CAP_LINKAT_TARGET = 0x200000000400400 + CAP_LISTEN = 0x200000800000000 + CAP_LOOKUP = 0x200000000000400 + CAP_MAC_GET = 0x400000000000001 + CAP_MAC_SET = 0x400000000000002 + CAP_MKDIRAT = 0x200000000800400 + CAP_MKFIFOAT = 0x200000001000400 + CAP_MKNODAT = 0x200000002000400 + CAP_MMAP = 0x200000000000010 + CAP_MMAP_R = 0x20000000000001d + CAP_MMAP_RW = 0x20000000000001f + CAP_MMAP_RWX = 0x20000000000003f + CAP_MMAP_RX = 0x20000000000003d + CAP_MMAP_W = 0x20000000000001e + CAP_MMAP_WX = 0x20000000000003e + CAP_MMAP_X = 0x20000000000003c + CAP_PDGETPID = 0x400000000000200 + CAP_PDKILL = 0x400000000000800 + CAP_PDWAIT = 0x400000000000400 + CAP_PEELOFF = 0x200001000000000 + CAP_POLL_EVENT = 0x400000000000020 + CAP_PREAD = 0x20000000000000d + CAP_PWRITE = 0x20000000000000e + CAP_READ = 0x200000000000001 + CAP_RECV = 0x200000000000001 + CAP_RENAMEAT_SOURCE = 0x200000004000400 + CAP_RENAMEAT_TARGET = 0x200040000000400 + CAP_RIGHTS_VERSION = 0x0 + CAP_RIGHTS_VERSION_00 = 0x0 + CAP_SEEK = 0x20000000000000c + CAP_SEEK_TELL = 0x200000000000004 + CAP_SEM_GETVALUE = 0x400000000000004 + CAP_SEM_POST = 0x400000000000008 + CAP_SEM_WAIT = 0x400000000000010 + CAP_SEND = 0x200000000000002 + CAP_SETSOCKOPT = 0x200002000000000 + CAP_SHUTDOWN = 0x200004000000000 + CAP_SOCK_CLIENT = 0x200007780000003 + CAP_SOCK_SERVER = 0x200007f60000003 + CAP_SYMLINKAT = 0x200000008000400 + CAP_TTYHOOK = 0x400000000000100 + CAP_UNLINKAT = 0x200000010000400 + CAP_UNUSED0_44 = 0x200080000000000 + CAP_UNUSED0_57 = 0x300000000000000 + CAP_UNUSED1_22 = 0x400000000200000 + CAP_UNUSED1_57 = 0x500000000000000 + CAP_WRITE = 0x200000000000002 + CFLUSH = 0xf + CLOCAL = 0x8000 + CLOCK_MONOTONIC = 0x4 + CLOCK_MONOTONIC_FAST = 0xc + CLOCK_MONOTONIC_PRECISE = 0xb + CLOCK_PROCESS_CPUTIME_ID = 0xf + CLOCK_PROF = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_REALTIME_FAST = 0xa + CLOCK_REALTIME_PRECISE = 0x9 + CLOCK_SECOND = 0xd + CLOCK_THREAD_CPUTIME_ID = 0xe + CLOCK_UPTIME = 0x5 + CLOCK_UPTIME_FAST = 0x8 + CLOCK_UPTIME_PRECISE = 0x7 + CLOCK_VIRTUAL = 0x1 + CREAD = 0x800 + CRTSCTS = 0x30000 + CS5 = 0x0 + CS6 = 0x100 + CS7 = 0x200 + CS8 = 0x300 + CSIZE = 0x300 + CSTART = 0x11 + CSTATUS = 0x14 + CSTOP = 0x13 + CSTOPB = 0x400 + CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 + CTL_MAXNAME = 0x18 + CTL_NET = 0x4 + DLT_A429 = 0xb8 + DLT_A653_ICM = 0xb9 + DLT_AIRONET_HEADER = 0x78 + DLT_AOS = 0xde + DLT_APPLE_IP_OVER_IEEE1394 = 0x8a + DLT_ARCNET = 0x7 + DLT_ARCNET_LINUX = 0x81 + DLT_ATM_CLIP = 0x13 + DLT_ATM_RFC1483 = 0xb + DLT_AURORA = 0x7e + DLT_AX25 = 0x3 + DLT_AX25_KISS = 0xca + DLT_BACNET_MS_TP = 0xa5 + DLT_BLUETOOTH_BREDR_BB = 0xff + DLT_BLUETOOTH_HCI_H4 = 0xbb + DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9 + DLT_BLUETOOTH_LE_LL = 0xfb + DLT_BLUETOOTH_LE_LL_WITH_PHDR = 0x100 + DLT_BLUETOOTH_LINUX_MONITOR = 0xfe + DLT_CAN20B = 0xbe + DLT_CAN_SOCKETCAN = 0xe3 + DLT_CHAOS = 0x5 + DLT_CHDLC = 0x68 + DLT_CISCO_IOS = 0x76 + DLT_C_HDLC = 0x68 + DLT_C_HDLC_WITH_DIR = 0xcd + DLT_DBUS = 0xe7 + DLT_DECT = 0xdd + DLT_DOCSIS = 0x8f + DLT_DVB_CI = 0xeb + DLT_ECONET = 0x73 + DLT_EN10MB = 0x1 + DLT_EN3MB = 0x2 + DLT_ENC = 0x6d + DLT_EPON = 0x103 + DLT_ERF = 0xc5 + DLT_ERF_ETH = 0xaf + DLT_ERF_POS = 0xb0 + DLT_FC_2 = 0xe0 + DLT_FC_2_WITH_FRAME_DELIMS = 0xe1 + DLT_FDDI = 0xa + DLT_FLEXRAY = 0xd2 + DLT_FRELAY = 0x6b + DLT_FRELAY_WITH_DIR = 0xce + DLT_GCOM_SERIAL = 0xad + DLT_GCOM_T1E1 = 0xac + DLT_GPF_F = 0xab + DLT_GPF_T = 0xaa + DLT_GPRS_LLC = 0xa9 + DLT_GSMTAP_ABIS = 0xda + DLT_GSMTAP_UM = 0xd9 + DLT_HHDLC = 0x79 + DLT_IBM_SN = 0x92 + DLT_IBM_SP = 0x91 + DLT_IEEE802 = 0x6 + DLT_IEEE802_11 = 0x69 + DLT_IEEE802_11_RADIO = 0x7f + DLT_IEEE802_11_RADIO_AVS = 0xa3 + DLT_IEEE802_15_4 = 0xc3 + DLT_IEEE802_15_4_LINUX = 0xbf + DLT_IEEE802_15_4_NOFCS = 0xe6 + DLT_IEEE802_15_4_NONASK_PHY = 0xd7 + DLT_IEEE802_16_MAC_CPS = 0xbc + DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1 + DLT_INFINIBAND = 0xf7 + DLT_IPFILTER = 0x74 + DLT_IPMB = 0xc7 + DLT_IPMB_LINUX = 0xd1 + DLT_IPMI_HPM_2 = 0x104 + DLT_IPNET = 0xe2 + DLT_IPOIB = 0xf2 + DLT_IPV4 = 0xe4 + DLT_IPV6 = 0xe5 + DLT_IP_OVER_FC = 0x7a + DLT_JUNIPER_ATM1 = 0x89 + DLT_JUNIPER_ATM2 = 0x87 + DLT_JUNIPER_ATM_CEMIC = 0xee + DLT_JUNIPER_CHDLC = 0xb5 + DLT_JUNIPER_ES = 0x84 + DLT_JUNIPER_ETHER = 0xb2 + DLT_JUNIPER_FIBRECHANNEL = 0xea + DLT_JUNIPER_FRELAY = 0xb4 + DLT_JUNIPER_GGSN = 0x85 + DLT_JUNIPER_ISM = 0xc2 + DLT_JUNIPER_MFR = 0x86 + DLT_JUNIPER_MLFR = 0x83 + DLT_JUNIPER_MLPPP = 0x82 + DLT_JUNIPER_MONITOR = 0xa4 + DLT_JUNIPER_PIC_PEER = 0xae + DLT_JUNIPER_PPP = 0xb3 + DLT_JUNIPER_PPPOE = 0xa7 + DLT_JUNIPER_PPPOE_ATM = 0xa8 + DLT_JUNIPER_SERVICES = 0x88 + DLT_JUNIPER_SRX_E2E = 0xe9 + DLT_JUNIPER_ST = 0xc8 + DLT_JUNIPER_VP = 0xb7 + DLT_JUNIPER_VS = 0xe8 + DLT_LAPB_WITH_DIR = 0xcf + DLT_LAPD = 0xcb + DLT_LIN = 0xd4 + DLT_LINUX_EVDEV = 0xd8 + DLT_LINUX_IRDA = 0x90 + DLT_LINUX_LAPD = 0xb1 + DLT_LINUX_PPP_WITHDIRECTION = 0xa6 + DLT_LINUX_SLL = 0x71 + DLT_LOOP = 0x6c + DLT_LTALK = 0x72 + DLT_MATCHING_MAX = 0x104 + DLT_MATCHING_MIN = 0x68 + DLT_MFR = 0xb6 + DLT_MOST = 0xd3 + DLT_MPEG_2_TS = 0xf3 + DLT_MPLS = 0xdb + DLT_MTP2 = 0x8c + DLT_MTP2_WITH_PHDR = 0x8b + DLT_MTP3 = 0x8d + DLT_MUX27010 = 0xec + DLT_NETANALYZER = 0xf0 + DLT_NETANALYZER_TRANSPARENT = 0xf1 + DLT_NETLINK = 0xfd + DLT_NFC_LLCP = 0xf5 + DLT_NFLOG = 0xef + DLT_NG40 = 0xf4 + DLT_NULL = 0x0 + DLT_PCI_EXP = 0x7d + DLT_PFLOG = 0x75 + DLT_PFSYNC = 0x79 + DLT_PKTAP = 0x102 + DLT_PPI = 0xc0 + DLT_PPP = 0x9 + DLT_PPP_BSDOS = 0x10 + DLT_PPP_ETHER = 0x33 + DLT_PPP_PPPD = 0xa6 + DLT_PPP_SERIAL = 0x32 + DLT_PPP_WITH_DIR = 0xcc + DLT_PPP_WITH_DIRECTION = 0xa6 + DLT_PRISM_HEADER = 0x77 + DLT_PROFIBUS_DL = 0x101 + DLT_PRONET = 0x4 + DLT_RAIF1 = 0xc6 + DLT_RAW = 0xc + DLT_RIO = 0x7c + DLT_RTAC_SERIAL = 0xfa + DLT_SCCP = 0x8e + DLT_SCTP = 0xf8 + DLT_SITA = 0xc4 + DLT_SLIP = 0x8 + DLT_SLIP_BSDOS = 0xf + DLT_STANAG_5066_D_PDU = 0xed + DLT_SUNATM = 0x7b + DLT_SYMANTEC_FIREWALL = 0x63 + DLT_TZSP = 0x80 + DLT_USB = 0xba + DLT_USBPCAP = 0xf9 + DLT_USB_LINUX = 0xbd + DLT_USB_LINUX_MMAPPED = 0xdc + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c + DLT_WIHART = 0xdf + DLT_WIRESHARK_UPPER_PDU = 0xfc + DLT_X2E_SERIAL = 0xd5 + DLT_X2E_XORAYA = 0xd6 + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + DT_WHT = 0xe + ECHO = 0x8 + ECHOCTL = 0x40 + ECHOE = 0x2 + ECHOK = 0x4 + ECHOKE = 0x1 + ECHONL = 0x10 + ECHOPRT = 0x20 + EVFILT_AIO = -0x3 + EVFILT_FS = -0x9 + EVFILT_LIO = -0xa + EVFILT_PROC = -0x5 + EVFILT_PROCDESC = -0x8 + EVFILT_READ = -0x1 + EVFILT_SENDFILE = -0xc + EVFILT_SIGNAL = -0x6 + EVFILT_SYSCOUNT = 0xc + EVFILT_TIMER = -0x7 + EVFILT_USER = -0xb + EVFILT_VNODE = -0x4 + EVFILT_WRITE = -0x2 + EV_ADD = 0x1 + EV_CLEAR = 0x20 + EV_DELETE = 0x2 + EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 + EV_DROP = 0x1000 + EV_ENABLE = 0x4 + EV_EOF = 0x8000 + EV_ERROR = 0x4000 + EV_FLAG1 = 0x2000 + EV_FLAG2 = 0x4000 + EV_FORCEONESHOT = 0x100 + EV_ONESHOT = 0x10 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf000 + EXTA = 0x4b00 + EXTATTR_NAMESPACE_EMPTY = 0x0 + EXTATTR_NAMESPACE_SYSTEM = 0x2 + EXTATTR_NAMESPACE_USER = 0x1 + EXTB = 0x9600 + EXTPROC = 0x800 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x400 + FLUSHO = 0x800000 + F_CANCEL = 0x5 + F_DUP2FD = 0xa + F_DUP2FD_CLOEXEC = 0x12 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0x11 + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLK = 0xb + F_GETOWN = 0x5 + F_OGETLK = 0x7 + F_OK = 0x0 + F_OSETLK = 0x8 + F_OSETLKW = 0x9 + F_RDAHEAD = 0x10 + F_RDLCK = 0x1 + F_READAHEAD = 0xf + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLK = 0xc + F_SETLKW = 0xd + F_SETLK_REMOTE = 0xe + F_SETOWN = 0x6 + F_UNLCK = 0x2 + F_UNLCKSYS = 0x4 + F_WRLCK = 0x3 + HUPCL = 0x4000 + HW_MACHINE = 0x1 + ICANON = 0x100 + ICMP6_FILTER = 0x12 + ICRNL = 0x100 + IEXTEN = 0x400 + IFAN_ARRIVAL = 0x0 + IFAN_DEPARTURE = 0x1 + IFF_ALLMULTI = 0x200 + IFF_ALTPHYS = 0x4000 + IFF_BROADCAST = 0x2 + IFF_CANTCHANGE = 0x218f52 + IFF_CANTCONFIG = 0x10000 + IFF_DEBUG = 0x4 + IFF_DRV_OACTIVE = 0x400 + IFF_DRV_RUNNING = 0x40 + IFF_DYING = 0x200000 + IFF_LINK0 = 0x1000 + IFF_LINK1 = 0x2000 + IFF_LINK2 = 0x4000 + IFF_LOOPBACK = 0x8 + IFF_MONITOR = 0x40000 + IFF_MULTICAST = 0x8000 + IFF_NOARP = 0x80 + IFF_OACTIVE = 0x400 + IFF_POINTOPOINT = 0x10 + IFF_PPROMISC = 0x20000 + IFF_PROMISC = 0x100 + IFF_RENAMING = 0x400000 + IFF_RUNNING = 0x40 + IFF_SIMPLEX = 0x800 + IFF_STATICARP = 0x80000 + IFF_UP = 0x1 + IFNAMSIZ = 0x10 + IFT_BRIDGE = 0xd1 + IFT_CARP = 0xf8 + IFT_IEEE1394 = 0x90 + IFT_INFINIBAND = 0xc7 + IFT_L2VLAN = 0x87 + IFT_L3IPVLAN = 0x88 + IFT_PPP = 0x17 + IFT_PROPVIRTUAL = 0x35 + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLASSD_HOST = 0xfffffff + IN_CLASSD_NET = 0xf0000000 + IN_CLASSD_NSHIFT = 0x1c + IN_LOOPBACKNET = 0x7f + IN_RFC3021_MASK = 0xfffffffe + IPPROTO_3PC = 0x22 + IPPROTO_ADFS = 0x44 + IPPROTO_AH = 0x33 + IPPROTO_AHIP = 0x3d + IPPROTO_APES = 0x63 + IPPROTO_ARGUS = 0xd + IPPROTO_AX25 = 0x5d + IPPROTO_BHA = 0x31 + IPPROTO_BLT = 0x1e + IPPROTO_BRSATMON = 0x4c + IPPROTO_CARP = 0x70 + IPPROTO_CFTP = 0x3e + IPPROTO_CHAOS = 0x10 + IPPROTO_CMTP = 0x26 + IPPROTO_CPHB = 0x49 + IPPROTO_CPNX = 0x48 + IPPROTO_DDP = 0x25 + IPPROTO_DGP = 0x56 + IPPROTO_DIVERT = 0x102 + IPPROTO_DONE = 0x101 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_EMCON = 0xe + IPPROTO_ENCAP = 0x62 + IPPROTO_EON = 0x50 + IPPROTO_ESP = 0x32 + IPPROTO_ETHERIP = 0x61 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GGP = 0x3 + IPPROTO_GMTP = 0x64 + IPPROTO_GRE = 0x2f + IPPROTO_HELLO = 0x3f + IPPROTO_HIP = 0x8b + IPPROTO_HMP = 0x14 + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IDPR = 0x23 + IPPROTO_IDRP = 0x2d + IPPROTO_IGMP = 0x2 + IPPROTO_IGP = 0x55 + IPPROTO_IGRP = 0x58 + IPPROTO_IL = 0x28 + IPPROTO_INLSP = 0x34 + IPPROTO_INP = 0x20 + IPPROTO_IP = 0x0 + IPPROTO_IPCOMP = 0x6c + IPPROTO_IPCV = 0x47 + IPPROTO_IPEIP = 0x5e + IPPROTO_IPIP = 0x4 + IPPROTO_IPPC = 0x43 + IPPROTO_IPV4 = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_IRTP = 0x1c + IPPROTO_KRYPTOLAN = 0x41 + IPPROTO_LARP = 0x5b + IPPROTO_LEAF1 = 0x19 + IPPROTO_LEAF2 = 0x1a + IPPROTO_MAX = 0x100 + IPPROTO_MEAS = 0x13 + IPPROTO_MH = 0x87 + IPPROTO_MHRP = 0x30 + IPPROTO_MICP = 0x5f + IPPROTO_MOBILE = 0x37 + IPPROTO_MPLS = 0x89 + IPPROTO_MTP = 0x5c + IPPROTO_MUX = 0x12 + IPPROTO_ND = 0x4d + IPPROTO_NHRP = 0x36 + IPPROTO_NONE = 0x3b + IPPROTO_NSP = 0x1f + IPPROTO_NVPII = 0xb + IPPROTO_OLD_DIVERT = 0xfe + IPPROTO_OSPFIGP = 0x59 + IPPROTO_PFSYNC = 0xf0 + IPPROTO_PGM = 0x71 + IPPROTO_PIGP = 0x9 + IPPROTO_PIM = 0x67 + IPPROTO_PRM = 0x15 + IPPROTO_PUP = 0xc + IPPROTO_PVP = 0x4b + IPPROTO_RAW = 0xff + IPPROTO_RCCMON = 0xa + IPPROTO_RDP = 0x1b + IPPROTO_RESERVED_253 = 0xfd + IPPROTO_RESERVED_254 = 0xfe + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_RVD = 0x42 + IPPROTO_SATEXPAK = 0x40 + IPPROTO_SATMON = 0x45 + IPPROTO_SCCSP = 0x60 + IPPROTO_SCTP = 0x84 + IPPROTO_SDRP = 0x2a + IPPROTO_SEND = 0x103 + IPPROTO_SEP = 0x21 + IPPROTO_SHIM6 = 0x8c + IPPROTO_SKIP = 0x39 + IPPROTO_SPACER = 0x7fff + IPPROTO_SRPC = 0x5a + IPPROTO_ST = 0x7 + IPPROTO_SVMTP = 0x52 + IPPROTO_SWIPE = 0x35 + IPPROTO_TCF = 0x57 + IPPROTO_TCP = 0x6 + IPPROTO_TLSP = 0x38 + IPPROTO_TP = 0x1d + IPPROTO_TPXX = 0x27 + IPPROTO_TRUNK1 = 0x17 + IPPROTO_TRUNK2 = 0x18 + IPPROTO_TTP = 0x54 + IPPROTO_UDP = 0x11 + IPPROTO_UDPLITE = 0x88 + IPPROTO_VINES = 0x53 + IPPROTO_VISA = 0x46 + IPPROTO_VMTP = 0x51 + IPPROTO_WBEXPAK = 0x4f + IPPROTO_WBMON = 0x4e + IPPROTO_WSN = 0x4a + IPPROTO_XNET = 0xf + IPPROTO_XTP = 0x24 + IPV6_AUTOFLOWLABEL = 0x3b + IPV6_BINDANY = 0x40 + IPV6_BINDMULTI = 0x41 + IPV6_BINDV6ONLY = 0x1b + IPV6_CHECKSUM = 0x1a + IPV6_DEFAULT_MULTICAST_HOPS = 0x1 + IPV6_DEFAULT_MULTICAST_LOOP = 0x1 + IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 + IPV6_FLOWID = 0x43 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FLOWTYPE = 0x44 + IPV6_FRAGTTL = 0x78 + IPV6_FW_ADD = 0x1e + IPV6_FW_DEL = 0x1f + IPV6_FW_FLUSH = 0x20 + IPV6_FW_GET = 0x22 + IPV6_FW_ZERO = 0x21 + IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 + IPV6_IPSEC_POLICY = 0x1c + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_MAXHLIM = 0xff + IPV6_MAXOPTHDR = 0x800 + IPV6_MAXPACKET = 0xffff + IPV6_MAX_GROUP_SRC_FILTER = 0x200 + IPV6_MAX_MEMBERSHIPS = 0xfff + IPV6_MAX_SOCK_SRC_FILTER = 0x80 + IPV6_MIN_MEMBERSHIPS = 0x1f + IPV6_MMTU = 0x500 + IPV6_MSFILTER = 0x4a + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_PATHMTU = 0x2c + IPV6_PKTINFO = 0x2e + IPV6_PORTRANGE = 0xe + IPV6_PORTRANGE_DEFAULT = 0x0 + IPV6_PORTRANGE_HIGH = 0x1 + IPV6_PORTRANGE_LOW = 0x2 + IPV6_PREFER_TEMPADDR = 0x3f + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVFLOWID = 0x46 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x24 + IPV6_RECVRSSBUCKETID = 0x47 + IPV6_RECVRTHDR = 0x26 + IPV6_RECVTCLASS = 0x39 + IPV6_RSSBUCKETID = 0x45 + IPV6_RSS_LISTEN_BUCKET = 0x42 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x23 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_SOCKOPT_RESERVED1 = 0x3 + IPV6_TCLASS = 0x3d + IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a + IPV6_V6ONLY = 0x1b + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 + IP_ADD_MEMBERSHIP = 0xc + IP_ADD_SOURCE_MEMBERSHIP = 0x46 + IP_BINDANY = 0x18 + IP_BINDMULTI = 0x19 + IP_BLOCK_SOURCE = 0x48 + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DONTFRAG = 0x43 + IP_DROP_MEMBERSHIP = 0xd + IP_DROP_SOURCE_MEMBERSHIP = 0x47 + IP_DUMMYNET3 = 0x31 + IP_DUMMYNET_CONFIGURE = 0x3c + IP_DUMMYNET_DEL = 0x3d + IP_DUMMYNET_FLUSH = 0x3e + IP_DUMMYNET_GET = 0x40 + IP_FLOWID = 0x5a + IP_FLOWTYPE = 0x5b + IP_FW3 = 0x30 + IP_FW_ADD = 0x32 + IP_FW_DEL = 0x33 + IP_FW_FLUSH = 0x34 + IP_FW_GET = 0x36 + IP_FW_NAT_CFG = 0x38 + IP_FW_NAT_DEL = 0x39 + IP_FW_NAT_GET_CONFIG = 0x3a + IP_FW_NAT_GET_LOG = 0x3b + IP_FW_RESETLOG = 0x37 + IP_FW_TABLE_ADD = 0x28 + IP_FW_TABLE_DEL = 0x29 + IP_FW_TABLE_FLUSH = 0x2a + IP_FW_TABLE_GETSIZE = 0x2b + IP_FW_TABLE_LIST = 0x2c + IP_FW_ZERO = 0x35 + IP_HDRINCL = 0x2 + IP_IPSEC_POLICY = 0x15 + IP_MAXPACKET = 0xffff + IP_MAX_GROUP_SRC_FILTER = 0x200 + IP_MAX_MEMBERSHIPS = 0xfff + IP_MAX_SOCK_MUTE_FILTER = 0x80 + IP_MAX_SOCK_SRC_FILTER = 0x80 + IP_MAX_SOURCE_FILTER = 0x400 + IP_MF = 0x2000 + IP_MINTTL = 0x42 + IP_MIN_MEMBERSHIPS = 0x1f + IP_MSFILTER = 0x4a + IP_MSS = 0x240 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_LOOP = 0xb + IP_MULTICAST_TTL = 0xa + IP_MULTICAST_VIF = 0xe + IP_OFFMASK = 0x1fff + IP_ONESBCAST = 0x17 + IP_OPTIONS = 0x1 + IP_PORTRANGE = 0x13 + IP_PORTRANGE_DEFAULT = 0x0 + IP_PORTRANGE_HIGH = 0x1 + IP_PORTRANGE_LOW = 0x2 + IP_RECVDSTADDR = 0x7 + IP_RECVFLOWID = 0x5d + IP_RECVIF = 0x14 + IP_RECVOPTS = 0x5 + IP_RECVRETOPTS = 0x6 + IP_RECVRSSBUCKETID = 0x5e + IP_RECVTOS = 0x44 + IP_RECVTTL = 0x41 + IP_RETOPTS = 0x8 + IP_RF = 0x8000 + IP_RSSBUCKETID = 0x5c + IP_RSS_LISTEN_BUCKET = 0x1a + IP_RSVP_OFF = 0x10 + IP_RSVP_ON = 0xf + IP_RSVP_VIF_OFF = 0x12 + IP_RSVP_VIF_ON = 0x11 + IP_SENDSRCADDR = 0x7 + IP_TOS = 0x3 + IP_TTL = 0x4 + IP_UNBLOCK_SOURCE = 0x49 + ISIG = 0x80 + ISTRIP = 0x20 + IXANY = 0x800 + IXOFF = 0x400 + IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_AUTOSYNC = 0x7 + MADV_CORE = 0x9 + MADV_DONTNEED = 0x4 + MADV_FREE = 0x5 + MADV_NOCORE = 0x8 + MADV_NORMAL = 0x0 + MADV_NOSYNC = 0x6 + MADV_PROTECT = 0xa + MADV_RANDOM = 0x1 + MADV_SEQUENTIAL = 0x2 + MADV_WILLNEED = 0x3 + MAP_32BIT = 0x80000 + MAP_ALIGNED_SUPER = 0x1000000 + MAP_ALIGNMENT_MASK = -0x1000000 + MAP_ALIGNMENT_SHIFT = 0x18 + MAP_ANON = 0x1000 + MAP_ANONYMOUS = 0x1000 + MAP_COPY = 0x2 + MAP_EXCL = 0x4000 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_HASSEMAPHORE = 0x200 + MAP_NOCORE = 0x20000 + MAP_NOSYNC = 0x800 + MAP_PREFAULT_READ = 0x40000 + MAP_PRIVATE = 0x2 + MAP_RESERVED0020 = 0x20 + MAP_RESERVED0040 = 0x40 + MAP_RESERVED0080 = 0x80 + MAP_RESERVED0100 = 0x100 + MAP_SHARED = 0x1 + MAP_STACK = 0x400 + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MNT_ACLS = 0x8000000 + MNT_ASYNC = 0x40 + MNT_AUTOMOUNTED = 0x200000000 + MNT_BYFSID = 0x8000000 + MNT_CMDFLAGS = 0xd0f0000 + MNT_DEFEXPORTED = 0x200 + MNT_DELEXPORT = 0x20000 + MNT_EXKERB = 0x800 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXPUBLIC = 0x20000000 + MNT_EXRDONLY = 0x80 + MNT_FORCE = 0x80000 + MNT_GJOURNAL = 0x2000000 + MNT_IGNORE = 0x800000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_MULTILABEL = 0x4000000 + MNT_NFS4ACLS = 0x10 + MNT_NOATIME = 0x10000000 + MNT_NOCLUSTERR = 0x40000000 + MNT_NOCLUSTERW = 0x80000000 + MNT_NOEXEC = 0x4 + MNT_NONBUSY = 0x4000000 + MNT_NOSUID = 0x8 + MNT_NOSYMFOLLOW = 0x400000 + MNT_NOWAIT = 0x2 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SNAPSHOT = 0x1000000 + MNT_SOFTDEP = 0x200000 + MNT_SUIDDIR = 0x100000 + MNT_SUJ = 0x100000000 + MNT_SUSPEND = 0x4 + MNT_SYNCHRONOUS = 0x2 + MNT_UNION = 0x20 + MNT_UPDATE = 0x10000 + MNT_UPDATEMASK = 0x2d8d0807e + MNT_USER = 0x8000 + MNT_VISFLAGMASK = 0x3fef0ffff + MNT_WAIT = 0x1 + MSG_CMSG_CLOEXEC = 0x40000 + MSG_COMPAT = 0x8000 + MSG_CTRUNC = 0x20 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x80 + MSG_EOF = 0x100 + MSG_EOR = 0x8 + MSG_NBIO = 0x4000 + MSG_NOSIGNAL = 0x20000 + MSG_NOTIFICATION = 0x2000 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_TRUNC = 0x10 + MSG_WAITALL = 0x40 + MSG_WAITFORONE = 0x80000 + MS_ASYNC = 0x1 + MS_INVALIDATE = 0x2 + MS_SYNC = 0x0 + NAME_MAX = 0xff + NET_RT_DUMP = 0x1 + NET_RT_FLAGS = 0x2 + NET_RT_IFLIST = 0x3 + NET_RT_IFLISTL = 0x5 + NET_RT_IFMALIST = 0x4 + NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 + NOTE_ATTRIB = 0x8 + NOTE_CHILD = 0x4 + NOTE_CLOSE = 0x100 + NOTE_CLOSE_WRITE = 0x200 + NOTE_DELETE = 0x1 + NOTE_EXEC = 0x20000000 + NOTE_EXIT = 0x80000000 + NOTE_EXTEND = 0x4 + NOTE_FFAND = 0x40000000 + NOTE_FFCOPY = 0xc0000000 + NOTE_FFCTRLMASK = 0xc0000000 + NOTE_FFLAGSMASK = 0xffffff + NOTE_FFNOP = 0x0 + NOTE_FFOR = 0x80000000 + NOTE_FILE_POLL = 0x2 + NOTE_FORK = 0x40000000 + NOTE_LINK = 0x10 + NOTE_LOWAT = 0x1 + NOTE_MSECONDS = 0x2 + NOTE_NSECONDS = 0x8 + NOTE_OPEN = 0x80 + NOTE_PCTRLMASK = 0xf0000000 + NOTE_PDATAMASK = 0xfffff + NOTE_READ = 0x400 + NOTE_RENAME = 0x20 + NOTE_REVOKE = 0x40 + NOTE_SECONDS = 0x1 + NOTE_TRACK = 0x1 + NOTE_TRACKERR = 0x2 + NOTE_TRIGGER = 0x1000000 + NOTE_USECONDS = 0x4 + NOTE_WRITE = 0x2 + OCRNL = 0x10 + ONLCR = 0x2 + ONLRET = 0x40 + ONOCR = 0x20 + ONOEOT = 0x8 + OPOST = 0x1 + OXTABS = 0x4 + O_ACCMODE = 0x3 + O_APPEND = 0x8 + O_ASYNC = 0x40 + O_CLOEXEC = 0x100000 + O_CREAT = 0x200 + O_DIRECT = 0x10000 + O_DIRECTORY = 0x20000 + O_EXCL = 0x800 + O_EXEC = 0x40000 + O_EXLOCK = 0x20 + O_FSYNC = 0x80 + O_NDELAY = 0x4 + O_NOCTTY = 0x8000 + O_NOFOLLOW = 0x100 + O_NONBLOCK = 0x4 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_SHLOCK = 0x10 + O_SYNC = 0x80 + O_TRUNC = 0x400 + O_TTY_INIT = 0x80000 + O_VERIFY = 0x200000 + O_WRONLY = 0x1 + PARENB = 0x1000 + PARMRK = 0x8 + PARODD = 0x2000 + PENDIN = 0x20000000 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PROT_EXEC = 0x4 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + RLIMIT_AS = 0xa + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 + RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0x7fffffffffffffff + RTAX_AUTHOR = 0x6 + RTAX_BRD = 0x7 + RTAX_DST = 0x0 + RTAX_GATEWAY = 0x1 + RTAX_GENMASK = 0x3 + RTAX_IFA = 0x5 + RTAX_IFP = 0x4 + RTAX_MAX = 0x8 + RTAX_NETMASK = 0x2 + RTA_AUTHOR = 0x40 + RTA_BRD = 0x80 + RTA_DST = 0x1 + RTA_GATEWAY = 0x2 + RTA_GENMASK = 0x8 + RTA_IFA = 0x20 + RTA_IFP = 0x10 + RTA_NETMASK = 0x4 + RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_DONE = 0x40 + RTF_DYNAMIC = 0x10 + RTF_FIXEDMTU = 0x80000 + RTF_FMASK = 0x1004d808 + RTF_GATEWAY = 0x2 + RTF_GWFLAG_COMPAT = 0x80000000 + RTF_HOST = 0x4 + RTF_LLDATA = 0x400 + RTF_LLINFO = 0x400 + RTF_LOCAL = 0x200000 + RTF_MODIFIED = 0x20 + RTF_MULTICAST = 0x800000 + RTF_PINNED = 0x100000 + RTF_PROTO1 = 0x8000 + RTF_PROTO2 = 0x4000 + RTF_PROTO3 = 0x40000 + RTF_REJECT = 0x8 + RTF_RNH_LOCKED = 0x40000000 + RTF_STATIC = 0x800 + RTF_STICKY = 0x10000000 + RTF_UP = 0x1 + RTF_XRESOLVE = 0x200 + RTM_ADD = 0x1 + RTM_CHANGE = 0x3 + RTM_DELADDR = 0xd + RTM_DELETE = 0x2 + RTM_DELMADDR = 0x10 + RTM_GET = 0x4 + RTM_IEEE80211 = 0x12 + RTM_IFANNOUNCE = 0x11 + RTM_IFINFO = 0xe + RTM_LOCK = 0x8 + RTM_LOSING = 0x5 + RTM_MISS = 0x7 + RTM_NEWADDR = 0xc + RTM_NEWMADDR = 0xf + RTM_REDIRECT = 0x6 + RTM_RESOLVE = 0xb + RTM_RTTUNIT = 0xf4240 + RTM_VERSION = 0x5 + RTV_EXPIRE = 0x4 + RTV_HOPCOUNT = 0x2 + RTV_MTU = 0x1 + RTV_RPIPE = 0x8 + RTV_RTT = 0x40 + RTV_RTTVAR = 0x80 + RTV_SPIPE = 0x10 + RTV_SSTHRESH = 0x20 + RTV_WEIGHT = 0x100 + RT_ALL_FIBS = -0x1 + RT_BLACKHOLE = 0x40 + RT_CACHING_CONTEXT = 0x1 + RT_DEFAULT_FIB = 0x0 + RT_HAS_GW = 0x80 + RT_HAS_HEADER = 0x10 + RT_HAS_HEADER_BIT = 0x4 + RT_L2_ME = 0x4 + RT_L2_ME_BIT = 0x2 + RT_LLE_CACHE = 0x100 + RT_MAY_LOOP = 0x8 + RT_MAY_LOOP_BIT = 0x3 + RT_NORTREF = 0x2 + RT_REJECT = 0x20 + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + RUSAGE_THREAD = 0x1 + SCM_BINTIME = 0x4 + SCM_CREDS = 0x3 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x2 + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDMULTI = 0x80206931 + SIOCAIFADDR = 0x8040691a + SIOCAIFGROUP = 0x80286987 + SIOCATMARK = 0x40047307 + SIOCDELMULTI = 0x80206932 + SIOCDIFADDR = 0x80206919 + SIOCDIFGROUP = 0x80286989 + SIOCDIFPHYADDR = 0x80206949 + SIOCGDRVSPEC = 0xc028697b + SIOCGETSGCNT = 0xc0207210 + SIOCGETVIFCNT = 0xc028720f + SIOCGHIWAT = 0x40047301 + SIOCGI2C = 0xc020693d + SIOCGIFADDR = 0xc0206921 + SIOCGIFBRDADDR = 0xc0206923 + SIOCGIFCAP = 0xc020691f + SIOCGIFCONF = 0xc0106924 + SIOCGIFDESCR = 0xc020692a + SIOCGIFDSTADDR = 0xc0206922 + SIOCGIFFIB = 0xc020695c + SIOCGIFFLAGS = 0xc0206911 + SIOCGIFGENERIC = 0xc020693a + SIOCGIFGMEMB = 0xc028698a + SIOCGIFGROUP = 0xc0286988 + SIOCGIFINDEX = 0xc0206920 + SIOCGIFMAC = 0xc0206926 + SIOCGIFMEDIA = 0xc0306938 + SIOCGIFMETRIC = 0xc0206917 + SIOCGIFMTU = 0xc0206933 + SIOCGIFNETMASK = 0xc0206925 + SIOCGIFPDSTADDR = 0xc0206948 + SIOCGIFPHYS = 0xc0206935 + SIOCGIFPSRCADDR = 0xc0206947 + SIOCGIFSTATUS = 0xc331693b + SIOCGIFXMEDIA = 0xc030698b + SIOCGLOWAT = 0x40047303 + SIOCGPGRP = 0x40047309 + SIOCGPRIVATE_0 = 0xc0206950 + SIOCGPRIVATE_1 = 0xc0206951 + SIOCGTUNFIB = 0xc020695e + SIOCIFCREATE = 0xc020697a + SIOCIFCREATE2 = 0xc020697c + SIOCIFDESTROY = 0x80206979 + SIOCIFGCLONERS = 0xc0106978 + SIOCSDRVSPEC = 0x8028697b + SIOCSHIWAT = 0x80047300 + SIOCSIFADDR = 0x8020690c + SIOCSIFBRDADDR = 0x80206913 + SIOCSIFCAP = 0x8020691e + SIOCSIFDESCR = 0x80206929 + SIOCSIFDSTADDR = 0x8020690e + SIOCSIFFIB = 0x8020695d + SIOCSIFFLAGS = 0x80206910 + SIOCSIFGENERIC = 0x80206939 + SIOCSIFLLADDR = 0x8020693c + SIOCSIFMAC = 0x80206927 + SIOCSIFMEDIA = 0xc0206937 + SIOCSIFMETRIC = 0x80206918 + SIOCSIFMTU = 0x80206934 + SIOCSIFNAME = 0x80206928 + SIOCSIFNETMASK = 0x80206916 + SIOCSIFPHYADDR = 0x80406946 + SIOCSIFPHYS = 0x80206936 + SIOCSIFRVNET = 0xc020695b + SIOCSIFVNET = 0xc020695a + SIOCSLOWAT = 0x80047302 + SIOCSPGRP = 0x80047308 + SIOCSTUNFIB = 0x8020695f + SOCK_CLOEXEC = 0x10000000 + SOCK_DGRAM = 0x2 + SOCK_MAXADDRLEN = 0xff + SOCK_NONBLOCK = 0x20000000 + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_SOCKET = 0xffff + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x2 + SO_ACCEPTFILTER = 0x1000 + SO_BINTIME = 0x2000 + SO_BROADCAST = 0x20 + SO_DEBUG = 0x1 + SO_DONTROUTE = 0x10 + SO_ERROR = 0x1007 + SO_KEEPALIVE = 0x8 + SO_LABEL = 0x1009 + SO_LINGER = 0x80 + SO_LISTENINCQLEN = 0x1013 + SO_LISTENQLEN = 0x1012 + SO_LISTENQLIMIT = 0x1011 + SO_NOSIGPIPE = 0x800 + SO_NO_DDP = 0x8000 + SO_NO_OFFLOAD = 0x4000 + SO_OOBINLINE = 0x100 + SO_PEERLABEL = 0x1010 + SO_PROTOCOL = 0x1016 + SO_PROTOTYPE = 0x1016 + SO_RCVBUF = 0x1002 + SO_RCVLOWAT = 0x1004 + SO_RCVTIMEO = 0x1006 + SO_REUSEADDR = 0x4 + SO_REUSEPORT = 0x200 + SO_SETFIB = 0x1014 + SO_SNDBUF = 0x1001 + SO_SNDLOWAT = 0x1003 + SO_SNDTIMEO = 0x1005 + SO_TIMESTAMP = 0x400 + SO_TYPE = 0x1008 + SO_USELOOPBACK = 0x40 + SO_USER_COOKIE = 0x1015 + SO_VENDOR = 0x80000000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IFWHT = 0xe000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + TAB0 = 0x0 + TAB3 = 0x4 + TABDLY = 0x4 + TCIFLUSH = 0x1 + TCIOFF = 0x3 + TCIOFLUSH = 0x3 + TCION = 0x4 + TCOFLUSH = 0x2 + TCOOFF = 0x1 + TCOON = 0x2 + TCP_CA_NAME_MAX = 0x10 + TCP_CCALGOOPT = 0x41 + TCP_CONGESTION = 0x40 + TCP_FASTOPEN = 0x401 + TCP_FUNCTION_BLK = 0x2000 + TCP_FUNCTION_NAME_LEN_MAX = 0x20 + TCP_INFO = 0x20 + TCP_KEEPCNT = 0x400 + TCP_KEEPIDLE = 0x100 + TCP_KEEPINIT = 0x80 + TCP_KEEPINTVL = 0x200 + TCP_MAXBURST = 0x4 + TCP_MAXHLEN = 0x3c + TCP_MAXOLEN = 0x28 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_SACK = 0x4 + TCP_MAX_WINSHIFT = 0xe + TCP_MD5SIG = 0x10 + TCP_MINMSS = 0xd8 + TCP_MSS = 0x218 + TCP_NODELAY = 0x1 + TCP_NOOPT = 0x8 + TCP_NOPUSH = 0x4 + TCP_PCAP_IN = 0x1000 + TCP_PCAP_OUT = 0x800 + TCP_VENDOR = 0x80000000 + TCSAFLUSH = 0x2 + TIOCCBRK = 0x2000747a + TIOCCDTR = 0x20007478 + TIOCCONS = 0x80047462 + TIOCDRAIN = 0x2000745e + TIOCEXCL = 0x2000740d + TIOCEXT = 0x80047460 + TIOCFLUSH = 0x80047410 + TIOCGDRAINWAIT = 0x40047456 + TIOCGETA = 0x402c7413 + TIOCGETD = 0x4004741a + TIOCGPGRP = 0x40047477 + TIOCGPTN = 0x4004740f + TIOCGSID = 0x40047463 + TIOCGWINSZ = 0x40087468 + TIOCMBIC = 0x8004746b + TIOCMBIS = 0x8004746c + TIOCMGDTRWAIT = 0x4004745a + TIOCMGET = 0x4004746a + TIOCMSDTRWAIT = 0x8004745b + TIOCMSET = 0x8004746d + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DCD = 0x40 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x20007471 + TIOCNXCL = 0x2000740e + TIOCOUTQ = 0x40047473 + TIOCPKT = 0x80047470 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCPTMASTER = 0x2000741c + TIOCSBRK = 0x2000747b + TIOCSCTTY = 0x20007461 + TIOCSDRAINWAIT = 0x80047457 + TIOCSDTR = 0x20007479 + TIOCSETA = 0x802c7414 + TIOCSETAF = 0x802c7416 + TIOCSETAW = 0x802c7415 + TIOCSETD = 0x8004741b + TIOCSIG = 0x2004745f + TIOCSPGRP = 0x80047476 + TIOCSTART = 0x2000746e + TIOCSTAT = 0x20007465 + TIOCSTI = 0x80017472 + TIOCSTOP = 0x2000746f + TIOCSWINSZ = 0x80087467 + TIOCTIMESTAMP = 0x40107459 + TIOCUCNTL = 0x80047466 + TOSTOP = 0x400000 + VDISCARD = 0xf + VDSUSP = 0xb + VEOF = 0x0 + VEOL = 0x1 + VEOL2 = 0x2 + VERASE = 0x3 + VERASE2 = 0x7 + VINTR = 0x8 + VKILL = 0x5 + VLNEXT = 0xe + VMIN = 0x10 + VQUIT = 0x9 + VREPRINT = 0x6 + VSTART = 0xc + VSTATUS = 0x12 + VSTOP = 0xd + VSUSP = 0xa + VTIME = 0x11 + VWERASE = 0x4 + WCONTINUED = 0x4 + WCOREFLAG = 0x80 + WEXITED = 0x10 + WLINUXCLONE = 0x80000000 + WNOHANG = 0x1 + WNOWAIT = 0x8 + WSTOPPED = 0x2 + WTRAPPED = 0x20 + WUNTRACED = 0x2 +) + +// Errors +const ( + E2BIG = syscall.Errno(0x7) + EACCES = syscall.Errno(0xd) + EADDRINUSE = syscall.Errno(0x30) + EADDRNOTAVAIL = syscall.Errno(0x31) + EAFNOSUPPORT = syscall.Errno(0x2f) + EAGAIN = syscall.Errno(0x23) + EALREADY = syscall.Errno(0x25) + EAUTH = syscall.Errno(0x50) + EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x59) + EBADRPC = syscall.Errno(0x48) + EBUSY = syscall.Errno(0x10) + ECANCELED = syscall.Errno(0x55) + ECAPMODE = syscall.Errno(0x5e) + ECHILD = syscall.Errno(0xa) + ECONNABORTED = syscall.Errno(0x35) + ECONNREFUSED = syscall.Errno(0x3d) + ECONNRESET = syscall.Errno(0x36) + EDEADLK = syscall.Errno(0xb) + EDESTADDRREQ = syscall.Errno(0x27) + EDOM = syscall.Errno(0x21) + EDOOFUS = syscall.Errno(0x58) + EDQUOT = syscall.Errno(0x45) + EEXIST = syscall.Errno(0x11) + EFAULT = syscall.Errno(0xe) + EFBIG = syscall.Errno(0x1b) + EFTYPE = syscall.Errno(0x4f) + EHOSTDOWN = syscall.Errno(0x40) + EHOSTUNREACH = syscall.Errno(0x41) + EIDRM = syscall.Errno(0x52) + EILSEQ = syscall.Errno(0x56) + EINPROGRESS = syscall.Errno(0x24) + EINTR = syscall.Errno(0x4) + EINVAL = syscall.Errno(0x16) + EIO = syscall.Errno(0x5) + EISCONN = syscall.Errno(0x38) + EISDIR = syscall.Errno(0x15) + ELAST = syscall.Errno(0x60) + ELOOP = syscall.Errno(0x3e) + EMFILE = syscall.Errno(0x18) + EMLINK = syscall.Errno(0x1f) + EMSGSIZE = syscall.Errno(0x28) + EMULTIHOP = syscall.Errno(0x5a) + ENAMETOOLONG = syscall.Errno(0x3f) + ENEEDAUTH = syscall.Errno(0x51) + ENETDOWN = syscall.Errno(0x32) + ENETRESET = syscall.Errno(0x34) + ENETUNREACH = syscall.Errno(0x33) + ENFILE = syscall.Errno(0x17) + ENOATTR = syscall.Errno(0x57) + ENOBUFS = syscall.Errno(0x37) + ENODEV = syscall.Errno(0x13) + ENOENT = syscall.Errno(0x2) + ENOEXEC = syscall.Errno(0x8) + ENOLCK = syscall.Errno(0x4d) + ENOLINK = syscall.Errno(0x5b) + ENOMEM = syscall.Errno(0xc) + ENOMSG = syscall.Errno(0x53) + ENOPROTOOPT = syscall.Errno(0x2a) + ENOSPC = syscall.Errno(0x1c) + ENOSYS = syscall.Errno(0x4e) + ENOTBLK = syscall.Errno(0xf) + ENOTCAPABLE = syscall.Errno(0x5d) + ENOTCONN = syscall.Errno(0x39) + ENOTDIR = syscall.Errno(0x14) + ENOTEMPTY = syscall.Errno(0x42) + ENOTRECOVERABLE = syscall.Errno(0x5f) + ENOTSOCK = syscall.Errno(0x26) + ENOTSUP = syscall.Errno(0x2d) + ENOTTY = syscall.Errno(0x19) + ENXIO = syscall.Errno(0x6) + EOPNOTSUPP = syscall.Errno(0x2d) + EOVERFLOW = syscall.Errno(0x54) + EOWNERDEAD = syscall.Errno(0x60) + EPERM = syscall.Errno(0x1) + EPFNOSUPPORT = syscall.Errno(0x2e) + EPIPE = syscall.Errno(0x20) + EPROCLIM = syscall.Errno(0x43) + EPROCUNAVAIL = syscall.Errno(0x4c) + EPROGMISMATCH = syscall.Errno(0x4b) + EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x5c) + EPROTONOSUPPORT = syscall.Errno(0x2b) + EPROTOTYPE = syscall.Errno(0x29) + ERANGE = syscall.Errno(0x22) + EREMOTE = syscall.Errno(0x47) + EROFS = syscall.Errno(0x1e) + ERPCMISMATCH = syscall.Errno(0x49) + ESHUTDOWN = syscall.Errno(0x3a) + ESOCKTNOSUPPORT = syscall.Errno(0x2c) + ESPIPE = syscall.Errno(0x1d) + ESRCH = syscall.Errno(0x3) + ESTALE = syscall.Errno(0x46) + ETIMEDOUT = syscall.Errno(0x3c) + ETOOMANYREFS = syscall.Errno(0x3b) + ETXTBSY = syscall.Errno(0x1a) + EUSERS = syscall.Errno(0x44) + EWOULDBLOCK = syscall.Errno(0x23) + EXDEV = syscall.Errno(0x12) +) + +// Signals +const ( + SIGABRT = syscall.Signal(0x6) + SIGALRM = syscall.Signal(0xe) + SIGBUS = syscall.Signal(0xa) + SIGCHLD = syscall.Signal(0x14) + SIGCONT = syscall.Signal(0x13) + SIGEMT = syscall.Signal(0x7) + SIGFPE = syscall.Signal(0x8) + SIGHUP = syscall.Signal(0x1) + SIGILL = syscall.Signal(0x4) + SIGINFO = syscall.Signal(0x1d) + SIGINT = syscall.Signal(0x2) + SIGIO = syscall.Signal(0x17) + SIGIOT = syscall.Signal(0x6) + SIGKILL = syscall.Signal(0x9) + SIGLIBRT = syscall.Signal(0x21) + SIGLWP = syscall.Signal(0x20) + SIGPIPE = syscall.Signal(0xd) + SIGPROF = syscall.Signal(0x1b) + SIGQUIT = syscall.Signal(0x3) + SIGSEGV = syscall.Signal(0xb) + SIGSTOP = syscall.Signal(0x11) + SIGSYS = syscall.Signal(0xc) + SIGTERM = syscall.Signal(0xf) + SIGTHR = syscall.Signal(0x20) + SIGTRAP = syscall.Signal(0x5) + SIGTSTP = syscall.Signal(0x12) + SIGTTIN = syscall.Signal(0x15) + SIGTTOU = syscall.Signal(0x16) + SIGURG = syscall.Signal(0x10) + SIGUSR1 = syscall.Signal(0x1e) + SIGUSR2 = syscall.Signal(0x1f) + SIGVTALRM = syscall.Signal(0x1a) + SIGWINCH = syscall.Signal(0x1c) + SIGXCPU = syscall.Signal(0x18) + SIGXFSZ = syscall.Signal(0x19) +) + +// Error table +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "ECANCELED", "operation canceled"}, + {86, "EILSEQ", "illegal byte sequence"}, + {87, "ENOATTR", "attribute not found"}, + {88, "EDOOFUS", "programming error"}, + {89, "EBADMSG", "bad message"}, + {90, "EMULTIHOP", "multihop attempted"}, + {91, "ENOLINK", "link has been severed"}, + {92, "EPROTO", "protocol error"}, + {93, "ENOTCAPABLE", "capabilities insufficient"}, + {94, "ECAPMODE", "not permitted in capability mode"}, + {95, "ENOTRECOVERABLE", "state not recoverable"}, + {96, "EOWNERDEAD", "previous owner died"}, +} + +// Signal table +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "unknown signal"}, + {33, "SIGLIBRT", "unknown signal"}, +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index db3c31ef8809..d180147f7972 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80041270 BLKBSZSET = 0x40041271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,6 +491,50 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 @@ -493,6 +542,7 @@ const ( FFDLY = 0x8000 FLUSHO = 0x1000 FP_XSTATE_MAGIC2 = 0x46505845 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -514,7 +564,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -639,7 +689,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -707,6 +757,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -778,6 +829,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -913,6 +965,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -922,6 +979,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1101,6 +1162,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1122,7 +1184,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1244,6 +1306,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1385,6 +1448,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1424,6 +1493,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1525,6 +1595,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x40085203 + RNDADDTOENTCNT = 0x40045201 + RNDCLEARPOOL = 0x5206 + RNDGETENTCNT = 0x80045200 + RNDGETPOOL = 0x80085202 + RNDRESEEDCRNG = 0x5207 + RNDZAPENTCNT = 0x5204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1732,6 +1809,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x800 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1893,6 +1972,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2012,7 +2102,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -2026,6 +2116,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2040,6 +2131,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2059,6 +2151,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2073,6 +2168,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x5409 TCSBRKP = 0x5425 @@ -2089,6 +2185,7 @@ const ( TCSETXF = 0x5434 TCSETXW = 0x5435 TCXONC = 0x540a + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -2096,6 +2193,7 @@ const ( TIOCGETD = 0x5424 TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x80285442 TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f TIOCGPKT = 0x80045438 @@ -2149,6 +2247,7 @@ const ( TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x5457 TIOCSPGRP = 0x5410 TIOCSPTLCK = 0x40045431 @@ -2189,6 +2288,7 @@ const ( TUNGETVNETBE = 0x800454df TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd + TUNSETCARRIER = 0x400454e2 TUNSETDEBUG = 0x400454c9 TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce @@ -2379,6 +2479,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 4785835b6bd9..1d277a412d7e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,6 +491,50 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 @@ -493,6 +542,7 @@ const ( FFDLY = 0x8000 FLUSHO = 0x1000 FP_XSTATE_MAGIC2 = 0x46505845 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -514,7 +564,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -639,7 +689,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -707,6 +757,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -778,6 +829,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -913,6 +965,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -922,6 +979,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1101,6 +1162,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1122,7 +1184,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1244,6 +1306,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1385,6 +1448,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1424,6 +1493,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1526,6 +1596,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x40085203 + RNDADDTOENTCNT = 0x40045201 + RNDCLEARPOOL = 0x5206 + RNDGETENTCNT = 0x80045200 + RNDGETPOOL = 0x80085202 + RNDRESEEDCRNG = 0x5207 + RNDZAPENTCNT = 0x5204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1733,6 +1810,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x800 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1894,6 +1973,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2013,7 +2103,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -2027,6 +2117,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2041,6 +2132,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2060,6 +2152,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2074,6 +2169,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x5409 TCSBRKP = 0x5425 @@ -2090,6 +2186,7 @@ const ( TCSETXF = 0x5434 TCSETXW = 0x5435 TCXONC = 0x540a + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -2097,6 +2194,7 @@ const ( TIOCGETD = 0x5424 TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x80285442 TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f TIOCGPKT = 0x80045438 @@ -2150,6 +2248,7 @@ const ( TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x5457 TIOCSPGRP = 0x5410 TIOCSPTLCK = 0x40045431 @@ -2190,6 +2289,7 @@ const ( TUNGETVNETBE = 0x800454df TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd + TUNSETCARRIER = 0x400454e2 TUNSETDEBUG = 0x400454c9 TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce @@ -2379,6 +2479,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 5e902423a10f..63ac45af8161 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80041270 BLKBSZSET = 0x40041271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1099,6 +1160,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1120,7 +1182,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1242,6 +1304,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1383,6 +1446,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1422,6 +1491,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1532,6 +1602,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x40085203 + RNDADDTOENTCNT = 0x40045201 + RNDCLEARPOOL = 0x5206 + RNDGETENTCNT = 0x80045200 + RNDGETPOOL = 0x80085202 + RNDRESEEDCRNG = 0x5207 + RNDZAPENTCNT = 0x5204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1739,6 +1816,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x800 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1900,6 +1979,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2019,7 +2109,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -2033,6 +2123,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2047,6 +2138,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2066,6 +2158,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2080,6 +2175,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x5409 TCSBRKP = 0x5425 @@ -2096,6 +2192,7 @@ const ( TCSETXF = 0x5434 TCSETXW = 0x5435 TCXONC = 0x540a + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -2103,6 +2200,7 @@ const ( TIOCGETD = 0x5424 TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x80285442 TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f TIOCGPKT = 0x80045438 @@ -2156,6 +2254,7 @@ const ( TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x5457 TIOCSPGRP = 0x5410 TIOCSPTLCK = 0x40045431 @@ -2196,6 +2295,7 @@ const ( TUNGETVNETBE = 0x800454df TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd + TUNSETCARRIER = 0x400454e2 TUNSETDEBUG = 0x400454c9 TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce @@ -2385,6 +2485,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index ebe9d8b411ac..81d3259edb01 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -488,6 +493,50 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 @@ -495,6 +544,7 @@ const ( FFDLY = 0x8000 FLUSHO = 0x1000 FPSIMD_MAGIC = 0x46508001 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -516,7 +566,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -641,7 +691,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -709,6 +759,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -780,6 +831,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -915,6 +967,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -924,6 +981,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1102,6 +1163,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1123,7 +1185,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1245,6 +1307,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1386,6 +1449,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1425,6 +1494,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1516,6 +1586,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x40085203 + RNDADDTOENTCNT = 0x40045201 + RNDCLEARPOOL = 0x5206 + RNDGETENTCNT = 0x80045200 + RNDGETPOOL = 0x80085202 + RNDRESEEDCRNG = 0x5207 + RNDZAPENTCNT = 0x5204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1723,6 +1800,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x800 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1884,6 +1963,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2004,7 +2094,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -2018,6 +2108,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2032,6 +2123,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2051,6 +2143,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2065,6 +2160,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x5409 TCSBRKP = 0x5425 @@ -2081,6 +2177,7 @@ const ( TCSETXF = 0x5434 TCSETXW = 0x5435 TCXONC = 0x540a + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -2088,6 +2185,7 @@ const ( TIOCGETD = 0x5424 TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x80285442 TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f TIOCGPKT = 0x80045438 @@ -2141,6 +2239,7 @@ const ( TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x5457 TIOCSPGRP = 0x5410 TIOCSPTLCK = 0x40045431 @@ -2181,6 +2280,7 @@ const ( TUNGETVNETBE = 0x800454df TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd + TUNSETCARRIER = 0x400454e2 TUNSETDEBUG = 0x400454c9 TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce @@ -2370,6 +2470,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index d467d211b519..58fc1eb9c829 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x2000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1099,6 +1160,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1120,7 +1182,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1242,6 +1304,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1383,6 +1446,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1422,6 +1491,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1525,6 +1595,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x80085203 + RNDADDTOENTCNT = 0x80045201 + RNDCLEARPOOL = 0x20005206 + RNDGETENTCNT = 0x40045200 + RNDGETPOOL = 0x40085202 + RNDRESEEDCRNG = 0x20005207 + RNDZAPENTCNT = 0x20005204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1732,6 +1809,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x80 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1893,6 +1972,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2013,7 +2103,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x5407 TCGETA = 0x5401 TCGETS = 0x540d @@ -2026,6 +2116,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2040,6 +2131,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2059,6 +2151,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2073,6 +2168,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x5410 TCSBRK = 0x5405 TCSBRKP = 0x5486 @@ -2086,6 +2182,7 @@ const ( TCSETSW = 0x540f TCSETSW2 = 0x8030542c TCXONC = 0x5406 + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x80047478 TIOCEXCL = 0x740d @@ -2094,6 +2191,7 @@ const ( TIOCGETP = 0x7408 TIOCGEXCL = 0x40045440 TIOCGICOUNT = 0x5492 + TIOCGISO7816 = 0x40285442 TIOCGLCKTRMIOS = 0x548b TIOCGLTC = 0x7474 TIOCGPGRP = 0x40047477 @@ -2150,6 +2248,7 @@ const ( TIOCSETN = 0x740a TIOCSETP = 0x7409 TIOCSIG = 0x80045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x548c TIOCSLTC = 0x7475 TIOCSPGRP = 0x80047476 @@ -2191,6 +2290,7 @@ const ( TUNGETVNETBE = 0x400454df TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd + TUNSETCARRIER = 0x800454e2 TUNSETDEBUG = 0x800454c9 TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce @@ -2381,6 +2481,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 9c293ed13c57..67336da6cd5f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x2000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1099,6 +1160,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1120,7 +1182,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1242,6 +1304,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1383,6 +1446,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1422,6 +1491,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1525,6 +1595,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x80085203 + RNDADDTOENTCNT = 0x80045201 + RNDCLEARPOOL = 0x20005206 + RNDGETENTCNT = 0x40045200 + RNDGETPOOL = 0x40085202 + RNDRESEEDCRNG = 0x20005207 + RNDZAPENTCNT = 0x20005204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1732,6 +1809,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x80 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1893,6 +1972,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2013,7 +2103,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x5407 TCGETA = 0x5401 TCGETS = 0x540d @@ -2026,6 +2116,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2040,6 +2131,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2059,6 +2151,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2073,6 +2168,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x5410 TCSBRK = 0x5405 TCSBRKP = 0x5486 @@ -2086,6 +2182,7 @@ const ( TCSETSW = 0x540f TCSETSW2 = 0x8030542c TCXONC = 0x5406 + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x80047478 TIOCEXCL = 0x740d @@ -2094,6 +2191,7 @@ const ( TIOCGETP = 0x7408 TIOCGEXCL = 0x40045440 TIOCGICOUNT = 0x5492 + TIOCGISO7816 = 0x40285442 TIOCGLCKTRMIOS = 0x548b TIOCGLTC = 0x7474 TIOCGPGRP = 0x40047477 @@ -2150,6 +2248,7 @@ const ( TIOCSETN = 0x740a TIOCSETP = 0x7409 TIOCSIG = 0x80045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x548c TIOCSLTC = 0x7475 TIOCSPGRP = 0x80047476 @@ -2191,6 +2290,7 @@ const ( TUNGETVNETBE = 0x400454df TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd + TUNSETCARRIER = 0x800454e2 TUNSETDEBUG = 0x800454c9 TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce @@ -2381,6 +2481,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index e2162508c8e9..af030dcbb0a6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x2000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1099,6 +1160,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1120,7 +1182,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1242,6 +1304,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1383,6 +1446,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1422,6 +1491,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1525,6 +1595,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x80085203 + RNDADDTOENTCNT = 0x80045201 + RNDCLEARPOOL = 0x20005206 + RNDGETENTCNT = 0x40045200 + RNDGETPOOL = 0x40085202 + RNDRESEEDCRNG = 0x20005207 + RNDZAPENTCNT = 0x20005204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1732,6 +1809,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x80 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1893,6 +1972,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2013,7 +2103,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x5407 TCGETA = 0x5401 TCGETS = 0x540d @@ -2026,6 +2116,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2040,6 +2131,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2059,6 +2151,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2073,6 +2168,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x5410 TCSBRK = 0x5405 TCSBRKP = 0x5486 @@ -2086,6 +2182,7 @@ const ( TCSETSW = 0x540f TCSETSW2 = 0x8030542c TCXONC = 0x5406 + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x80047478 TIOCEXCL = 0x740d @@ -2094,6 +2191,7 @@ const ( TIOCGETP = 0x7408 TIOCGEXCL = 0x40045440 TIOCGICOUNT = 0x5492 + TIOCGISO7816 = 0x40285442 TIOCGLCKTRMIOS = 0x548b TIOCGLTC = 0x7474 TIOCGPGRP = 0x40047477 @@ -2150,6 +2248,7 @@ const ( TIOCSETN = 0x740a TIOCSETP = 0x7409 TIOCSIG = 0x80045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x548c TIOCSLTC = 0x7475 TIOCSPGRP = 0x80047476 @@ -2191,6 +2290,7 @@ const ( TUNGETVNETBE = 0x400454df TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd + TUNSETCARRIER = 0x800454e2 TUNSETDEBUG = 0x800454c9 TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce @@ -2381,6 +2481,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 836c0c654edb..be225da7d914 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x2000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1099,6 +1160,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1120,7 +1182,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1242,6 +1304,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1383,6 +1446,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1422,6 +1491,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1525,6 +1595,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x80085203 + RNDADDTOENTCNT = 0x80045201 + RNDCLEARPOOL = 0x20005206 + RNDGETENTCNT = 0x40045200 + RNDGETPOOL = 0x40085202 + RNDRESEEDCRNG = 0x20005207 + RNDZAPENTCNT = 0x20005204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1732,6 +1809,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x80 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1893,6 +1972,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2013,7 +2103,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x5407 TCGETA = 0x5401 TCGETS = 0x540d @@ -2026,6 +2116,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2040,6 +2131,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2059,6 +2151,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2073,6 +2168,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x5410 TCSBRK = 0x5405 TCSBRKP = 0x5486 @@ -2086,6 +2182,7 @@ const ( TCSETSW = 0x540f TCSETSW2 = 0x8030542c TCXONC = 0x5406 + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x80047478 TIOCEXCL = 0x740d @@ -2094,6 +2191,7 @@ const ( TIOCGETP = 0x7408 TIOCGEXCL = 0x40045440 TIOCGICOUNT = 0x5492 + TIOCGISO7816 = 0x40285442 TIOCGLCKTRMIOS = 0x548b TIOCGLTC = 0x7474 TIOCGPGRP = 0x40047477 @@ -2150,6 +2248,7 @@ const ( TIOCSETN = 0x740a TIOCSETP = 0x7409 TIOCSIG = 0x80045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x548c TIOCSLTC = 0x7475 TIOCSPGRP = 0x80047476 @@ -2191,6 +2290,7 @@ const ( TUNGETVNETBE = 0x400454df TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd + TUNSETCARRIER = 0x800454e2 TUNSETDEBUG = 0x800454c9 TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce @@ -2381,6 +2481,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 7ca61843172d..fcbc70173a07 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x3000 CREAD = 0x800 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x4000 FFDLY = 0x4000 FLUSHO = 0x800000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1098,6 +1159,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1119,7 +1181,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1243,6 +1305,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1385,6 +1448,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1424,6 +1493,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1502,6 +1572,8 @@ const ( PTRACE_SINGLEBLOCK = 0x100 PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 + PTRACE_SYSEMU = 0x1d + PTRACE_SYSEMU_SINGLESTEP = 0x1e PTRACE_TRACEME = 0x0 PT_CCR = 0x26 PT_CTR = 0x23 @@ -1581,6 +1653,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x80085203 + RNDADDTOENTCNT = 0x80045201 + RNDCLEARPOOL = 0x20005206 + RNDGETENTCNT = 0x40045200 + RNDGETPOOL = 0x40085202 + RNDRESEEDCRNG = 0x20005207 + RNDZAPENTCNT = 0x20005204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1788,6 +1867,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x800 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1949,6 +2030,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2068,7 +2160,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x2000741f TCGETA = 0x40147417 TCGETS = 0x402c7413 @@ -2080,6 +2172,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2094,6 +2187,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2113,6 +2207,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2127,6 +2224,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x2000741d TCSBRKP = 0x5425 @@ -2137,6 +2235,7 @@ const ( TCSETSF = 0x802c7416 TCSETSW = 0x802c7415 TCXONC = 0x2000741e + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -2146,6 +2245,7 @@ const ( TIOCGETP = 0x40067408 TIOCGEXCL = 0x40045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x40285442 TIOCGLCKTRMIOS = 0x5456 TIOCGLTC = 0x40067474 TIOCGPGRP = 0x40047477 @@ -2206,6 +2306,7 @@ const ( TIOCSETN = 0x8006740a TIOCSETP = 0x80067409 TIOCSIG = 0x80045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x5457 TIOCSLTC = 0x80067475 TIOCSPGRP = 0x80047476 @@ -2249,6 +2350,7 @@ const ( TUNGETVNETBE = 0x400454df TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd + TUNSETCARRIER = 0x800454e2 TUNSETDEBUG = 0x800454c9 TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce @@ -2438,6 +2540,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0xc00 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 839ac214cd18..5cd3b4ed0e6f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x3000 CREAD = 0x800 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x4000 FFDLY = 0x4000 FLUSHO = 0x800000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1098,6 +1159,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1119,7 +1181,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1243,6 +1305,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1385,6 +1448,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1424,6 +1493,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1502,6 +1572,8 @@ const ( PTRACE_SINGLEBLOCK = 0x100 PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 + PTRACE_SYSEMU = 0x1d + PTRACE_SYSEMU_SINGLESTEP = 0x1e PTRACE_TRACEME = 0x0 PT_CCR = 0x26 PT_CTR = 0x23 @@ -1581,6 +1653,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x80085203 + RNDADDTOENTCNT = 0x80045201 + RNDCLEARPOOL = 0x20005206 + RNDGETENTCNT = 0x40045200 + RNDGETPOOL = 0x40085202 + RNDRESEEDCRNG = 0x20005207 + RNDZAPENTCNT = 0x20005204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1788,6 +1867,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x800 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1949,6 +2030,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2068,7 +2160,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x2000741f TCGETA = 0x40147417 TCGETS = 0x402c7413 @@ -2080,6 +2172,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2094,6 +2187,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2113,6 +2207,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2127,6 +2224,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x2000741d TCSBRKP = 0x5425 @@ -2137,6 +2235,7 @@ const ( TCSETSF = 0x802c7416 TCSETSW = 0x802c7415 TCXONC = 0x2000741e + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -2146,6 +2245,7 @@ const ( TIOCGETP = 0x40067408 TIOCGEXCL = 0x40045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x40285442 TIOCGLCKTRMIOS = 0x5456 TIOCGLTC = 0x40067474 TIOCGPGRP = 0x40047477 @@ -2206,6 +2306,7 @@ const ( TIOCSETN = 0x8006740a TIOCSETP = 0x80067409 TIOCSIG = 0x80045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x5457 TIOCSLTC = 0x80067475 TIOCSPGRP = 0x80047476 @@ -2249,6 +2350,7 @@ const ( TUNGETVNETBE = 0x400454df TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd + TUNSETCARRIER = 0x800454e2 TUNSETDEBUG = 0x800454c9 TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce @@ -2438,6 +2540,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0xc00 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index a747aa1b7133..0465451e884f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1099,6 +1160,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1120,7 +1182,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1242,6 +1304,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1383,6 +1446,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1422,6 +1491,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1513,6 +1583,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x40085203 + RNDADDTOENTCNT = 0x40045201 + RNDCLEARPOOL = 0x5206 + RNDGETENTCNT = 0x80045200 + RNDGETPOOL = 0x80085202 + RNDRESEEDCRNG = 0x5207 + RNDZAPENTCNT = 0x5204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1720,6 +1797,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x800 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1881,6 +1960,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2000,7 +2090,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -2014,6 +2104,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2028,6 +2119,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2047,6 +2139,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2061,6 +2156,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x5409 TCSBRKP = 0x5425 @@ -2077,6 +2173,7 @@ const ( TCSETXF = 0x5434 TCSETXW = 0x5435 TCXONC = 0x540a + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -2084,6 +2181,7 @@ const ( TIOCGETD = 0x5424 TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x80285442 TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f TIOCGPKT = 0x80045438 @@ -2137,6 +2235,7 @@ const ( TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x5457 TIOCSPGRP = 0x5410 TIOCSPTLCK = 0x40045431 @@ -2177,6 +2276,7 @@ const ( TUNGETVNETBE = 0x800454df TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd + TUNSETCARRIER = 0x400454e2 TUNSETDEBUG = 0x400454c9 TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce @@ -2366,6 +2466,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 96aff508322f..e1592a17a317 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -174,6 +174,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 @@ -319,6 +320,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -486,12 +491,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -513,7 +563,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -638,7 +688,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -706,6 +756,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -777,6 +828,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -912,6 +964,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -921,6 +978,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1099,6 +1160,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1120,7 +1182,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1242,6 +1304,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1383,6 +1446,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1422,6 +1491,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1586,6 +1656,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x40085203 + RNDADDTOENTCNT = 0x40045201 + RNDCLEARPOOL = 0x5206 + RNDGETENTCNT = 0x80045200 + RNDGETPOOL = 0x80085202 + RNDRESEEDCRNG = 0x5207 + RNDZAPENTCNT = 0x5204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1793,6 +1870,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x80000 + SFD_NONBLOCK = 0x800 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1954,6 +2033,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 @@ -2073,7 +2163,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -2087,6 +2177,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2101,6 +2192,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2120,6 +2212,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2134,6 +2229,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x5409 TCSBRKP = 0x5425 @@ -2150,6 +2246,7 @@ const ( TCSETXF = 0x5434 TCSETXW = 0x5435 TCXONC = 0x540a + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -2157,6 +2254,7 @@ const ( TIOCGETD = 0x5424 TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x80285442 TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f TIOCGPKT = 0x80045438 @@ -2210,6 +2308,7 @@ const ( TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 + TIOCSISO7816 = 0xc0285443 TIOCSLCKTRMIOS = 0x5457 TIOCSPGRP = 0x5410 TIOCSPTLCK = 0x40045431 @@ -2250,6 +2349,7 @@ const ( TUNGETVNETBE = 0x800454df TUNGETVNETHDRSZ = 0x800454d7 TUNGETVNETLE = 0x800454dd + TUNSETCARRIER = 0x400454e2 TUNSETDEBUG = 0x400454c9 TUNSETFILTEREBPF = 0x800454e1 TUNSETGROUP = 0x400454ce @@ -2439,6 +2539,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 ) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 38cdd81a3e98..4be507343cdd 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -41,7 +41,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2c + AF_MAX = 0x2d AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -177,6 +177,7 @@ const ( B9600 = 0xd BALLOON_KVM_MAGIC = 0x13661366 BDEVFS_MAGIC = 0x62646576 + BINDERFS_SUPER_MAGIC = 0x6c6f6f70 BINFMTFS_MAGIC = 0x42494e4d BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 @@ -322,6 +323,10 @@ const ( CRDLY = 0x600 CREAD = 0x80 CRTSCTS = 0x80000000 + CRYPTO_MAX_NAME = 0x40 + CRYPTO_MSG_MAX = 0x15 + CRYPTO_NR_MSGTYPES = 0x6 + CRYPTO_REPORT_MAXSIZE = 0x160 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -490,12 +495,57 @@ const ( FALLOC_FL_PUNCH_HOLE = 0x2 FALLOC_FL_UNSHARE_RANGE = 0x40 FALLOC_FL_ZERO_RANGE = 0x10 + FANOTIFY_METADATA_VERSION = 0x3 + FAN_ACCESS = 0x1 + FAN_ACCESS_PERM = 0x20000 + FAN_ALLOW = 0x1 + FAN_ALL_CLASS_BITS = 0xc + FAN_ALL_EVENTS = 0x3b + FAN_ALL_INIT_FLAGS = 0x3f + FAN_ALL_MARK_FLAGS = 0xff + FAN_ALL_OUTGOING_EVENTS = 0x3403b + FAN_ALL_PERM_EVENTS = 0x30000 + FAN_AUDIT = 0x10 + FAN_CLASS_CONTENT = 0x4 + FAN_CLASS_NOTIF = 0x0 + FAN_CLASS_PRE_CONTENT = 0x8 + FAN_CLOEXEC = 0x1 + FAN_CLOSE = 0x18 + FAN_CLOSE_NOWRITE = 0x10 + FAN_CLOSE_WRITE = 0x8 + FAN_DENY = 0x2 + FAN_ENABLE_AUDIT = 0x40 + FAN_EVENT_METADATA_LEN = 0x18 + FAN_EVENT_ON_CHILD = 0x8000000 + FAN_MARK_ADD = 0x1 + FAN_MARK_DONT_FOLLOW = 0x4 + FAN_MARK_FILESYSTEM = 0x100 + FAN_MARK_FLUSH = 0x80 + FAN_MARK_IGNORED_MASK = 0x20 + FAN_MARK_IGNORED_SURV_MODIFY = 0x40 + FAN_MARK_INODE = 0x0 + FAN_MARK_MOUNT = 0x10 + FAN_MARK_ONLYDIR = 0x8 + FAN_MARK_REMOVE = 0x2 + FAN_MODIFY = 0x2 + FAN_NOFD = -0x1 + FAN_NONBLOCK = 0x2 + FAN_ONDIR = 0x40000000 + FAN_OPEN = 0x20 + FAN_OPEN_EXEC = 0x1000 + FAN_OPEN_EXEC_PERM = 0x40000 + FAN_OPEN_PERM = 0x10000 + FAN_Q_OVERFLOW = 0x4000 + FAN_REPORT_TID = 0x100 + FAN_UNLIMITED_MARKS = 0x20 + FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 FF0 = 0x0 FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_ADIANTUM = 0x9 FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 @@ -517,7 +567,7 @@ const ( FS_POLICY_FLAGS_PAD_4 = 0x0 FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 - FS_POLICY_FLAGS_VALID = 0x3 + FS_POLICY_FLAGS_VALID = 0x7 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 F_DUPFD = 0x0 @@ -642,7 +692,7 @@ const ( IFA_F_STABLE_PRIVACY = 0x800 IFA_F_TEMPORARY = 0x1 IFA_F_TENTATIVE = 0x40 - IFA_MAX = 0x9 + IFA_MAX = 0xa IFF_ALLMULTI = 0x200 IFF_ATTACH_QUEUE = 0x200 IFF_AUTOMEDIA = 0x4000 @@ -710,6 +760,7 @@ const ( IN_ISDIR = 0x40000000 IN_LOOPBACKNET = 0x7f IN_MASK_ADD = 0x20000000 + IN_MASK_CREATE = 0x10000000 IN_MODIFY = 0x2 IN_MOVE = 0xc0 IN_MOVED_FROM = 0x40 @@ -781,6 +832,7 @@ const ( IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 + IPV6_MULTICAST_ALL = 0x1d IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 @@ -916,6 +968,11 @@ const ( KEYCTL_JOIN_SESSION_KEYRING = 0x1 KEYCTL_LINK = 0x8 KEYCTL_NEGATE = 0xd + KEYCTL_PKEY_DECRYPT = 0x1a + KEYCTL_PKEY_ENCRYPT = 0x19 + KEYCTL_PKEY_QUERY = 0x18 + KEYCTL_PKEY_SIGN = 0x1b + KEYCTL_PKEY_VERIFY = 0x1c KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 KEYCTL_RESTRICT_KEYRING = 0x1d @@ -925,6 +982,10 @@ const ( KEYCTL_SETPERM = 0x5 KEYCTL_SET_REQKEY_KEYRING = 0xe KEYCTL_SET_TIMEOUT = 0xf + KEYCTL_SUPPORTS_DECRYPT = 0x2 + KEYCTL_SUPPORTS_ENCRYPT = 0x1 + KEYCTL_SUPPORTS_SIGN = 0x4 + KEYCTL_SUPPORTS_VERIFY = 0x8 KEYCTL_UNLINK = 0x9 KEYCTL_UPDATE = 0x2 KEY_REQKEY_DEFL_DEFAULT = 0x0 @@ -1103,6 +1164,7 @@ const ( NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 + NETLINK_GET_STRICT_CHK = 0xc NETLINK_INET_DIAG = 0x4 NETLINK_IP6_FW = 0xd NETLINK_ISCSI = 0x8 @@ -1124,7 +1186,7 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NETNSA_MAX = 0x3 + NETNSA_MAX = 0x5 NETNSA_NSID_NOT_ASSIGNED = -0x1 NFNETLINK_V0 = 0x0 NFNLGRP_ACCT_QUOTA = 0x8 @@ -1246,6 +1308,7 @@ const ( PACKET_FASTROUTE = 0x6 PACKET_HDRLEN = 0xb PACKET_HOST = 0x0 + PACKET_IGNORE_OUTGOING = 0x17 PACKET_KERNEL = 0x7 PACKET_LOOPBACK = 0x5 PACKET_LOSS = 0xe @@ -1387,6 +1450,12 @@ const ( PR_MCE_KILL_SET = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b + PR_PAC_APDAKEY = 0x4 + PR_PAC_APDBKEY = 0x8 + PR_PAC_APGAKEY = 0x10 + PR_PAC_APIAKEY = 0x1 + PR_PAC_APIBKEY = 0x2 + PR_PAC_RESET_KEYS = 0x36 PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_DUMPABLE = 0x4 PR_SET_ENDIAN = 0x14 @@ -1426,6 +1495,7 @@ const ( PR_SPEC_DISABLE = 0x4 PR_SPEC_ENABLE = 0x2 PR_SPEC_FORCE_DISABLE = 0x8 + PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_PRCTL = 0x1 PR_SPEC_STORE_BYPASS = 0x0 @@ -1578,6 +1648,13 @@ const ( RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 RLIM_INFINITY = 0xffffffffffffffff + RNDADDENTROPY = 0x80085203 + RNDADDTOENTCNT = 0x80045201 + RNDCLEARPOOL = 0x20005206 + RNDGETENTCNT = 0x40045200 + RNDGETPOOL = 0x40085202 + RNDRESEEDCRNG = 0x20005207 + RNDZAPENTCNT = 0x20005204 RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 @@ -1785,6 +1862,8 @@ const ( SECCOMP_MODE_STRICT = 0x1 SECURITYFS_MAGIC = 0x73636673 SELINUX_MAGIC = 0xf97cff8c + SFD_CLOEXEC = 0x400000 + SFD_NONBLOCK = 0x4000 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1946,6 +2025,17 @@ const ( SO_DETACH_FILTER = 0x1b SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 + SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 + SO_EE_CODE_TXTIME_MISSED = 0x2 + SO_EE_CODE_ZEROCOPY_COPIED = 0x1 + SO_EE_ORIGIN_ICMP = 0x2 + SO_EE_ORIGIN_ICMP6 = 0x3 + SO_EE_ORIGIN_LOCAL = 0x1 + SO_EE_ORIGIN_NONE = 0x0 + SO_EE_ORIGIN_TIMESTAMPING = 0x4 + SO_EE_ORIGIN_TXSTATUS = 0x4 + SO_EE_ORIGIN_TXTIME = 0x6 + SO_EE_ORIGIN_ZEROCOPY = 0x5 SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x33 @@ -2065,7 +2155,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0x8 + TASKSTATS_VERSION = 0x9 TCFLSH = 0x20005407 TCGETA = 0x40125401 TCGETS = 0x40245408 @@ -2078,6 +2168,7 @@ const ( TCOOFF = 0x0 TCOON = 0x1 TCP_CC_INFO = 0x1a + TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -2092,6 +2183,7 @@ const ( TCP_FASTOPEN_KEY = 0x21 TCP_FASTOPEN_NO_COOKIE = 0x22 TCP_INFO = 0xb + TCP_INQ = 0x24 TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 TCP_KEEPINTVL = 0x5 @@ -2111,6 +2203,9 @@ const ( TCP_QUEUE_SEQ = 0x15 TCP_QUICKACK = 0xc TCP_REPAIR = 0x13 + TCP_REPAIR_OFF = 0x0 + TCP_REPAIR_OFF_NO_WP = -0x1 + TCP_REPAIR_ON = 0x1 TCP_REPAIR_OPTIONS = 0x16 TCP_REPAIR_QUEUE = 0x14 TCP_REPAIR_WINDOW = 0x1d @@ -2125,6 +2220,7 @@ const ( TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa + TCP_ZEROCOPY_RECEIVE = 0x23 TCSAFLUSH = 0x2 TCSBRK = 0x20005405 TCSBRKP = 0x5425 @@ -2138,6 +2234,7 @@ const ( TCSETSW = 0x8024540a TCSETSW2 = 0x802c540e TCXONC = 0x20005406 + TIMER_ABSTIME = 0x1 TIOCCBRK = 0x2000747a TIOCCONS = 0x20007424 TIOCEXCL = 0x2000740d @@ -2145,6 +2242,7 @@ const ( TIOCGETD = 0x40047400 TIOCGEXCL = 0x40045440 TIOCGICOUNT = 0x545d + TIOCGISO7816 = 0x40285443 TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x40047483 TIOCGPKT = 0x40045438 @@ -2197,6 +2295,7 @@ const ( TIOCSERSWILD = 0x5455 TIOCSETD = 0x80047401 TIOCSIG = 0x80047488 + TIOCSISO7816 = 0xc0285444 TIOCSLCKTRMIOS = 0x5457 TIOCSPGRP = 0x80047482 TIOCSPTLCK = 0x80047487 @@ -2239,6 +2338,7 @@ const ( TUNGETVNETBE = 0x400454df TUNGETVNETHDRSZ = 0x400454d7 TUNGETVNETLE = 0x400454dd + TUNSETCARRIER = 0x800454e2 TUNSETDEBUG = 0x800454c9 TUNSETFILTEREBPF = 0x400454e1 TUNSETGROUP = 0x800454ce @@ -2428,6 +2528,7 @@ const ( XDP_UMEM_REG = 0x4 XDP_ZEROCOPY = 0x4 XENFS_SUPER_MAGIC = 0xabba1974 + XFS_SUPER_MAGIC = 0x58465342 XTABS = 0x1800 ZSMALLOC_MAGIC = 0x58295829 __TIOCFLUSH = 0x80047410 diff --git a/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go new file mode 100644 index 000000000000..fb6c60441daa --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go @@ -0,0 +1,1762 @@ +// mkerrors.sh -m64 +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build arm64,netbsd + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs -- -m64 _const.go + +package unix + +import "syscall" + +const ( + AF_APPLETALK = 0x10 + AF_ARP = 0x1c + AF_BLUETOOTH = 0x1f + AF_CCITT = 0xa + AF_CHAOS = 0x5 + AF_CNT = 0x15 + AF_COIP = 0x14 + AF_DATAKIT = 0x9 + AF_DECnet = 0xc + AF_DLI = 0xd + AF_E164 = 0x1a + AF_ECMA = 0x8 + AF_HYLINK = 0xf + AF_IEEE80211 = 0x20 + AF_IMPLINK = 0x3 + AF_INET = 0x2 + AF_INET6 = 0x18 + AF_IPX = 0x17 + AF_ISDN = 0x1a + AF_ISO = 0x7 + AF_LAT = 0xe + AF_LINK = 0x12 + AF_LOCAL = 0x1 + AF_MAX = 0x23 + AF_MPLS = 0x21 + AF_NATM = 0x1b + AF_NS = 0x6 + AF_OROUTE = 0x11 + AF_OSI = 0x7 + AF_PUP = 0x4 + AF_ROUTE = 0x22 + AF_SNA = 0xb + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + ARPHRD_ARCNET = 0x7 + ARPHRD_ETHER = 0x1 + ARPHRD_FRELAY = 0xf + ARPHRD_IEEE1394 = 0x18 + ARPHRD_IEEE802 = 0x6 + ARPHRD_STRIP = 0x17 + B0 = 0x0 + B110 = 0x6e + B115200 = 0x1c200 + B1200 = 0x4b0 + B134 = 0x86 + B14400 = 0x3840 + B150 = 0x96 + B1800 = 0x708 + B19200 = 0x4b00 + B200 = 0xc8 + B230400 = 0x38400 + B2400 = 0x960 + B28800 = 0x7080 + B300 = 0x12c + B38400 = 0x9600 + B460800 = 0x70800 + B4800 = 0x12c0 + B50 = 0x32 + B57600 = 0xe100 + B600 = 0x258 + B7200 = 0x1c20 + B75 = 0x4b + B76800 = 0x12c00 + B921600 = 0xe1000 + B9600 = 0x2580 + BIOCFEEDBACK = 0x8004427d + BIOCFLUSH = 0x20004268 + BIOCGBLEN = 0x40044266 + BIOCGDLT = 0x4004426a + BIOCGDLTLIST = 0xc0104277 + BIOCGETIF = 0x4090426b + BIOCGFEEDBACK = 0x4004427c + BIOCGHDRCMPLT = 0x40044274 + BIOCGRTIMEOUT = 0x4010427b + BIOCGSEESENT = 0x40044278 + BIOCGSTATS = 0x4080426f + BIOCGSTATSOLD = 0x4008426f + BIOCIMMEDIATE = 0x80044270 + BIOCPROMISC = 0x20004269 + BIOCSBLEN = 0xc0044266 + BIOCSDLT = 0x80044276 + BIOCSETF = 0x80104267 + BIOCSETIF = 0x8090426c + BIOCSFEEDBACK = 0x8004427d + BIOCSHDRCMPLT = 0x80044275 + BIOCSRTIMEOUT = 0x8010427a + BIOCSSEESENT = 0x80044279 + BIOCSTCPF = 0x80104272 + BIOCSUDPF = 0x80104273 + BIOCVERSION = 0x40044271 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALIGNMENT = 0x8 + BPF_ALIGNMENT32 = 0x4 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_DFLTBUFSIZE = 0x100000 + BPF_DIV = 0x30 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXBUFSIZE = 0x1000000 + BPF_MAXINSNS = 0x200 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINBUFSIZE = 0x20 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_OR = 0x40 + BPF_RELEASE = 0x30bb6 + BPF_RET = 0x6 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_W = 0x0 + BPF_X = 0x8 + BRKINT = 0x2 + CFLUSH = 0xf + CLOCAL = 0x8000 + CLONE_CSIGNAL = 0xff + CLONE_FILES = 0x400 + CLONE_FS = 0x200 + CLONE_PID = 0x1000 + CLONE_PTRACE = 0x2000 + CLONE_SIGHAND = 0x800 + CLONE_VFORK = 0x4000 + CLONE_VM = 0x100 + CREAD = 0x800 + CRTSCTS = 0x10000 + CS5 = 0x0 + CS6 = 0x100 + CS7 = 0x200 + CS8 = 0x300 + CSIZE = 0x300 + CSTART = 0x11 + CSTATUS = 0x14 + CSTOP = 0x13 + CSTOPB = 0x400 + CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 + CTL_MAXNAME = 0xc + CTL_NET = 0x4 + CTL_QUERY = -0x2 + DIOCBSFLUSH = 0x20006478 + DLT_A429 = 0xb8 + DLT_A653_ICM = 0xb9 + DLT_AIRONET_HEADER = 0x78 + DLT_AOS = 0xde + DLT_APPLE_IP_OVER_IEEE1394 = 0x8a + DLT_ARCNET = 0x7 + DLT_ARCNET_LINUX = 0x81 + DLT_ATM_CLIP = 0x13 + DLT_ATM_RFC1483 = 0xb + DLT_AURORA = 0x7e + DLT_AX25 = 0x3 + DLT_AX25_KISS = 0xca + DLT_BACNET_MS_TP = 0xa5 + DLT_BLUETOOTH_HCI_H4 = 0xbb + DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9 + DLT_CAN20B = 0xbe + DLT_CAN_SOCKETCAN = 0xe3 + DLT_CHAOS = 0x5 + DLT_CISCO_IOS = 0x76 + DLT_C_HDLC = 0x68 + DLT_C_HDLC_WITH_DIR = 0xcd + DLT_DECT = 0xdd + DLT_DOCSIS = 0x8f + DLT_ECONET = 0x73 + DLT_EN10MB = 0x1 + DLT_EN3MB = 0x2 + DLT_ENC = 0x6d + DLT_ERF = 0xc5 + DLT_ERF_ETH = 0xaf + DLT_ERF_POS = 0xb0 + DLT_FC_2 = 0xe0 + DLT_FC_2_WITH_FRAME_DELIMS = 0xe1 + DLT_FDDI = 0xa + DLT_FLEXRAY = 0xd2 + DLT_FRELAY = 0x6b + DLT_FRELAY_WITH_DIR = 0xce + DLT_GCOM_SERIAL = 0xad + DLT_GCOM_T1E1 = 0xac + DLT_GPF_F = 0xab + DLT_GPF_T = 0xaa + DLT_GPRS_LLC = 0xa9 + DLT_GSMTAP_ABIS = 0xda + DLT_GSMTAP_UM = 0xd9 + DLT_HDLC = 0x10 + DLT_HHDLC = 0x79 + DLT_HIPPI = 0xf + DLT_IBM_SN = 0x92 + DLT_IBM_SP = 0x91 + DLT_IEEE802 = 0x6 + DLT_IEEE802_11 = 0x69 + DLT_IEEE802_11_RADIO = 0x7f + DLT_IEEE802_11_RADIO_AVS = 0xa3 + DLT_IEEE802_15_4 = 0xc3 + DLT_IEEE802_15_4_LINUX = 0xbf + DLT_IEEE802_15_4_NONASK_PHY = 0xd7 + DLT_IEEE802_16_MAC_CPS = 0xbc + DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1 + DLT_IPMB = 0xc7 + DLT_IPMB_LINUX = 0xd1 + DLT_IPNET = 0xe2 + DLT_IPV4 = 0xe4 + DLT_IPV6 = 0xe5 + DLT_IP_OVER_FC = 0x7a + DLT_JUNIPER_ATM1 = 0x89 + DLT_JUNIPER_ATM2 = 0x87 + DLT_JUNIPER_CHDLC = 0xb5 + DLT_JUNIPER_ES = 0x84 + DLT_JUNIPER_ETHER = 0xb2 + DLT_JUNIPER_FRELAY = 0xb4 + DLT_JUNIPER_GGSN = 0x85 + DLT_JUNIPER_ISM = 0xc2 + DLT_JUNIPER_MFR = 0x86 + DLT_JUNIPER_MLFR = 0x83 + DLT_JUNIPER_MLPPP = 0x82 + DLT_JUNIPER_MONITOR = 0xa4 + DLT_JUNIPER_PIC_PEER = 0xae + DLT_JUNIPER_PPP = 0xb3 + DLT_JUNIPER_PPPOE = 0xa7 + DLT_JUNIPER_PPPOE_ATM = 0xa8 + DLT_JUNIPER_SERVICES = 0x88 + DLT_JUNIPER_ST = 0xc8 + DLT_JUNIPER_VP = 0xb7 + DLT_LAPB_WITH_DIR = 0xcf + DLT_LAPD = 0xcb + DLT_LIN = 0xd4 + DLT_LINUX_EVDEV = 0xd8 + DLT_LINUX_IRDA = 0x90 + DLT_LINUX_LAPD = 0xb1 + DLT_LINUX_SLL = 0x71 + DLT_LOOP = 0x6c + DLT_LTALK = 0x72 + DLT_MFR = 0xb6 + DLT_MOST = 0xd3 + DLT_MPLS = 0xdb + DLT_MTP2 = 0x8c + DLT_MTP2_WITH_PHDR = 0x8b + DLT_MTP3 = 0x8d + DLT_NULL = 0x0 + DLT_PCI_EXP = 0x7d + DLT_PFLOG = 0x75 + DLT_PFSYNC = 0x12 + DLT_PPI = 0xc0 + DLT_PPP = 0x9 + DLT_PPP_BSDOS = 0xe + DLT_PPP_ETHER = 0x33 + DLT_PPP_PPPD = 0xa6 + DLT_PPP_SERIAL = 0x32 + DLT_PPP_WITH_DIR = 0xcc + DLT_PRISM_HEADER = 0x77 + DLT_PRONET = 0x4 + DLT_RAIF1 = 0xc6 + DLT_RAW = 0xc + DLT_RAWAF_MASK = 0x2240000 + DLT_RIO = 0x7c + DLT_SCCP = 0x8e + DLT_SITA = 0xc4 + DLT_SLIP = 0x8 + DLT_SLIP_BSDOS = 0xd + DLT_SUNATM = 0x7b + DLT_SYMANTEC_FIREWALL = 0x63 + DLT_TZSP = 0x80 + DLT_USB = 0xba + DLT_USB_LINUX = 0xbd + DLT_USB_LINUX_MMAPPED = 0xdc + DLT_WIHART = 0xdf + DLT_X2E_SERIAL = 0xd5 + DLT_X2E_XORAYA = 0xd6 + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + DT_WHT = 0xe + ECHO = 0x8 + ECHOCTL = 0x40 + ECHOE = 0x2 + ECHOK = 0x4 + ECHOKE = 0x1 + ECHONL = 0x10 + ECHOPRT = 0x20 + EMUL_LINUX = 0x1 + EMUL_LINUX32 = 0x5 + EMUL_MAXID = 0x6 + ETHERCAP_JUMBO_MTU = 0x4 + ETHERCAP_VLAN_HWTAGGING = 0x2 + ETHERCAP_VLAN_MTU = 0x1 + ETHERMIN = 0x2e + ETHERMTU = 0x5dc + ETHERMTU_JUMBO = 0x2328 + ETHERTYPE_8023 = 0x4 + ETHERTYPE_AARP = 0x80f3 + ETHERTYPE_ACCTON = 0x8390 + ETHERTYPE_AEONIC = 0x8036 + ETHERTYPE_ALPHA = 0x814a + ETHERTYPE_AMBER = 0x6008 + ETHERTYPE_AMOEBA = 0x8145 + ETHERTYPE_APOLLO = 0x80f7 + ETHERTYPE_APOLLODOMAIN = 0x8019 + ETHERTYPE_APPLETALK = 0x809b + ETHERTYPE_APPLITEK = 0x80c7 + ETHERTYPE_ARGONAUT = 0x803a + ETHERTYPE_ARP = 0x806 + ETHERTYPE_AT = 0x809b + ETHERTYPE_ATALK = 0x809b + ETHERTYPE_ATOMIC = 0x86df + ETHERTYPE_ATT = 0x8069 + ETHERTYPE_ATTSTANFORD = 0x8008 + ETHERTYPE_AUTOPHON = 0x806a + ETHERTYPE_AXIS = 0x8856 + ETHERTYPE_BCLOOP = 0x9003 + ETHERTYPE_BOFL = 0x8102 + ETHERTYPE_CABLETRON = 0x7034 + ETHERTYPE_CHAOS = 0x804 + ETHERTYPE_COMDESIGN = 0x806c + ETHERTYPE_COMPUGRAPHIC = 0x806d + ETHERTYPE_COUNTERPOINT = 0x8062 + ETHERTYPE_CRONUS = 0x8004 + ETHERTYPE_CRONUSVLN = 0x8003 + ETHERTYPE_DCA = 0x1234 + ETHERTYPE_DDE = 0x807b + ETHERTYPE_DEBNI = 0xaaaa + ETHERTYPE_DECAM = 0x8048 + ETHERTYPE_DECCUST = 0x6006 + ETHERTYPE_DECDIAG = 0x6005 + ETHERTYPE_DECDNS = 0x803c + ETHERTYPE_DECDTS = 0x803e + ETHERTYPE_DECEXPER = 0x6000 + ETHERTYPE_DECLAST = 0x8041 + ETHERTYPE_DECLTM = 0x803f + ETHERTYPE_DECMUMPS = 0x6009 + ETHERTYPE_DECNETBIOS = 0x8040 + ETHERTYPE_DELTACON = 0x86de + ETHERTYPE_DIDDLE = 0x4321 + ETHERTYPE_DLOG1 = 0x660 + ETHERTYPE_DLOG2 = 0x661 + ETHERTYPE_DN = 0x6003 + ETHERTYPE_DOGFIGHT = 0x1989 + ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_ECMA = 0x803 + ETHERTYPE_ENCRYPT = 0x803d + ETHERTYPE_ES = 0x805d + ETHERTYPE_EXCELAN = 0x8010 + ETHERTYPE_EXPERDATA = 0x8049 + ETHERTYPE_FLIP = 0x8146 + ETHERTYPE_FLOWCONTROL = 0x8808 + ETHERTYPE_FRARP = 0x808 + ETHERTYPE_GENDYN = 0x8068 + ETHERTYPE_HAYES = 0x8130 + ETHERTYPE_HIPPI_FP = 0x8180 + ETHERTYPE_HITACHI = 0x8820 + ETHERTYPE_HP = 0x8005 + ETHERTYPE_IEEEPUP = 0xa00 + ETHERTYPE_IEEEPUPAT = 0xa01 + ETHERTYPE_IMLBL = 0x4c42 + ETHERTYPE_IMLBLDIAG = 0x424c + ETHERTYPE_IP = 0x800 + ETHERTYPE_IPAS = 0x876c + ETHERTYPE_IPV6 = 0x86dd + ETHERTYPE_IPX = 0x8137 + ETHERTYPE_IPXNEW = 0x8037 + ETHERTYPE_KALPANA = 0x8582 + ETHERTYPE_LANBRIDGE = 0x8038 + ETHERTYPE_LANPROBE = 0x8888 + ETHERTYPE_LAT = 0x6004 + ETHERTYPE_LBACK = 0x9000 + ETHERTYPE_LITTLE = 0x8060 + ETHERTYPE_LOGICRAFT = 0x8148 + ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MATRA = 0x807a + ETHERTYPE_MAX = 0xffff + ETHERTYPE_MERIT = 0x807c + ETHERTYPE_MICP = 0x873a + ETHERTYPE_MOPDL = 0x6001 + ETHERTYPE_MOPRC = 0x6002 + ETHERTYPE_MOTOROLA = 0x818d + ETHERTYPE_MPLS = 0x8847 + ETHERTYPE_MPLS_MCAST = 0x8848 + ETHERTYPE_MUMPS = 0x813f + ETHERTYPE_NBPCC = 0x3c04 + ETHERTYPE_NBPCLAIM = 0x3c09 + ETHERTYPE_NBPCLREQ = 0x3c05 + ETHERTYPE_NBPCLRSP = 0x3c06 + ETHERTYPE_NBPCREQ = 0x3c02 + ETHERTYPE_NBPCRSP = 0x3c03 + ETHERTYPE_NBPDG = 0x3c07 + ETHERTYPE_NBPDGB = 0x3c08 + ETHERTYPE_NBPDLTE = 0x3c0a + ETHERTYPE_NBPRAR = 0x3c0c + ETHERTYPE_NBPRAS = 0x3c0b + ETHERTYPE_NBPRST = 0x3c0d + ETHERTYPE_NBPSCD = 0x3c01 + ETHERTYPE_NBPVCD = 0x3c00 + ETHERTYPE_NBS = 0x802 + ETHERTYPE_NCD = 0x8149 + ETHERTYPE_NESTAR = 0x8006 + ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NOVELL = 0x8138 + ETHERTYPE_NS = 0x600 + ETHERTYPE_NSAT = 0x601 + ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NTRAILER = 0x10 + ETHERTYPE_OS9 = 0x7007 + ETHERTYPE_OS9NET = 0x7009 + ETHERTYPE_PACER = 0x80c6 + ETHERTYPE_PAE = 0x888e + ETHERTYPE_PCS = 0x4242 + ETHERTYPE_PLANNING = 0x8044 + ETHERTYPE_PPP = 0x880b + ETHERTYPE_PPPOE = 0x8864 + ETHERTYPE_PPPOEDISC = 0x8863 + ETHERTYPE_PRIMENTS = 0x7031 + ETHERTYPE_PUP = 0x200 + ETHERTYPE_PUPAT = 0x200 + ETHERTYPE_RACAL = 0x7030 + ETHERTYPE_RATIONAL = 0x8150 + ETHERTYPE_RAWFR = 0x6559 + ETHERTYPE_RCL = 0x1995 + ETHERTYPE_RDP = 0x8739 + ETHERTYPE_RETIX = 0x80f2 + ETHERTYPE_REVARP = 0x8035 + ETHERTYPE_SCA = 0x6007 + ETHERTYPE_SECTRA = 0x86db + ETHERTYPE_SECUREDATA = 0x876d + ETHERTYPE_SGITW = 0x817e + ETHERTYPE_SG_BOUNCE = 0x8016 + ETHERTYPE_SG_DIAG = 0x8013 + ETHERTYPE_SG_NETGAMES = 0x8014 + ETHERTYPE_SG_RESV = 0x8015 + ETHERTYPE_SIMNET = 0x5208 + ETHERTYPE_SLOWPROTOCOLS = 0x8809 + ETHERTYPE_SNA = 0x80d5 + ETHERTYPE_SNMP = 0x814c + ETHERTYPE_SONIX = 0xfaf5 + ETHERTYPE_SPIDER = 0x809f + ETHERTYPE_SPRITE = 0x500 + ETHERTYPE_STP = 0x8181 + ETHERTYPE_TALARIS = 0x812b + ETHERTYPE_TALARISMC = 0x852b + ETHERTYPE_TCPCOMP = 0x876b + ETHERTYPE_TCPSM = 0x9002 + ETHERTYPE_TEC = 0x814f + ETHERTYPE_TIGAN = 0x802f + ETHERTYPE_TRAIL = 0x1000 + ETHERTYPE_TRANSETHER = 0x6558 + ETHERTYPE_TYMSHARE = 0x802e + ETHERTYPE_UBBST = 0x7005 + ETHERTYPE_UBDEBUG = 0x900 + ETHERTYPE_UBDIAGLOOP = 0x7002 + ETHERTYPE_UBDL = 0x7000 + ETHERTYPE_UBNIU = 0x7001 + ETHERTYPE_UBNMC = 0x7003 + ETHERTYPE_VALID = 0x1600 + ETHERTYPE_VARIAN = 0x80dd + ETHERTYPE_VAXELN = 0x803b + ETHERTYPE_VEECO = 0x8067 + ETHERTYPE_VEXP = 0x805b + ETHERTYPE_VGLAB = 0x8131 + ETHERTYPE_VINES = 0xbad + ETHERTYPE_VINESECHO = 0xbaf + ETHERTYPE_VINESLOOP = 0xbae + ETHERTYPE_VITAL = 0xff00 + ETHERTYPE_VLAN = 0x8100 + ETHERTYPE_VLTLMAN = 0x8080 + ETHERTYPE_VPROD = 0x805c + ETHERTYPE_VURESERVED = 0x8147 + ETHERTYPE_WATERLOO = 0x8130 + ETHERTYPE_WELLFLEET = 0x8103 + ETHERTYPE_X25 = 0x805 + ETHERTYPE_X75 = 0x801 + ETHERTYPE_XNSSM = 0x9001 + ETHERTYPE_XTP = 0x817d + ETHER_ADDR_LEN = 0x6 + ETHER_CRC_LEN = 0x4 + ETHER_CRC_POLY_BE = 0x4c11db6 + ETHER_CRC_POLY_LE = 0xedb88320 + ETHER_HDR_LEN = 0xe + ETHER_MAX_LEN = 0x5ee + ETHER_MAX_LEN_JUMBO = 0x233a + ETHER_MIN_LEN = 0x40 + ETHER_PPPOE_ENCAP_LEN = 0x8 + ETHER_TYPE_LEN = 0x2 + ETHER_VLAN_ENCAP_LEN = 0x4 + EVFILT_AIO = 0x2 + EVFILT_PROC = 0x4 + EVFILT_READ = 0x0 + EVFILT_SIGNAL = 0x5 + EVFILT_SYSCOUNT = 0x7 + EVFILT_TIMER = 0x6 + EVFILT_VNODE = 0x3 + EVFILT_WRITE = 0x1 + EV_ADD = 0x1 + EV_CLEAR = 0x20 + EV_DELETE = 0x2 + EV_DISABLE = 0x8 + EV_ENABLE = 0x4 + EV_EOF = 0x8000 + EV_ERROR = 0x4000 + EV_FLAG1 = 0x2000 + EV_ONESHOT = 0x10 + EV_SYSFLAGS = 0xf000 + EXTA = 0x4b00 + EXTATTR_CMD_START = 0x1 + EXTATTR_CMD_STOP = 0x2 + EXTATTR_NAMESPACE_SYSTEM = 0x2 + EXTATTR_NAMESPACE_USER = 0x1 + EXTB = 0x9600 + EXTPROC = 0x800 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x100 + FLUSHO = 0x800000 + F_CLOSEM = 0xa + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0xc + F_FSCTL = -0x80000000 + F_FSDIRMASK = 0x70000000 + F_FSIN = 0x10000000 + F_FSINOUT = 0x30000000 + F_FSOUT = 0x20000000 + F_FSPRIV = 0x8000 + F_FSVOID = 0x40000000 + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLK = 0x7 + F_GETNOSIGPIPE = 0xd + F_GETOWN = 0x5 + F_MAXFD = 0xb + F_OK = 0x0 + F_PARAM_MASK = 0xfff + F_PARAM_MAX = 0xfff + F_RDLCK = 0x1 + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLK = 0x8 + F_SETLKW = 0x9 + F_SETNOSIGPIPE = 0xe + F_SETOWN = 0x6 + F_UNLCK = 0x2 + F_WRLCK = 0x3 + HUPCL = 0x4000 + HW_MACHINE = 0x1 + ICANON = 0x100 + ICMP6_FILTER = 0x12 + ICRNL = 0x100 + IEXTEN = 0x400 + IFAN_ARRIVAL = 0x0 + IFAN_DEPARTURE = 0x1 + IFA_ROUTE = 0x1 + IFF_ALLMULTI = 0x200 + IFF_BROADCAST = 0x2 + IFF_CANTCHANGE = 0x8f52 + IFF_DEBUG = 0x4 + IFF_LINK0 = 0x1000 + IFF_LINK1 = 0x2000 + IFF_LINK2 = 0x4000 + IFF_LOOPBACK = 0x8 + IFF_MULTICAST = 0x8000 + IFF_NOARP = 0x80 + IFF_NOTRAILERS = 0x20 + IFF_OACTIVE = 0x400 + IFF_POINTOPOINT = 0x10 + IFF_PROMISC = 0x100 + IFF_RUNNING = 0x40 + IFF_SIMPLEX = 0x800 + IFF_UP = 0x1 + IFNAMSIZ = 0x10 + IFT_1822 = 0x2 + IFT_A12MPPSWITCH = 0x82 + IFT_AAL2 = 0xbb + IFT_AAL5 = 0x31 + IFT_ADSL = 0x5e + IFT_AFLANE8023 = 0x3b + IFT_AFLANE8025 = 0x3c + IFT_ARAP = 0x58 + IFT_ARCNET = 0x23 + IFT_ARCNETPLUS = 0x24 + IFT_ASYNC = 0x54 + IFT_ATM = 0x25 + IFT_ATMDXI = 0x69 + IFT_ATMFUNI = 0x6a + IFT_ATMIMA = 0x6b + IFT_ATMLOGICAL = 0x50 + IFT_ATMRADIO = 0xbd + IFT_ATMSUBINTERFACE = 0x86 + IFT_ATMVCIENDPT = 0xc2 + IFT_ATMVIRTUAL = 0x95 + IFT_BGPPOLICYACCOUNTING = 0xa2 + IFT_BRIDGE = 0xd1 + IFT_BSC = 0x53 + IFT_CARP = 0xf8 + IFT_CCTEMUL = 0x3d + IFT_CEPT = 0x13 + IFT_CES = 0x85 + IFT_CHANNEL = 0x46 + IFT_CNR = 0x55 + IFT_COFFEE = 0x84 + IFT_COMPOSITELINK = 0x9b + IFT_DCN = 0x8d + IFT_DIGITALPOWERLINE = 0x8a + IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba + IFT_DLSW = 0x4a + IFT_DOCSCABLEDOWNSTREAM = 0x80 + IFT_DOCSCABLEMACLAYER = 0x7f + IFT_DOCSCABLEUPSTREAM = 0x81 + IFT_DOCSCABLEUPSTREAMCHANNEL = 0xcd + IFT_DS0 = 0x51 + IFT_DS0BUNDLE = 0x52 + IFT_DS1FDL = 0xaa + IFT_DS3 = 0x1e + IFT_DTM = 0x8c + IFT_DVBASILN = 0xac + IFT_DVBASIOUT = 0xad + IFT_DVBRCCDOWNSTREAM = 0x93 + IFT_DVBRCCMACLAYER = 0x92 + IFT_DVBRCCUPSTREAM = 0x94 + IFT_ECONET = 0xce + IFT_EON = 0x19 + IFT_EPLRS = 0x57 + IFT_ESCON = 0x49 + IFT_ETHER = 0x6 + IFT_FAITH = 0xf2 + IFT_FAST = 0x7d + IFT_FASTETHER = 0x3e + IFT_FASTETHERFX = 0x45 + IFT_FDDI = 0xf + IFT_FIBRECHANNEL = 0x38 + IFT_FRAMERELAYINTERCONNECT = 0x3a + IFT_FRAMERELAYMPI = 0x5c + IFT_FRDLCIENDPT = 0xc1 + IFT_FRELAY = 0x20 + IFT_FRELAYDCE = 0x2c + IFT_FRF16MFRBUNDLE = 0xa3 + IFT_FRFORWARD = 0x9e + IFT_G703AT2MB = 0x43 + IFT_G703AT64K = 0x42 + IFT_GIF = 0xf0 + IFT_GIGABITETHERNET = 0x75 + IFT_GR303IDT = 0xb2 + IFT_GR303RDT = 0xb1 + IFT_H323GATEKEEPER = 0xa4 + IFT_H323PROXY = 0xa5 + IFT_HDH1822 = 0x3 + IFT_HDLC = 0x76 + IFT_HDSL2 = 0xa8 + IFT_HIPERLAN2 = 0xb7 + IFT_HIPPI = 0x2f + IFT_HIPPIINTERFACE = 0x39 + IFT_HOSTPAD = 0x5a + IFT_HSSI = 0x2e + IFT_HY = 0xe + IFT_IBM370PARCHAN = 0x48 + IFT_IDSL = 0x9a + IFT_IEEE1394 = 0x90 + IFT_IEEE80211 = 0x47 + IFT_IEEE80212 = 0x37 + IFT_IEEE8023ADLAG = 0xa1 + IFT_IFGSN = 0x91 + IFT_IMT = 0xbe + IFT_INFINIBAND = 0xc7 + IFT_INTERLEAVE = 0x7c + IFT_IP = 0x7e + IFT_IPFORWARD = 0x8e + IFT_IPOVERATM = 0x72 + IFT_IPOVERCDLC = 0x6d + IFT_IPOVERCLAW = 0x6e + IFT_IPSWITCH = 0x4e + IFT_ISDN = 0x3f + IFT_ISDNBASIC = 0x14 + IFT_ISDNPRIMARY = 0x15 + IFT_ISDNS = 0x4b + IFT_ISDNU = 0x4c + IFT_ISO88022LLC = 0x29 + IFT_ISO88023 = 0x7 + IFT_ISO88024 = 0x8 + IFT_ISO88025 = 0x9 + IFT_ISO88025CRFPINT = 0x62 + IFT_ISO88025DTR = 0x56 + IFT_ISO88025FIBER = 0x73 + IFT_ISO88026 = 0xa + IFT_ISUP = 0xb3 + IFT_L2VLAN = 0x87 + IFT_L3IPVLAN = 0x88 + IFT_L3IPXVLAN = 0x89 + IFT_LAPB = 0x10 + IFT_LAPD = 0x4d + IFT_LAPF = 0x77 + IFT_LINEGROUP = 0xd2 + IFT_LOCALTALK = 0x2a + IFT_LOOP = 0x18 + IFT_MEDIAMAILOVERIP = 0x8b + IFT_MFSIGLINK = 0xa7 + IFT_MIOX25 = 0x26 + IFT_MODEM = 0x30 + IFT_MPC = 0x71 + IFT_MPLS = 0xa6 + IFT_MPLSTUNNEL = 0x96 + IFT_MSDSL = 0x8f + IFT_MVL = 0xbf + IFT_MYRINET = 0x63 + IFT_NFAS = 0xaf + IFT_NSIP = 0x1b + IFT_OPTICALCHANNEL = 0xc3 + IFT_OPTICALTRANSPORT = 0xc4 + IFT_OTHER = 0x1 + IFT_P10 = 0xc + IFT_P80 = 0xd + IFT_PARA = 0x22 + IFT_PFLOG = 0xf5 + IFT_PFSYNC = 0xf6 + IFT_PLC = 0xae + IFT_PON155 = 0xcf + IFT_PON622 = 0xd0 + IFT_POS = 0xab + IFT_PPP = 0x17 + IFT_PPPMULTILINKBUNDLE = 0x6c + IFT_PROPATM = 0xc5 + IFT_PROPBWAP2MP = 0xb8 + IFT_PROPCNLS = 0x59 + IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 + IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 + IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 + IFT_PROPMUX = 0x36 + IFT_PROPVIRTUAL = 0x35 + IFT_PROPWIRELESSP2P = 0x9d + IFT_PTPSERIAL = 0x16 + IFT_PVC = 0xf1 + IFT_Q2931 = 0xc9 + IFT_QLLC = 0x44 + IFT_RADIOMAC = 0xbc + IFT_RADSL = 0x5f + IFT_REACHDSL = 0xc0 + IFT_RFC1483 = 0x9f + IFT_RS232 = 0x21 + IFT_RSRB = 0x4f + IFT_SDLC = 0x11 + IFT_SDSL = 0x60 + IFT_SHDSL = 0xa9 + IFT_SIP = 0x1f + IFT_SIPSIG = 0xcc + IFT_SIPTG = 0xcb + IFT_SLIP = 0x1c + IFT_SMDSDXI = 0x2b + IFT_SMDSICIP = 0x34 + IFT_SONET = 0x27 + IFT_SONETOVERHEADCHANNEL = 0xb9 + IFT_SONETPATH = 0x32 + IFT_SONETVT = 0x33 + IFT_SRP = 0x97 + IFT_SS7SIGLINK = 0x9c + IFT_STACKTOSTACK = 0x6f + IFT_STARLAN = 0xb + IFT_STF = 0xd7 + IFT_T1 = 0x12 + IFT_TDLC = 0x74 + IFT_TELINK = 0xc8 + IFT_TERMPAD = 0x5b + IFT_TR008 = 0xb0 + IFT_TRANSPHDLC = 0x7b + IFT_TUNNEL = 0x83 + IFT_ULTRA = 0x1d + IFT_USB = 0xa0 + IFT_V11 = 0x40 + IFT_V35 = 0x2d + IFT_V36 = 0x41 + IFT_V37 = 0x78 + IFT_VDSL = 0x61 + IFT_VIRTUALIPADDRESS = 0x70 + IFT_VIRTUALTG = 0xca + IFT_VOICEDID = 0xd5 + IFT_VOICEEM = 0x64 + IFT_VOICEEMFGD = 0xd3 + IFT_VOICEENCAP = 0x67 + IFT_VOICEFGDEANA = 0xd4 + IFT_VOICEFXO = 0x65 + IFT_VOICEFXS = 0x66 + IFT_VOICEOVERATM = 0x98 + IFT_VOICEOVERCABLE = 0xc6 + IFT_VOICEOVERFRAMERELAY = 0x99 + IFT_VOICEOVERIP = 0x68 + IFT_X213 = 0x5d + IFT_X25 = 0x5 + IFT_X25DDN = 0x4 + IFT_X25HUNTGROUP = 0x7a + IFT_X25MLP = 0x79 + IFT_X25PLE = 0x28 + IFT_XETHER = 0x1a + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLASSD_HOST = 0xfffffff + IN_CLASSD_NET = 0xf0000000 + IN_CLASSD_NSHIFT = 0x1c + IN_LOOPBACKNET = 0x7f + IPPROTO_AH = 0x33 + IPPROTO_CARP = 0x70 + IPPROTO_DONE = 0x101 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_ENCAP = 0x62 + IPPROTO_EON = 0x50 + IPPROTO_ESP = 0x32 + IPPROTO_ETHERIP = 0x61 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GGP = 0x3 + IPPROTO_GRE = 0x2f + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IGMP = 0x2 + IPPROTO_IP = 0x0 + IPPROTO_IPCOMP = 0x6c + IPPROTO_IPIP = 0x4 + IPPROTO_IPV4 = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_IPV6_ICMP = 0x3a + IPPROTO_MAX = 0x100 + IPPROTO_MAXID = 0x34 + IPPROTO_MOBILE = 0x37 + IPPROTO_NONE = 0x3b + IPPROTO_PFSYNC = 0xf0 + IPPROTO_PIM = 0x67 + IPPROTO_PUP = 0xc + IPPROTO_RAW = 0xff + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_UDP = 0x11 + IPPROTO_VRRP = 0x70 + IPV6_CHECKSUM = 0x1a + IPV6_DEFAULT_MULTICAST_HOPS = 0x1 + IPV6_DEFAULT_MULTICAST_LOOP = 0x1 + IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 + IPV6_FAITH = 0x1d + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FRAGTTL = 0x78 + IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 + IPV6_IPSEC_POLICY = 0x1c + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_MAXHLIM = 0xff + IPV6_MAXPACKET = 0xffff + IPV6_MMTU = 0x500 + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_PATHMTU = 0x2c + IPV6_PKTINFO = 0x2e + IPV6_PORTRANGE = 0xe + IPV6_PORTRANGE_DEFAULT = 0x0 + IPV6_PORTRANGE_HIGH = 0x1 + IPV6_PORTRANGE_LOW = 0x2 + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x24 + IPV6_RECVRTHDR = 0x26 + IPV6_RECVTCLASS = 0x39 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x23 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_SOCKOPT_RESERVED1 = 0x3 + IPV6_TCLASS = 0x3d + IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a + IPV6_V6ONLY = 0x1b + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 + IP_ADD_MEMBERSHIP = 0xc + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DROP_MEMBERSHIP = 0xd + IP_EF = 0x8000 + IP_ERRORMTU = 0x15 + IP_HDRINCL = 0x2 + IP_IPSEC_POLICY = 0x16 + IP_MAXPACKET = 0xffff + IP_MAX_MEMBERSHIPS = 0x14 + IP_MF = 0x2000 + IP_MINFRAGSIZE = 0x45 + IP_MINTTL = 0x18 + IP_MSS = 0x240 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_LOOP = 0xb + IP_MULTICAST_TTL = 0xa + IP_OFFMASK = 0x1fff + IP_OPTIONS = 0x1 + IP_PORTRANGE = 0x13 + IP_PORTRANGE_DEFAULT = 0x0 + IP_PORTRANGE_HIGH = 0x1 + IP_PORTRANGE_LOW = 0x2 + IP_RECVDSTADDR = 0x7 + IP_RECVIF = 0x14 + IP_RECVOPTS = 0x5 + IP_RECVRETOPTS = 0x6 + IP_RECVTTL = 0x17 + IP_RETOPTS = 0x8 + IP_RF = 0x8000 + IP_TOS = 0x3 + IP_TTL = 0x4 + ISIG = 0x80 + ISTRIP = 0x20 + IXANY = 0x800 + IXOFF = 0x400 + IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_DONTNEED = 0x4 + MADV_FREE = 0x6 + MADV_NORMAL = 0x0 + MADV_RANDOM = 0x1 + MADV_SEQUENTIAL = 0x2 + MADV_SPACEAVAIL = 0x5 + MADV_WILLNEED = 0x3 + MAP_ALIGNMENT_16MB = 0x18000000 + MAP_ALIGNMENT_1TB = 0x28000000 + MAP_ALIGNMENT_256TB = 0x30000000 + MAP_ALIGNMENT_4GB = 0x20000000 + MAP_ALIGNMENT_64KB = 0x10000000 + MAP_ALIGNMENT_64PB = 0x38000000 + MAP_ALIGNMENT_MASK = -0x1000000 + MAP_ALIGNMENT_SHIFT = 0x18 + MAP_ANON = 0x1000 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_HASSEMAPHORE = 0x200 + MAP_INHERIT = 0x80 + MAP_INHERIT_COPY = 0x1 + MAP_INHERIT_DEFAULT = 0x1 + MAP_INHERIT_DONATE_COPY = 0x3 + MAP_INHERIT_NONE = 0x2 + MAP_INHERIT_SHARE = 0x0 + MAP_NORESERVE = 0x40 + MAP_PRIVATE = 0x2 + MAP_RENAME = 0x20 + MAP_SHARED = 0x1 + MAP_STACK = 0x2000 + MAP_TRYFIXED = 0x400 + MAP_WIRED = 0x800 + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MNT_ASYNC = 0x40 + MNT_BASIC_FLAGS = 0xe782807f + MNT_DEFEXPORTED = 0x200 + MNT_DISCARD = 0x800000 + MNT_EXKERB = 0x800 + MNT_EXNORESPORT = 0x8000000 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXPUBLIC = 0x10000000 + MNT_EXRDONLY = 0x80 + MNT_EXTATTR = 0x1000000 + MNT_FORCE = 0x80000 + MNT_GETARGS = 0x400000 + MNT_IGNORE = 0x100000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_LOG = 0x2000000 + MNT_NOATIME = 0x4000000 + MNT_NOCOREDUMP = 0x8000 + MNT_NODEV = 0x10 + MNT_NODEVMTIME = 0x40000000 + MNT_NOEXEC = 0x4 + MNT_NOSUID = 0x8 + MNT_NOWAIT = 0x2 + MNT_OP_FLAGS = 0x4d0000 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELATIME = 0x20000 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SOFTDEP = 0x80000000 + MNT_SYMPERM = 0x20000000 + MNT_SYNCHRONOUS = 0x2 + MNT_UNION = 0x20 + MNT_UPDATE = 0x10000 + MNT_VISFLAGMASK = 0xff90ffff + MNT_WAIT = 0x1 + MSG_BCAST = 0x100 + MSG_CMSG_CLOEXEC = 0x800 + MSG_CONTROLMBUF = 0x2000000 + MSG_CTRUNC = 0x20 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x80 + MSG_EOR = 0x8 + MSG_IOVUSRSPACE = 0x4000000 + MSG_LENUSRSPACE = 0x8000000 + MSG_MCAST = 0x200 + MSG_NAMEMBUF = 0x1000000 + MSG_NBIO = 0x1000 + MSG_NOSIGNAL = 0x400 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_TRUNC = 0x10 + MSG_USERFLAGS = 0xffffff + MSG_WAITALL = 0x40 + MS_ASYNC = 0x1 + MS_INVALIDATE = 0x2 + MS_SYNC = 0x4 + NAME_MAX = 0x1ff + NET_RT_DUMP = 0x1 + NET_RT_FLAGS = 0x2 + NET_RT_IFLIST = 0x5 + NET_RT_MAXID = 0x6 + NET_RT_OIFLIST = 0x4 + NET_RT_OOIFLIST = 0x3 + NOFLSH = 0x80000000 + NOTE_ATTRIB = 0x8 + NOTE_CHILD = 0x4 + NOTE_DELETE = 0x1 + NOTE_EXEC = 0x20000000 + NOTE_EXIT = 0x80000000 + NOTE_EXTEND = 0x4 + NOTE_FORK = 0x40000000 + NOTE_LINK = 0x10 + NOTE_LOWAT = 0x1 + NOTE_PCTRLMASK = 0xf0000000 + NOTE_PDATAMASK = 0xfffff + NOTE_RENAME = 0x20 + NOTE_REVOKE = 0x40 + NOTE_TRACK = 0x1 + NOTE_TRACKERR = 0x2 + NOTE_WRITE = 0x2 + OCRNL = 0x10 + OFIOGETBMAP = 0xc004667a + ONLCR = 0x2 + ONLRET = 0x40 + ONOCR = 0x20 + ONOEOT = 0x8 + OPOST = 0x1 + O_ACCMODE = 0x3 + O_ALT_IO = 0x40000 + O_APPEND = 0x8 + O_ASYNC = 0x40 + O_CLOEXEC = 0x400000 + O_CREAT = 0x200 + O_DIRECT = 0x80000 + O_DIRECTORY = 0x200000 + O_DSYNC = 0x10000 + O_EXCL = 0x800 + O_EXLOCK = 0x20 + O_FSYNC = 0x80 + O_NDELAY = 0x4 + O_NOCTTY = 0x8000 + O_NOFOLLOW = 0x100 + O_NONBLOCK = 0x4 + O_NOSIGPIPE = 0x1000000 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_RSYNC = 0x20000 + O_SHLOCK = 0x10 + O_SYNC = 0x80 + O_TRUNC = 0x400 + O_WRONLY = 0x1 + PARENB = 0x1000 + PARMRK = 0x8 + PARODD = 0x2000 + PENDIN = 0x20000000 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PRI_IOFLUSH = 0x7c + PROT_EXEC = 0x4 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + RLIMIT_AS = 0xa + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 + RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0x7fffffffffffffff + RTAX_AUTHOR = 0x6 + RTAX_BRD = 0x7 + RTAX_DST = 0x0 + RTAX_GATEWAY = 0x1 + RTAX_GENMASK = 0x3 + RTAX_IFA = 0x5 + RTAX_IFP = 0x4 + RTAX_MAX = 0x9 + RTAX_NETMASK = 0x2 + RTAX_TAG = 0x8 + RTA_AUTHOR = 0x40 + RTA_BRD = 0x80 + RTA_DST = 0x1 + RTA_GATEWAY = 0x2 + RTA_GENMASK = 0x8 + RTA_IFA = 0x20 + RTA_IFP = 0x10 + RTA_NETMASK = 0x4 + RTA_TAG = 0x100 + RTF_ANNOUNCE = 0x20000 + RTF_BLACKHOLE = 0x1000 + RTF_CLONED = 0x2000 + RTF_CLONING = 0x100 + RTF_DONE = 0x40 + RTF_DYNAMIC = 0x10 + RTF_GATEWAY = 0x2 + RTF_HOST = 0x4 + RTF_LLINFO = 0x400 + RTF_MASK = 0x80 + RTF_MODIFIED = 0x20 + RTF_PROTO1 = 0x8000 + RTF_PROTO2 = 0x4000 + RTF_REJECT = 0x8 + RTF_SRC = 0x10000 + RTF_STATIC = 0x800 + RTF_UP = 0x1 + RTF_XRESOLVE = 0x200 + RTM_ADD = 0x1 + RTM_CHANGE = 0x3 + RTM_CHGADDR = 0x15 + RTM_DELADDR = 0xd + RTM_DELETE = 0x2 + RTM_GET = 0x4 + RTM_IEEE80211 = 0x11 + RTM_IFANNOUNCE = 0x10 + RTM_IFINFO = 0x14 + RTM_LLINFO_UPD = 0x13 + RTM_LOCK = 0x8 + RTM_LOSING = 0x5 + RTM_MISS = 0x7 + RTM_NEWADDR = 0xc + RTM_OIFINFO = 0xf + RTM_OLDADD = 0x9 + RTM_OLDDEL = 0xa + RTM_OOIFINFO = 0xe + RTM_REDIRECT = 0x6 + RTM_RESOLVE = 0xb + RTM_RTTUNIT = 0xf4240 + RTM_SETGATE = 0x12 + RTM_VERSION = 0x4 + RTV_EXPIRE = 0x4 + RTV_HOPCOUNT = 0x2 + RTV_MTU = 0x1 + RTV_RPIPE = 0x8 + RTV_RTT = 0x40 + RTV_RTTVAR = 0x80 + RTV_SPIPE = 0x10 + RTV_SSTHRESH = 0x20 + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + SCM_CREDS = 0x4 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x8 + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDMULTI = 0x80906931 + SIOCADDRT = 0x8038720a + SIOCAIFADDR = 0x8040691a + SIOCALIFADDR = 0x8118691c + SIOCATMARK = 0x40047307 + SIOCDELMULTI = 0x80906932 + SIOCDELRT = 0x8038720b + SIOCDIFADDR = 0x80906919 + SIOCDIFPHYADDR = 0x80906949 + SIOCDLIFADDR = 0x8118691e + SIOCGDRVSPEC = 0xc028697b + SIOCGETPFSYNC = 0xc09069f8 + SIOCGETSGCNT = 0xc0207534 + SIOCGETVIFCNT = 0xc0287533 + SIOCGHIWAT = 0x40047301 + SIOCGIFADDR = 0xc0906921 + SIOCGIFADDRPREF = 0xc0986920 + SIOCGIFALIAS = 0xc040691b + SIOCGIFBRDADDR = 0xc0906923 + SIOCGIFCAP = 0xc0206976 + SIOCGIFCONF = 0xc0106926 + SIOCGIFDATA = 0xc0986985 + SIOCGIFDLT = 0xc0906977 + SIOCGIFDSTADDR = 0xc0906922 + SIOCGIFFLAGS = 0xc0906911 + SIOCGIFGENERIC = 0xc090693a + SIOCGIFMEDIA = 0xc0306936 + SIOCGIFMETRIC = 0xc0906917 + SIOCGIFMTU = 0xc090697e + SIOCGIFNETMASK = 0xc0906925 + SIOCGIFPDSTADDR = 0xc0906948 + SIOCGIFPSRCADDR = 0xc0906947 + SIOCGLIFADDR = 0xc118691d + SIOCGLIFPHYADDR = 0xc118694b + SIOCGLINKSTR = 0xc0286987 + SIOCGLOWAT = 0x40047303 + SIOCGPGRP = 0x40047309 + SIOCGVH = 0xc0906983 + SIOCIFCREATE = 0x8090697a + SIOCIFDESTROY = 0x80906979 + SIOCIFGCLONERS = 0xc0106978 + SIOCINITIFADDR = 0xc0706984 + SIOCSDRVSPEC = 0x8028697b + SIOCSETPFSYNC = 0x809069f7 + SIOCSHIWAT = 0x80047300 + SIOCSIFADDR = 0x8090690c + SIOCSIFADDRPREF = 0x8098691f + SIOCSIFBRDADDR = 0x80906913 + SIOCSIFCAP = 0x80206975 + SIOCSIFDSTADDR = 0x8090690e + SIOCSIFFLAGS = 0x80906910 + SIOCSIFGENERIC = 0x80906939 + SIOCSIFMEDIA = 0xc0906935 + SIOCSIFMETRIC = 0x80906918 + SIOCSIFMTU = 0x8090697f + SIOCSIFNETMASK = 0x80906916 + SIOCSIFPHYADDR = 0x80406946 + SIOCSLIFPHYADDR = 0x8118694a + SIOCSLINKSTR = 0x80286988 + SIOCSLOWAT = 0x80047302 + SIOCSPGRP = 0x80047308 + SIOCSVH = 0xc0906982 + SIOCZIFDATA = 0xc0986986 + SOCK_CLOEXEC = 0x10000000 + SOCK_DGRAM = 0x2 + SOCK_FLAGS_MASK = 0xf0000000 + SOCK_NONBLOCK = 0x20000000 + SOCK_NOSIGPIPE = 0x40000000 + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_SOCKET = 0xffff + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x2 + SO_ACCEPTFILTER = 0x1000 + SO_BROADCAST = 0x20 + SO_DEBUG = 0x1 + SO_DONTROUTE = 0x10 + SO_ERROR = 0x1007 + SO_KEEPALIVE = 0x8 + SO_LINGER = 0x80 + SO_NOHEADER = 0x100a + SO_NOSIGPIPE = 0x800 + SO_OOBINLINE = 0x100 + SO_OVERFLOWED = 0x1009 + SO_RCVBUF = 0x1002 + SO_RCVLOWAT = 0x1004 + SO_RCVTIMEO = 0x100c + SO_REUSEADDR = 0x4 + SO_REUSEPORT = 0x200 + SO_SNDBUF = 0x1001 + SO_SNDLOWAT = 0x1003 + SO_SNDTIMEO = 0x100b + SO_TIMESTAMP = 0x2000 + SO_TYPE = 0x1008 + SO_USELOOPBACK = 0x40 + SYSCTL_VERSION = 0x1000000 + SYSCTL_VERS_0 = 0x0 + SYSCTL_VERS_1 = 0x1000000 + SYSCTL_VERS_MASK = 0xff000000 + S_ARCH1 = 0x10000 + S_ARCH2 = 0x20000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IFWHT = 0xe000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + S_LOGIN_SET = 0x1 + TCIFLUSH = 0x1 + TCIOFLUSH = 0x3 + TCOFLUSH = 0x2 + TCP_CONGCTL = 0x20 + TCP_KEEPCNT = 0x6 + TCP_KEEPIDLE = 0x3 + TCP_KEEPINIT = 0x7 + TCP_KEEPINTVL = 0x5 + TCP_MAXBURST = 0x4 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_WINSHIFT = 0xe + TCP_MD5SIG = 0x10 + TCP_MINMSS = 0xd8 + TCP_MSS = 0x218 + TCP_NODELAY = 0x1 + TCSAFLUSH = 0x2 + TIOCCBRK = 0x2000747a + TIOCCDTR = 0x20007478 + TIOCCONS = 0x80047462 + TIOCDCDTIMESTAMP = 0x40107458 + TIOCDRAIN = 0x2000745e + TIOCEXCL = 0x2000740d + TIOCEXT = 0x80047460 + TIOCFLAG_CDTRCTS = 0x10 + TIOCFLAG_CLOCAL = 0x2 + TIOCFLAG_CRTSCTS = 0x4 + TIOCFLAG_MDMBUF = 0x8 + TIOCFLAG_SOFTCAR = 0x1 + TIOCFLUSH = 0x80047410 + TIOCGETA = 0x402c7413 + TIOCGETD = 0x4004741a + TIOCGFLAGS = 0x4004745d + TIOCGLINED = 0x40207442 + TIOCGPGRP = 0x40047477 + TIOCGQSIZE = 0x40047481 + TIOCGRANTPT = 0x20007447 + TIOCGSID = 0x40047463 + TIOCGSIZE = 0x40087468 + TIOCGWINSZ = 0x40087468 + TIOCMBIC = 0x8004746b + TIOCMBIS = 0x8004746c + TIOCMGET = 0x4004746a + TIOCMSET = 0x8004746d + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x20007471 + TIOCNXCL = 0x2000740e + TIOCOUTQ = 0x40047473 + TIOCPKT = 0x80047470 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCPTMGET = 0x40287446 + TIOCPTSNAME = 0x40287448 + TIOCRCVFRAME = 0x80087445 + TIOCREMOTE = 0x80047469 + TIOCSBRK = 0x2000747b + TIOCSCTTY = 0x20007461 + TIOCSDTR = 0x20007479 + TIOCSETA = 0x802c7414 + TIOCSETAF = 0x802c7416 + TIOCSETAW = 0x802c7415 + TIOCSETD = 0x8004741b + TIOCSFLAGS = 0x8004745c + TIOCSIG = 0x2000745f + TIOCSLINED = 0x80207443 + TIOCSPGRP = 0x80047476 + TIOCSQSIZE = 0x80047480 + TIOCSSIZE = 0x80087467 + TIOCSTART = 0x2000746e + TIOCSTAT = 0x80047465 + TIOCSTI = 0x80017472 + TIOCSTOP = 0x2000746f + TIOCSWINSZ = 0x80087467 + TIOCUCNTL = 0x80047466 + TIOCXMTFRAME = 0x80087444 + TOSTOP = 0x400000 + VDISCARD = 0xf + VDSUSP = 0xb + VEOF = 0x0 + VEOL = 0x1 + VEOL2 = 0x2 + VERASE = 0x3 + VINTR = 0x8 + VKILL = 0x5 + VLNEXT = 0xe + VMIN = 0x10 + VQUIT = 0x9 + VREPRINT = 0x6 + VSTART = 0xc + VSTATUS = 0x12 + VSTOP = 0xd + VSUSP = 0xa + VTIME = 0x11 + VWERASE = 0x4 + WALL = 0x8 + WALLSIG = 0x8 + WALTSIG = 0x4 + WCLONE = 0x4 + WCOREFLAG = 0x80 + WNOHANG = 0x1 + WNOWAIT = 0x10000 + WNOZOMBIE = 0x20000 + WOPTSCHECKED = 0x40000 + WSTOPPED = 0x7f + WUNTRACED = 0x2 +) + +// Errors +const ( + E2BIG = syscall.Errno(0x7) + EACCES = syscall.Errno(0xd) + EADDRINUSE = syscall.Errno(0x30) + EADDRNOTAVAIL = syscall.Errno(0x31) + EAFNOSUPPORT = syscall.Errno(0x2f) + EAGAIN = syscall.Errno(0x23) + EALREADY = syscall.Errno(0x25) + EAUTH = syscall.Errno(0x50) + EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x58) + EBADRPC = syscall.Errno(0x48) + EBUSY = syscall.Errno(0x10) + ECANCELED = syscall.Errno(0x57) + ECHILD = syscall.Errno(0xa) + ECONNABORTED = syscall.Errno(0x35) + ECONNREFUSED = syscall.Errno(0x3d) + ECONNRESET = syscall.Errno(0x36) + EDEADLK = syscall.Errno(0xb) + EDESTADDRREQ = syscall.Errno(0x27) + EDOM = syscall.Errno(0x21) + EDQUOT = syscall.Errno(0x45) + EEXIST = syscall.Errno(0x11) + EFAULT = syscall.Errno(0xe) + EFBIG = syscall.Errno(0x1b) + EFTYPE = syscall.Errno(0x4f) + EHOSTDOWN = syscall.Errno(0x40) + EHOSTUNREACH = syscall.Errno(0x41) + EIDRM = syscall.Errno(0x52) + EILSEQ = syscall.Errno(0x55) + EINPROGRESS = syscall.Errno(0x24) + EINTR = syscall.Errno(0x4) + EINVAL = syscall.Errno(0x16) + EIO = syscall.Errno(0x5) + EISCONN = syscall.Errno(0x38) + EISDIR = syscall.Errno(0x15) + ELAST = syscall.Errno(0x60) + ELOOP = syscall.Errno(0x3e) + EMFILE = syscall.Errno(0x18) + EMLINK = syscall.Errno(0x1f) + EMSGSIZE = syscall.Errno(0x28) + EMULTIHOP = syscall.Errno(0x5e) + ENAMETOOLONG = syscall.Errno(0x3f) + ENEEDAUTH = syscall.Errno(0x51) + ENETDOWN = syscall.Errno(0x32) + ENETRESET = syscall.Errno(0x34) + ENETUNREACH = syscall.Errno(0x33) + ENFILE = syscall.Errno(0x17) + ENOATTR = syscall.Errno(0x5d) + ENOBUFS = syscall.Errno(0x37) + ENODATA = syscall.Errno(0x59) + ENODEV = syscall.Errno(0x13) + ENOENT = syscall.Errno(0x2) + ENOEXEC = syscall.Errno(0x8) + ENOLCK = syscall.Errno(0x4d) + ENOLINK = syscall.Errno(0x5f) + ENOMEM = syscall.Errno(0xc) + ENOMSG = syscall.Errno(0x53) + ENOPROTOOPT = syscall.Errno(0x2a) + ENOSPC = syscall.Errno(0x1c) + ENOSR = syscall.Errno(0x5a) + ENOSTR = syscall.Errno(0x5b) + ENOSYS = syscall.Errno(0x4e) + ENOTBLK = syscall.Errno(0xf) + ENOTCONN = syscall.Errno(0x39) + ENOTDIR = syscall.Errno(0x14) + ENOTEMPTY = syscall.Errno(0x42) + ENOTSOCK = syscall.Errno(0x26) + ENOTSUP = syscall.Errno(0x56) + ENOTTY = syscall.Errno(0x19) + ENXIO = syscall.Errno(0x6) + EOPNOTSUPP = syscall.Errno(0x2d) + EOVERFLOW = syscall.Errno(0x54) + EPERM = syscall.Errno(0x1) + EPFNOSUPPORT = syscall.Errno(0x2e) + EPIPE = syscall.Errno(0x20) + EPROCLIM = syscall.Errno(0x43) + EPROCUNAVAIL = syscall.Errno(0x4c) + EPROGMISMATCH = syscall.Errno(0x4b) + EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x60) + EPROTONOSUPPORT = syscall.Errno(0x2b) + EPROTOTYPE = syscall.Errno(0x29) + ERANGE = syscall.Errno(0x22) + EREMOTE = syscall.Errno(0x47) + EROFS = syscall.Errno(0x1e) + ERPCMISMATCH = syscall.Errno(0x49) + ESHUTDOWN = syscall.Errno(0x3a) + ESOCKTNOSUPPORT = syscall.Errno(0x2c) + ESPIPE = syscall.Errno(0x1d) + ESRCH = syscall.Errno(0x3) + ESTALE = syscall.Errno(0x46) + ETIME = syscall.Errno(0x5c) + ETIMEDOUT = syscall.Errno(0x3c) + ETOOMANYREFS = syscall.Errno(0x3b) + ETXTBSY = syscall.Errno(0x1a) + EUSERS = syscall.Errno(0x44) + EWOULDBLOCK = syscall.Errno(0x23) + EXDEV = syscall.Errno(0x12) +) + +// Signals +const ( + SIGABRT = syscall.Signal(0x6) + SIGALRM = syscall.Signal(0xe) + SIGBUS = syscall.Signal(0xa) + SIGCHLD = syscall.Signal(0x14) + SIGCONT = syscall.Signal(0x13) + SIGEMT = syscall.Signal(0x7) + SIGFPE = syscall.Signal(0x8) + SIGHUP = syscall.Signal(0x1) + SIGILL = syscall.Signal(0x4) + SIGINFO = syscall.Signal(0x1d) + SIGINT = syscall.Signal(0x2) + SIGIO = syscall.Signal(0x17) + SIGIOT = syscall.Signal(0x6) + SIGKILL = syscall.Signal(0x9) + SIGPIPE = syscall.Signal(0xd) + SIGPROF = syscall.Signal(0x1b) + SIGPWR = syscall.Signal(0x20) + SIGQUIT = syscall.Signal(0x3) + SIGSEGV = syscall.Signal(0xb) + SIGSTOP = syscall.Signal(0x11) + SIGSYS = syscall.Signal(0xc) + SIGTERM = syscall.Signal(0xf) + SIGTRAP = syscall.Signal(0x5) + SIGTSTP = syscall.Signal(0x12) + SIGTTIN = syscall.Signal(0x15) + SIGTTOU = syscall.Signal(0x16) + SIGURG = syscall.Signal(0x10) + SIGUSR1 = syscall.Signal(0x1e) + SIGUSR2 = syscall.Signal(0x1f) + SIGVTALRM = syscall.Signal(0x1a) + SIGWINCH = syscall.Signal(0x1c) + SIGXCPU = syscall.Signal(0x18) + SIGXFSZ = syscall.Signal(0x19) +) + +// Error table +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large or too small"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol option not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "connection timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disc quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC prog. not avail"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIDRM", "identifier removed"}, + {83, "ENOMSG", "no message of desired type"}, + {84, "EOVERFLOW", "value too large to be stored in data type"}, + {85, "EILSEQ", "illegal byte sequence"}, + {86, "ENOTSUP", "not supported"}, + {87, "ECANCELED", "operation Canceled"}, + {88, "EBADMSG", "bad or Corrupt message"}, + {89, "ENODATA", "no message available"}, + {90, "ENOSR", "no STREAM resources"}, + {91, "ENOSTR", "not a STREAM"}, + {92, "ETIME", "STREAM ioctl timeout"}, + {93, "ENOATTR", "attribute not found"}, + {94, "EMULTIHOP", "multihop attempted"}, + {95, "ENOLINK", "link has been severed"}, + {96, "ELAST", "protocol error"}, +} + +// Signal table +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGIOT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "stopped (signal)"}, + {18, "SIGTSTP", "stopped"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGPWR", "power fail/restart"}, +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go new file mode 100644 index 000000000000..ec5f92de8883 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go @@ -0,0 +1,1789 @@ +// mkerrors.sh -m64 +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build arm64,openbsd + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs -- -m64 _const.go + +package unix + +import "syscall" + +const ( + AF_APPLETALK = 0x10 + AF_BLUETOOTH = 0x20 + AF_CCITT = 0xa + AF_CHAOS = 0x5 + AF_CNT = 0x15 + AF_COIP = 0x14 + AF_DATAKIT = 0x9 + AF_DECnet = 0xc + AF_DLI = 0xd + AF_E164 = 0x1a + AF_ECMA = 0x8 + AF_ENCAP = 0x1c + AF_HYLINK = 0xf + AF_IMPLINK = 0x3 + AF_INET = 0x2 + AF_INET6 = 0x18 + AF_IPX = 0x17 + AF_ISDN = 0x1a + AF_ISO = 0x7 + AF_KEY = 0x1e + AF_LAT = 0xe + AF_LINK = 0x12 + AF_LOCAL = 0x1 + AF_MAX = 0x24 + AF_MPLS = 0x21 + AF_NATM = 0x1b + AF_NS = 0x6 + AF_OSI = 0x7 + AF_PUP = 0x4 + AF_ROUTE = 0x11 + AF_SIP = 0x1d + AF_SNA = 0xb + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + ALTWERASE = 0x200 + ARPHRD_ETHER = 0x1 + ARPHRD_FRELAY = 0xf + ARPHRD_IEEE1394 = 0x18 + ARPHRD_IEEE802 = 0x6 + B0 = 0x0 + B110 = 0x6e + B115200 = 0x1c200 + B1200 = 0x4b0 + B134 = 0x86 + B14400 = 0x3840 + B150 = 0x96 + B1800 = 0x708 + B19200 = 0x4b00 + B200 = 0xc8 + B230400 = 0x38400 + B2400 = 0x960 + B28800 = 0x7080 + B300 = 0x12c + B38400 = 0x9600 + B4800 = 0x12c0 + B50 = 0x32 + B57600 = 0xe100 + B600 = 0x258 + B7200 = 0x1c20 + B75 = 0x4b + B76800 = 0x12c00 + B9600 = 0x2580 + BIOCFLUSH = 0x20004268 + BIOCGBLEN = 0x40044266 + BIOCGDIRFILT = 0x4004427c + BIOCGDLT = 0x4004426a + BIOCGDLTLIST = 0xc010427b + BIOCGETIF = 0x4020426b + BIOCGFILDROP = 0x40044278 + BIOCGHDRCMPLT = 0x40044274 + BIOCGRSIG = 0x40044273 + BIOCGRTIMEOUT = 0x4010426e + BIOCGSTATS = 0x4008426f + BIOCIMMEDIATE = 0x80044270 + BIOCLOCK = 0x20004276 + BIOCPROMISC = 0x20004269 + BIOCSBLEN = 0xc0044266 + BIOCSDIRFILT = 0x8004427d + BIOCSDLT = 0x8004427a + BIOCSETF = 0x80104267 + BIOCSETIF = 0x8020426c + BIOCSETWF = 0x80104277 + BIOCSFILDROP = 0x80044279 + BIOCSHDRCMPLT = 0x80044275 + BIOCSRSIG = 0x80044272 + BIOCSRTIMEOUT = 0x8010426d + BIOCVERSION = 0x40044271 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALIGNMENT = 0x4 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_DIRECTION_IN = 0x1 + BPF_DIRECTION_OUT = 0x2 + BPF_DIV = 0x30 + BPF_FILDROP_CAPTURE = 0x1 + BPF_FILDROP_DROP = 0x2 + BPF_FILDROP_PASS = 0x0 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXBUFSIZE = 0x200000 + BPF_MAXINSNS = 0x200 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINBUFSIZE = 0x20 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_OR = 0x40 + BPF_RELEASE = 0x30bb6 + BPF_RET = 0x6 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_W = 0x0 + BPF_X = 0x8 + BRKINT = 0x2 + CFLUSH = 0xf + CLOCAL = 0x8000 + CLOCK_BOOTTIME = 0x6 + CLOCK_MONOTONIC = 0x3 + CLOCK_PROCESS_CPUTIME_ID = 0x2 + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x4 + CLOCK_UPTIME = 0x5 + CREAD = 0x800 + CRTSCTS = 0x10000 + CS5 = 0x0 + CS6 = 0x100 + CS7 = 0x200 + CS8 = 0x300 + CSIZE = 0x300 + CSTART = 0x11 + CSTATUS = 0xff + CSTOP = 0x13 + CSTOPB = 0x400 + CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 + CTL_MAXNAME = 0xc + CTL_NET = 0x4 + DIOCOSFPFLUSH = 0x2000444e + DLT_ARCNET = 0x7 + DLT_ATM_RFC1483 = 0xb + DLT_AX25 = 0x3 + DLT_CHAOS = 0x5 + DLT_C_HDLC = 0x68 + DLT_EN10MB = 0x1 + DLT_EN3MB = 0x2 + DLT_ENC = 0xd + DLT_FDDI = 0xa + DLT_IEEE802 = 0x6 + DLT_IEEE802_11 = 0x69 + DLT_IEEE802_11_RADIO = 0x7f + DLT_LOOP = 0xc + DLT_MPLS = 0xdb + DLT_NULL = 0x0 + DLT_OPENFLOW = 0x10b + DLT_PFLOG = 0x75 + DLT_PFSYNC = 0x12 + DLT_PPP = 0x9 + DLT_PPP_BSDOS = 0x10 + DLT_PPP_ETHER = 0x33 + DLT_PPP_SERIAL = 0x32 + DLT_PRONET = 0x4 + DLT_RAW = 0xe + DLT_SLIP = 0x8 + DLT_SLIP_BSDOS = 0xf + DLT_USBPCAP = 0xf9 + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + ECHO = 0x8 + ECHOCTL = 0x40 + ECHOE = 0x2 + ECHOK = 0x4 + ECHOKE = 0x1 + ECHONL = 0x10 + ECHOPRT = 0x20 + EMT_TAGOVF = 0x1 + EMUL_ENABLED = 0x1 + EMUL_NATIVE = 0x2 + ENDRUNDISC = 0x9 + ETHERMIN = 0x2e + ETHERMTU = 0x5dc + ETHERTYPE_8023 = 0x4 + ETHERTYPE_AARP = 0x80f3 + ETHERTYPE_ACCTON = 0x8390 + ETHERTYPE_AEONIC = 0x8036 + ETHERTYPE_ALPHA = 0x814a + ETHERTYPE_AMBER = 0x6008 + ETHERTYPE_AMOEBA = 0x8145 + ETHERTYPE_AOE = 0x88a2 + ETHERTYPE_APOLLO = 0x80f7 + ETHERTYPE_APOLLODOMAIN = 0x8019 + ETHERTYPE_APPLETALK = 0x809b + ETHERTYPE_APPLITEK = 0x80c7 + ETHERTYPE_ARGONAUT = 0x803a + ETHERTYPE_ARP = 0x806 + ETHERTYPE_AT = 0x809b + ETHERTYPE_ATALK = 0x809b + ETHERTYPE_ATOMIC = 0x86df + ETHERTYPE_ATT = 0x8069 + ETHERTYPE_ATTSTANFORD = 0x8008 + ETHERTYPE_AUTOPHON = 0x806a + ETHERTYPE_AXIS = 0x8856 + ETHERTYPE_BCLOOP = 0x9003 + ETHERTYPE_BOFL = 0x8102 + ETHERTYPE_CABLETRON = 0x7034 + ETHERTYPE_CHAOS = 0x804 + ETHERTYPE_COMDESIGN = 0x806c + ETHERTYPE_COMPUGRAPHIC = 0x806d + ETHERTYPE_COUNTERPOINT = 0x8062 + ETHERTYPE_CRONUS = 0x8004 + ETHERTYPE_CRONUSVLN = 0x8003 + ETHERTYPE_DCA = 0x1234 + ETHERTYPE_DDE = 0x807b + ETHERTYPE_DEBNI = 0xaaaa + ETHERTYPE_DECAM = 0x8048 + ETHERTYPE_DECCUST = 0x6006 + ETHERTYPE_DECDIAG = 0x6005 + ETHERTYPE_DECDNS = 0x803c + ETHERTYPE_DECDTS = 0x803e + ETHERTYPE_DECEXPER = 0x6000 + ETHERTYPE_DECLAST = 0x8041 + ETHERTYPE_DECLTM = 0x803f + ETHERTYPE_DECMUMPS = 0x6009 + ETHERTYPE_DECNETBIOS = 0x8040 + ETHERTYPE_DELTACON = 0x86de + ETHERTYPE_DIDDLE = 0x4321 + ETHERTYPE_DLOG1 = 0x660 + ETHERTYPE_DLOG2 = 0x661 + ETHERTYPE_DN = 0x6003 + ETHERTYPE_DOGFIGHT = 0x1989 + ETHERTYPE_DSMD = 0x8039 + ETHERTYPE_ECMA = 0x803 + ETHERTYPE_ENCRYPT = 0x803d + ETHERTYPE_ES = 0x805d + ETHERTYPE_EXCELAN = 0x8010 + ETHERTYPE_EXPERDATA = 0x8049 + ETHERTYPE_FLIP = 0x8146 + ETHERTYPE_FLOWCONTROL = 0x8808 + ETHERTYPE_FRARP = 0x808 + ETHERTYPE_GENDYN = 0x8068 + ETHERTYPE_HAYES = 0x8130 + ETHERTYPE_HIPPI_FP = 0x8180 + ETHERTYPE_HITACHI = 0x8820 + ETHERTYPE_HP = 0x8005 + ETHERTYPE_IEEEPUP = 0xa00 + ETHERTYPE_IEEEPUPAT = 0xa01 + ETHERTYPE_IMLBL = 0x4c42 + ETHERTYPE_IMLBLDIAG = 0x424c + ETHERTYPE_IP = 0x800 + ETHERTYPE_IPAS = 0x876c + ETHERTYPE_IPV6 = 0x86dd + ETHERTYPE_IPX = 0x8137 + ETHERTYPE_IPXNEW = 0x8037 + ETHERTYPE_KALPANA = 0x8582 + ETHERTYPE_LANBRIDGE = 0x8038 + ETHERTYPE_LANPROBE = 0x8888 + ETHERTYPE_LAT = 0x6004 + ETHERTYPE_LBACK = 0x9000 + ETHERTYPE_LITTLE = 0x8060 + ETHERTYPE_LLDP = 0x88cc + ETHERTYPE_LOGICRAFT = 0x8148 + ETHERTYPE_LOOPBACK = 0x9000 + ETHERTYPE_MATRA = 0x807a + ETHERTYPE_MAX = 0xffff + ETHERTYPE_MERIT = 0x807c + ETHERTYPE_MICP = 0x873a + ETHERTYPE_MOPDL = 0x6001 + ETHERTYPE_MOPRC = 0x6002 + ETHERTYPE_MOTOROLA = 0x818d + ETHERTYPE_MPLS = 0x8847 + ETHERTYPE_MPLS_MCAST = 0x8848 + ETHERTYPE_MUMPS = 0x813f + ETHERTYPE_NBPCC = 0x3c04 + ETHERTYPE_NBPCLAIM = 0x3c09 + ETHERTYPE_NBPCLREQ = 0x3c05 + ETHERTYPE_NBPCLRSP = 0x3c06 + ETHERTYPE_NBPCREQ = 0x3c02 + ETHERTYPE_NBPCRSP = 0x3c03 + ETHERTYPE_NBPDG = 0x3c07 + ETHERTYPE_NBPDGB = 0x3c08 + ETHERTYPE_NBPDLTE = 0x3c0a + ETHERTYPE_NBPRAR = 0x3c0c + ETHERTYPE_NBPRAS = 0x3c0b + ETHERTYPE_NBPRST = 0x3c0d + ETHERTYPE_NBPSCD = 0x3c01 + ETHERTYPE_NBPVCD = 0x3c00 + ETHERTYPE_NBS = 0x802 + ETHERTYPE_NCD = 0x8149 + ETHERTYPE_NESTAR = 0x8006 + ETHERTYPE_NETBEUI = 0x8191 + ETHERTYPE_NOVELL = 0x8138 + ETHERTYPE_NS = 0x600 + ETHERTYPE_NSAT = 0x601 + ETHERTYPE_NSCOMPAT = 0x807 + ETHERTYPE_NTRAILER = 0x10 + ETHERTYPE_OS9 = 0x7007 + ETHERTYPE_OS9NET = 0x7009 + ETHERTYPE_PACER = 0x80c6 + ETHERTYPE_PAE = 0x888e + ETHERTYPE_PBB = 0x88e7 + ETHERTYPE_PCS = 0x4242 + ETHERTYPE_PLANNING = 0x8044 + ETHERTYPE_PPP = 0x880b + ETHERTYPE_PPPOE = 0x8864 + ETHERTYPE_PPPOEDISC = 0x8863 + ETHERTYPE_PRIMENTS = 0x7031 + ETHERTYPE_PUP = 0x200 + ETHERTYPE_PUPAT = 0x200 + ETHERTYPE_QINQ = 0x88a8 + ETHERTYPE_RACAL = 0x7030 + ETHERTYPE_RATIONAL = 0x8150 + ETHERTYPE_RAWFR = 0x6559 + ETHERTYPE_RCL = 0x1995 + ETHERTYPE_RDP = 0x8739 + ETHERTYPE_RETIX = 0x80f2 + ETHERTYPE_REVARP = 0x8035 + ETHERTYPE_SCA = 0x6007 + ETHERTYPE_SECTRA = 0x86db + ETHERTYPE_SECUREDATA = 0x876d + ETHERTYPE_SGITW = 0x817e + ETHERTYPE_SG_BOUNCE = 0x8016 + ETHERTYPE_SG_DIAG = 0x8013 + ETHERTYPE_SG_NETGAMES = 0x8014 + ETHERTYPE_SG_RESV = 0x8015 + ETHERTYPE_SIMNET = 0x5208 + ETHERTYPE_SLOW = 0x8809 + ETHERTYPE_SNA = 0x80d5 + ETHERTYPE_SNMP = 0x814c + ETHERTYPE_SONIX = 0xfaf5 + ETHERTYPE_SPIDER = 0x809f + ETHERTYPE_SPRITE = 0x500 + ETHERTYPE_STP = 0x8181 + ETHERTYPE_TALARIS = 0x812b + ETHERTYPE_TALARISMC = 0x852b + ETHERTYPE_TCPCOMP = 0x876b + ETHERTYPE_TCPSM = 0x9002 + ETHERTYPE_TEC = 0x814f + ETHERTYPE_TIGAN = 0x802f + ETHERTYPE_TRAIL = 0x1000 + ETHERTYPE_TRANSETHER = 0x6558 + ETHERTYPE_TYMSHARE = 0x802e + ETHERTYPE_UBBST = 0x7005 + ETHERTYPE_UBDEBUG = 0x900 + ETHERTYPE_UBDIAGLOOP = 0x7002 + ETHERTYPE_UBDL = 0x7000 + ETHERTYPE_UBNIU = 0x7001 + ETHERTYPE_UBNMC = 0x7003 + ETHERTYPE_VALID = 0x1600 + ETHERTYPE_VARIAN = 0x80dd + ETHERTYPE_VAXELN = 0x803b + ETHERTYPE_VEECO = 0x8067 + ETHERTYPE_VEXP = 0x805b + ETHERTYPE_VGLAB = 0x8131 + ETHERTYPE_VINES = 0xbad + ETHERTYPE_VINESECHO = 0xbaf + ETHERTYPE_VINESLOOP = 0xbae + ETHERTYPE_VITAL = 0xff00 + ETHERTYPE_VLAN = 0x8100 + ETHERTYPE_VLTLMAN = 0x8080 + ETHERTYPE_VPROD = 0x805c + ETHERTYPE_VURESERVED = 0x8147 + ETHERTYPE_WATERLOO = 0x8130 + ETHERTYPE_WELLFLEET = 0x8103 + ETHERTYPE_X25 = 0x805 + ETHERTYPE_X75 = 0x801 + ETHERTYPE_XNSSM = 0x9001 + ETHERTYPE_XTP = 0x817d + ETHER_ADDR_LEN = 0x6 + ETHER_ALIGN = 0x2 + ETHER_CRC_LEN = 0x4 + ETHER_CRC_POLY_BE = 0x4c11db6 + ETHER_CRC_POLY_LE = 0xedb88320 + ETHER_HDR_LEN = 0xe + ETHER_MAX_DIX_LEN = 0x600 + ETHER_MAX_HARDMTU_LEN = 0xff9b + ETHER_MAX_LEN = 0x5ee + ETHER_MIN_LEN = 0x40 + ETHER_TYPE_LEN = 0x2 + ETHER_VLAN_ENCAP_LEN = 0x4 + EVFILT_AIO = -0x3 + EVFILT_DEVICE = -0x8 + EVFILT_PROC = -0x5 + EVFILT_READ = -0x1 + EVFILT_SIGNAL = -0x6 + EVFILT_SYSCOUNT = 0x8 + EVFILT_TIMER = -0x7 + EVFILT_VNODE = -0x4 + EVFILT_WRITE = -0x2 + EVL_ENCAPLEN = 0x4 + EVL_PRIO_BITS = 0xd + EVL_PRIO_MAX = 0x7 + EVL_VLID_MASK = 0xfff + EVL_VLID_MAX = 0xffe + EVL_VLID_MIN = 0x1 + EVL_VLID_NULL = 0x0 + EV_ADD = 0x1 + EV_CLEAR = 0x20 + EV_DELETE = 0x2 + EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 + EV_ENABLE = 0x4 + EV_EOF = 0x8000 + EV_ERROR = 0x4000 + EV_FLAG1 = 0x2000 + EV_ONESHOT = 0x10 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf000 + EXTA = 0x4b00 + EXTB = 0x9600 + EXTPROC = 0x800 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x400 + FLUSHO = 0x800000 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0xa + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLK = 0x7 + F_GETOWN = 0x5 + F_ISATTY = 0xb + F_OK = 0x0 + F_RDLCK = 0x1 + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLK = 0x8 + F_SETLKW = 0x9 + F_SETOWN = 0x6 + F_UNLCK = 0x2 + F_WRLCK = 0x3 + HUPCL = 0x4000 + HW_MACHINE = 0x1 + ICANON = 0x100 + ICMP6_FILTER = 0x12 + ICRNL = 0x100 + IEXTEN = 0x400 + IFAN_ARRIVAL = 0x0 + IFAN_DEPARTURE = 0x1 + IFF_ALLMULTI = 0x200 + IFF_BROADCAST = 0x2 + IFF_CANTCHANGE = 0x8e52 + IFF_DEBUG = 0x4 + IFF_LINK0 = 0x1000 + IFF_LINK1 = 0x2000 + IFF_LINK2 = 0x4000 + IFF_LOOPBACK = 0x8 + IFF_MULTICAST = 0x8000 + IFF_NOARP = 0x80 + IFF_OACTIVE = 0x400 + IFF_POINTOPOINT = 0x10 + IFF_PROMISC = 0x100 + IFF_RUNNING = 0x40 + IFF_SIMPLEX = 0x800 + IFF_STATICARP = 0x20 + IFF_UP = 0x1 + IFNAMSIZ = 0x10 + IFT_1822 = 0x2 + IFT_A12MPPSWITCH = 0x82 + IFT_AAL2 = 0xbb + IFT_AAL5 = 0x31 + IFT_ADSL = 0x5e + IFT_AFLANE8023 = 0x3b + IFT_AFLANE8025 = 0x3c + IFT_ARAP = 0x58 + IFT_ARCNET = 0x23 + IFT_ARCNETPLUS = 0x24 + IFT_ASYNC = 0x54 + IFT_ATM = 0x25 + IFT_ATMDXI = 0x69 + IFT_ATMFUNI = 0x6a + IFT_ATMIMA = 0x6b + IFT_ATMLOGICAL = 0x50 + IFT_ATMRADIO = 0xbd + IFT_ATMSUBINTERFACE = 0x86 + IFT_ATMVCIENDPT = 0xc2 + IFT_ATMVIRTUAL = 0x95 + IFT_BGPPOLICYACCOUNTING = 0xa2 + IFT_BLUETOOTH = 0xf8 + IFT_BRIDGE = 0xd1 + IFT_BSC = 0x53 + IFT_CARP = 0xf7 + IFT_CCTEMUL = 0x3d + IFT_CEPT = 0x13 + IFT_CES = 0x85 + IFT_CHANNEL = 0x46 + IFT_CNR = 0x55 + IFT_COFFEE = 0x84 + IFT_COMPOSITELINK = 0x9b + IFT_DCN = 0x8d + IFT_DIGITALPOWERLINE = 0x8a + IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba + IFT_DLSW = 0x4a + IFT_DOCSCABLEDOWNSTREAM = 0x80 + IFT_DOCSCABLEMACLAYER = 0x7f + IFT_DOCSCABLEUPSTREAM = 0x81 + IFT_DOCSCABLEUPSTREAMCHANNEL = 0xcd + IFT_DS0 = 0x51 + IFT_DS0BUNDLE = 0x52 + IFT_DS1FDL = 0xaa + IFT_DS3 = 0x1e + IFT_DTM = 0x8c + IFT_DUMMY = 0xf1 + IFT_DVBASILN = 0xac + IFT_DVBASIOUT = 0xad + IFT_DVBRCCDOWNSTREAM = 0x93 + IFT_DVBRCCMACLAYER = 0x92 + IFT_DVBRCCUPSTREAM = 0x94 + IFT_ECONET = 0xce + IFT_ENC = 0xf4 + IFT_EON = 0x19 + IFT_EPLRS = 0x57 + IFT_ESCON = 0x49 + IFT_ETHER = 0x6 + IFT_FAITH = 0xf3 + IFT_FAST = 0x7d + IFT_FASTETHER = 0x3e + IFT_FASTETHERFX = 0x45 + IFT_FDDI = 0xf + IFT_FIBRECHANNEL = 0x38 + IFT_FRAMERELAYINTERCONNECT = 0x3a + IFT_FRAMERELAYMPI = 0x5c + IFT_FRDLCIENDPT = 0xc1 + IFT_FRELAY = 0x20 + IFT_FRELAYDCE = 0x2c + IFT_FRF16MFRBUNDLE = 0xa3 + IFT_FRFORWARD = 0x9e + IFT_G703AT2MB = 0x43 + IFT_G703AT64K = 0x42 + IFT_GIF = 0xf0 + IFT_GIGABITETHERNET = 0x75 + IFT_GR303IDT = 0xb2 + IFT_GR303RDT = 0xb1 + IFT_H323GATEKEEPER = 0xa4 + IFT_H323PROXY = 0xa5 + IFT_HDH1822 = 0x3 + IFT_HDLC = 0x76 + IFT_HDSL2 = 0xa8 + IFT_HIPERLAN2 = 0xb7 + IFT_HIPPI = 0x2f + IFT_HIPPIINTERFACE = 0x39 + IFT_HOSTPAD = 0x5a + IFT_HSSI = 0x2e + IFT_HY = 0xe + IFT_IBM370PARCHAN = 0x48 + IFT_IDSL = 0x9a + IFT_IEEE1394 = 0x90 + IFT_IEEE80211 = 0x47 + IFT_IEEE80212 = 0x37 + IFT_IEEE8023ADLAG = 0xa1 + IFT_IFGSN = 0x91 + IFT_IMT = 0xbe + IFT_INFINIBAND = 0xc7 + IFT_INTERLEAVE = 0x7c + IFT_IP = 0x7e + IFT_IPFORWARD = 0x8e + IFT_IPOVERATM = 0x72 + IFT_IPOVERCDLC = 0x6d + IFT_IPOVERCLAW = 0x6e + IFT_IPSWITCH = 0x4e + IFT_ISDN = 0x3f + IFT_ISDNBASIC = 0x14 + IFT_ISDNPRIMARY = 0x15 + IFT_ISDNS = 0x4b + IFT_ISDNU = 0x4c + IFT_ISO88022LLC = 0x29 + IFT_ISO88023 = 0x7 + IFT_ISO88024 = 0x8 + IFT_ISO88025 = 0x9 + IFT_ISO88025CRFPINT = 0x62 + IFT_ISO88025DTR = 0x56 + IFT_ISO88025FIBER = 0x73 + IFT_ISO88026 = 0xa + IFT_ISUP = 0xb3 + IFT_L2VLAN = 0x87 + IFT_L3IPVLAN = 0x88 + IFT_L3IPXVLAN = 0x89 + IFT_LAPB = 0x10 + IFT_LAPD = 0x4d + IFT_LAPF = 0x77 + IFT_LINEGROUP = 0xd2 + IFT_LOCALTALK = 0x2a + IFT_LOOP = 0x18 + IFT_MBIM = 0xfa + IFT_MEDIAMAILOVERIP = 0x8b + IFT_MFSIGLINK = 0xa7 + IFT_MIOX25 = 0x26 + IFT_MODEM = 0x30 + IFT_MPC = 0x71 + IFT_MPLS = 0xa6 + IFT_MPLSTUNNEL = 0x96 + IFT_MSDSL = 0x8f + IFT_MVL = 0xbf + IFT_MYRINET = 0x63 + IFT_NFAS = 0xaf + IFT_NSIP = 0x1b + IFT_OPTICALCHANNEL = 0xc3 + IFT_OPTICALTRANSPORT = 0xc4 + IFT_OTHER = 0x1 + IFT_P10 = 0xc + IFT_P80 = 0xd + IFT_PARA = 0x22 + IFT_PFLOG = 0xf5 + IFT_PFLOW = 0xf9 + IFT_PFSYNC = 0xf6 + IFT_PLC = 0xae + IFT_PON155 = 0xcf + IFT_PON622 = 0xd0 + IFT_POS = 0xab + IFT_PPP = 0x17 + IFT_PPPMULTILINKBUNDLE = 0x6c + IFT_PROPATM = 0xc5 + IFT_PROPBWAP2MP = 0xb8 + IFT_PROPCNLS = 0x59 + IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 + IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 + IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 + IFT_PROPMUX = 0x36 + IFT_PROPVIRTUAL = 0x35 + IFT_PROPWIRELESSP2P = 0x9d + IFT_PTPSERIAL = 0x16 + IFT_PVC = 0xf2 + IFT_Q2931 = 0xc9 + IFT_QLLC = 0x44 + IFT_RADIOMAC = 0xbc + IFT_RADSL = 0x5f + IFT_REACHDSL = 0xc0 + IFT_RFC1483 = 0x9f + IFT_RS232 = 0x21 + IFT_RSRB = 0x4f + IFT_SDLC = 0x11 + IFT_SDSL = 0x60 + IFT_SHDSL = 0xa9 + IFT_SIP = 0x1f + IFT_SIPSIG = 0xcc + IFT_SIPTG = 0xcb + IFT_SLIP = 0x1c + IFT_SMDSDXI = 0x2b + IFT_SMDSICIP = 0x34 + IFT_SONET = 0x27 + IFT_SONETOVERHEADCHANNEL = 0xb9 + IFT_SONETPATH = 0x32 + IFT_SONETVT = 0x33 + IFT_SRP = 0x97 + IFT_SS7SIGLINK = 0x9c + IFT_STACKTOSTACK = 0x6f + IFT_STARLAN = 0xb + IFT_T1 = 0x12 + IFT_TDLC = 0x74 + IFT_TELINK = 0xc8 + IFT_TERMPAD = 0x5b + IFT_TR008 = 0xb0 + IFT_TRANSPHDLC = 0x7b + IFT_TUNNEL = 0x83 + IFT_ULTRA = 0x1d + IFT_USB = 0xa0 + IFT_V11 = 0x40 + IFT_V35 = 0x2d + IFT_V36 = 0x41 + IFT_V37 = 0x78 + IFT_VDSL = 0x61 + IFT_VIRTUALIPADDRESS = 0x70 + IFT_VIRTUALTG = 0xca + IFT_VOICEDID = 0xd5 + IFT_VOICEEM = 0x64 + IFT_VOICEEMFGD = 0xd3 + IFT_VOICEENCAP = 0x67 + IFT_VOICEFGDEANA = 0xd4 + IFT_VOICEFXO = 0x65 + IFT_VOICEFXS = 0x66 + IFT_VOICEOVERATM = 0x98 + IFT_VOICEOVERCABLE = 0xc6 + IFT_VOICEOVERFRAMERELAY = 0x99 + IFT_VOICEOVERIP = 0x68 + IFT_X213 = 0x5d + IFT_X25 = 0x5 + IFT_X25DDN = 0x4 + IFT_X25HUNTGROUP = 0x7a + IFT_X25MLP = 0x79 + IFT_X25PLE = 0x28 + IFT_XETHER = 0x1a + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLASSD_HOST = 0xfffffff + IN_CLASSD_NET = 0xf0000000 + IN_CLASSD_NSHIFT = 0x1c + IN_LOOPBACKNET = 0x7f + IN_RFC3021_HOST = 0x1 + IN_RFC3021_NET = 0xfffffffe + IN_RFC3021_NSHIFT = 0x1f + IPPROTO_AH = 0x33 + IPPROTO_CARP = 0x70 + IPPROTO_DIVERT = 0x102 + IPPROTO_DONE = 0x101 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_ENCAP = 0x62 + IPPROTO_EON = 0x50 + IPPROTO_ESP = 0x32 + IPPROTO_ETHERIP = 0x61 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GGP = 0x3 + IPPROTO_GRE = 0x2f + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IGMP = 0x2 + IPPROTO_IP = 0x0 + IPPROTO_IPCOMP = 0x6c + IPPROTO_IPIP = 0x4 + IPPROTO_IPV4 = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_MAX = 0x100 + IPPROTO_MAXID = 0x103 + IPPROTO_MOBILE = 0x37 + IPPROTO_MPLS = 0x89 + IPPROTO_NONE = 0x3b + IPPROTO_PFSYNC = 0xf0 + IPPROTO_PIM = 0x67 + IPPROTO_PUP = 0xc + IPPROTO_RAW = 0xff + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_UDP = 0x11 + IPV6_AUTH_LEVEL = 0x35 + IPV6_AUTOFLOWLABEL = 0x3b + IPV6_CHECKSUM = 0x1a + IPV6_DEFAULT_MULTICAST_HOPS = 0x1 + IPV6_DEFAULT_MULTICAST_LOOP = 0x1 + IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 + IPV6_ESP_NETWORK_LEVEL = 0x37 + IPV6_ESP_TRANS_LEVEL = 0x36 + IPV6_FAITH = 0x1d + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FRAGTTL = 0x78 + IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 + IPV6_IPCOMP_LEVEL = 0x3c + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_MAXHLIM = 0xff + IPV6_MAXPACKET = 0xffff + IPV6_MINHOPCOUNT = 0x41 + IPV6_MMTU = 0x500 + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_OPTIONS = 0x1 + IPV6_PATHMTU = 0x2c + IPV6_PIPEX = 0x3f + IPV6_PKTINFO = 0x2e + IPV6_PORTRANGE = 0xe + IPV6_PORTRANGE_DEFAULT = 0x0 + IPV6_PORTRANGE_HIGH = 0x1 + IPV6_PORTRANGE_LOW = 0x2 + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVDSTPORT = 0x40 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x24 + IPV6_RECVRTHDR = 0x26 + IPV6_RECVTCLASS = 0x39 + IPV6_RTABLE = 0x1021 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x23 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_SOCKOPT_RESERVED1 = 0x3 + IPV6_TCLASS = 0x3d + IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a + IPV6_V6ONLY = 0x1b + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 + IP_ADD_MEMBERSHIP = 0xc + IP_AUTH_LEVEL = 0x14 + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DROP_MEMBERSHIP = 0xd + IP_ESP_NETWORK_LEVEL = 0x16 + IP_ESP_TRANS_LEVEL = 0x15 + IP_HDRINCL = 0x2 + IP_IPCOMP_LEVEL = 0x1d + IP_IPDEFTTL = 0x25 + IP_IPSECFLOWINFO = 0x24 + IP_IPSEC_LOCAL_AUTH = 0x1b + IP_IPSEC_LOCAL_CRED = 0x19 + IP_IPSEC_LOCAL_ID = 0x17 + IP_IPSEC_REMOTE_AUTH = 0x1c + IP_IPSEC_REMOTE_CRED = 0x1a + IP_IPSEC_REMOTE_ID = 0x18 + IP_MAXPACKET = 0xffff + IP_MAX_MEMBERSHIPS = 0xfff + IP_MF = 0x2000 + IP_MINTTL = 0x20 + IP_MIN_MEMBERSHIPS = 0xf + IP_MSS = 0x240 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_LOOP = 0xb + IP_MULTICAST_TTL = 0xa + IP_OFFMASK = 0x1fff + IP_OPTIONS = 0x1 + IP_PIPEX = 0x22 + IP_PORTRANGE = 0x13 + IP_PORTRANGE_DEFAULT = 0x0 + IP_PORTRANGE_HIGH = 0x1 + IP_PORTRANGE_LOW = 0x2 + IP_RECVDSTADDR = 0x7 + IP_RECVDSTPORT = 0x21 + IP_RECVIF = 0x1e + IP_RECVOPTS = 0x5 + IP_RECVRETOPTS = 0x6 + IP_RECVRTABLE = 0x23 + IP_RECVTTL = 0x1f + IP_RETOPTS = 0x8 + IP_RF = 0x8000 + IP_RTABLE = 0x1021 + IP_SENDSRCADDR = 0x7 + IP_TOS = 0x3 + IP_TTL = 0x4 + ISIG = 0x80 + ISTRIP = 0x20 + IUCLC = 0x1000 + IXANY = 0x800 + IXOFF = 0x400 + IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 + LCNT_OVERLOAD_FLUSH = 0x6 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_DONTNEED = 0x4 + MADV_FREE = 0x6 + MADV_NORMAL = 0x0 + MADV_RANDOM = 0x1 + MADV_SEQUENTIAL = 0x2 + MADV_SPACEAVAIL = 0x5 + MADV_WILLNEED = 0x3 + MAP_ANON = 0x1000 + MAP_ANONYMOUS = 0x1000 + MAP_CONCEAL = 0x8000 + MAP_COPY = 0x2 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_FLAGMASK = 0xfff7 + MAP_HASSEMAPHORE = 0x0 + MAP_INHERIT = 0x0 + MAP_INHERIT_COPY = 0x1 + MAP_INHERIT_NONE = 0x2 + MAP_INHERIT_SHARE = 0x0 + MAP_INHERIT_ZERO = 0x3 + MAP_NOEXTEND = 0x0 + MAP_NORESERVE = 0x0 + MAP_PRIVATE = 0x2 + MAP_RENAME = 0x0 + MAP_SHARED = 0x1 + MAP_STACK = 0x4000 + MAP_TRYFIXED = 0x0 + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MNT_ASYNC = 0x40 + MNT_DEFEXPORTED = 0x200 + MNT_DELEXPORT = 0x20000 + MNT_DOOMED = 0x8000000 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXRDONLY = 0x80 + MNT_FORCE = 0x80000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_NOATIME = 0x8000 + MNT_NODEV = 0x10 + MNT_NOEXEC = 0x4 + MNT_NOPERM = 0x20 + MNT_NOSUID = 0x8 + MNT_NOWAIT = 0x2 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SOFTDEP = 0x4000000 + MNT_STALLED = 0x100000 + MNT_SWAPPABLE = 0x200000 + MNT_SYNCHRONOUS = 0x2 + MNT_UPDATE = 0x10000 + MNT_VISFLAGMASK = 0x400ffff + MNT_WAIT = 0x1 + MNT_WANTRDWR = 0x2000000 + MNT_WXALLOWED = 0x800 + MSG_BCAST = 0x100 + MSG_CMSG_CLOEXEC = 0x800 + MSG_CTRUNC = 0x20 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x80 + MSG_EOR = 0x8 + MSG_MCAST = 0x200 + MSG_NOSIGNAL = 0x400 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_TRUNC = 0x10 + MSG_WAITALL = 0x40 + MS_ASYNC = 0x1 + MS_INVALIDATE = 0x4 + MS_SYNC = 0x2 + NAME_MAX = 0xff + NET_RT_DUMP = 0x1 + NET_RT_FLAGS = 0x2 + NET_RT_IFLIST = 0x3 + NET_RT_IFNAMES = 0x6 + NET_RT_MAXID = 0x7 + NET_RT_STATS = 0x4 + NET_RT_TABLE = 0x5 + NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 + NOTE_ATTRIB = 0x8 + NOTE_CHANGE = 0x1 + NOTE_CHILD = 0x4 + NOTE_DELETE = 0x1 + NOTE_EOF = 0x2 + NOTE_EXEC = 0x20000000 + NOTE_EXIT = 0x80000000 + NOTE_EXTEND = 0x4 + NOTE_FORK = 0x40000000 + NOTE_LINK = 0x10 + NOTE_LOWAT = 0x1 + NOTE_PCTRLMASK = 0xf0000000 + NOTE_PDATAMASK = 0xfffff + NOTE_RENAME = 0x20 + NOTE_REVOKE = 0x40 + NOTE_TRACK = 0x1 + NOTE_TRACKERR = 0x2 + NOTE_TRUNCATE = 0x80 + NOTE_WRITE = 0x2 + OCRNL = 0x10 + OLCUC = 0x20 + ONLCR = 0x2 + ONLRET = 0x80 + ONOCR = 0x40 + ONOEOT = 0x8 + OPOST = 0x1 + OXTABS = 0x4 + O_ACCMODE = 0x3 + O_APPEND = 0x8 + O_ASYNC = 0x40 + O_CLOEXEC = 0x10000 + O_CREAT = 0x200 + O_DIRECTORY = 0x20000 + O_DSYNC = 0x80 + O_EXCL = 0x800 + O_EXLOCK = 0x20 + O_FSYNC = 0x80 + O_NDELAY = 0x4 + O_NOCTTY = 0x8000 + O_NOFOLLOW = 0x100 + O_NONBLOCK = 0x4 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_RSYNC = 0x80 + O_SHLOCK = 0x10 + O_SYNC = 0x80 + O_TRUNC = 0x400 + O_WRONLY = 0x1 + PARENB = 0x1000 + PARMRK = 0x8 + PARODD = 0x2000 + PENDIN = 0x20000000 + PF_FLUSH = 0x1 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PROT_EXEC = 0x4 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 + RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0x7fffffffffffffff + RTAX_AUTHOR = 0x6 + RTAX_BFD = 0xb + RTAX_BRD = 0x7 + RTAX_DNS = 0xc + RTAX_DST = 0x0 + RTAX_GATEWAY = 0x1 + RTAX_GENMASK = 0x3 + RTAX_IFA = 0x5 + RTAX_IFP = 0x4 + RTAX_LABEL = 0xa + RTAX_MAX = 0xf + RTAX_NETMASK = 0x2 + RTAX_SEARCH = 0xe + RTAX_SRC = 0x8 + RTAX_SRCMASK = 0x9 + RTAX_STATIC = 0xd + RTA_AUTHOR = 0x40 + RTA_BFD = 0x800 + RTA_BRD = 0x80 + RTA_DNS = 0x1000 + RTA_DST = 0x1 + RTA_GATEWAY = 0x2 + RTA_GENMASK = 0x8 + RTA_IFA = 0x20 + RTA_IFP = 0x10 + RTA_LABEL = 0x400 + RTA_NETMASK = 0x4 + RTA_SEARCH = 0x4000 + RTA_SRC = 0x100 + RTA_SRCMASK = 0x200 + RTA_STATIC = 0x2000 + RTF_ANNOUNCE = 0x4000 + RTF_BFD = 0x1000000 + RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_CACHED = 0x20000 + RTF_CLONED = 0x10000 + RTF_CLONING = 0x100 + RTF_CONNECTED = 0x800000 + RTF_DONE = 0x40 + RTF_DYNAMIC = 0x10 + RTF_FMASK = 0x110fc08 + RTF_GATEWAY = 0x2 + RTF_HOST = 0x4 + RTF_LLINFO = 0x400 + RTF_LOCAL = 0x200000 + RTF_MODIFIED = 0x20 + RTF_MPATH = 0x40000 + RTF_MPLS = 0x100000 + RTF_MULTICAST = 0x200 + RTF_PERMANENT_ARP = 0x2000 + RTF_PROTO1 = 0x8000 + RTF_PROTO2 = 0x4000 + RTF_PROTO3 = 0x2000 + RTF_REJECT = 0x8 + RTF_STATIC = 0x800 + RTF_UP = 0x1 + RTF_USETRAILERS = 0x8000 + RTM_80211INFO = 0x15 + RTM_ADD = 0x1 + RTM_BFD = 0x12 + RTM_CHANGE = 0x3 + RTM_CHGADDRATTR = 0x14 + RTM_DELADDR = 0xd + RTM_DELETE = 0x2 + RTM_DESYNC = 0x10 + RTM_GET = 0x4 + RTM_IFANNOUNCE = 0xf + RTM_IFINFO = 0xe + RTM_INVALIDATE = 0x11 + RTM_LOSING = 0x5 + RTM_MAXSIZE = 0x800 + RTM_MISS = 0x7 + RTM_NEWADDR = 0xc + RTM_PROPOSAL = 0x13 + RTM_REDIRECT = 0x6 + RTM_RESOLVE = 0xb + RTM_RTTUNIT = 0xf4240 + RTM_VERSION = 0x5 + RTV_EXPIRE = 0x4 + RTV_HOPCOUNT = 0x2 + RTV_MTU = 0x1 + RTV_RPIPE = 0x8 + RTV_RTT = 0x40 + RTV_RTTVAR = 0x80 + RTV_SPIPE = 0x10 + RTV_SSTHRESH = 0x20 + RT_TABLEID_BITS = 0x8 + RT_TABLEID_MASK = 0xff + RT_TABLEID_MAX = 0xff + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + RUSAGE_THREAD = 0x1 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x4 + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDMULTI = 0x80206931 + SIOCAIFADDR = 0x8040691a + SIOCAIFGROUP = 0x80286987 + SIOCATMARK = 0x40047307 + SIOCBRDGADD = 0x8060693c + SIOCBRDGADDL = 0x80606949 + SIOCBRDGADDS = 0x80606941 + SIOCBRDGARL = 0x808c694d + SIOCBRDGDADDR = 0x81286947 + SIOCBRDGDEL = 0x8060693d + SIOCBRDGDELS = 0x80606942 + SIOCBRDGFLUSH = 0x80606948 + SIOCBRDGFRL = 0x808c694e + SIOCBRDGGCACHE = 0xc0186941 + SIOCBRDGGFD = 0xc0186952 + SIOCBRDGGHT = 0xc0186951 + SIOCBRDGGIFFLGS = 0xc060693e + SIOCBRDGGMA = 0xc0186953 + SIOCBRDGGPARAM = 0xc0406958 + SIOCBRDGGPRI = 0xc0186950 + SIOCBRDGGRL = 0xc030694f + SIOCBRDGGTO = 0xc0186946 + SIOCBRDGIFS = 0xc0606942 + SIOCBRDGRTS = 0xc0206943 + SIOCBRDGSADDR = 0xc1286944 + SIOCBRDGSCACHE = 0x80186940 + SIOCBRDGSFD = 0x80186952 + SIOCBRDGSHT = 0x80186951 + SIOCBRDGSIFCOST = 0x80606955 + SIOCBRDGSIFFLGS = 0x8060693f + SIOCBRDGSIFPRIO = 0x80606954 + SIOCBRDGSIFPROT = 0x8060694a + SIOCBRDGSMA = 0x80186953 + SIOCBRDGSPRI = 0x80186950 + SIOCBRDGSPROTO = 0x8018695a + SIOCBRDGSTO = 0x80186945 + SIOCBRDGSTXHC = 0x80186959 + SIOCDELLABEL = 0x80206997 + SIOCDELMULTI = 0x80206932 + SIOCDIFADDR = 0x80206919 + SIOCDIFGROUP = 0x80286989 + SIOCDIFPARENT = 0x802069b4 + SIOCDIFPHYADDR = 0x80206949 + SIOCDPWE3NEIGHBOR = 0x802069de + SIOCDVNETID = 0x802069af + SIOCGETKALIVE = 0xc01869a4 + SIOCGETLABEL = 0x8020699a + SIOCGETMPWCFG = 0xc02069ae + SIOCGETPFLOW = 0xc02069fe + SIOCGETPFSYNC = 0xc02069f8 + SIOCGETSGCNT = 0xc0207534 + SIOCGETVIFCNT = 0xc0287533 + SIOCGETVLAN = 0xc0206990 + SIOCGIFADDR = 0xc0206921 + SIOCGIFBRDADDR = 0xc0206923 + SIOCGIFCONF = 0xc0106924 + SIOCGIFDATA = 0xc020691b + SIOCGIFDESCR = 0xc0206981 + SIOCGIFDSTADDR = 0xc0206922 + SIOCGIFFLAGS = 0xc0206911 + SIOCGIFGATTR = 0xc028698b + SIOCGIFGENERIC = 0xc020693a + SIOCGIFGLIST = 0xc028698d + SIOCGIFGMEMB = 0xc028698a + SIOCGIFGROUP = 0xc0286988 + SIOCGIFHARDMTU = 0xc02069a5 + SIOCGIFLLPRIO = 0xc02069b6 + SIOCGIFMEDIA = 0xc0406938 + SIOCGIFMETRIC = 0xc0206917 + SIOCGIFMTU = 0xc020697e + SIOCGIFNETMASK = 0xc0206925 + SIOCGIFPAIR = 0xc02069b1 + SIOCGIFPARENT = 0xc02069b3 + SIOCGIFPRIORITY = 0xc020699c + SIOCGIFRDOMAIN = 0xc02069a0 + SIOCGIFRTLABEL = 0xc0206983 + SIOCGIFRXR = 0x802069aa + SIOCGIFSFFPAGE = 0xc1126939 + SIOCGIFXFLAGS = 0xc020699e + SIOCGLIFPHYADDR = 0xc218694b + SIOCGLIFPHYDF = 0xc02069c2 + SIOCGLIFPHYECN = 0xc02069c8 + SIOCGLIFPHYRTABLE = 0xc02069a2 + SIOCGLIFPHYTTL = 0xc02069a9 + SIOCGPGRP = 0x40047309 + SIOCGPWE3 = 0xc0206998 + SIOCGPWE3CTRLWORD = 0xc02069dc + SIOCGPWE3FAT = 0xc02069dd + SIOCGPWE3NEIGHBOR = 0xc21869de + SIOCGSPPPPARAMS = 0xc0206994 + SIOCGTXHPRIO = 0xc02069c6 + SIOCGUMBINFO = 0xc02069be + SIOCGUMBPARAM = 0xc02069c0 + SIOCGVH = 0xc02069f6 + SIOCGVNETFLOWID = 0xc02069c4 + SIOCGVNETID = 0xc02069a7 + SIOCIFAFATTACH = 0x801169ab + SIOCIFAFDETACH = 0x801169ac + SIOCIFCREATE = 0x8020697a + SIOCIFDESTROY = 0x80206979 + SIOCIFGCLONERS = 0xc0106978 + SIOCSETKALIVE = 0x801869a3 + SIOCSETLABEL = 0x80206999 + SIOCSETMPWCFG = 0x802069ad + SIOCSETPFLOW = 0x802069fd + SIOCSETPFSYNC = 0x802069f7 + SIOCSETVLAN = 0x8020698f + SIOCSIFADDR = 0x8020690c + SIOCSIFBRDADDR = 0x80206913 + SIOCSIFDESCR = 0x80206980 + SIOCSIFDSTADDR = 0x8020690e + SIOCSIFFLAGS = 0x80206910 + SIOCSIFGATTR = 0x8028698c + SIOCSIFGENERIC = 0x80206939 + SIOCSIFLLADDR = 0x8020691f + SIOCSIFLLPRIO = 0x802069b5 + SIOCSIFMEDIA = 0xc0206937 + SIOCSIFMETRIC = 0x80206918 + SIOCSIFMTU = 0x8020697f + SIOCSIFNETMASK = 0x80206916 + SIOCSIFPAIR = 0x802069b0 + SIOCSIFPARENT = 0x802069b2 + SIOCSIFPRIORITY = 0x8020699b + SIOCSIFRDOMAIN = 0x8020699f + SIOCSIFRTLABEL = 0x80206982 + SIOCSIFXFLAGS = 0x8020699d + SIOCSLIFPHYADDR = 0x8218694a + SIOCSLIFPHYDF = 0x802069c1 + SIOCSLIFPHYECN = 0x802069c7 + SIOCSLIFPHYRTABLE = 0x802069a1 + SIOCSLIFPHYTTL = 0x802069a8 + SIOCSPGRP = 0x80047308 + SIOCSPWE3CTRLWORD = 0x802069dc + SIOCSPWE3FAT = 0x802069dd + SIOCSPWE3NEIGHBOR = 0x821869de + SIOCSSPPPPARAMS = 0x80206993 + SIOCSTXHPRIO = 0x802069c5 + SIOCSUMBPARAM = 0x802069bf + SIOCSVH = 0xc02069f5 + SIOCSVNETFLOWID = 0x802069c3 + SIOCSVNETID = 0x802069a6 + SIOCSWGDPID = 0xc018695b + SIOCSWGMAXFLOW = 0xc0186960 + SIOCSWGMAXGROUP = 0xc018695d + SIOCSWSDPID = 0x8018695c + SIOCSWSPORTNO = 0xc060695f + SOCK_CLOEXEC = 0x8000 + SOCK_DGRAM = 0x2 + SOCK_DNS = 0x1000 + SOCK_NONBLOCK = 0x4000 + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_SOCKET = 0xffff + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x2 + SO_BINDANY = 0x1000 + SO_BROADCAST = 0x20 + SO_DEBUG = 0x1 + SO_DONTROUTE = 0x10 + SO_ERROR = 0x1007 + SO_KEEPALIVE = 0x8 + SO_LINGER = 0x80 + SO_NETPROC = 0x1020 + SO_OOBINLINE = 0x100 + SO_PEERCRED = 0x1022 + SO_RCVBUF = 0x1002 + SO_RCVLOWAT = 0x1004 + SO_RCVTIMEO = 0x1006 + SO_REUSEADDR = 0x4 + SO_REUSEPORT = 0x200 + SO_RTABLE = 0x1021 + SO_SNDBUF = 0x1001 + SO_SNDLOWAT = 0x1003 + SO_SNDTIMEO = 0x1005 + SO_SPLICE = 0x1023 + SO_TIMESTAMP = 0x800 + SO_TYPE = 0x1008 + SO_USELOOPBACK = 0x40 + SO_ZEROIZE = 0x2000 + S_BLKSIZE = 0x200 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + TCIFLUSH = 0x1 + TCIOFF = 0x3 + TCIOFLUSH = 0x3 + TCION = 0x4 + TCOFLUSH = 0x2 + TCOOFF = 0x1 + TCOON = 0x2 + TCP_MAXBURST = 0x4 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_SACK = 0x3 + TCP_MAX_WINSHIFT = 0xe + TCP_MD5SIG = 0x4 + TCP_MSS = 0x200 + TCP_NODELAY = 0x1 + TCP_NOPUSH = 0x10 + TCP_SACK_ENABLE = 0x8 + TCSAFLUSH = 0x2 + TIMER_ABSTIME = 0x1 + TIMER_RELTIME = 0x0 + TIOCCBRK = 0x2000747a + TIOCCDTR = 0x20007478 + TIOCCHKVERAUTH = 0x2000741e + TIOCCLRVERAUTH = 0x2000741d + TIOCCONS = 0x80047462 + TIOCDRAIN = 0x2000745e + TIOCEXCL = 0x2000740d + TIOCEXT = 0x80047460 + TIOCFLAG_CLOCAL = 0x2 + TIOCFLAG_CRTSCTS = 0x4 + TIOCFLAG_MDMBUF = 0x8 + TIOCFLAG_PPS = 0x10 + TIOCFLAG_SOFTCAR = 0x1 + TIOCFLUSH = 0x80047410 + TIOCGETA = 0x402c7413 + TIOCGETD = 0x4004741a + TIOCGFLAGS = 0x4004745d + TIOCGPGRP = 0x40047477 + TIOCGSID = 0x40047463 + TIOCGTSTAMP = 0x4010745b + TIOCGWINSZ = 0x40087468 + TIOCMBIC = 0x8004746b + TIOCMBIS = 0x8004746c + TIOCMGET = 0x4004746a + TIOCMODG = 0x4004746a + TIOCMODS = 0x8004746d + TIOCMSET = 0x8004746d + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x20007471 + TIOCNXCL = 0x2000740e + TIOCOUTQ = 0x40047473 + TIOCPKT = 0x80047470 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCREMOTE = 0x80047469 + TIOCSBRK = 0x2000747b + TIOCSCTTY = 0x20007461 + TIOCSDTR = 0x20007479 + TIOCSETA = 0x802c7414 + TIOCSETAF = 0x802c7416 + TIOCSETAW = 0x802c7415 + TIOCSETD = 0x8004741b + TIOCSETVERAUTH = 0x8004741c + TIOCSFLAGS = 0x8004745c + TIOCSIG = 0x8004745f + TIOCSPGRP = 0x80047476 + TIOCSTART = 0x2000746e + TIOCSTAT = 0x20007465 + TIOCSTOP = 0x2000746f + TIOCSTSTAMP = 0x8008745a + TIOCSWINSZ = 0x80087467 + TIOCUCNTL = 0x80047466 + TIOCUCNTL_CBRK = 0x7a + TIOCUCNTL_SBRK = 0x7b + TOSTOP = 0x400000 + UTIME_NOW = -0x2 + UTIME_OMIT = -0x1 + VDISCARD = 0xf + VDSUSP = 0xb + VEOF = 0x0 + VEOL = 0x1 + VEOL2 = 0x2 + VERASE = 0x3 + VINTR = 0x8 + VKILL = 0x5 + VLNEXT = 0xe + VMIN = 0x10 + VM_ANONMIN = 0x7 + VM_LOADAVG = 0x2 + VM_MALLOC_CONF = 0xc + VM_MAXID = 0xd + VM_MAXSLP = 0xa + VM_METER = 0x1 + VM_NKMEMPAGES = 0x6 + VM_PSSTRINGS = 0x3 + VM_SWAPENCRYPT = 0x5 + VM_USPACE = 0xb + VM_UVMEXP = 0x4 + VM_VNODEMIN = 0x9 + VM_VTEXTMIN = 0x8 + VQUIT = 0x9 + VREPRINT = 0x6 + VSTART = 0xc + VSTATUS = 0x12 + VSTOP = 0xd + VSUSP = 0xa + VTIME = 0x11 + VWERASE = 0x4 + WALTSIG = 0x4 + WCONTINUED = 0x8 + WCOREFLAG = 0x80 + WNOHANG = 0x1 + WUNTRACED = 0x2 + XCASE = 0x1000000 +) + +// Errors +const ( + E2BIG = syscall.Errno(0x7) + EACCES = syscall.Errno(0xd) + EADDRINUSE = syscall.Errno(0x30) + EADDRNOTAVAIL = syscall.Errno(0x31) + EAFNOSUPPORT = syscall.Errno(0x2f) + EAGAIN = syscall.Errno(0x23) + EALREADY = syscall.Errno(0x25) + EAUTH = syscall.Errno(0x50) + EBADF = syscall.Errno(0x9) + EBADMSG = syscall.Errno(0x5c) + EBADRPC = syscall.Errno(0x48) + EBUSY = syscall.Errno(0x10) + ECANCELED = syscall.Errno(0x58) + ECHILD = syscall.Errno(0xa) + ECONNABORTED = syscall.Errno(0x35) + ECONNREFUSED = syscall.Errno(0x3d) + ECONNRESET = syscall.Errno(0x36) + EDEADLK = syscall.Errno(0xb) + EDESTADDRREQ = syscall.Errno(0x27) + EDOM = syscall.Errno(0x21) + EDQUOT = syscall.Errno(0x45) + EEXIST = syscall.Errno(0x11) + EFAULT = syscall.Errno(0xe) + EFBIG = syscall.Errno(0x1b) + EFTYPE = syscall.Errno(0x4f) + EHOSTDOWN = syscall.Errno(0x40) + EHOSTUNREACH = syscall.Errno(0x41) + EIDRM = syscall.Errno(0x59) + EILSEQ = syscall.Errno(0x54) + EINPROGRESS = syscall.Errno(0x24) + EINTR = syscall.Errno(0x4) + EINVAL = syscall.Errno(0x16) + EIO = syscall.Errno(0x5) + EIPSEC = syscall.Errno(0x52) + EISCONN = syscall.Errno(0x38) + EISDIR = syscall.Errno(0x15) + ELAST = syscall.Errno(0x5f) + ELOOP = syscall.Errno(0x3e) + EMEDIUMTYPE = syscall.Errno(0x56) + EMFILE = syscall.Errno(0x18) + EMLINK = syscall.Errno(0x1f) + EMSGSIZE = syscall.Errno(0x28) + ENAMETOOLONG = syscall.Errno(0x3f) + ENEEDAUTH = syscall.Errno(0x51) + ENETDOWN = syscall.Errno(0x32) + ENETRESET = syscall.Errno(0x34) + ENETUNREACH = syscall.Errno(0x33) + ENFILE = syscall.Errno(0x17) + ENOATTR = syscall.Errno(0x53) + ENOBUFS = syscall.Errno(0x37) + ENODEV = syscall.Errno(0x13) + ENOENT = syscall.Errno(0x2) + ENOEXEC = syscall.Errno(0x8) + ENOLCK = syscall.Errno(0x4d) + ENOMEDIUM = syscall.Errno(0x55) + ENOMEM = syscall.Errno(0xc) + ENOMSG = syscall.Errno(0x5a) + ENOPROTOOPT = syscall.Errno(0x2a) + ENOSPC = syscall.Errno(0x1c) + ENOSYS = syscall.Errno(0x4e) + ENOTBLK = syscall.Errno(0xf) + ENOTCONN = syscall.Errno(0x39) + ENOTDIR = syscall.Errno(0x14) + ENOTEMPTY = syscall.Errno(0x42) + ENOTRECOVERABLE = syscall.Errno(0x5d) + ENOTSOCK = syscall.Errno(0x26) + ENOTSUP = syscall.Errno(0x5b) + ENOTTY = syscall.Errno(0x19) + ENXIO = syscall.Errno(0x6) + EOPNOTSUPP = syscall.Errno(0x2d) + EOVERFLOW = syscall.Errno(0x57) + EOWNERDEAD = syscall.Errno(0x5e) + EPERM = syscall.Errno(0x1) + EPFNOSUPPORT = syscall.Errno(0x2e) + EPIPE = syscall.Errno(0x20) + EPROCLIM = syscall.Errno(0x43) + EPROCUNAVAIL = syscall.Errno(0x4c) + EPROGMISMATCH = syscall.Errno(0x4b) + EPROGUNAVAIL = syscall.Errno(0x4a) + EPROTO = syscall.Errno(0x5f) + EPROTONOSUPPORT = syscall.Errno(0x2b) + EPROTOTYPE = syscall.Errno(0x29) + ERANGE = syscall.Errno(0x22) + EREMOTE = syscall.Errno(0x47) + EROFS = syscall.Errno(0x1e) + ERPCMISMATCH = syscall.Errno(0x49) + ESHUTDOWN = syscall.Errno(0x3a) + ESOCKTNOSUPPORT = syscall.Errno(0x2c) + ESPIPE = syscall.Errno(0x1d) + ESRCH = syscall.Errno(0x3) + ESTALE = syscall.Errno(0x46) + ETIMEDOUT = syscall.Errno(0x3c) + ETOOMANYREFS = syscall.Errno(0x3b) + ETXTBSY = syscall.Errno(0x1a) + EUSERS = syscall.Errno(0x44) + EWOULDBLOCK = syscall.Errno(0x23) + EXDEV = syscall.Errno(0x12) +) + +// Signals +const ( + SIGABRT = syscall.Signal(0x6) + SIGALRM = syscall.Signal(0xe) + SIGBUS = syscall.Signal(0xa) + SIGCHLD = syscall.Signal(0x14) + SIGCONT = syscall.Signal(0x13) + SIGEMT = syscall.Signal(0x7) + SIGFPE = syscall.Signal(0x8) + SIGHUP = syscall.Signal(0x1) + SIGILL = syscall.Signal(0x4) + SIGINFO = syscall.Signal(0x1d) + SIGINT = syscall.Signal(0x2) + SIGIO = syscall.Signal(0x17) + SIGIOT = syscall.Signal(0x6) + SIGKILL = syscall.Signal(0x9) + SIGPIPE = syscall.Signal(0xd) + SIGPROF = syscall.Signal(0x1b) + SIGQUIT = syscall.Signal(0x3) + SIGSEGV = syscall.Signal(0xb) + SIGSTOP = syscall.Signal(0x11) + SIGSYS = syscall.Signal(0xc) + SIGTERM = syscall.Signal(0xf) + SIGTHR = syscall.Signal(0x20) + SIGTRAP = syscall.Signal(0x5) + SIGTSTP = syscall.Signal(0x12) + SIGTTIN = syscall.Signal(0x15) + SIGTTOU = syscall.Signal(0x16) + SIGURG = syscall.Signal(0x10) + SIGUSR1 = syscall.Signal(0x1e) + SIGUSR2 = syscall.Signal(0x1f) + SIGVTALRM = syscall.Signal(0x1a) + SIGWINCH = syscall.Signal(0x1c) + SIGXCPU = syscall.Signal(0x18) + SIGXFSZ = syscall.Signal(0x19) +) + +// Error table +var errorList = [...]struct { + num syscall.Errno + name string + desc string +}{ + {1, "EPERM", "operation not permitted"}, + {2, "ENOENT", "no such file or directory"}, + {3, "ESRCH", "no such process"}, + {4, "EINTR", "interrupted system call"}, + {5, "EIO", "input/output error"}, + {6, "ENXIO", "device not configured"}, + {7, "E2BIG", "argument list too long"}, + {8, "ENOEXEC", "exec format error"}, + {9, "EBADF", "bad file descriptor"}, + {10, "ECHILD", "no child processes"}, + {11, "EDEADLK", "resource deadlock avoided"}, + {12, "ENOMEM", "cannot allocate memory"}, + {13, "EACCES", "permission denied"}, + {14, "EFAULT", "bad address"}, + {15, "ENOTBLK", "block device required"}, + {16, "EBUSY", "device busy"}, + {17, "EEXIST", "file exists"}, + {18, "EXDEV", "cross-device link"}, + {19, "ENODEV", "operation not supported by device"}, + {20, "ENOTDIR", "not a directory"}, + {21, "EISDIR", "is a directory"}, + {22, "EINVAL", "invalid argument"}, + {23, "ENFILE", "too many open files in system"}, + {24, "EMFILE", "too many open files"}, + {25, "ENOTTY", "inappropriate ioctl for device"}, + {26, "ETXTBSY", "text file busy"}, + {27, "EFBIG", "file too large"}, + {28, "ENOSPC", "no space left on device"}, + {29, "ESPIPE", "illegal seek"}, + {30, "EROFS", "read-only file system"}, + {31, "EMLINK", "too many links"}, + {32, "EPIPE", "broken pipe"}, + {33, "EDOM", "numerical argument out of domain"}, + {34, "ERANGE", "result too large"}, + {35, "EAGAIN", "resource temporarily unavailable"}, + {36, "EINPROGRESS", "operation now in progress"}, + {37, "EALREADY", "operation already in progress"}, + {38, "ENOTSOCK", "socket operation on non-socket"}, + {39, "EDESTADDRREQ", "destination address required"}, + {40, "EMSGSIZE", "message too long"}, + {41, "EPROTOTYPE", "protocol wrong type for socket"}, + {42, "ENOPROTOOPT", "protocol not available"}, + {43, "EPROTONOSUPPORT", "protocol not supported"}, + {44, "ESOCKTNOSUPPORT", "socket type not supported"}, + {45, "EOPNOTSUPP", "operation not supported"}, + {46, "EPFNOSUPPORT", "protocol family not supported"}, + {47, "EAFNOSUPPORT", "address family not supported by protocol family"}, + {48, "EADDRINUSE", "address already in use"}, + {49, "EADDRNOTAVAIL", "can't assign requested address"}, + {50, "ENETDOWN", "network is down"}, + {51, "ENETUNREACH", "network is unreachable"}, + {52, "ENETRESET", "network dropped connection on reset"}, + {53, "ECONNABORTED", "software caused connection abort"}, + {54, "ECONNRESET", "connection reset by peer"}, + {55, "ENOBUFS", "no buffer space available"}, + {56, "EISCONN", "socket is already connected"}, + {57, "ENOTCONN", "socket is not connected"}, + {58, "ESHUTDOWN", "can't send after socket shutdown"}, + {59, "ETOOMANYREFS", "too many references: can't splice"}, + {60, "ETIMEDOUT", "operation timed out"}, + {61, "ECONNREFUSED", "connection refused"}, + {62, "ELOOP", "too many levels of symbolic links"}, + {63, "ENAMETOOLONG", "file name too long"}, + {64, "EHOSTDOWN", "host is down"}, + {65, "EHOSTUNREACH", "no route to host"}, + {66, "ENOTEMPTY", "directory not empty"}, + {67, "EPROCLIM", "too many processes"}, + {68, "EUSERS", "too many users"}, + {69, "EDQUOT", "disk quota exceeded"}, + {70, "ESTALE", "stale NFS file handle"}, + {71, "EREMOTE", "too many levels of remote in path"}, + {72, "EBADRPC", "RPC struct is bad"}, + {73, "ERPCMISMATCH", "RPC version wrong"}, + {74, "EPROGUNAVAIL", "RPC program not available"}, + {75, "EPROGMISMATCH", "program version wrong"}, + {76, "EPROCUNAVAIL", "bad procedure for program"}, + {77, "ENOLCK", "no locks available"}, + {78, "ENOSYS", "function not implemented"}, + {79, "EFTYPE", "inappropriate file type or format"}, + {80, "EAUTH", "authentication error"}, + {81, "ENEEDAUTH", "need authenticator"}, + {82, "EIPSEC", "IPsec processing failure"}, + {83, "ENOATTR", "attribute not found"}, + {84, "EILSEQ", "illegal byte sequence"}, + {85, "ENOMEDIUM", "no medium found"}, + {86, "EMEDIUMTYPE", "wrong medium type"}, + {87, "EOVERFLOW", "value too large to be stored in data type"}, + {88, "ECANCELED", "operation canceled"}, + {89, "EIDRM", "identifier removed"}, + {90, "ENOMSG", "no message of desired type"}, + {91, "ENOTSUP", "not supported"}, + {92, "EBADMSG", "bad message"}, + {93, "ENOTRECOVERABLE", "state not recoverable"}, + {94, "EOWNERDEAD", "previous owner died"}, + {95, "ELAST", "protocol error"}, +} + +// Signal table +var signalList = [...]struct { + num syscall.Signal + name string + desc string +}{ + {1, "SIGHUP", "hangup"}, + {2, "SIGINT", "interrupt"}, + {3, "SIGQUIT", "quit"}, + {4, "SIGILL", "illegal instruction"}, + {5, "SIGTRAP", "trace/BPT trap"}, + {6, "SIGABRT", "abort trap"}, + {7, "SIGEMT", "EMT trap"}, + {8, "SIGFPE", "floating point exception"}, + {9, "SIGKILL", "killed"}, + {10, "SIGBUS", "bus error"}, + {11, "SIGSEGV", "segmentation fault"}, + {12, "SIGSYS", "bad system call"}, + {13, "SIGPIPE", "broken pipe"}, + {14, "SIGALRM", "alarm clock"}, + {15, "SIGTERM", "terminated"}, + {16, "SIGURG", "urgent I/O condition"}, + {17, "SIGSTOP", "suspended (signal)"}, + {18, "SIGTSTP", "suspended"}, + {19, "SIGCONT", "continued"}, + {20, "SIGCHLD", "child exited"}, + {21, "SIGTTIN", "stopped (tty input)"}, + {22, "SIGTTOU", "stopped (tty output)"}, + {23, "SIGIO", "I/O possible"}, + {24, "SIGXCPU", "cputime limit exceeded"}, + {25, "SIGXFSZ", "filesize limit exceeded"}, + {26, "SIGVTALRM", "virtual timer expired"}, + {27, "SIGPROF", "profiling timer expired"}, + {28, "SIGWINCH", "window size changes"}, + {29, "SIGINFO", "information request"}, + {30, "SIGUSR1", "user defined signal 1"}, + {31, "SIGUSR2", "user defined signal 2"}, + {32, "SIGTHR", "thread AST"}, +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go index 6bae21e5d894..4a9e99a0e123 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go @@ -1,4 +1,4 @@ -// mksyscall_aix_ppc.pl -aix -tags aix,ppc syscall_aix.go syscall_aix_ppc.go +// go run mksyscall_aix_ppc.go -aix -tags aix,ppc syscall_aix.go syscall_aix_ppc.go // Code generated by the command above; see README.md. DO NOT EDIT. // +build aix,ppc @@ -83,6 +83,8 @@ int lstat(uintptr_t, uintptr_t); int pause(); int pread64(int, uintptr_t, size_t, long long); int pwrite64(int, uintptr_t, size_t, long long); +#define c_select select +int select(int, uintptr_t, uintptr_t, uintptr_t, uintptr_t); int pselect(int, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); int setregid(int, int); int setreuid(int, int); @@ -103,8 +105,8 @@ int getpeername(int, uintptr_t, uintptr_t); int getsockname(int, uintptr_t, uintptr_t); int recvfrom(int, uintptr_t, size_t, int, uintptr_t, uintptr_t); int sendto(int, uintptr_t, size_t, int, uintptr_t, uintptr_t); -int recvmsg(int, uintptr_t, int); -int sendmsg(int, uintptr_t, int); +int nrecvmsg(int, uintptr_t, int); +int nsendmsg(int, uintptr_t, int); int munmap(uintptr_t, uintptr_t); int madvise(uintptr_t, size_t, int); int mprotect(uintptr_t, size_t, int); @@ -118,6 +120,8 @@ int poll(uintptr_t, int, int); int gettimeofday(uintptr_t, uintptr_t); int time(uintptr_t); int utime(uintptr_t, uintptr_t); +unsigned long long getsystemcfg(int); +int umount(uintptr_t); int getrlimit64(int, uintptr_t); int setrlimit64(int, uintptr_t); long long lseek64(int, long long, int); @@ -1004,6 +1008,17 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + r0, er := C.c_select(C.int(nfd), C.uintptr_t(uintptr(unsafe.Pointer(r))), C.uintptr_t(uintptr(unsafe.Pointer(w))), C.uintptr_t(uintptr(unsafe.Pointer(e))), C.uintptr_t(uintptr(unsafe.Pointer(timeout)))) + n = int(r0) + if r0 == -1 && er != nil { + err = er + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { r0, er := C.pselect(C.int(nfd), C.uintptr_t(uintptr(unsafe.Pointer(r))), C.uintptr_t(uintptr(unsafe.Pointer(w))), C.uintptr_t(uintptr(unsafe.Pointer(e))), C.uintptr_t(uintptr(unsafe.Pointer(timeout))), C.uintptr_t(uintptr(unsafe.Pointer(sigmask)))) n = int(r0) @@ -1225,7 +1240,7 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, er := C.recvmsg(C.int(s), C.uintptr_t(uintptr(unsafe.Pointer(msg))), C.int(flags)) + r0, er := C.nrecvmsg(C.int(s), C.uintptr_t(uintptr(unsafe.Pointer(msg))), C.int(flags)) n = int(r0) if r0 == -1 && er != nil { err = er @@ -1236,7 +1251,7 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, er := C.sendmsg(C.int(s), C.uintptr_t(uintptr(unsafe.Pointer(msg))), C.int(flags)) + r0, er := C.nsendmsg(C.int(s), C.uintptr_t(uintptr(unsafe.Pointer(msg))), C.int(flags)) n = int(r0) if r0 == -1 && er != nil { err = er @@ -1409,6 +1424,25 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsystemcfg(label int) (n uint64) { + r0, _ := C.getsystemcfg(C.int(label)) + n = uint64(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func umount(target string) (err error) { + _p0 := uintptr(unsafe.Pointer(C.CString(target))) + r0, er := C.umount(C.uintptr_t(_p0)) + if r0 == -1 && er != nil { + err = er + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getrlimit(resource int, rlim *Rlimit) (err error) { r0, er := C.getrlimit64(C.int(resource), C.uintptr_t(uintptr(unsafe.Pointer(rlim)))) if r0 == -1 && er != nil { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go index 3e929e520e08..c3371ddc2fff 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go @@ -1,4 +1,4 @@ -// mksyscall_aix_ppc64.pl -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go +// go run mksyscall_aix_ppc64.go -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go // Code generated by the command above; see README.md. DO NOT EDIT. // +build aix,ppc64 @@ -960,6 +960,17 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + r0, e1 := callselect(nfd, uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { r0, e1 := callpselect(nfd, uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) n = int(r0) @@ -1189,7 +1200,7 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, e1 := callrecvmsg(s, uintptr(unsafe.Pointer(msg)), flags) + r0, e1 := callnrecvmsg(s, uintptr(unsafe.Pointer(msg)), flags) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1200,7 +1211,7 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, e1 := callsendmsg(s, uintptr(unsafe.Pointer(msg)), flags) + r0, e1 := callnsendmsg(s, uintptr(unsafe.Pointer(msg)), flags) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1367,6 +1378,29 @@ func Utime(path string, buf *Utimbuf) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getsystemcfg(label int) (n uint64) { + r0, _ := callgetsystemcfg(label) + n = uint64(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func umount(target string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(target) + if err != nil { + return + } + _, e1 := callumount(uintptr(unsafe.Pointer(_p0))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getrlimit(resource int, rlim *Rlimit) (err error) { _, e1 := callgetrlimit(resource, uintptr(unsafe.Pointer(rlim))) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go index a185ee842412..4eda72323470 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go @@ -1,4 +1,4 @@ -// mksyscall_aix_ppc64.pl -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go +// go run mksyscall_aix_ppc64.go -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go // Code generated by the command above; see README.md. DO NOT EDIT. // +build aix,ppc64 @@ -85,6 +85,7 @@ import ( //go:cgo_import_dynamic libc_pause pause "libc.a/shr_64.o" //go:cgo_import_dynamic libc_pread64 pread64 "libc.a/shr_64.o" //go:cgo_import_dynamic libc_pwrite64 pwrite64 "libc.a/shr_64.o" +//go:cgo_import_dynamic libc_select select "libc.a/shr_64.o" //go:cgo_import_dynamic libc_pselect pselect "libc.a/shr_64.o" //go:cgo_import_dynamic libc_setregid setregid "libc.a/shr_64.o" //go:cgo_import_dynamic libc_setreuid setreuid "libc.a/shr_64.o" @@ -105,8 +106,8 @@ import ( //go:cgo_import_dynamic libc_getsockname getsockname "libc.a/shr_64.o" //go:cgo_import_dynamic libc_recvfrom recvfrom "libc.a/shr_64.o" //go:cgo_import_dynamic libc_sendto sendto "libc.a/shr_64.o" -//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.a/shr_64.o" -//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.a/shr_64.o" +//go:cgo_import_dynamic libc_nrecvmsg nrecvmsg "libc.a/shr_64.o" +//go:cgo_import_dynamic libc_nsendmsg nsendmsg "libc.a/shr_64.o" //go:cgo_import_dynamic libc_munmap munmap "libc.a/shr_64.o" //go:cgo_import_dynamic libc_madvise madvise "libc.a/shr_64.o" //go:cgo_import_dynamic libc_mprotect mprotect "libc.a/shr_64.o" @@ -120,6 +121,8 @@ import ( //go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.a/shr_64.o" //go:cgo_import_dynamic libc_time time "libc.a/shr_64.o" //go:cgo_import_dynamic libc_utime utime "libc.a/shr_64.o" +//go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o" +//go:cgo_import_dynamic libc_umount umount "libc.a/shr_64.o" //go:cgo_import_dynamic libc_getrlimit getrlimit "libc.a/shr_64.o" //go:cgo_import_dynamic libc_setrlimit setrlimit "libc.a/shr_64.o" //go:cgo_import_dynamic libc_lseek lseek "libc.a/shr_64.o" @@ -200,6 +203,7 @@ import ( //go:linkname libc_pause libc_pause //go:linkname libc_pread64 libc_pread64 //go:linkname libc_pwrite64 libc_pwrite64 +//go:linkname libc_select libc_select //go:linkname libc_pselect libc_pselect //go:linkname libc_setregid libc_setregid //go:linkname libc_setreuid libc_setreuid @@ -220,8 +224,8 @@ import ( //go:linkname libc_getsockname libc_getsockname //go:linkname libc_recvfrom libc_recvfrom //go:linkname libc_sendto libc_sendto -//go:linkname libc_recvmsg libc_recvmsg -//go:linkname libc_sendmsg libc_sendmsg +//go:linkname libc_nrecvmsg libc_nrecvmsg +//go:linkname libc_nsendmsg libc_nsendmsg //go:linkname libc_munmap libc_munmap //go:linkname libc_madvise libc_madvise //go:linkname libc_mprotect libc_mprotect @@ -235,6 +239,8 @@ import ( //go:linkname libc_gettimeofday libc_gettimeofday //go:linkname libc_time libc_time //go:linkname libc_utime libc_utime +//go:linkname libc_getsystemcfg libc_getsystemcfg +//go:linkname libc_umount libc_umount //go:linkname libc_getrlimit libc_getrlimit //go:linkname libc_setrlimit libc_setrlimit //go:linkname libc_lseek libc_lseek @@ -318,6 +324,7 @@ var ( libc_pause, libc_pread64, libc_pwrite64, + libc_select, libc_pselect, libc_setregid, libc_setreuid, @@ -338,8 +345,8 @@ var ( libc_getsockname, libc_recvfrom, libc_sendto, - libc_recvmsg, - libc_sendmsg, + libc_nrecvmsg, + libc_nsendmsg, libc_munmap, libc_madvise, libc_mprotect, @@ -353,6 +360,8 @@ var ( libc_gettimeofday, libc_time, libc_utime, + libc_getsystemcfg, + libc_umount, libc_getrlimit, libc_setrlimit, libc_lseek, @@ -890,6 +899,13 @@ func callpwrite64(fd int, _p0 uintptr, _lenp0 int, offset int64) (r1 uintptr, e1 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func callselect(nfd int, r uintptr, w uintptr, e uintptr, timeout uintptr) (r1 uintptr, e1 Errno) { + r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_select)), 5, uintptr(nfd), r, w, e, timeout, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func callpselect(nfd int, r uintptr, w uintptr, e uintptr, timeout uintptr, sigmask uintptr) (r1 uintptr, e1 Errno) { r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_pselect)), 6, uintptr(nfd), r, w, e, timeout, sigmask) return @@ -1030,15 +1046,15 @@ func callsendto(s int, _p0 uintptr, _lenp0 int, flags int, to uintptr, addrlen u // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func callrecvmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) { - r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_recvmsg)), 3, uintptr(s), msg, uintptr(flags), 0, 0, 0) +func callnrecvmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) { + r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_nrecvmsg)), 3, uintptr(s), msg, uintptr(flags), 0, 0, 0) return } // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func callsendmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) { - r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_sendmsg)), 3, uintptr(s), msg, uintptr(flags), 0, 0, 0) +func callnsendmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) { + r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_nsendmsg)), 3, uintptr(s), msg, uintptr(flags), 0, 0, 0) return } @@ -1135,6 +1151,20 @@ func callutime(_p0 uintptr, buf uintptr) (r1 uintptr, e1 Errno) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func callgetsystemcfg(label int) (r1 uintptr, e1 Errno) { + r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getsystemcfg)), 1, uintptr(label), 0, 0, 0, 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func callumount(_p0 uintptr) (r1 uintptr, e1 Errno) { + r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_umount)), 1, _p0, 0, 0, 0, 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func callgetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) { r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getrlimit)), 2, uintptr(resource), rlim, 0, 0, 0, 0) return diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go index aef7c0e78465..e5c4cbdd6c97 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go @@ -1,4 +1,4 @@ -// mksyscall_aix_ppc64.pl -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go +// go run mksyscall_aix_ppc64.go -aix -tags aix,ppc64 syscall_aix.go syscall_aix_ppc64.go // Code generated by the command above; see README.md. DO NOT EDIT. // +build aix,ppc64 @@ -83,6 +83,8 @@ int lstat(uintptr_t, uintptr_t); int pause(); int pread64(int, uintptr_t, size_t, long long); int pwrite64(int, uintptr_t, size_t, long long); +#define c_select select +int select(int, uintptr_t, uintptr_t, uintptr_t, uintptr_t); int pselect(int, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); int setregid(int, int); int setreuid(int, int); @@ -103,8 +105,8 @@ int getpeername(int, uintptr_t, uintptr_t); int getsockname(int, uintptr_t, uintptr_t); int recvfrom(int, uintptr_t, size_t, int, uintptr_t, uintptr_t); int sendto(int, uintptr_t, size_t, int, uintptr_t, uintptr_t); -int recvmsg(int, uintptr_t, int); -int sendmsg(int, uintptr_t, int); +int nrecvmsg(int, uintptr_t, int); +int nsendmsg(int, uintptr_t, int); int munmap(uintptr_t, uintptr_t); int madvise(uintptr_t, size_t, int); int mprotect(uintptr_t, size_t, int); @@ -118,6 +120,8 @@ int poll(uintptr_t, int, int); int gettimeofday(uintptr_t, uintptr_t); int time(uintptr_t); int utime(uintptr_t, uintptr_t); +unsigned long long getsystemcfg(int); +int umount(uintptr_t); int getrlimit(int, uintptr_t); int setrlimit(int, uintptr_t); long long lseek(int, long long, int); @@ -731,6 +735,14 @@ func callpwrite64(fd int, _p0 uintptr, _lenp0 int, offset int64) (r1 uintptr, e1 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func callselect(nfd int, r uintptr, w uintptr, e uintptr, timeout uintptr) (r1 uintptr, e1 Errno) { + r1 = uintptr(C.c_select(C.int(nfd), C.uintptr_t(r), C.uintptr_t(w), C.uintptr_t(e), C.uintptr_t(timeout))) + e1 = syscall.GetErrno() + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func callpselect(nfd int, r uintptr, w uintptr, e uintptr, timeout uintptr, sigmask uintptr) (r1 uintptr, e1 Errno) { r1 = uintptr(C.pselect(C.int(nfd), C.uintptr_t(r), C.uintptr_t(w), C.uintptr_t(e), C.uintptr_t(timeout), C.uintptr_t(sigmask))) e1 = syscall.GetErrno() @@ -891,16 +903,16 @@ func callsendto(s int, _p0 uintptr, _lenp0 int, flags int, to uintptr, addrlen u // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func callrecvmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) { - r1 = uintptr(C.recvmsg(C.int(s), C.uintptr_t(msg), C.int(flags))) +func callnrecvmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) { + r1 = uintptr(C.nrecvmsg(C.int(s), C.uintptr_t(msg), C.int(flags))) e1 = syscall.GetErrno() return } // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func callsendmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) { - r1 = uintptr(C.sendmsg(C.int(s), C.uintptr_t(msg), C.int(flags))) +func callnsendmsg(s int, msg uintptr, flags int) (r1 uintptr, e1 Errno) { + r1 = uintptr(C.nsendmsg(C.int(s), C.uintptr_t(msg), C.int(flags))) e1 = syscall.GetErrno() return } @@ -1011,6 +1023,22 @@ func callutime(_p0 uintptr, buf uintptr) (r1 uintptr, e1 Errno) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func callgetsystemcfg(label int) (r1 uintptr, e1 Errno) { + r1 = uintptr(C.getsystemcfg(C.int(label))) + e1 = syscall.GetErrno() + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func callumount(_p0 uintptr) (r1 uintptr, e1 Errno) { + r1 = uintptr(C.umount(C.uintptr_t(_p0))) + e1 = syscall.GetErrno() + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func callgetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) { r1 = uintptr(C.getrlimit(C.int(resource), C.uintptr_t(rlim))) e1 = syscall.GetErrno() diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index b50178d67922..c142e33e92e9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -943,6 +943,21 @@ func libc_chroot_trampoline() // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockGettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := syscall_syscall(funcPC(libc_clock_gettime_trampoline), uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +func libc_clock_gettime_trampoline() + +//go:linkname libc_clock_gettime libc_clock_gettime +//go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := syscall_syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index da9b900a8c61..1a3915197d4e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -108,6 +108,8 @@ TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0 JMP libc_chown(SB) TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0 JMP libc_chroot(SB) +TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0 + JMP libc_clock_gettime(SB) TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0 JMP libc_close(SB) TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go index da9986dd213c..ae9f1a21e622 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go @@ -1194,6 +1194,26 @@ func Rename(from string, to string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(fromfd int, from string, tofd int, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Revoke(path string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go new file mode 100644 index 000000000000..c6df9d2e8f62 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go @@ -0,0 +1,2015 @@ +// go run mksyscall.go -tags freebsd,arm64 -- syscall_bsd.go syscall_freebsd.go syscall_freebsd_arm64.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build freebsd,arm64 + +package unix + +import ( + "syscall" + "unsafe" +) + +var _ syscall.Errno + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getgroups(ngid int, gid *_Gid_t) (n int, err error) { + r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setgroups(ngid int, gid *_Gid_t) (err error) { + _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { + r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) + wpid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { + r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socket(domain int, typ int, proto int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { + _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { + _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Shutdown(s int, how int) (err error) { + _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { + _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { + r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { + var _p0 unsafe.Pointer + if len(mib) > 0 { + _p0 = unsafe.Pointer(&mib[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimes(path string, timeval *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func futimes(fd int, timeval *[2]Timeval) (err error) { + _, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fcntl(fd int, cmd int, arg int) (val int, err error) { + r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe2(p *[2]_C_int, flags int) (err error) { + _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Access(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { + _, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func CapEnter() (err error) { + _, _, e1 := Syscall(SYS_CAP_ENTER, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func capRightsGet(version int, fd int, rightsp *CapRights) (err error) { + _, _, e1 := Syscall(SYS___CAP_RIGHTS_GET, uintptr(version), uintptr(fd), uintptr(unsafe.Pointer(rightsp))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func capRightsLimit(fd int, rightsp *CapRights) (err error) { + _, _, e1 := Syscall(SYS_CAP_RIGHTS_LIMIT, uintptr(fd), uintptr(unsafe.Pointer(rightsp)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chflags(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chmod(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chroot(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(fd int) (nfd int, err error) { + r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0) + nfd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup2(from int, to int) (err error) { + _, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Exit(code int) { + Syscall(SYS_EXIT, uintptr(code), 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FD, uintptr(fd), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_POSIX_FADVISE, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchdir(fd int) (err error) { + _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchflags(fd int, flags int) (err error) { + _, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmod(fd int, mode uint32) (err error) { + _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchown(fd int, uid int, gid int) (err error) { + _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flock(fd int, how int) (err error) { + _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fpathconf(fd int, name int) (val int, err error) { + r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fstat(fd int, stat *stat_freebsd11_t) (err error) { + _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fstat_freebsd12(fd int, stat *Stat_t) (err error) { + _, _, e1 := Syscall(SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) { + _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) { + _, _, e1 := Syscall(SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsync(fd int) (err error) { + _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Ftruncate(fd int, length int64) (err error) { + _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getdtablesize() (size int) { + r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0) + size = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getegid() (egid int) { + r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + egid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Geteuid() (uid int) { + r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getgid() (gid int) { + r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgid(pid int) (pgid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) + pgid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgrp() (pgrp int) { + r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0) + pgrp = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpid() (pid int) { + r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + pid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getppid() (ppid int) { + r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + ppid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpriority(which int, who int) (prio int, err error) { + r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) + prio = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrusage(who int, rusage *Rusage) (err error) { + _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Gettimeofday(tv *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getuid() (uid int) { + r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Issetugid() (tainted bool) { + r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0) + tainted = bool(r0 != 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kill(pid int, signum syscall.Signal) (err error) { + _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kqueue() (fd int, err error) { + r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lchown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Link(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Listen(s int, backlog int) (err error) { + _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func lstat(path string, stat *stat_freebsd11_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdir(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdirat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifo(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mknod(path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mknodat(fd int, path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Nanosleep(time *Timespec, leftover *Timespec) (err error) { + _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Open(path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(fdat), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pathconf(path string, name int) (val int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func read(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlink(path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rename(from string, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Renameat(fromfd int, from string, tofd int, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Revoke(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rmdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { + r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) + newoffset = int64(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) { + _, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setegid(egid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seteuid(euid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setgid(gid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setlogin(name string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(name) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpgid(pid int, pgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpriority(which int, who int, prio int) (err error) { + _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setregid(rgid int, egid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setreuid(ruid int, euid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresgid(rgid int, egid int, sgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresuid(ruid int, euid int, suid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setsid() (pid int, err error) { + r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) + pid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Settimeofday(tp *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setuid(uid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func stat(path string, stat *stat_freebsd11_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func statfs(path string, stat *statfs_freebsd11_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func statfs_freebsd12(path string, stat *Statfs_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlink(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Sync() (err error) { + _, _, e1 := Syscall(SYS_SYNC, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Truncate(path string, length int64) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Umask(newmask int) (oldmask int) { + r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0) + oldmask = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Undelete(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlink(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlinkat(dirfd int, path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unmount(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func write(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos)) + ret = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func munmap(addr uintptr, length uintptr) (err error) { + _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readlen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writelen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) { + r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) + nfd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go index 5356a517594d..feb3c03933cb 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(mask>>32), uintptr(dirFd), uintptr(unsafe.Pointer(pathname))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { @@ -1901,6 +1945,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { r0, _, e1 := Syscall6(SYS_SENDFILE64, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) written = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go index 0f6d265d8b07..fa0cb252a915 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1906,6 +1950,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) off = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go index 012261ad549f..daec1d5d2c81 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(mask>>32), uintptr(dirFd), uintptr(unsafe.Pointer(pathname))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,42 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe(p *[2]_C_int) (err error) { + _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe2(p *[2]_C_int, flags int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 { @@ -2016,6 +2070,26 @@ func Pause() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { r0, _, e1 := Syscall6(SYS_SENDFILE64, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) written = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go index b890cb03c6e1..ad9820b598ed 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1829,6 +1873,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) off = int64(r0) @@ -2189,3 +2253,18 @@ func pipe2(p *[2]_C_int, flags int) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(cmdline) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_KEXEC_FILE_LOAD, uintptr(kernelFd), uintptr(initrdFd), uintptr(cmdlineLen), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go index cc17b43d3556..c82ce7d29940 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask>>32), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1820,6 +1864,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { r0, _, e1 := Syscall6(SYS__NEWSELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) n = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go index caf1408ec4e5..d1b77c193497 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1719,21 +1763,6 @@ func Fchown(fd int, uid int, gid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1865,6 +1894,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) off = int64(r0) @@ -2293,6 +2342,21 @@ func fstat(fd int, st *stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func fstatat(dirfd int, path string, st *stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(st)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func lstat(path string, st *stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go index 266be8b4abbf..b8e45f98c7c5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1719,21 +1763,6 @@ func Fchown(fd int, uid int, gid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1865,6 +1894,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) off = int64(r0) @@ -2293,6 +2342,21 @@ func fstat(fd int, st *stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func fstatat(dirfd int, path string, st *stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(st)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func lstat(path string, st *stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go index b16b3e102989..e26c748d4e08 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(mask>>32), uintptr(dirFd), uintptr(unsafe.Pointer(pathname))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1820,6 +1864,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { r0, _, e1 := Syscall6(SYS__NEWSELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) n = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go index 27b6a6bf0e39..0a958ca0b368 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1921,6 +1965,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) off = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go index f7ecc9afda57..658f361e7738 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1921,6 +1965,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) off = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go index e3cd4e53f994..daff300399a3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -2189,3 +2233,18 @@ func pipe2(p *[2]_C_int, flags int) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(cmdline) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_KEXEC_FILE_LOAD, uintptr(kernelFd), uintptr(initrdFd), uintptr(cmdlineLen), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go index 3001d3798198..caf6ea866352 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { @@ -1891,6 +1935,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) off = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go index aafe3660fa28..369a04b57db4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go @@ -14,6 +14,27 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { + r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { + _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func fchmodat(dirfd int, path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -437,6 +458,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { + _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Close(fd int) (err error) { _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) if e1 != 0 { @@ -1195,26 +1226,6 @@ func Removexattr(path string, attr string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) @@ -1370,6 +1381,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Signalfd(fd int, mask *Sigset_t, flags int) { + SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1661,6 +1679,32 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(pathname) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { var _p0 unsafe.Pointer if len(events) > 0 { @@ -1890,6 +1934,26 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) off = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go new file mode 100644 index 000000000000..603d14433496 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go @@ -0,0 +1,1826 @@ +// go run mksyscall.go -netbsd -tags netbsd,arm64 syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm64.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build netbsd,arm64 + +package unix + +import ( + "syscall" + "unsafe" +) + +var _ syscall.Errno + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getgroups(ngid int, gid *_Gid_t) (n int, err error) { + r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setgroups(ngid int, gid *_Gid_t) (err error) { + _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { + r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) + wpid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { + r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socket(domain int, typ int, proto int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { + _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { + _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Shutdown(s int, how int) (err error) { + _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { + _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { + r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { + var _p0 unsafe.Pointer + if len(mib) > 0 { + _p0 = unsafe.Pointer(&mib[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimes(path string, timeval *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func futimes(fd int, timeval *[2]Timeval) (err error) { + _, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fcntl(fd int, cmd int, arg int) (val int, err error) { + r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe() (fd1 int, fd2 int, err error) { + r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) + fd1 = int(r0) + fd2 = int(r1) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Access(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { + _, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chflags(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chmod(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chroot(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(fd int) (nfd int, err error) { + r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0) + nfd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup2(from int, to int) (err error) { + _, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Exit(code int) { + Syscall(SYS_EXIT, uintptr(code), 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FD, uintptr(fd), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(file) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_GET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_SET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(attrname) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_EXTATTR_DELETE_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(link) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0) + ret = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), 0, uintptr(length), uintptr(advice)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchdir(fd int) (err error) { + _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchflags(fd int, flags int) (err error) { + _, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmod(fd int, mode uint32) (err error) { + _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchown(fd int, uid int, gid int) (err error) { + _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flock(fd int, how int) (err error) { + _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fpathconf(fd int, name int) (val int, err error) { + r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstat(fd int, stat *Stat_t) (err error) { + _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsync(fd int) (err error) { + _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Ftruncate(fd int, length int64) (err error) { + _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getegid() (egid int) { + r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + egid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Geteuid() (uid int) { + r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getgid() (gid int) { + r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgid(pid int) (pgid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) + pgid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgrp() (pgrp int) { + r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0) + pgrp = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpid() (pid int) { + r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + pid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getppid() (ppid int) { + r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + ppid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpriority(which int, who int) (prio int, err error) { + r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) + prio = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrusage(who int, rusage *Rusage) (err error) { + _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Gettimeofday(tv *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getuid() (uid int) { + r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Issetugid() (tainted bool) { + r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0) + tainted = bool(r0 != 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kill(pid int, signum syscall.Signal) (err error) { + _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kqueue() (fd int, err error) { + r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lchown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Link(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Listen(s int, backlog int) (err error) { + _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lstat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdir(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdirat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifo(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifoat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknod(path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Nanosleep(time *Timespec, leftover *Timespec) (err error) { + _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Open(path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pathconf(path string, name int) (val int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func read(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlink(path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rename(from string, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Renameat(fromfd int, from string, tofd int, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Revoke(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rmdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { + r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0) + newoffset = int64(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) { + _, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setegid(egid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seteuid(euid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setgid(gid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpgid(pid int, pgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpriority(which int, who int, prio int) (err error) { + _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setregid(rgid int, egid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setreuid(ruid int, euid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setsid() (pid int, err error) { + r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) + pid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Settimeofday(tp *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setuid(uid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Stat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlink(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Sync() (err error) { + _, _, e1 := Syscall(SYS_SYNC, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Truncate(path string, length int64) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Umask(newmask int) (oldmask int) { + r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0) + oldmask = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlink(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlinkat(dirfd int, path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unmount(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func write(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { + r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0) + ret = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func munmap(addr uintptr, length uintptr) (err error) { + _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readlen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writelen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go new file mode 100644 index 000000000000..eb589904614b --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -0,0 +1,1692 @@ +// go run mksyscall.go -openbsd -tags openbsd,arm64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm64.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build openbsd,arm64 + +package unix + +import ( + "syscall" + "unsafe" +) + +var _ syscall.Errno + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getgroups(ngid int, gid *_Gid_t) (n int, err error) { + r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setgroups(ngid int, gid *_Gid_t) (err error) { + _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { + r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) + wpid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { + r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { + _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socket(domain int, typ int, proto int) (fd int, err error) { + r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { + _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { + _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Shutdown(s int, how int) (err error) { + _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { + _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) { + r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { + var _p0 unsafe.Pointer + if len(mib) > 0 { + _p0 = unsafe.Pointer(&mib[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimes(path string, timeval *[2]Timeval) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func futimes(fd int, timeval *[2]Timeval) (err error) { + _, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fcntl(fd int, cmd int, arg int) (val int, err error) { + r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe(p *[2]_C_int) (err error) { + _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Access(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { + _, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chflags(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chmod(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Chroot(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(fd int) (nfd int, err error) { + r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0) + nfd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup2(from int, to int) (err error) { + _, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Exit(code int) { + Syscall(SYS_EXIT, uintptr(code), 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchdir(fd int) (err error) { + _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchflags(fd int, flags int) (err error) { + _, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmod(fd int, mode uint32) (err error) { + _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchown(fd int, uid int, gid int) (err error) { + _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Flock(fd int, how int) (err error) { + _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fpathconf(fd int, name int) (val int, err error) { + r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstat(fd int, stat *Stat_t) (err error) { + _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstatfs(fd int, stat *Statfs_t) (err error) { + _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fsync(fd int) (err error) { + _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Ftruncate(fd int, length int64) (err error) { + _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getegid() (egid int) { + r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + egid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Geteuid() (uid int) { + r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getgid() (gid int) { + r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgid(pid int) (pgid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) + pgid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpgrp() (pgrp int) { + r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0) + pgrp = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpid() (pid int) { + r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + pid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getppid() (ppid int) { + r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + ppid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getpriority(which int, who int) (prio int, err error) { + r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) + prio = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrtable() (rtable int, err error) { + r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0) + rtable = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getrusage(who int, rusage *Rusage) (err error) { + _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getsid(pid int) (sid int, err error) { + r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) + sid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Gettimeofday(tv *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Getuid() (uid int) { + r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Issetugid() (tainted bool) { + r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0) + tainted = bool(r0 != 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kill(pid int, signum syscall.Signal) (err error) { + _, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Kqueue() (fd int, err error) { + r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lchown(path string, uid int, gid int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Link(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Listen(s int, backlog int) (err error) { + _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Lstat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdir(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkdirat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifo(path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mkfifoat(dirfd int, path string, mode uint32) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknod(path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Nanosleep(time *Timespec, leftover *Timespec) (err error) { + _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Open(path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0) + fd = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pathconf(path string, name int) (val int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0) + val = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func read(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlink(path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(buf) > 0 { + _p1 = unsafe.Pointer(&buf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rename(from string, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Renameat(fromfd int, from string, tofd int, to string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(from) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(to) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Revoke(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Rmdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { + r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0) + newoffset = int64(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) { + _, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setegid(egid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seteuid(euid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setgid(gid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setlogin(name string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(name) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpgid(pid int, pgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setpriority(which int, who int, prio int) (err error) { + _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setregid(rgid int, egid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setreuid(ruid int, euid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresgid(rgid int, egid int, sgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresuid(ruid int, euid int, suid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrlimit(which int, lim *Rlimit) (err error) { + _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setrtable(rtable int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setsid() (pid int, err error) { + r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) + pid = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Settimeofday(tp *Timeval) (err error) { + _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setuid(uid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Stat(path string, stat *Stat_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Statfs(path string, stat *Statfs_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlink(path string, link string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(link) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(oldpath) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(newpath) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Sync() (err error) { + _, _, e1 := Syscall(SYS_SYNC, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Truncate(path string, length int64) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Umask(newmask int) (oldmask int) { + r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0) + oldmask = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlink(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unlinkat(dirfd int, path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Unmount(path string, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func write(fd int, p []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) { + r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0) + ret = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func munmap(addr uintptr, length uintptr) (err error) { + _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func readlen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writelen(fd int, buf *byte, nbuf int) (n int, err error) { + r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 97b22a499ed3..5f614760c6c8 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -1,4 +1,4 @@ -// mksyscall_solaris.pl -tags solaris,amd64 syscall_solaris.go syscall_solaris_amd64.go +// go run mksyscall_solaris.go -tags solaris,amd64 syscall_solaris.go syscall_solaris_amd64.go // Code generated by the command above; see README.md. DO NOT EDIT. // +build solaris,amd64 diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go index b005031abed3..37dcc74c2de5 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go @@ -1,6 +1,8 @@ // mksysctl_openbsd.pl // Code generated by the command above; DO NOT EDIT. +// +build 386,openbsd + package unix type mibentry struct { diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go index d014451c9d8e..fe6caa6eb7f2 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go @@ -1,4 +1,4 @@ -// mksysctl_openbsd.pl +// go run mksysctl_openbsd.go // Code generated by the command above; DO NOT EDIT. // +build amd64,openbsd diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go index b005031abed3..6eb8c0b086a6 100644 --- a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go @@ -1,6 +1,8 @@ -// mksysctl_openbsd.pl +// go run mksysctl_openbsd.go // Code generated by the command above; DO NOT EDIT. +// +build arm,openbsd + package unix type mibentry struct { diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go new file mode 100644 index 000000000000..ba4304fd2338 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go @@ -0,0 +1,275 @@ +// go run mksysctl_openbsd.go +// Code generated by the command above; DO NOT EDIT. + +// +build arm64,openbsd + +package unix + +type mibentry struct { + ctlname string + ctloid []_C_int +} + +var sysctlMib = []mibentry{ + {"ddb.console", []_C_int{9, 6}}, + {"ddb.log", []_C_int{9, 7}}, + {"ddb.max_line", []_C_int{9, 3}}, + {"ddb.max_width", []_C_int{9, 2}}, + {"ddb.panic", []_C_int{9, 5}}, + {"ddb.profile", []_C_int{9, 9}}, + {"ddb.radix", []_C_int{9, 1}}, + {"ddb.tab_stop_width", []_C_int{9, 4}}, + {"ddb.trigger", []_C_int{9, 8}}, + {"fs.posix.setuid", []_C_int{3, 1, 1}}, + {"hw.allowpowerdown", []_C_int{6, 22}}, + {"hw.byteorder", []_C_int{6, 4}}, + {"hw.cpuspeed", []_C_int{6, 12}}, + {"hw.diskcount", []_C_int{6, 10}}, + {"hw.disknames", []_C_int{6, 8}}, + {"hw.diskstats", []_C_int{6, 9}}, + {"hw.machine", []_C_int{6, 1}}, + {"hw.model", []_C_int{6, 2}}, + {"hw.ncpu", []_C_int{6, 3}}, + {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.ncpuonline", []_C_int{6, 25}}, + {"hw.pagesize", []_C_int{6, 7}}, + {"hw.perfpolicy", []_C_int{6, 23}}, + {"hw.physmem", []_C_int{6, 19}}, + {"hw.product", []_C_int{6, 15}}, + {"hw.serialno", []_C_int{6, 17}}, + {"hw.setperf", []_C_int{6, 13}}, + {"hw.smt", []_C_int{6, 24}}, + {"hw.usermem", []_C_int{6, 20}}, + {"hw.uuid", []_C_int{6, 18}}, + {"hw.vendor", []_C_int{6, 14}}, + {"hw.version", []_C_int{6, 16}}, + {"kern.allowkmem", []_C_int{1, 52}}, + {"kern.argmax", []_C_int{1, 8}}, + {"kern.audio", []_C_int{1, 84}}, + {"kern.boottime", []_C_int{1, 21}}, + {"kern.bufcachepercent", []_C_int{1, 72}}, + {"kern.ccpu", []_C_int{1, 45}}, + {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consdev", []_C_int{1, 75}}, + {"kern.cp_time", []_C_int{1, 40}}, + {"kern.cp_time2", []_C_int{1, 71}}, + {"kern.cpustats", []_C_int{1, 85}}, + {"kern.domainname", []_C_int{1, 22}}, + {"kern.file", []_C_int{1, 73}}, + {"kern.forkstat", []_C_int{1, 42}}, + {"kern.fscale", []_C_int{1, 46}}, + {"kern.fsync", []_C_int{1, 33}}, + {"kern.global_ptrace", []_C_int{1, 81}}, + {"kern.hostid", []_C_int{1, 11}}, + {"kern.hostname", []_C_int{1, 10}}, + {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, + {"kern.job_control", []_C_int{1, 19}}, + {"kern.malloc.buckets", []_C_int{1, 39, 1}}, + {"kern.malloc.kmemnames", []_C_int{1, 39, 3}}, + {"kern.maxclusters", []_C_int{1, 67}}, + {"kern.maxfiles", []_C_int{1, 7}}, + {"kern.maxlocksperuid", []_C_int{1, 70}}, + {"kern.maxpartitions", []_C_int{1, 23}}, + {"kern.maxproc", []_C_int{1, 6}}, + {"kern.maxthread", []_C_int{1, 25}}, + {"kern.maxvnodes", []_C_int{1, 5}}, + {"kern.mbstat", []_C_int{1, 59}}, + {"kern.msgbuf", []_C_int{1, 48}}, + {"kern.msgbufsize", []_C_int{1, 38}}, + {"kern.nchstats", []_C_int{1, 41}}, + {"kern.netlivelocks", []_C_int{1, 76}}, + {"kern.nfiles", []_C_int{1, 56}}, + {"kern.ngroups", []_C_int{1, 18}}, + {"kern.nosuidcoredump", []_C_int{1, 32}}, + {"kern.nprocs", []_C_int{1, 47}}, + {"kern.nselcoll", []_C_int{1, 43}}, + {"kern.nthreads", []_C_int{1, 26}}, + {"kern.numvnodes", []_C_int{1, 58}}, + {"kern.osrelease", []_C_int{1, 2}}, + {"kern.osrevision", []_C_int{1, 3}}, + {"kern.ostype", []_C_int{1, 1}}, + {"kern.osversion", []_C_int{1, 27}}, + {"kern.pool_debug", []_C_int{1, 77}}, + {"kern.posix1version", []_C_int{1, 17}}, + {"kern.proc", []_C_int{1, 66}}, + {"kern.rawpartition", []_C_int{1, 24}}, + {"kern.saved_ids", []_C_int{1, 20}}, + {"kern.securelevel", []_C_int{1, 9}}, + {"kern.seminfo", []_C_int{1, 61}}, + {"kern.shminfo", []_C_int{1, 62}}, + {"kern.somaxconn", []_C_int{1, 28}}, + {"kern.sominconn", []_C_int{1, 29}}, + {"kern.splassert", []_C_int{1, 54}}, + {"kern.stackgap_random", []_C_int{1, 50}}, + {"kern.sysvipc_info", []_C_int{1, 51}}, + {"kern.sysvmsg", []_C_int{1, 34}}, + {"kern.sysvsem", []_C_int{1, 35}}, + {"kern.sysvshm", []_C_int{1, 36}}, + {"kern.timecounter.choice", []_C_int{1, 69, 4}}, + {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, + {"kern.timecounter.tick", []_C_int{1, 69, 1}}, + {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, + {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, + {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, + {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, + {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, + {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, + {"kern.ttycount", []_C_int{1, 57}}, + {"kern.version", []_C_int{1, 4}}, + {"kern.watchdog.auto", []_C_int{1, 64, 2}}, + {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"kern.witnesswatch", []_C_int{1, 53}}, + {"kern.wxabort", []_C_int{1, 74}}, + {"net.bpf.bufsize", []_C_int{4, 31, 1}}, + {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, + {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, + {"net.inet.ah.stats", []_C_int{4, 2, 51, 2}}, + {"net.inet.carp.allow", []_C_int{4, 2, 112, 1}}, + {"net.inet.carp.log", []_C_int{4, 2, 112, 3}}, + {"net.inet.carp.preempt", []_C_int{4, 2, 112, 2}}, + {"net.inet.carp.stats", []_C_int{4, 2, 112, 4}}, + {"net.inet.divert.recvspace", []_C_int{4, 2, 258, 1}}, + {"net.inet.divert.sendspace", []_C_int{4, 2, 258, 2}}, + {"net.inet.divert.stats", []_C_int{4, 2, 258, 3}}, + {"net.inet.esp.enable", []_C_int{4, 2, 50, 1}}, + {"net.inet.esp.stats", []_C_int{4, 2, 50, 4}}, + {"net.inet.esp.udpencap", []_C_int{4, 2, 50, 2}}, + {"net.inet.esp.udpencap_port", []_C_int{4, 2, 50, 3}}, + {"net.inet.etherip.allow", []_C_int{4, 2, 97, 1}}, + {"net.inet.etherip.stats", []_C_int{4, 2, 97, 2}}, + {"net.inet.gre.allow", []_C_int{4, 2, 47, 1}}, + {"net.inet.gre.wccp", []_C_int{4, 2, 47, 2}}, + {"net.inet.icmp.bmcastecho", []_C_int{4, 2, 1, 2}}, + {"net.inet.icmp.errppslimit", []_C_int{4, 2, 1, 3}}, + {"net.inet.icmp.maskrepl", []_C_int{4, 2, 1, 1}}, + {"net.inet.icmp.rediraccept", []_C_int{4, 2, 1, 4}}, + {"net.inet.icmp.redirtimeout", []_C_int{4, 2, 1, 5}}, + {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, + {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, + {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}}, + {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}}, + {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, + {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, + {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, + {"net.inet.ip.ifq.drops", []_C_int{4, 2, 0, 30, 3}}, + {"net.inet.ip.ifq.len", []_C_int{4, 2, 0, 30, 1}}, + {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, + {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, + {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}}, + {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, + {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}}, + {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, + {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, + {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, + {"net.inet.ip.multipath", []_C_int{4, 2, 0, 32}}, + {"net.inet.ip.portfirst", []_C_int{4, 2, 0, 7}}, + {"net.inet.ip.porthifirst", []_C_int{4, 2, 0, 9}}, + {"net.inet.ip.porthilast", []_C_int{4, 2, 0, 10}}, + {"net.inet.ip.portlast", []_C_int{4, 2, 0, 8}}, + {"net.inet.ip.redirect", []_C_int{4, 2, 0, 2}}, + {"net.inet.ip.sourceroute", []_C_int{4, 2, 0, 5}}, + {"net.inet.ip.stats", []_C_int{4, 2, 0, 33}}, + {"net.inet.ip.ttl", []_C_int{4, 2, 0, 3}}, + {"net.inet.ipcomp.enable", []_C_int{4, 2, 108, 1}}, + {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, + {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, + {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, + {"net.inet.mobileip.allow", []_C_int{4, 2, 55, 1}}, + {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, + {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, + {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, + {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, + {"net.inet.tcp.drop", []_C_int{4, 2, 6, 19}}, + {"net.inet.tcp.ecn", []_C_int{4, 2, 6, 14}}, + {"net.inet.tcp.ident", []_C_int{4, 2, 6, 9}}, + {"net.inet.tcp.keepidle", []_C_int{4, 2, 6, 3}}, + {"net.inet.tcp.keepinittime", []_C_int{4, 2, 6, 2}}, + {"net.inet.tcp.keepintvl", []_C_int{4, 2, 6, 4}}, + {"net.inet.tcp.mssdflt", []_C_int{4, 2, 6, 11}}, + {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, + {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, + {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}}, + {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, + {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, + {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, + {"net.inet.tcp.slowhz", []_C_int{4, 2, 6, 5}}, + {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, + {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, + {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}}, + {"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}}, + {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, + {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, + {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}}, + {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, + {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, + {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, + {"net.inet6.divert.sendspace", []_C_int{4, 24, 86, 2}}, + {"net.inet6.divert.stats", []_C_int{4, 24, 86, 3}}, + {"net.inet6.icmp6.errppslimit", []_C_int{4, 24, 30, 14}}, + {"net.inet6.icmp6.mtudisc_hiwat", []_C_int{4, 24, 30, 16}}, + {"net.inet6.icmp6.mtudisc_lowat", []_C_int{4, 24, 30, 17}}, + {"net.inet6.icmp6.nd6_debug", []_C_int{4, 24, 30, 18}}, + {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, + {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, + {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, + {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, + {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, + {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, + {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, + {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, + {"net.inet6.ip6.defmcasthlim", []_C_int{4, 24, 17, 18}}, + {"net.inet6.ip6.forwarding", []_C_int{4, 24, 17, 1}}, + {"net.inet6.ip6.forwsrcrt", []_C_int{4, 24, 17, 5}}, + {"net.inet6.ip6.hdrnestlimit", []_C_int{4, 24, 17, 15}}, + {"net.inet6.ip6.hlim", []_C_int{4, 24, 17, 3}}, + {"net.inet6.ip6.log_interval", []_C_int{4, 24, 17, 14}}, + {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, + {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, + {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, + {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}}, + {"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}}, + {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, + {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, + {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, + {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, + {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, + {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, + {"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}}, + {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, + {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, + {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, + {"net.key.sadb_dump", []_C_int{4, 30, 1}}, + {"net.key.spd_dump", []_C_int{4, 30, 2}}, + {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, + {"net.mpls.ifq.drops", []_C_int{4, 33, 3, 3}}, + {"net.mpls.ifq.len", []_C_int{4, 33, 3, 1}}, + {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, + {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, + {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, + {"net.mpls.maxloop_inkernel", []_C_int{4, 33, 4}}, + {"net.mpls.ttl", []_C_int{4, 33, 2}}, + {"net.pflow.stats", []_C_int{4, 34, 1}}, + {"net.pipex.enable", []_C_int{4, 35, 1}}, + {"vm.anonmin", []_C_int{2, 7}}, + {"vm.loadavg", []_C_int{2, 2}}, + {"vm.malloc_conf", []_C_int{2, 12}}, + {"vm.maxslp", []_C_int{2, 10}}, + {"vm.nkmempages", []_C_int{2, 6}}, + {"vm.psstrings", []_C_int{2, 3}}, + {"vm.swapencrypt.enable", []_C_int{2, 5, 0}}, + {"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}}, + {"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}}, + {"vm.uspace", []_C_int{2, 11}}, + {"vm.uvmexp", []_C_int{2, 4}}, + {"vm.vmmeter", []_C_int{2, 1}}, + {"vm.vnodemin", []_C_int{2, 9}}, + {"vm.vtextmin", []_C_int{2, 8}}, +} diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go index d1d36da3f512..f33614532f99 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go @@ -1,4 +1,4 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/syscall.h +// go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/syscall.h // Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,darwin diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go index e35de4145ed9..654dd3da3be4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go @@ -1,4 +1,4 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/syscall.h +// go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/sys/syscall.h // Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,darwin @@ -431,6 +431,8 @@ const ( SYS_NTP_ADJTIME = 527 SYS_NTP_GETTIME = 528 SYS_OS_FAULT_WITH_PAYLOAD = 529 - SYS_MAXSYSCALL = 530 + SYS_KQUEUE_WORKLOOP_CTL = 530 + SYS___MACH_BRIDGE_REMOTE_TIME = 531 + SYS_MAXSYSCALL = 532 SYS_INVALID = 63 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go index f2df27db2c23..103a72ed1c0e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go @@ -1,4 +1,4 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.1.sdk/usr/include/sys/syscall.h +// go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.1.sdk/usr/include/sys/syscall.h // Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,darwin diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go index 9694630232f5..7ab2130b967b 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go @@ -1,4 +1,4 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.1.sdk/usr/include/sys/syscall.h +// go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.1.sdk/usr/include/sys/syscall.h // Code generated by the command above; see README.md. DO NOT EDIT. // +build arm64,darwin diff --git a/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go index b2c9ef81b819..464c9a9832dc 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go @@ -1,4 +1,4 @@ -// mksysnum_dragonfly.pl +// go run mksysnum.go https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master // Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,dragonfly @@ -13,7 +13,7 @@ const ( SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, size_t nbyte); } SYS_OPEN = 5 // { int open(char *path, int flags, int mode); } SYS_CLOSE = 6 // { int close(int fd); } - SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, \ + SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, struct rusage *rusage); } wait4 wait_args int SYS_LINK = 9 // { int link(char *path, char *link); } SYS_UNLINK = 10 // { int unlink(char *path); } SYS_CHDIR = 12 // { int chdir(char *path); } @@ -22,17 +22,17 @@ const ( SYS_CHMOD = 15 // { int chmod(char *path, int mode); } SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); } SYS_OBREAK = 17 // { int obreak(char *nsize); } break obreak_args int - SYS_GETFSSTAT = 18 // { int getfsstat(struct statfs *buf, long bufsize, \ + SYS_GETFSSTAT = 18 // { int getfsstat(struct statfs *buf, long bufsize, int flags); } SYS_GETPID = 20 // { pid_t getpid(void); } - SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, \ + SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, caddr_t data); } SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); } SYS_SETUID = 23 // { int setuid(uid_t uid); } SYS_GETUID = 24 // { uid_t getuid(void); } SYS_GETEUID = 25 // { uid_t geteuid(void); } - SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, \ + SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, int data); } SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, int flags); } SYS_SENDMSG = 28 // { int sendmsg(int s, caddr_t msg, int flags); } - SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, \ + SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, int flags, caddr_t from, int *fromlenaddr); } SYS_ACCEPT = 30 // { int accept(int s, caddr_t name, int *anamelen); } SYS_GETPEERNAME = 31 // { int getpeername(int fdes, caddr_t asa, int *alen); } SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, caddr_t asa, int *alen); } @@ -45,8 +45,8 @@ const ( SYS_DUP = 41 // { int dup(int fd); } SYS_PIPE = 42 // { int pipe(void); } SYS_GETEGID = 43 // { gid_t getegid(void); } - SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, \ - SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, \ + SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); } + SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, int pid); } SYS_GETGID = 47 // { gid_t getgid(void); } SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int namelen); } SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); } @@ -67,32 +67,32 @@ const ( SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); } SYS_MPROTECT = 74 // { int mprotect(void *addr, size_t len, int prot); } SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, int behav); } - SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, \ + SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, char *vec); } SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, gid_t *gidset); } SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, gid_t *gidset); } SYS_GETPGRP = 81 // { int getpgrp(void); } SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); } - SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, \ + SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, struct itimerval *oitv); } SYS_SWAPON = 85 // { int swapon(char *name); } SYS_GETITIMER = 86 // { int getitimer(u_int which, struct itimerval *itv); } SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); } SYS_DUP2 = 90 // { int dup2(int from, int to); } SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); } - SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, \ + SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } SYS_FSYNC = 95 // { int fsync(int fd); } SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, int prio); } SYS_SOCKET = 97 // { int socket(int domain, int type, int protocol); } SYS_CONNECT = 98 // { int connect(int s, caddr_t name, int namelen); } SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); } SYS_BIND = 104 // { int bind(int s, caddr_t name, int namelen); } - SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, \ + SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, caddr_t val, int valsize); } SYS_LISTEN = 106 // { int listen(int s, int backlog); } - SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, \ + SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, struct timezone *tzp); } SYS_GETRUSAGE = 117 // { int getrusage(int who, struct rusage *rusage); } - SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, \ + SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, caddr_t val, int *avalsize); } SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); } - SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, \ - SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, \ + SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, struct timezone *tzp); } SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); } SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); } SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); } @@ -100,15 +100,15 @@ const ( SYS_RENAME = 128 // { int rename(char *from, char *to); } SYS_FLOCK = 131 // { int flock(int fd, int how); } SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); } - SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, \ + SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen); } SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); } - SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, \ + SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, int *rsv); } SYS_MKDIR = 136 // { int mkdir(char *path, int mode); } SYS_RMDIR = 137 // { int rmdir(char *path); } SYS_UTIMES = 138 // { int utimes(char *path, struct timeval *tptr); } - SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, \ + SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, struct timeval *olddelta); } SYS_SETSID = 147 // { int setsid(void); } - SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, \ + SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, caddr_t arg); } SYS_STATFS = 157 // { int statfs(char *path, struct statfs *buf); } SYS_FSTATFS = 158 // { int fstatfs(int fd, struct statfs *buf); } SYS_GETFH = 161 // { int getfh(char *fname, struct fhandle *fhp); } @@ -116,53 +116,53 @@ const ( SYS_SETDOMAINNAME = 163 // { int setdomainname(char *domainname, int len); } SYS_UNAME = 164 // { int uname(struct utsname *name); } SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); } - SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, \ - SYS_EXTPREAD = 173 // { ssize_t extpread(int fd, void *buf, \ - SYS_EXTPWRITE = 174 // { ssize_t extpwrite(int fd, const void *buf, \ + SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, struct rtprio *rtp); } + SYS_EXTPREAD = 173 // { ssize_t extpread(int fd, void *buf, size_t nbyte, int flags, off_t offset); } + SYS_EXTPWRITE = 174 // { ssize_t extpwrite(int fd, const void *buf, size_t nbyte, int flags, off_t offset); } SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); } SYS_SETGID = 181 // { int setgid(gid_t gid); } SYS_SETEGID = 182 // { int setegid(gid_t egid); } SYS_SETEUID = 183 // { int seteuid(uid_t euid); } SYS_PATHCONF = 191 // { int pathconf(char *path, int name); } SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); } - SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, \ - SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, \ - SYS_MMAP = 197 // { caddr_t mmap(caddr_t addr, size_t len, int prot, \ + SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int + SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int + SYS_MMAP = 197 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, int pad, off_t pos); } // SYS_NOSYS = 198; // { int nosys(void); } __syscall __syscall_args int - SYS_LSEEK = 199 // { off_t lseek(int fd, int pad, off_t offset, \ + SYS_LSEEK = 199 // { off_t lseek(int fd, int pad, off_t offset, int whence); } SYS_TRUNCATE = 200 // { int truncate(char *path, int pad, off_t length); } SYS_FTRUNCATE = 201 // { int ftruncate(int fd, int pad, off_t length); } - SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, void *old, \ + SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int SYS_MLOCK = 203 // { int mlock(const void *addr, size_t len); } SYS_MUNLOCK = 204 // { int munlock(const void *addr, size_t len); } SYS_UNDELETE = 205 // { int undelete(char *path); } SYS_FUTIMES = 206 // { int futimes(int fd, struct timeval *tptr); } SYS_GETPGID = 207 // { int getpgid(pid_t pid); } - SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, \ - SYS___SEMCTL = 220 // { int __semctl(int semid, int semnum, int cmd, \ + SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS___SEMCTL = 220 // { int __semctl(int semid, int semnum, int cmd, union semun *arg); } SYS_SEMGET = 221 // { int semget(key_t key, int nsems, int semflg); } - SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, \ - SYS_MSGCTL = 224 // { int msgctl(int msqid, int cmd, \ + SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, u_int nsops); } + SYS_MSGCTL = 224 // { int msgctl(int msqid, int cmd, struct msqid_ds *buf); } SYS_MSGGET = 225 // { int msgget(key_t key, int msgflg); } - SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, \ - SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, \ - SYS_SHMAT = 228 // { caddr_t shmat(int shmid, const void *shmaddr, \ - SYS_SHMCTL = 229 // { int shmctl(int shmid, int cmd, \ + SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { caddr_t shmat(int shmid, const void *shmaddr, int shmflg); } + SYS_SHMCTL = 229 // { int shmctl(int shmid, int cmd, struct shmid_ds *buf); } SYS_SHMDT = 230 // { int shmdt(const void *shmaddr); } SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, int shmflg); } - SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, \ - SYS_CLOCK_SETTIME = 233 // { int clock_settime(clockid_t clock_id, \ - SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, \ - SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, \ + SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 233 // { int clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, int inherit); } SYS_RFORK = 251 // { int rfork(int flags); } - SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, \ + SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); } SYS_ISSETUGID = 253 // { int issetugid(void); } SYS_LCHOWN = 254 // { int lchown(char *path, int uid, int gid); } SYS_LCHMOD = 274 // { int lchmod(char *path, mode_t mode); } SYS_LUTIMES = 276 // { int lutimes(char *path, struct timeval *tptr); } - SYS_EXTPREADV = 289 // { ssize_t extpreadv(int fd, struct iovec *iovp, \ - SYS_EXTPWRITEV = 290 // { ssize_t extpwritev(int fd, struct iovec *iovp,\ + SYS_EXTPREADV = 289 // { ssize_t extpreadv(int fd, struct iovec *iovp, u_int iovcnt, int flags, off_t offset); } + SYS_EXTPWRITEV = 290 // { ssize_t extpwritev(int fd, struct iovec *iovp,u_int iovcnt, int flags, off_t offset); } SYS_FHSTATFS = 297 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); } SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); } SYS_MODNEXT = 300 // { int modnext(int modid); } @@ -200,34 +200,34 @@ const ( SYS_UTRACE = 335 // { int utrace(const void *addr, size_t len); } SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, void *data); } SYS_JAIL = 338 // { int jail(struct jail *jail); } - SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, const sigset_t *set, \ + SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, const sigset_t *set, sigset_t *oset); } SYS_SIGSUSPEND = 341 // { int sigsuspend(const sigset_t *sigmask); } - SYS_SIGACTION = 342 // { int sigaction(int sig, const struct sigaction *act, \ + SYS_SIGACTION = 342 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); } SYS_SIGPENDING = 343 // { int sigpending(sigset_t *set); } SYS_SIGRETURN = 344 // { int sigreturn(ucontext_t *sigcntxp); } - SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set,\ - SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set,\ - SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, \ - SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, \ - SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, acl_type_t type, \ - SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, acl_type_t type, \ - SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, \ + SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set,siginfo_t *info, const struct timespec *timeout); } + SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set,siginfo_t *info); } + SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, acl_type_t type); } SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, acl_type_t type); } - SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, \ - SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, \ - SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, \ - SYS_EXTATTR_SET_FILE = 356 // { int extattr_set_file(const char *path, \ - SYS_EXTATTR_GET_FILE = 357 // { int extattr_get_file(const char *path, \ - SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, \ + SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); } + SYS_EXTATTR_SET_FILE = 356 // { int extattr_set_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_FILE = 357 // { int extattr_get_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); } SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); } SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } SYS_KQUEUE = 362 // { int kqueue(void); } - SYS_KEVENT = 363 // { int kevent(int fd, \ + SYS_KEVENT = 363 // { int kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } SYS_KENV = 390 // { int kenv(int what, const char *name, char *value, int len); } SYS_LCHFLAGS = 391 // { int lchflags(char *path, int flags); } SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, int count); } - SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, \ + SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); } SYS_VARSYM_SET = 450 // { int varsym_set(int level, const char *name, const char *data); } SYS_VARSYM_GET = 451 // { int varsym_get(int mask, const char *wild, char *buf, int bufsize); } SYS_VARSYM_LIST = 452 // { int varsym_list(int level, char *buf, int maxsize, int *marker); } @@ -245,58 +245,58 @@ const ( SYS_FSTAT = 476 // { int fstat(int fd, struct stat *sb); } SYS_LSTAT = 477 // { int lstat(const char *path, struct stat *ub); } SYS_FHSTAT = 478 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); } - SYS_GETDIRENTRIES = 479 // { int getdirentries(int fd, char *buf, u_int count, \ + SYS_GETDIRENTRIES = 479 // { int getdirentries(int fd, char *buf, u_int count, long *basep); } SYS_GETDENTS = 480 // { int getdents(int fd, char *buf, size_t count); } - SYS_USCHED_SET = 481 // { int usched_set(pid_t pid, int cmd, void *data, \ + SYS_USCHED_SET = 481 // { int usched_set(pid_t pid, int cmd, void *data, int bytes); } SYS_EXTACCEPT = 482 // { int extaccept(int s, int flags, caddr_t name, int *anamelen); } SYS_EXTCONNECT = 483 // { int extconnect(int s, int flags, caddr_t name, int namelen); } SYS_MCONTROL = 485 // { int mcontrol(void *addr, size_t len, int behav, off_t value); } SYS_VMSPACE_CREATE = 486 // { int vmspace_create(void *id, int type, void *data); } SYS_VMSPACE_DESTROY = 487 // { int vmspace_destroy(void *id); } - SYS_VMSPACE_CTL = 488 // { int vmspace_ctl(void *id, int cmd, \ - SYS_VMSPACE_MMAP = 489 // { int vmspace_mmap(void *id, void *addr, size_t len, \ - SYS_VMSPACE_MUNMAP = 490 // { int vmspace_munmap(void *id, void *addr, \ - SYS_VMSPACE_MCONTROL = 491 // { int vmspace_mcontrol(void *id, void *addr, \ - SYS_VMSPACE_PREAD = 492 // { ssize_t vmspace_pread(void *id, void *buf, \ - SYS_VMSPACE_PWRITE = 493 // { ssize_t vmspace_pwrite(void *id, const void *buf, \ + SYS_VMSPACE_CTL = 488 // { int vmspace_ctl(void *id, int cmd, struct trapframe *tframe, struct vextframe *vframe); } + SYS_VMSPACE_MMAP = 489 // { int vmspace_mmap(void *id, void *addr, size_t len, int prot, int flags, int fd, off_t offset); } + SYS_VMSPACE_MUNMAP = 490 // { int vmspace_munmap(void *id, void *addr, size_t len); } + SYS_VMSPACE_MCONTROL = 491 // { int vmspace_mcontrol(void *id, void *addr, size_t len, int behav, off_t value); } + SYS_VMSPACE_PREAD = 492 // { ssize_t vmspace_pread(void *id, void *buf, size_t nbyte, int flags, off_t offset); } + SYS_VMSPACE_PWRITE = 493 // { ssize_t vmspace_pwrite(void *id, const void *buf, size_t nbyte, int flags, off_t offset); } SYS_EXTEXIT = 494 // { void extexit(int how, int status, void *addr); } SYS_LWP_CREATE = 495 // { int lwp_create(struct lwp_params *params); } SYS_LWP_GETTID = 496 // { lwpid_t lwp_gettid(void); } SYS_LWP_KILL = 497 // { int lwp_kill(pid_t pid, lwpid_t tid, int signum); } SYS_LWP_RTPRIO = 498 // { int lwp_rtprio(int function, pid_t pid, lwpid_t tid, struct rtprio *rtp); } - SYS_PSELECT = 499 // { int pselect(int nd, fd_set *in, fd_set *ou, \ + SYS_PSELECT = 499 // { int pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *sigmask); } SYS_STATVFS = 500 // { int statvfs(const char *path, struct statvfs *buf); } SYS_FSTATVFS = 501 // { int fstatvfs(int fd, struct statvfs *buf); } SYS_FHSTATVFS = 502 // { int fhstatvfs(const struct fhandle *u_fhp, struct statvfs *buf); } - SYS_GETVFSSTAT = 503 // { int getvfsstat(struct statfs *buf, \ + SYS_GETVFSSTAT = 503 // { int getvfsstat(struct statfs *buf, struct statvfs *vbuf, long vbufsize, int flags); } SYS_OPENAT = 504 // { int openat(int fd, char *path, int flags, int mode); } - SYS_FSTATAT = 505 // { int fstatat(int fd, char *path, \ - SYS_FCHMODAT = 506 // { int fchmodat(int fd, char *path, int mode, \ - SYS_FCHOWNAT = 507 // { int fchownat(int fd, char *path, int uid, int gid, \ + SYS_FSTATAT = 505 // { int fstatat(int fd, char *path, struct stat *sb, int flags); } + SYS_FCHMODAT = 506 // { int fchmodat(int fd, char *path, int mode, int flags); } + SYS_FCHOWNAT = 507 // { int fchownat(int fd, char *path, int uid, int gid, int flags); } SYS_UNLINKAT = 508 // { int unlinkat(int fd, char *path, int flags); } - SYS_FACCESSAT = 509 // { int faccessat(int fd, char *path, int amode, \ - SYS_MQ_OPEN = 510 // { mqd_t mq_open(const char * name, int oflag, \ + SYS_FACCESSAT = 509 // { int faccessat(int fd, char *path, int amode, int flags); } + SYS_MQ_OPEN = 510 // { mqd_t mq_open(const char * name, int oflag, mode_t mode, struct mq_attr *attr); } SYS_MQ_CLOSE = 511 // { int mq_close(mqd_t mqdes); } SYS_MQ_UNLINK = 512 // { int mq_unlink(const char *name); } - SYS_MQ_GETATTR = 513 // { int mq_getattr(mqd_t mqdes, \ - SYS_MQ_SETATTR = 514 // { int mq_setattr(mqd_t mqdes, \ - SYS_MQ_NOTIFY = 515 // { int mq_notify(mqd_t mqdes, \ - SYS_MQ_SEND = 516 // { int mq_send(mqd_t mqdes, const char *msg_ptr, \ - SYS_MQ_RECEIVE = 517 // { ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, \ - SYS_MQ_TIMEDSEND = 518 // { int mq_timedsend(mqd_t mqdes, \ - SYS_MQ_TIMEDRECEIVE = 519 // { ssize_t mq_timedreceive(mqd_t mqdes, \ + SYS_MQ_GETATTR = 513 // { int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat); } + SYS_MQ_SETATTR = 514 // { int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat); } + SYS_MQ_NOTIFY = 515 // { int mq_notify(mqd_t mqdes, const struct sigevent *notification); } + SYS_MQ_SEND = 516 // { int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio); } + SYS_MQ_RECEIVE = 517 // { ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio); } + SYS_MQ_TIMEDSEND = 518 // { int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout); } + SYS_MQ_TIMEDRECEIVE = 519 // { ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); } SYS_IOPRIO_SET = 520 // { int ioprio_set(int which, int who, int prio); } SYS_IOPRIO_GET = 521 // { int ioprio_get(int which, int who); } SYS_CHROOT_KERNEL = 522 // { int chroot_kernel(char *path); } - SYS_RENAMEAT = 523 // { int renameat(int oldfd, char *old, int newfd, \ + SYS_RENAMEAT = 523 // { int renameat(int oldfd, char *old, int newfd, char *new); } SYS_MKDIRAT = 524 // { int mkdirat(int fd, char *path, mode_t mode); } SYS_MKFIFOAT = 525 // { int mkfifoat(int fd, char *path, mode_t mode); } - SYS_MKNODAT = 526 // { int mknodat(int fd, char *path, mode_t mode, \ - SYS_READLINKAT = 527 // { int readlinkat(int fd, char *path, char *buf, \ + SYS_MKNODAT = 526 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); } + SYS_READLINKAT = 527 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); } SYS_SYMLINKAT = 528 // { int symlinkat(char *path1, int fd, char *path2); } SYS_SWAPOFF = 529 // { int swapoff(char *name); } - SYS_VQUOTACTL = 530 // { int vquotactl(const char *path, \ - SYS_LINKAT = 531 // { int linkat(int fd1, char *path1, int fd2, \ + SYS_VQUOTACTL = 530 // { int vquotactl(const char *path, struct plistref *pref); } + SYS_LINKAT = 531 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flags); } SYS_EACCESS = 532 // { int eaccess(char *path, int flags); } SYS_LPATHCONF = 533 // { int lpathconf(char *path, int name); } SYS_VMM_GUEST_CTL = 534 // { int vmm_guest_ctl(int op, struct vmm_guest_options *options); } @@ -308,7 +308,7 @@ const ( SYS_FUTIMENS = 540 // { int futimens(int fd, const struct timespec *ts); } SYS_ACCEPT4 = 541 // { int accept4(int s, caddr_t name, int *anamelen, int flags); } SYS_LWP_SETNAME = 542 // { int lwp_setname(lwpid_t tid, const char *name); } - SYS_PPOLL = 543 // { int ppoll(struct pollfd *fds, u_int nfds, \ + SYS_PPOLL = 543 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *sigmask); } SYS_LWP_SETAFFINITY = 544 // { int lwp_setaffinity(pid_t pid, lwpid_t tid, const cpumask_t *mask); } SYS_LWP_GETAFFINITY = 545 // { int lwp_getaffinity(pid_t pid, lwpid_t tid, cpumask_t *mask); } SYS_LWP_CREATE2 = 546 // { int lwp_create2(struct lwp_params *params, const cpumask_t *mask); } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go index 1ab8780c3b0b..55c3a32945d3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go @@ -1,4 +1,4 @@ -// mksysnum_freebsd.pl +// go run mksysnum.go https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master // Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,freebsd @@ -7,13 +7,13 @@ package unix const ( // SYS_NOSYS = 0; // { int nosys(void); } syscall nosys_args int - SYS_EXIT = 1 // { void sys_exit(int rval); } exit \ + SYS_EXIT = 1 // { void sys_exit(int rval); } exit sys_exit_args void SYS_FORK = 2 // { int fork(void); } - SYS_READ = 3 // { ssize_t read(int fd, void *buf, \ - SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, \ + SYS_READ = 3 // { ssize_t read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, size_t nbyte); } SYS_OPEN = 5 // { int open(char *path, int flags, int mode); } SYS_CLOSE = 6 // { int close(int fd); } - SYS_WAIT4 = 7 // { int wait4(int pid, int *status, \ + SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, struct rusage *rusage); } SYS_LINK = 9 // { int link(char *path, char *link); } SYS_UNLINK = 10 // { int unlink(char *path); } SYS_CHDIR = 12 // { int chdir(char *path); } @@ -21,20 +21,20 @@ const ( SYS_MKNOD = 14 // { int mknod(char *path, int mode, int dev); } SYS_CHMOD = 15 // { int chmod(char *path, int mode); } SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); } - SYS_OBREAK = 17 // { int obreak(char *nsize); } break \ + SYS_OBREAK = 17 // { int obreak(char *nsize); } break obreak_args int SYS_GETPID = 20 // { pid_t getpid(void); } - SYS_MOUNT = 21 // { int mount(char *type, char *path, \ + SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, caddr_t data); } SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); } SYS_SETUID = 23 // { int setuid(uid_t uid); } SYS_GETUID = 24 // { uid_t getuid(void); } SYS_GETEUID = 25 // { uid_t geteuid(void); } - SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, \ - SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, \ - SYS_SENDMSG = 28 // { int sendmsg(int s, struct msghdr *msg, \ - SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, \ - SYS_ACCEPT = 30 // { int accept(int s, \ - SYS_GETPEERNAME = 31 // { int getpeername(int fdes, \ - SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, \ + SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { int sendmsg(int s, struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, int flags, struct sockaddr * __restrict from, __socklen_t * __restrict fromlenaddr); } + SYS_ACCEPT = 30 // { int accept(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen); } + SYS_GETPEERNAME = 31 // { int getpeername(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); } + SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); } SYS_ACCESS = 33 // { int access(char *path, int amode); } SYS_CHFLAGS = 34 // { int chflags(const char *path, u_long flags); } SYS_FCHFLAGS = 35 // { int fchflags(int fd, u_long flags); } @@ -44,55 +44,55 @@ const ( SYS_DUP = 41 // { int dup(u_int fd); } SYS_PIPE = 42 // { int pipe(void); } SYS_GETEGID = 43 // { gid_t getegid(void); } - SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, \ - SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, \ + SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); } + SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, int pid); } SYS_GETGID = 47 // { gid_t getgid(void); } - SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int \ + SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int namelen); } SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); } SYS_ACCT = 51 // { int acct(char *path); } - SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, \ - SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, \ + SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, stack_t *oss); } + SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, caddr_t data); } SYS_REBOOT = 55 // { int reboot(int opt); } SYS_REVOKE = 56 // { int revoke(char *path); } SYS_SYMLINK = 57 // { int symlink(char *path, char *link); } - SYS_READLINK = 58 // { ssize_t readlink(char *path, char *buf, \ - SYS_EXECVE = 59 // { int execve(char *fname, char **argv, \ - SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args \ + SYS_READLINK = 58 // { ssize_t readlink(char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int execve(char *fname, char **argv, char **envv); } + SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args int SYS_CHROOT = 61 // { int chroot(char *path); } - SYS_MSYNC = 65 // { int msync(void *addr, size_t len, \ + SYS_MSYNC = 65 // { int msync(void *addr, size_t len, int flags); } SYS_VFORK = 66 // { int vfork(void); } SYS_SBRK = 69 // { int sbrk(int incr); } SYS_SSTK = 70 // { int sstk(int incr); } - SYS_OVADVISE = 72 // { int ovadvise(int anom); } vadvise \ + SYS_OVADVISE = 72 // { int ovadvise(int anom); } vadvise ovadvise_args int SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); } - SYS_MPROTECT = 74 // { int mprotect(const void *addr, size_t len, \ - SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, \ - SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, \ - SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, \ - SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, \ + SYS_MPROTECT = 74 // { int mprotect(const void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, int behav); } + SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, char *vec); } + SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, gid_t *gidset); } SYS_GETPGRP = 81 // { int getpgrp(void); } SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); } - SYS_SETITIMER = 83 // { int setitimer(u_int which, struct \ + SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, struct itimerval *oitv); } SYS_SWAPON = 85 // { int swapon(char *name); } - SYS_GETITIMER = 86 // { int getitimer(u_int which, \ + SYS_GETITIMER = 86 // { int getitimer(u_int which, struct itimerval *itv); } SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); } SYS_DUP2 = 90 // { int dup2(u_int from, u_int to); } SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); } - SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, \ + SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } SYS_FSYNC = 95 // { int fsync(int fd); } - SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, \ - SYS_SOCKET = 97 // { int socket(int domain, int type, \ - SYS_CONNECT = 98 // { int connect(int s, caddr_t name, \ + SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, int prio); } + SYS_SOCKET = 97 // { int socket(int domain, int type, int protocol); } + SYS_CONNECT = 98 // { int connect(int s, caddr_t name, int namelen); } SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); } - SYS_BIND = 104 // { int bind(int s, caddr_t name, \ - SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, \ + SYS_BIND = 104 // { int bind(int s, caddr_t name, int namelen); } + SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, caddr_t val, int valsize); } SYS_LISTEN = 106 // { int listen(int s, int backlog); } - SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, \ - SYS_GETRUSAGE = 117 // { int getrusage(int who, \ - SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, \ - SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, \ - SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, \ - SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, \ + SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_GETRUSAGE = 117 // { int getrusage(int who, struct rusage *rusage); } + SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, caddr_t val, int *avalsize); } + SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, struct timezone *tzp); } SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); } SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); } SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); } @@ -100,26 +100,26 @@ const ( SYS_RENAME = 128 // { int rename(char *from, char *to); } SYS_FLOCK = 131 // { int flock(int fd, int how); } SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); } - SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, \ + SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen); } SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); } - SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, \ + SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, int *rsv); } SYS_MKDIR = 136 // { int mkdir(char *path, int mode); } SYS_RMDIR = 137 // { int rmdir(char *path); } - SYS_UTIMES = 138 // { int utimes(char *path, \ - SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, \ + SYS_UTIMES = 138 // { int utimes(char *path, struct timeval *tptr); } + SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, struct timeval *olddelta); } SYS_SETSID = 147 // { int setsid(void); } - SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, \ + SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, caddr_t arg); } SYS_NLM_SYSCALL = 154 // { int nlm_syscall(int debug_level, int grace_period, int addr_count, char **addrs); } SYS_NFSSVC = 155 // { int nfssvc(int flag, caddr_t argp); } - SYS_LGETFH = 160 // { int lgetfh(char *fname, \ - SYS_GETFH = 161 // { int getfh(char *fname, \ + SYS_LGETFH = 160 // { int lgetfh(char *fname, struct fhandle *fhp); } + SYS_GETFH = 161 // { int getfh(char *fname, struct fhandle *fhp); } SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); } - SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, \ - SYS_SEMSYS = 169 // { int semsys(int which, int a2, int a3, \ - SYS_MSGSYS = 170 // { int msgsys(int which, int a2, int a3, \ - SYS_SHMSYS = 171 // { int shmsys(int which, int a2, int a3, \ - SYS_FREEBSD6_PREAD = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \ - SYS_FREEBSD6_PWRITE = 174 // { ssize_t freebsd6_pwrite(int fd, \ + SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, struct rtprio *rtp); } + SYS_SEMSYS = 169 // { int semsys(int which, int a2, int a3, int a4, int a5); } + SYS_MSGSYS = 170 // { int msgsys(int which, int a2, int a3, int a4, int a5, int a6); } + SYS_SHMSYS = 171 // { int shmsys(int which, int a2, int a3, int a4); } + SYS_FREEBSD6_PREAD = 173 // { ssize_t freebsd6_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_FREEBSD6_PWRITE = 174 // { ssize_t freebsd6_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } SYS_SETFIB = 175 // { int setfib(int fibnum); } SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); } SYS_SETGID = 181 // { int setgid(gid_t gid); } @@ -130,274 +130,274 @@ const ( SYS_LSTAT = 190 // { int lstat(char *path, struct stat *ub); } SYS_PATHCONF = 191 // { int pathconf(char *path, int name); } SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); } - SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, \ - SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, \ - SYS_GETDIRENTRIES = 196 // { int getdirentries(int fd, char *buf, \ - SYS_FREEBSD6_MMAP = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \ - SYS_FREEBSD6_LSEEK = 199 // { off_t freebsd6_lseek(int fd, int pad, \ - SYS_FREEBSD6_TRUNCATE = 200 // { int freebsd6_truncate(char *path, int pad, \ - SYS_FREEBSD6_FTRUNCATE = 201 // { int freebsd6_ftruncate(int fd, int pad, \ - SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, \ + SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int + SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int + SYS_GETDIRENTRIES = 196 // { int getdirentries(int fd, char *buf, u_int count, long *basep); } + SYS_FREEBSD6_MMAP = 197 // { caddr_t freebsd6_mmap(caddr_t addr, size_t len, int prot, int flags, int fd, int pad, off_t pos); } + SYS_FREEBSD6_LSEEK = 199 // { off_t freebsd6_lseek(int fd, int pad, off_t offset, int whence); } + SYS_FREEBSD6_TRUNCATE = 200 // { int freebsd6_truncate(char *path, int pad, off_t length); } + SYS_FREEBSD6_FTRUNCATE = 201 // { int freebsd6_ftruncate(int fd, int pad, off_t length); } + SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int SYS_MLOCK = 203 // { int mlock(const void *addr, size_t len); } SYS_MUNLOCK = 204 // { int munlock(const void *addr, size_t len); } SYS_UNDELETE = 205 // { int undelete(char *path); } SYS_FUTIMES = 206 // { int futimes(int fd, struct timeval *tptr); } SYS_GETPGID = 207 // { int getpgid(pid_t pid); } - SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, \ - SYS_SEMGET = 221 // { int semget(key_t key, int nsems, \ - SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, \ + SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS_SEMGET = 221 // { int semget(key_t key, int nsems, int semflg); } + SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); } SYS_MSGGET = 225 // { int msgget(key_t key, int msgflg); } - SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, \ - SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, \ - SYS_SHMAT = 228 // { int shmat(int shmid, const void *shmaddr, \ + SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); } SYS_SHMDT = 230 // { int shmdt(const void *shmaddr); } - SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, \ - SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, \ - SYS_CLOCK_SETTIME = 233 // { int clock_settime( \ - SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, \ - SYS_KTIMER_CREATE = 235 // { int ktimer_create(clockid_t clock_id, \ + SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, int shmflg); } + SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 233 // { int clock_settime( clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_KTIMER_CREATE = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); } SYS_KTIMER_DELETE = 236 // { int ktimer_delete(int timerid); } - SYS_KTIMER_SETTIME = 237 // { int ktimer_settime(int timerid, int flags, \ - SYS_KTIMER_GETTIME = 238 // { int ktimer_gettime(int timerid, struct \ + SYS_KTIMER_SETTIME = 237 // { int ktimer_settime(int timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue); } + SYS_KTIMER_GETTIME = 238 // { int ktimer_gettime(int timerid, struct itimerspec *value); } SYS_KTIMER_GETOVERRUN = 239 // { int ktimer_getoverrun(int timerid); } - SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, \ + SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } SYS_FFCLOCK_GETCOUNTER = 241 // { int ffclock_getcounter(ffcounter *ffcount); } - SYS_FFCLOCK_SETESTIMATE = 242 // { int ffclock_setestimate( \ - SYS_FFCLOCK_GETESTIMATE = 243 // { int ffclock_getestimate( \ - SYS_CLOCK_GETCPUCLOCKID2 = 247 // { int clock_getcpuclockid2(id_t id,\ + SYS_FFCLOCK_SETESTIMATE = 242 // { int ffclock_setestimate( struct ffclock_estimate *cest); } + SYS_FFCLOCK_GETESTIMATE = 243 // { int ffclock_getestimate( struct ffclock_estimate *cest); } + SYS_CLOCK_GETCPUCLOCKID2 = 247 // { int clock_getcpuclockid2(id_t id,int which, clockid_t *clock_id); } SYS_NTP_GETTIME = 248 // { int ntp_gettime(struct ntptimeval *ntvp); } - SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, \ + SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, int inherit); } SYS_RFORK = 251 // { int rfork(int flags); } - SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, \ + SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); } SYS_ISSETUGID = 253 // { int issetugid(void); } SYS_LCHOWN = 254 // { int lchown(char *path, int uid, int gid); } SYS_AIO_READ = 255 // { int aio_read(struct aiocb *aiocbp); } SYS_AIO_WRITE = 256 // { int aio_write(struct aiocb *aiocbp); } - SYS_LIO_LISTIO = 257 // { int lio_listio(int mode, \ - SYS_GETDENTS = 272 // { int getdents(int fd, char *buf, \ + SYS_LIO_LISTIO = 257 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); } + SYS_GETDENTS = 272 // { int getdents(int fd, char *buf, size_t count); } SYS_LCHMOD = 274 // { int lchmod(char *path, mode_t mode); } - SYS_LUTIMES = 276 // { int lutimes(char *path, \ + SYS_LUTIMES = 276 // { int lutimes(char *path, struct timeval *tptr); } SYS_NSTAT = 278 // { int nstat(char *path, struct nstat *ub); } SYS_NFSTAT = 279 // { int nfstat(int fd, struct nstat *sb); } SYS_NLSTAT = 280 // { int nlstat(char *path, struct nstat *ub); } - SYS_PREADV = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \ - SYS_PWRITEV = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \ - SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, \ - SYS_FHSTAT = 299 // { int fhstat(const struct fhandle *u_fhp, \ + SYS_PREADV = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); } + SYS_PWRITEV = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); } + SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); } + SYS_FHSTAT = 299 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); } SYS_MODNEXT = 300 // { int modnext(int modid); } - SYS_MODSTAT = 301 // { int modstat(int modid, \ + SYS_MODSTAT = 301 // { int modstat(int modid, struct module_stat *stat); } SYS_MODFNEXT = 302 // { int modfnext(int modid); } SYS_MODFIND = 303 // { int modfind(const char *name); } SYS_KLDLOAD = 304 // { int kldload(const char *file); } SYS_KLDUNLOAD = 305 // { int kldunload(int fileid); } SYS_KLDFIND = 306 // { int kldfind(const char *file); } SYS_KLDNEXT = 307 // { int kldnext(int fileid); } - SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct \ + SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); } SYS_KLDFIRSTMOD = 309 // { int kldfirstmod(int fileid); } SYS_GETSID = 310 // { int getsid(pid_t pid); } - SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, \ - SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, \ + SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); } SYS_AIO_RETURN = 314 // { int aio_return(struct aiocb *aiocbp); } - SYS_AIO_SUSPEND = 315 // { int aio_suspend( \ - SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, \ + SYS_AIO_SUSPEND = 315 // { int aio_suspend( struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); } + SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); } SYS_AIO_ERROR = 317 // { int aio_error(struct aiocb *aiocbp); } SYS_OAIO_READ = 318 // { int oaio_read(struct oaiocb *aiocbp); } SYS_OAIO_WRITE = 319 // { int oaio_write(struct oaiocb *aiocbp); } - SYS_OLIO_LISTIO = 320 // { int olio_listio(int mode, \ + SYS_OLIO_LISTIO = 320 // { int olio_listio(int mode, struct oaiocb * const *acb_list, int nent, struct osigevent *sig); } SYS_YIELD = 321 // { int yield(void); } SYS_MLOCKALL = 324 // { int mlockall(int how); } SYS_MUNLOCKALL = 325 // { int munlockall(void); } SYS___GETCWD = 326 // { int __getcwd(char *buf, u_int buflen); } - SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, \ - SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct \ - SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int \ + SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); } + SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); } + SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); } SYS_SCHED_GETSCHEDULER = 330 // { int sched_getscheduler (pid_t pid); } SYS_SCHED_YIELD = 331 // { int sched_yield (void); } SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); } SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); } - SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, \ + SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, struct timespec *interval); } SYS_UTRACE = 335 // { int utrace(const void *addr, size_t len); } - SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, \ + SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, void *data); } SYS_JAIL = 338 // { int jail(struct jail *jail); } - SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, \ + SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, const sigset_t *set, sigset_t *oset); } SYS_SIGSUSPEND = 341 // { int sigsuspend(const sigset_t *sigmask); } SYS_SIGPENDING = 343 // { int sigpending(sigset_t *set); } - SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set, \ - SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set, \ - SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, \ - SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, \ - SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, \ - SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, \ - SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, \ - SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, \ - SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, \ - SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, \ - SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, \ - SYS_EXTATTR_SET_FILE = 356 // { ssize_t extattr_set_file( \ - SYS_EXTATTR_GET_FILE = 357 // { ssize_t extattr_get_file( \ - SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, \ - SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete( \ - SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \ - SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \ + SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout); } + SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set, siginfo_t *info); } + SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, acl_type_t type); } + SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, acl_type_t type); } + SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); } + SYS_EXTATTR_SET_FILE = 356 // { ssize_t extattr_set_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_FILE = 357 // { ssize_t extattr_get_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); } + SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete( struct aiocb **aiocbp, struct timespec *timeout); } + SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } SYS_KQUEUE = 362 // { int kqueue(void); } - SYS_KEVENT = 363 // { int kevent(int fd, \ - SYS_EXTATTR_SET_FD = 371 // { ssize_t extattr_set_fd(int fd, \ - SYS_EXTATTR_GET_FD = 372 // { ssize_t extattr_get_fd(int fd, \ - SYS_EXTATTR_DELETE_FD = 373 // { int extattr_delete_fd(int fd, \ + SYS_KEVENT = 363 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } + SYS_EXTATTR_SET_FD = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_FD = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FD = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); } SYS___SETUGID = 374 // { int __setugid(int flag); } SYS_EACCESS = 376 // { int eaccess(char *path, int amode); } - SYS_NMOUNT = 378 // { int nmount(struct iovec *iovp, \ + SYS_NMOUNT = 378 // { int nmount(struct iovec *iovp, unsigned int iovcnt, int flags); } SYS___MAC_GET_PROC = 384 // { int __mac_get_proc(struct mac *mac_p); } SYS___MAC_SET_PROC = 385 // { int __mac_set_proc(struct mac *mac_p); } - SYS___MAC_GET_FD = 386 // { int __mac_get_fd(int fd, \ - SYS___MAC_GET_FILE = 387 // { int __mac_get_file(const char *path_p, \ - SYS___MAC_SET_FD = 388 // { int __mac_set_fd(int fd, \ - SYS___MAC_SET_FILE = 389 // { int __mac_set_file(const char *path_p, \ - SYS_KENV = 390 // { int kenv(int what, const char *name, \ - SYS_LCHFLAGS = 391 // { int lchflags(const char *path, \ - SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, \ - SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, \ - SYS_MAC_SYSCALL = 394 // { int mac_syscall(const char *policy, \ - SYS_GETFSSTAT = 395 // { int getfsstat(struct statfs *buf, \ - SYS_STATFS = 396 // { int statfs(char *path, \ + SYS___MAC_GET_FD = 386 // { int __mac_get_fd(int fd, struct mac *mac_p); } + SYS___MAC_GET_FILE = 387 // { int __mac_get_file(const char *path_p, struct mac *mac_p); } + SYS___MAC_SET_FD = 388 // { int __mac_set_fd(int fd, struct mac *mac_p); } + SYS___MAC_SET_FILE = 389 // { int __mac_set_file(const char *path_p, struct mac *mac_p); } + SYS_KENV = 390 // { int kenv(int what, const char *name, char *value, int len); } + SYS_LCHFLAGS = 391 // { int lchflags(const char *path, u_long flags); } + SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, int count); } + SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); } + SYS_MAC_SYSCALL = 394 // { int mac_syscall(const char *policy, int call, void *arg); } + SYS_GETFSSTAT = 395 // { int getfsstat(struct statfs *buf, long bufsize, int flags); } + SYS_STATFS = 396 // { int statfs(char *path, struct statfs *buf); } SYS_FSTATFS = 397 // { int fstatfs(int fd, struct statfs *buf); } - SYS_FHSTATFS = 398 // { int fhstatfs(const struct fhandle *u_fhp, \ + SYS_FHSTATFS = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); } SYS_KSEM_CLOSE = 400 // { int ksem_close(semid_t id); } SYS_KSEM_POST = 401 // { int ksem_post(semid_t id); } SYS_KSEM_WAIT = 402 // { int ksem_wait(semid_t id); } SYS_KSEM_TRYWAIT = 403 // { int ksem_trywait(semid_t id); } - SYS_KSEM_INIT = 404 // { int ksem_init(semid_t *idp, \ - SYS_KSEM_OPEN = 405 // { int ksem_open(semid_t *idp, \ + SYS_KSEM_INIT = 404 // { int ksem_init(semid_t *idp, unsigned int value); } + SYS_KSEM_OPEN = 405 // { int ksem_open(semid_t *idp, const char *name, int oflag, mode_t mode, unsigned int value); } SYS_KSEM_UNLINK = 406 // { int ksem_unlink(const char *name); } SYS_KSEM_GETVALUE = 407 // { int ksem_getvalue(semid_t id, int *val); } SYS_KSEM_DESTROY = 408 // { int ksem_destroy(semid_t id); } - SYS___MAC_GET_PID = 409 // { int __mac_get_pid(pid_t pid, \ - SYS___MAC_GET_LINK = 410 // { int __mac_get_link(const char *path_p, \ - SYS___MAC_SET_LINK = 411 // { int __mac_set_link(const char *path_p, \ - SYS_EXTATTR_SET_LINK = 412 // { ssize_t extattr_set_link( \ - SYS_EXTATTR_GET_LINK = 413 // { ssize_t extattr_get_link( \ - SYS_EXTATTR_DELETE_LINK = 414 // { int extattr_delete_link( \ - SYS___MAC_EXECVE = 415 // { int __mac_execve(char *fname, char **argv, \ - SYS_SIGACTION = 416 // { int sigaction(int sig, \ - SYS_SIGRETURN = 417 // { int sigreturn( \ + SYS___MAC_GET_PID = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); } + SYS___MAC_GET_LINK = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); } + SYS___MAC_SET_LINK = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); } + SYS_EXTATTR_SET_LINK = 412 // { ssize_t extattr_set_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_LINK = 413 // { ssize_t extattr_get_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_LINK = 414 // { int extattr_delete_link( const char *path, int attrnamespace, const char *attrname); } + SYS___MAC_EXECVE = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); } + SYS_SIGACTION = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); } + SYS_SIGRETURN = 417 // { int sigreturn( const struct __ucontext *sigcntxp); } SYS_GETCONTEXT = 421 // { int getcontext(struct __ucontext *ucp); } - SYS_SETCONTEXT = 422 // { int setcontext( \ - SYS_SWAPCONTEXT = 423 // { int swapcontext(struct __ucontext *oucp, \ + SYS_SETCONTEXT = 422 // { int setcontext( const struct __ucontext *ucp); } + SYS_SWAPCONTEXT = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); } SYS_SWAPOFF = 424 // { int swapoff(const char *name); } - SYS___ACL_GET_LINK = 425 // { int __acl_get_link(const char *path, \ - SYS___ACL_SET_LINK = 426 // { int __acl_set_link(const char *path, \ - SYS___ACL_DELETE_LINK = 427 // { int __acl_delete_link(const char *path, \ - SYS___ACL_ACLCHECK_LINK = 428 // { int __acl_aclcheck_link(const char *path, \ - SYS_SIGWAIT = 429 // { int sigwait(const sigset_t *set, \ - SYS_THR_CREATE = 430 // { int thr_create(ucontext_t *ctx, long *id, \ + SYS___ACL_GET_LINK = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_LINK = 426 // { int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_DELETE_LINK = 427 // { int __acl_delete_link(const char *path, acl_type_t type); } + SYS___ACL_ACLCHECK_LINK = 428 // { int __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS_SIGWAIT = 429 // { int sigwait(const sigset_t *set, int *sig); } + SYS_THR_CREATE = 430 // { int thr_create(ucontext_t *ctx, long *id, int flags); } SYS_THR_EXIT = 431 // { void thr_exit(long *state); } SYS_THR_SELF = 432 // { int thr_self(long *id); } SYS_THR_KILL = 433 // { int thr_kill(long id, int sig); } SYS__UMTX_LOCK = 434 // { int _umtx_lock(struct umtx *umtx); } SYS__UMTX_UNLOCK = 435 // { int _umtx_unlock(struct umtx *umtx); } SYS_JAIL_ATTACH = 436 // { int jail_attach(int jid); } - SYS_EXTATTR_LIST_FD = 437 // { ssize_t extattr_list_fd(int fd, \ - SYS_EXTATTR_LIST_FILE = 438 // { ssize_t extattr_list_file( \ - SYS_EXTATTR_LIST_LINK = 439 // { ssize_t extattr_list_link( \ - SYS_KSEM_TIMEDWAIT = 441 // { int ksem_timedwait(semid_t id, \ - SYS_THR_SUSPEND = 442 // { int thr_suspend( \ + SYS_EXTATTR_LIST_FD = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); } + SYS_EXTATTR_LIST_FILE = 438 // { ssize_t extattr_list_file( const char *path, int attrnamespace, void *data, size_t nbytes); } + SYS_EXTATTR_LIST_LINK = 439 // { ssize_t extattr_list_link( const char *path, int attrnamespace, void *data, size_t nbytes); } + SYS_KSEM_TIMEDWAIT = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); } + SYS_THR_SUSPEND = 442 // { int thr_suspend( const struct timespec *timeout); } SYS_THR_WAKE = 443 // { int thr_wake(long id); } SYS_KLDUNLOADF = 444 // { int kldunloadf(int fileid, int flags); } - SYS_AUDIT = 445 // { int audit(const void *record, \ - SYS_AUDITON = 446 // { int auditon(int cmd, void *data, \ + SYS_AUDIT = 445 // { int audit(const void *record, u_int length); } + SYS_AUDITON = 446 // { int auditon(int cmd, void *data, u_int length); } SYS_GETAUID = 447 // { int getauid(uid_t *auid); } SYS_SETAUID = 448 // { int setauid(uid_t *auid); } SYS_GETAUDIT = 449 // { int getaudit(struct auditinfo *auditinfo); } SYS_SETAUDIT = 450 // { int setaudit(struct auditinfo *auditinfo); } - SYS_GETAUDIT_ADDR = 451 // { int getaudit_addr( \ - SYS_SETAUDIT_ADDR = 452 // { int setaudit_addr( \ + SYS_GETAUDIT_ADDR = 451 // { int getaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); } + SYS_SETAUDIT_ADDR = 452 // { int setaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); } SYS_AUDITCTL = 453 // { int auditctl(char *path); } - SYS__UMTX_OP = 454 // { int _umtx_op(void *obj, int op, \ - SYS_THR_NEW = 455 // { int thr_new(struct thr_param *param, \ + SYS__UMTX_OP = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); } + SYS_THR_NEW = 455 // { int thr_new(struct thr_param *param, int param_size); } SYS_SIGQUEUE = 456 // { int sigqueue(pid_t pid, int signum, void *value); } - SYS_KMQ_OPEN = 457 // { int kmq_open(const char *path, int flags, \ - SYS_KMQ_SETATTR = 458 // { int kmq_setattr(int mqd, \ - SYS_KMQ_TIMEDRECEIVE = 459 // { int kmq_timedreceive(int mqd, \ - SYS_KMQ_TIMEDSEND = 460 // { int kmq_timedsend(int mqd, \ - SYS_KMQ_NOTIFY = 461 // { int kmq_notify(int mqd, \ + SYS_KMQ_OPEN = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); } + SYS_KMQ_SETATTR = 458 // { int kmq_setattr(int mqd, const struct mq_attr *attr, struct mq_attr *oattr); } + SYS_KMQ_TIMEDRECEIVE = 459 // { int kmq_timedreceive(int mqd, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); } + SYS_KMQ_TIMEDSEND = 460 // { int kmq_timedsend(int mqd, const char *msg_ptr, size_t msg_len,unsigned msg_prio, const struct timespec *abs_timeout);} + SYS_KMQ_NOTIFY = 461 // { int kmq_notify(int mqd, const struct sigevent *sigev); } SYS_KMQ_UNLINK = 462 // { int kmq_unlink(const char *path); } SYS_ABORT2 = 463 // { int abort2(const char *why, int nargs, void **args); } SYS_THR_SET_NAME = 464 // { int thr_set_name(long id, const char *name); } SYS_AIO_FSYNC = 465 // { int aio_fsync(int op, struct aiocb *aiocbp); } - SYS_RTPRIO_THREAD = 466 // { int rtprio_thread(int function, \ + SYS_RTPRIO_THREAD = 466 // { int rtprio_thread(int function, lwpid_t lwpid, struct rtprio *rtp); } SYS_SCTP_PEELOFF = 471 // { int sctp_peeloff(int sd, uint32_t name); } - SYS_SCTP_GENERIC_SENDMSG = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \ - SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \ - SYS_SCTP_GENERIC_RECVMSG = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \ - SYS_PREAD = 475 // { ssize_t pread(int fd, void *buf, \ - SYS_PWRITE = 476 // { ssize_t pwrite(int fd, const void *buf, \ - SYS_MMAP = 477 // { caddr_t mmap(caddr_t addr, size_t len, \ - SYS_LSEEK = 478 // { off_t lseek(int fd, off_t offset, \ + SYS_SCTP_GENERIC_SENDMSG = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); } + SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); } + SYS_SCTP_GENERIC_RECVMSG = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr * from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); } + SYS_PREAD = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); } + SYS_PWRITE = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); } + SYS_MMAP = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); } + SYS_LSEEK = 478 // { off_t lseek(int fd, off_t offset, int whence); } SYS_TRUNCATE = 479 // { int truncate(char *path, off_t length); } SYS_FTRUNCATE = 480 // { int ftruncate(int fd, off_t length); } SYS_THR_KILL2 = 481 // { int thr_kill2(pid_t pid, long id, int sig); } - SYS_SHM_OPEN = 482 // { int shm_open(const char *path, int flags, \ + SYS_SHM_OPEN = 482 // { int shm_open(const char *path, int flags, mode_t mode); } SYS_SHM_UNLINK = 483 // { int shm_unlink(const char *path); } SYS_CPUSET = 484 // { int cpuset(cpusetid_t *setid); } - SYS_CPUSET_SETID = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \ - SYS_CPUSET_GETID = 486 // { int cpuset_getid(cpulevel_t level, \ - SYS_CPUSET_GETAFFINITY = 487 // { int cpuset_getaffinity(cpulevel_t level, \ - SYS_CPUSET_SETAFFINITY = 488 // { int cpuset_setaffinity(cpulevel_t level, \ - SYS_FACCESSAT = 489 // { int faccessat(int fd, char *path, int amode, \ - SYS_FCHMODAT = 490 // { int fchmodat(int fd, char *path, mode_t mode, \ - SYS_FCHOWNAT = 491 // { int fchownat(int fd, char *path, uid_t uid, \ - SYS_FEXECVE = 492 // { int fexecve(int fd, char **argv, \ - SYS_FSTATAT = 493 // { int fstatat(int fd, char *path, \ - SYS_FUTIMESAT = 494 // { int futimesat(int fd, char *path, \ - SYS_LINKAT = 495 // { int linkat(int fd1, char *path1, int fd2, \ + SYS_CPUSET_SETID = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, cpusetid_t setid); } + SYS_CPUSET_GETID = 486 // { int cpuset_getid(cpulevel_t level, cpuwhich_t which, id_t id, cpusetid_t *setid); } + SYS_CPUSET_GETAFFINITY = 487 // { int cpuset_getaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, cpuset_t *mask); } + SYS_CPUSET_SETAFFINITY = 488 // { int cpuset_setaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, const cpuset_t *mask); } + SYS_FACCESSAT = 489 // { int faccessat(int fd, char *path, int amode, int flag); } + SYS_FCHMODAT = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); } + SYS_FEXECVE = 492 // { int fexecve(int fd, char **argv, char **envv); } + SYS_FSTATAT = 493 // { int fstatat(int fd, char *path, struct stat *buf, int flag); } + SYS_FUTIMESAT = 494 // { int futimesat(int fd, char *path, struct timeval *times); } + SYS_LINKAT = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); } SYS_MKDIRAT = 496 // { int mkdirat(int fd, char *path, mode_t mode); } SYS_MKFIFOAT = 497 // { int mkfifoat(int fd, char *path, mode_t mode); } - SYS_MKNODAT = 498 // { int mknodat(int fd, char *path, mode_t mode, \ - SYS_OPENAT = 499 // { int openat(int fd, char *path, int flag, \ - SYS_READLINKAT = 500 // { int readlinkat(int fd, char *path, char *buf, \ - SYS_RENAMEAT = 501 // { int renameat(int oldfd, char *old, int newfd, \ - SYS_SYMLINKAT = 502 // { int symlinkat(char *path1, int fd, \ + SYS_MKNODAT = 498 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 499 // { int openat(int fd, char *path, int flag, mode_t mode); } + SYS_READLINKAT = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); } + SYS_RENAMEAT = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); } + SYS_SYMLINKAT = 502 // { int symlinkat(char *path1, int fd, char *path2); } SYS_UNLINKAT = 503 // { int unlinkat(int fd, char *path, int flag); } SYS_POSIX_OPENPT = 504 // { int posix_openpt(int flags); } SYS_GSSD_SYSCALL = 505 // { int gssd_syscall(char *path); } - SYS_JAIL_GET = 506 // { int jail_get(struct iovec *iovp, \ - SYS_JAIL_SET = 507 // { int jail_set(struct iovec *iovp, \ + SYS_JAIL_GET = 506 // { int jail_get(struct iovec *iovp, unsigned int iovcnt, int flags); } + SYS_JAIL_SET = 507 // { int jail_set(struct iovec *iovp, unsigned int iovcnt, int flags); } SYS_JAIL_REMOVE = 508 // { int jail_remove(int jid); } SYS_CLOSEFROM = 509 // { int closefrom(int lowfd); } - SYS___SEMCTL = 510 // { int __semctl(int semid, int semnum, \ - SYS_MSGCTL = 511 // { int msgctl(int msqid, int cmd, \ - SYS_SHMCTL = 512 // { int shmctl(int shmid, int cmd, \ + SYS___SEMCTL = 510 // { int __semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_MSGCTL = 511 // { int msgctl(int msqid, int cmd, struct msqid_ds *buf); } + SYS_SHMCTL = 512 // { int shmctl(int shmid, int cmd, struct shmid_ds *buf); } SYS_LPATHCONF = 513 // { int lpathconf(char *path, int name); } - SYS___CAP_RIGHTS_GET = 515 // { int __cap_rights_get(int version, \ + SYS___CAP_RIGHTS_GET = 515 // { int __cap_rights_get(int version, int fd, cap_rights_t *rightsp); } SYS_CAP_ENTER = 516 // { int cap_enter(void); } SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); } SYS_PDFORK = 518 // { int pdfork(int *fdp, int flags); } SYS_PDKILL = 519 // { int pdkill(int fd, int signum); } SYS_PDGETPID = 520 // { int pdgetpid(int fd, pid_t *pidp); } - SYS_PSELECT = 522 // { int pselect(int nd, fd_set *in, \ - SYS_GETLOGINCLASS = 523 // { int getloginclass(char *namebuf, \ + SYS_PSELECT = 522 // { int pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *sm); } + SYS_GETLOGINCLASS = 523 // { int getloginclass(char *namebuf, size_t namelen); } SYS_SETLOGINCLASS = 524 // { int setloginclass(const char *namebuf); } - SYS_RCTL_GET_RACCT = 525 // { int rctl_get_racct(const void *inbufp, \ - SYS_RCTL_GET_RULES = 526 // { int rctl_get_rules(const void *inbufp, \ - SYS_RCTL_GET_LIMITS = 527 // { int rctl_get_limits(const void *inbufp, \ - SYS_RCTL_ADD_RULE = 528 // { int rctl_add_rule(const void *inbufp, \ - SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, \ - SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, \ - SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, \ - SYS_WAIT6 = 532 // { int wait6(idtype_t idtype, id_t id, \ - SYS_CAP_RIGHTS_LIMIT = 533 // { int cap_rights_limit(int fd, \ - SYS_CAP_IOCTLS_LIMIT = 534 // { int cap_ioctls_limit(int fd, \ - SYS_CAP_IOCTLS_GET = 535 // { ssize_t cap_ioctls_get(int fd, \ - SYS_CAP_FCNTLS_LIMIT = 536 // { int cap_fcntls_limit(int fd, \ - SYS_CAP_FCNTLS_GET = 537 // { int cap_fcntls_get(int fd, \ - SYS_BINDAT = 538 // { int bindat(int fd, int s, caddr_t name, \ - SYS_CONNECTAT = 539 // { int connectat(int fd, int s, caddr_t name, \ - SYS_CHFLAGSAT = 540 // { int chflagsat(int fd, const char *path, \ - SYS_ACCEPT4 = 541 // { int accept4(int s, \ + SYS_RCTL_GET_RACCT = 525 // { int rctl_get_racct(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_GET_RULES = 526 // { int rctl_get_rules(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_GET_LIMITS = 527 // { int rctl_get_limits(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_ADD_RULE = 528 // { int rctl_add_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, off_t offset, off_t len); } + SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, off_t len, int advice); } + SYS_WAIT6 = 532 // { int wait6(idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *info); } + SYS_CAP_RIGHTS_LIMIT = 533 // { int cap_rights_limit(int fd, cap_rights_t *rightsp); } + SYS_CAP_IOCTLS_LIMIT = 534 // { int cap_ioctls_limit(int fd, const u_long *cmds, size_t ncmds); } + SYS_CAP_IOCTLS_GET = 535 // { ssize_t cap_ioctls_get(int fd, u_long *cmds, size_t maxcmds); } + SYS_CAP_FCNTLS_LIMIT = 536 // { int cap_fcntls_limit(int fd, uint32_t fcntlrights); } + SYS_CAP_FCNTLS_GET = 537 // { int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); } + SYS_BINDAT = 538 // { int bindat(int fd, int s, caddr_t name, int namelen); } + SYS_CONNECTAT = 539 // { int connectat(int fd, int s, caddr_t name, int namelen); } + SYS_CHFLAGSAT = 540 // { int chflagsat(int fd, const char *path, u_long flags, int atflag); } + SYS_ACCEPT4 = 541 // { int accept4(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen, int flags); } SYS_PIPE2 = 542 // { int pipe2(int *fildes, int flags); } SYS_AIO_MLOCK = 543 // { int aio_mlock(struct aiocb *aiocbp); } - SYS_PROCCTL = 544 // { int procctl(idtype_t idtype, id_t id, \ - SYS_PPOLL = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \ - SYS_FUTIMENS = 546 // { int futimens(int fd, \ - SYS_UTIMENSAT = 547 // { int utimensat(int fd, \ + SYS_PROCCTL = 544 // { int procctl(idtype_t idtype, id_t id, int com, void *data); } + SYS_PPOLL = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); } + SYS_FUTIMENS = 546 // { int futimens(int fd, struct timespec *times); } + SYS_UTIMENSAT = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); } ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go index b66f900dff76..b39be6cb8f4a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go @@ -1,4 +1,4 @@ -// mksysnum_freebsd.pl +// go run mksysnum.go https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master // Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,freebsd @@ -7,13 +7,13 @@ package unix const ( // SYS_NOSYS = 0; // { int nosys(void); } syscall nosys_args int - SYS_EXIT = 1 // { void sys_exit(int rval); } exit \ + SYS_EXIT = 1 // { void sys_exit(int rval); } exit sys_exit_args void SYS_FORK = 2 // { int fork(void); } - SYS_READ = 3 // { ssize_t read(int fd, void *buf, \ - SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, \ + SYS_READ = 3 // { ssize_t read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, size_t nbyte); } SYS_OPEN = 5 // { int open(char *path, int flags, int mode); } SYS_CLOSE = 6 // { int close(int fd); } - SYS_WAIT4 = 7 // { int wait4(int pid, int *status, \ + SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, struct rusage *rusage); } SYS_LINK = 9 // { int link(char *path, char *link); } SYS_UNLINK = 10 // { int unlink(char *path); } SYS_CHDIR = 12 // { int chdir(char *path); } @@ -21,20 +21,20 @@ const ( SYS_MKNOD = 14 // { int mknod(char *path, int mode, int dev); } SYS_CHMOD = 15 // { int chmod(char *path, int mode); } SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); } - SYS_OBREAK = 17 // { int obreak(char *nsize); } break \ + SYS_OBREAK = 17 // { int obreak(char *nsize); } break obreak_args int SYS_GETPID = 20 // { pid_t getpid(void); } - SYS_MOUNT = 21 // { int mount(char *type, char *path, \ + SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, caddr_t data); } SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); } SYS_SETUID = 23 // { int setuid(uid_t uid); } SYS_GETUID = 24 // { uid_t getuid(void); } SYS_GETEUID = 25 // { uid_t geteuid(void); } - SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, \ - SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, \ - SYS_SENDMSG = 28 // { int sendmsg(int s, struct msghdr *msg, \ - SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, \ - SYS_ACCEPT = 30 // { int accept(int s, \ - SYS_GETPEERNAME = 31 // { int getpeername(int fdes, \ - SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, \ + SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { int sendmsg(int s, struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, int flags, struct sockaddr * __restrict from, __socklen_t * __restrict fromlenaddr); } + SYS_ACCEPT = 30 // { int accept(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen); } + SYS_GETPEERNAME = 31 // { int getpeername(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); } + SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); } SYS_ACCESS = 33 // { int access(char *path, int amode); } SYS_CHFLAGS = 34 // { int chflags(const char *path, u_long flags); } SYS_FCHFLAGS = 35 // { int fchflags(int fd, u_long flags); } @@ -44,55 +44,55 @@ const ( SYS_DUP = 41 // { int dup(u_int fd); } SYS_PIPE = 42 // { int pipe(void); } SYS_GETEGID = 43 // { gid_t getegid(void); } - SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, \ - SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, \ + SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); } + SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, int pid); } SYS_GETGID = 47 // { gid_t getgid(void); } - SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int \ + SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int namelen); } SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); } SYS_ACCT = 51 // { int acct(char *path); } - SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, \ - SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, \ + SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, stack_t *oss); } + SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, caddr_t data); } SYS_REBOOT = 55 // { int reboot(int opt); } SYS_REVOKE = 56 // { int revoke(char *path); } SYS_SYMLINK = 57 // { int symlink(char *path, char *link); } - SYS_READLINK = 58 // { ssize_t readlink(char *path, char *buf, \ - SYS_EXECVE = 59 // { int execve(char *fname, char **argv, \ - SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args \ + SYS_READLINK = 58 // { ssize_t readlink(char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int execve(char *fname, char **argv, char **envv); } + SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args int SYS_CHROOT = 61 // { int chroot(char *path); } - SYS_MSYNC = 65 // { int msync(void *addr, size_t len, \ + SYS_MSYNC = 65 // { int msync(void *addr, size_t len, int flags); } SYS_VFORK = 66 // { int vfork(void); } SYS_SBRK = 69 // { int sbrk(int incr); } SYS_SSTK = 70 // { int sstk(int incr); } - SYS_OVADVISE = 72 // { int ovadvise(int anom); } vadvise \ + SYS_OVADVISE = 72 // { int ovadvise(int anom); } vadvise ovadvise_args int SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); } - SYS_MPROTECT = 74 // { int mprotect(const void *addr, size_t len, \ - SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, \ - SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, \ - SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, \ - SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, \ + SYS_MPROTECT = 74 // { int mprotect(const void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, int behav); } + SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, char *vec); } + SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, gid_t *gidset); } SYS_GETPGRP = 81 // { int getpgrp(void); } SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); } - SYS_SETITIMER = 83 // { int setitimer(u_int which, struct \ + SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, struct itimerval *oitv); } SYS_SWAPON = 85 // { int swapon(char *name); } - SYS_GETITIMER = 86 // { int getitimer(u_int which, \ + SYS_GETITIMER = 86 // { int getitimer(u_int which, struct itimerval *itv); } SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); } SYS_DUP2 = 90 // { int dup2(u_int from, u_int to); } SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); } - SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, \ + SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } SYS_FSYNC = 95 // { int fsync(int fd); } - SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, \ - SYS_SOCKET = 97 // { int socket(int domain, int type, \ - SYS_CONNECT = 98 // { int connect(int s, caddr_t name, \ + SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, int prio); } + SYS_SOCKET = 97 // { int socket(int domain, int type, int protocol); } + SYS_CONNECT = 98 // { int connect(int s, caddr_t name, int namelen); } SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); } - SYS_BIND = 104 // { int bind(int s, caddr_t name, \ - SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, \ + SYS_BIND = 104 // { int bind(int s, caddr_t name, int namelen); } + SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, caddr_t val, int valsize); } SYS_LISTEN = 106 // { int listen(int s, int backlog); } - SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, \ - SYS_GETRUSAGE = 117 // { int getrusage(int who, \ - SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, \ - SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, \ - SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, \ - SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, \ + SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_GETRUSAGE = 117 // { int getrusage(int who, struct rusage *rusage); } + SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, caddr_t val, int *avalsize); } + SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, struct timezone *tzp); } SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); } SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); } SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); } @@ -100,26 +100,26 @@ const ( SYS_RENAME = 128 // { int rename(char *from, char *to); } SYS_FLOCK = 131 // { int flock(int fd, int how); } SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); } - SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, \ + SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen); } SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); } - SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, \ + SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, int *rsv); } SYS_MKDIR = 136 // { int mkdir(char *path, int mode); } SYS_RMDIR = 137 // { int rmdir(char *path); } - SYS_UTIMES = 138 // { int utimes(char *path, \ - SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, \ + SYS_UTIMES = 138 // { int utimes(char *path, struct timeval *tptr); } + SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, struct timeval *olddelta); } SYS_SETSID = 147 // { int setsid(void); } - SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, \ + SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, caddr_t arg); } SYS_NLM_SYSCALL = 154 // { int nlm_syscall(int debug_level, int grace_period, int addr_count, char **addrs); } SYS_NFSSVC = 155 // { int nfssvc(int flag, caddr_t argp); } - SYS_LGETFH = 160 // { int lgetfh(char *fname, \ - SYS_GETFH = 161 // { int getfh(char *fname, \ + SYS_LGETFH = 160 // { int lgetfh(char *fname, struct fhandle *fhp); } + SYS_GETFH = 161 // { int getfh(char *fname, struct fhandle *fhp); } SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); } - SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, \ - SYS_SEMSYS = 169 // { int semsys(int which, int a2, int a3, \ - SYS_MSGSYS = 170 // { int msgsys(int which, int a2, int a3, \ - SYS_SHMSYS = 171 // { int shmsys(int which, int a2, int a3, \ - SYS_FREEBSD6_PREAD = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \ - SYS_FREEBSD6_PWRITE = 174 // { ssize_t freebsd6_pwrite(int fd, \ + SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, struct rtprio *rtp); } + SYS_SEMSYS = 169 // { int semsys(int which, int a2, int a3, int a4, int a5); } + SYS_MSGSYS = 170 // { int msgsys(int which, int a2, int a3, int a4, int a5, int a6); } + SYS_SHMSYS = 171 // { int shmsys(int which, int a2, int a3, int a4); } + SYS_FREEBSD6_PREAD = 173 // { ssize_t freebsd6_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_FREEBSD6_PWRITE = 174 // { ssize_t freebsd6_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } SYS_SETFIB = 175 // { int setfib(int fibnum); } SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); } SYS_SETGID = 181 // { int setgid(gid_t gid); } @@ -130,274 +130,274 @@ const ( SYS_LSTAT = 190 // { int lstat(char *path, struct stat *ub); } SYS_PATHCONF = 191 // { int pathconf(char *path, int name); } SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); } - SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, \ - SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, \ - SYS_GETDIRENTRIES = 196 // { int getdirentries(int fd, char *buf, \ - SYS_FREEBSD6_MMAP = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \ - SYS_FREEBSD6_LSEEK = 199 // { off_t freebsd6_lseek(int fd, int pad, \ - SYS_FREEBSD6_TRUNCATE = 200 // { int freebsd6_truncate(char *path, int pad, \ - SYS_FREEBSD6_FTRUNCATE = 201 // { int freebsd6_ftruncate(int fd, int pad, \ - SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, \ + SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int + SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int + SYS_GETDIRENTRIES = 196 // { int getdirentries(int fd, char *buf, u_int count, long *basep); } + SYS_FREEBSD6_MMAP = 197 // { caddr_t freebsd6_mmap(caddr_t addr, size_t len, int prot, int flags, int fd, int pad, off_t pos); } + SYS_FREEBSD6_LSEEK = 199 // { off_t freebsd6_lseek(int fd, int pad, off_t offset, int whence); } + SYS_FREEBSD6_TRUNCATE = 200 // { int freebsd6_truncate(char *path, int pad, off_t length); } + SYS_FREEBSD6_FTRUNCATE = 201 // { int freebsd6_ftruncate(int fd, int pad, off_t length); } + SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int SYS_MLOCK = 203 // { int mlock(const void *addr, size_t len); } SYS_MUNLOCK = 204 // { int munlock(const void *addr, size_t len); } SYS_UNDELETE = 205 // { int undelete(char *path); } SYS_FUTIMES = 206 // { int futimes(int fd, struct timeval *tptr); } SYS_GETPGID = 207 // { int getpgid(pid_t pid); } - SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, \ - SYS_SEMGET = 221 // { int semget(key_t key, int nsems, \ - SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, \ + SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS_SEMGET = 221 // { int semget(key_t key, int nsems, int semflg); } + SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); } SYS_MSGGET = 225 // { int msgget(key_t key, int msgflg); } - SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, \ - SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, \ - SYS_SHMAT = 228 // { int shmat(int shmid, const void *shmaddr, \ + SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); } SYS_SHMDT = 230 // { int shmdt(const void *shmaddr); } - SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, \ - SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, \ - SYS_CLOCK_SETTIME = 233 // { int clock_settime( \ - SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, \ - SYS_KTIMER_CREATE = 235 // { int ktimer_create(clockid_t clock_id, \ + SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, int shmflg); } + SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 233 // { int clock_settime( clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_KTIMER_CREATE = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); } SYS_KTIMER_DELETE = 236 // { int ktimer_delete(int timerid); } - SYS_KTIMER_SETTIME = 237 // { int ktimer_settime(int timerid, int flags, \ - SYS_KTIMER_GETTIME = 238 // { int ktimer_gettime(int timerid, struct \ + SYS_KTIMER_SETTIME = 237 // { int ktimer_settime(int timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue); } + SYS_KTIMER_GETTIME = 238 // { int ktimer_gettime(int timerid, struct itimerspec *value); } SYS_KTIMER_GETOVERRUN = 239 // { int ktimer_getoverrun(int timerid); } - SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, \ + SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } SYS_FFCLOCK_GETCOUNTER = 241 // { int ffclock_getcounter(ffcounter *ffcount); } - SYS_FFCLOCK_SETESTIMATE = 242 // { int ffclock_setestimate( \ - SYS_FFCLOCK_GETESTIMATE = 243 // { int ffclock_getestimate( \ - SYS_CLOCK_GETCPUCLOCKID2 = 247 // { int clock_getcpuclockid2(id_t id,\ + SYS_FFCLOCK_SETESTIMATE = 242 // { int ffclock_setestimate( struct ffclock_estimate *cest); } + SYS_FFCLOCK_GETESTIMATE = 243 // { int ffclock_getestimate( struct ffclock_estimate *cest); } + SYS_CLOCK_GETCPUCLOCKID2 = 247 // { int clock_getcpuclockid2(id_t id,int which, clockid_t *clock_id); } SYS_NTP_GETTIME = 248 // { int ntp_gettime(struct ntptimeval *ntvp); } - SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, \ + SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, int inherit); } SYS_RFORK = 251 // { int rfork(int flags); } - SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, \ + SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); } SYS_ISSETUGID = 253 // { int issetugid(void); } SYS_LCHOWN = 254 // { int lchown(char *path, int uid, int gid); } SYS_AIO_READ = 255 // { int aio_read(struct aiocb *aiocbp); } SYS_AIO_WRITE = 256 // { int aio_write(struct aiocb *aiocbp); } - SYS_LIO_LISTIO = 257 // { int lio_listio(int mode, \ - SYS_GETDENTS = 272 // { int getdents(int fd, char *buf, \ + SYS_LIO_LISTIO = 257 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); } + SYS_GETDENTS = 272 // { int getdents(int fd, char *buf, size_t count); } SYS_LCHMOD = 274 // { int lchmod(char *path, mode_t mode); } - SYS_LUTIMES = 276 // { int lutimes(char *path, \ + SYS_LUTIMES = 276 // { int lutimes(char *path, struct timeval *tptr); } SYS_NSTAT = 278 // { int nstat(char *path, struct nstat *ub); } SYS_NFSTAT = 279 // { int nfstat(int fd, struct nstat *sb); } SYS_NLSTAT = 280 // { int nlstat(char *path, struct nstat *ub); } - SYS_PREADV = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \ - SYS_PWRITEV = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \ - SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, \ - SYS_FHSTAT = 299 // { int fhstat(const struct fhandle *u_fhp, \ + SYS_PREADV = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); } + SYS_PWRITEV = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); } + SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); } + SYS_FHSTAT = 299 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); } SYS_MODNEXT = 300 // { int modnext(int modid); } - SYS_MODSTAT = 301 // { int modstat(int modid, \ + SYS_MODSTAT = 301 // { int modstat(int modid, struct module_stat *stat); } SYS_MODFNEXT = 302 // { int modfnext(int modid); } SYS_MODFIND = 303 // { int modfind(const char *name); } SYS_KLDLOAD = 304 // { int kldload(const char *file); } SYS_KLDUNLOAD = 305 // { int kldunload(int fileid); } SYS_KLDFIND = 306 // { int kldfind(const char *file); } SYS_KLDNEXT = 307 // { int kldnext(int fileid); } - SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct \ + SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); } SYS_KLDFIRSTMOD = 309 // { int kldfirstmod(int fileid); } SYS_GETSID = 310 // { int getsid(pid_t pid); } - SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, \ - SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, \ + SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); } SYS_AIO_RETURN = 314 // { int aio_return(struct aiocb *aiocbp); } - SYS_AIO_SUSPEND = 315 // { int aio_suspend( \ - SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, \ + SYS_AIO_SUSPEND = 315 // { int aio_suspend( struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); } + SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); } SYS_AIO_ERROR = 317 // { int aio_error(struct aiocb *aiocbp); } SYS_OAIO_READ = 318 // { int oaio_read(struct oaiocb *aiocbp); } SYS_OAIO_WRITE = 319 // { int oaio_write(struct oaiocb *aiocbp); } - SYS_OLIO_LISTIO = 320 // { int olio_listio(int mode, \ + SYS_OLIO_LISTIO = 320 // { int olio_listio(int mode, struct oaiocb * const *acb_list, int nent, struct osigevent *sig); } SYS_YIELD = 321 // { int yield(void); } SYS_MLOCKALL = 324 // { int mlockall(int how); } SYS_MUNLOCKALL = 325 // { int munlockall(void); } SYS___GETCWD = 326 // { int __getcwd(char *buf, u_int buflen); } - SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, \ - SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct \ - SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int \ + SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); } + SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); } + SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); } SYS_SCHED_GETSCHEDULER = 330 // { int sched_getscheduler (pid_t pid); } SYS_SCHED_YIELD = 331 // { int sched_yield (void); } SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); } SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); } - SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, \ + SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, struct timespec *interval); } SYS_UTRACE = 335 // { int utrace(const void *addr, size_t len); } - SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, \ + SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, void *data); } SYS_JAIL = 338 // { int jail(struct jail *jail); } - SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, \ + SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, const sigset_t *set, sigset_t *oset); } SYS_SIGSUSPEND = 341 // { int sigsuspend(const sigset_t *sigmask); } SYS_SIGPENDING = 343 // { int sigpending(sigset_t *set); } - SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set, \ - SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set, \ - SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, \ - SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, \ - SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, \ - SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, \ - SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, \ - SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, \ - SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, \ - SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, \ - SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, \ - SYS_EXTATTR_SET_FILE = 356 // { ssize_t extattr_set_file( \ - SYS_EXTATTR_GET_FILE = 357 // { ssize_t extattr_get_file( \ - SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, \ - SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete( \ - SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \ - SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \ + SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout); } + SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set, siginfo_t *info); } + SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, acl_type_t type); } + SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, acl_type_t type); } + SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); } + SYS_EXTATTR_SET_FILE = 356 // { ssize_t extattr_set_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_FILE = 357 // { ssize_t extattr_get_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); } + SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete( struct aiocb **aiocbp, struct timespec *timeout); } + SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } SYS_KQUEUE = 362 // { int kqueue(void); } - SYS_KEVENT = 363 // { int kevent(int fd, \ - SYS_EXTATTR_SET_FD = 371 // { ssize_t extattr_set_fd(int fd, \ - SYS_EXTATTR_GET_FD = 372 // { ssize_t extattr_get_fd(int fd, \ - SYS_EXTATTR_DELETE_FD = 373 // { int extattr_delete_fd(int fd, \ + SYS_KEVENT = 363 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } + SYS_EXTATTR_SET_FD = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_FD = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FD = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); } SYS___SETUGID = 374 // { int __setugid(int flag); } SYS_EACCESS = 376 // { int eaccess(char *path, int amode); } - SYS_NMOUNT = 378 // { int nmount(struct iovec *iovp, \ + SYS_NMOUNT = 378 // { int nmount(struct iovec *iovp, unsigned int iovcnt, int flags); } SYS___MAC_GET_PROC = 384 // { int __mac_get_proc(struct mac *mac_p); } SYS___MAC_SET_PROC = 385 // { int __mac_set_proc(struct mac *mac_p); } - SYS___MAC_GET_FD = 386 // { int __mac_get_fd(int fd, \ - SYS___MAC_GET_FILE = 387 // { int __mac_get_file(const char *path_p, \ - SYS___MAC_SET_FD = 388 // { int __mac_set_fd(int fd, \ - SYS___MAC_SET_FILE = 389 // { int __mac_set_file(const char *path_p, \ - SYS_KENV = 390 // { int kenv(int what, const char *name, \ - SYS_LCHFLAGS = 391 // { int lchflags(const char *path, \ - SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, \ - SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, \ - SYS_MAC_SYSCALL = 394 // { int mac_syscall(const char *policy, \ - SYS_GETFSSTAT = 395 // { int getfsstat(struct statfs *buf, \ - SYS_STATFS = 396 // { int statfs(char *path, \ + SYS___MAC_GET_FD = 386 // { int __mac_get_fd(int fd, struct mac *mac_p); } + SYS___MAC_GET_FILE = 387 // { int __mac_get_file(const char *path_p, struct mac *mac_p); } + SYS___MAC_SET_FD = 388 // { int __mac_set_fd(int fd, struct mac *mac_p); } + SYS___MAC_SET_FILE = 389 // { int __mac_set_file(const char *path_p, struct mac *mac_p); } + SYS_KENV = 390 // { int kenv(int what, const char *name, char *value, int len); } + SYS_LCHFLAGS = 391 // { int lchflags(const char *path, u_long flags); } + SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, int count); } + SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); } + SYS_MAC_SYSCALL = 394 // { int mac_syscall(const char *policy, int call, void *arg); } + SYS_GETFSSTAT = 395 // { int getfsstat(struct statfs *buf, long bufsize, int flags); } + SYS_STATFS = 396 // { int statfs(char *path, struct statfs *buf); } SYS_FSTATFS = 397 // { int fstatfs(int fd, struct statfs *buf); } - SYS_FHSTATFS = 398 // { int fhstatfs(const struct fhandle *u_fhp, \ + SYS_FHSTATFS = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); } SYS_KSEM_CLOSE = 400 // { int ksem_close(semid_t id); } SYS_KSEM_POST = 401 // { int ksem_post(semid_t id); } SYS_KSEM_WAIT = 402 // { int ksem_wait(semid_t id); } SYS_KSEM_TRYWAIT = 403 // { int ksem_trywait(semid_t id); } - SYS_KSEM_INIT = 404 // { int ksem_init(semid_t *idp, \ - SYS_KSEM_OPEN = 405 // { int ksem_open(semid_t *idp, \ + SYS_KSEM_INIT = 404 // { int ksem_init(semid_t *idp, unsigned int value); } + SYS_KSEM_OPEN = 405 // { int ksem_open(semid_t *idp, const char *name, int oflag, mode_t mode, unsigned int value); } SYS_KSEM_UNLINK = 406 // { int ksem_unlink(const char *name); } SYS_KSEM_GETVALUE = 407 // { int ksem_getvalue(semid_t id, int *val); } SYS_KSEM_DESTROY = 408 // { int ksem_destroy(semid_t id); } - SYS___MAC_GET_PID = 409 // { int __mac_get_pid(pid_t pid, \ - SYS___MAC_GET_LINK = 410 // { int __mac_get_link(const char *path_p, \ - SYS___MAC_SET_LINK = 411 // { int __mac_set_link(const char *path_p, \ - SYS_EXTATTR_SET_LINK = 412 // { ssize_t extattr_set_link( \ - SYS_EXTATTR_GET_LINK = 413 // { ssize_t extattr_get_link( \ - SYS_EXTATTR_DELETE_LINK = 414 // { int extattr_delete_link( \ - SYS___MAC_EXECVE = 415 // { int __mac_execve(char *fname, char **argv, \ - SYS_SIGACTION = 416 // { int sigaction(int sig, \ - SYS_SIGRETURN = 417 // { int sigreturn( \ + SYS___MAC_GET_PID = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); } + SYS___MAC_GET_LINK = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); } + SYS___MAC_SET_LINK = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); } + SYS_EXTATTR_SET_LINK = 412 // { ssize_t extattr_set_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_LINK = 413 // { ssize_t extattr_get_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_LINK = 414 // { int extattr_delete_link( const char *path, int attrnamespace, const char *attrname); } + SYS___MAC_EXECVE = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); } + SYS_SIGACTION = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); } + SYS_SIGRETURN = 417 // { int sigreturn( const struct __ucontext *sigcntxp); } SYS_GETCONTEXT = 421 // { int getcontext(struct __ucontext *ucp); } - SYS_SETCONTEXT = 422 // { int setcontext( \ - SYS_SWAPCONTEXT = 423 // { int swapcontext(struct __ucontext *oucp, \ + SYS_SETCONTEXT = 422 // { int setcontext( const struct __ucontext *ucp); } + SYS_SWAPCONTEXT = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); } SYS_SWAPOFF = 424 // { int swapoff(const char *name); } - SYS___ACL_GET_LINK = 425 // { int __acl_get_link(const char *path, \ - SYS___ACL_SET_LINK = 426 // { int __acl_set_link(const char *path, \ - SYS___ACL_DELETE_LINK = 427 // { int __acl_delete_link(const char *path, \ - SYS___ACL_ACLCHECK_LINK = 428 // { int __acl_aclcheck_link(const char *path, \ - SYS_SIGWAIT = 429 // { int sigwait(const sigset_t *set, \ - SYS_THR_CREATE = 430 // { int thr_create(ucontext_t *ctx, long *id, \ + SYS___ACL_GET_LINK = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_LINK = 426 // { int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_DELETE_LINK = 427 // { int __acl_delete_link(const char *path, acl_type_t type); } + SYS___ACL_ACLCHECK_LINK = 428 // { int __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS_SIGWAIT = 429 // { int sigwait(const sigset_t *set, int *sig); } + SYS_THR_CREATE = 430 // { int thr_create(ucontext_t *ctx, long *id, int flags); } SYS_THR_EXIT = 431 // { void thr_exit(long *state); } SYS_THR_SELF = 432 // { int thr_self(long *id); } SYS_THR_KILL = 433 // { int thr_kill(long id, int sig); } SYS__UMTX_LOCK = 434 // { int _umtx_lock(struct umtx *umtx); } SYS__UMTX_UNLOCK = 435 // { int _umtx_unlock(struct umtx *umtx); } SYS_JAIL_ATTACH = 436 // { int jail_attach(int jid); } - SYS_EXTATTR_LIST_FD = 437 // { ssize_t extattr_list_fd(int fd, \ - SYS_EXTATTR_LIST_FILE = 438 // { ssize_t extattr_list_file( \ - SYS_EXTATTR_LIST_LINK = 439 // { ssize_t extattr_list_link( \ - SYS_KSEM_TIMEDWAIT = 441 // { int ksem_timedwait(semid_t id, \ - SYS_THR_SUSPEND = 442 // { int thr_suspend( \ + SYS_EXTATTR_LIST_FD = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); } + SYS_EXTATTR_LIST_FILE = 438 // { ssize_t extattr_list_file( const char *path, int attrnamespace, void *data, size_t nbytes); } + SYS_EXTATTR_LIST_LINK = 439 // { ssize_t extattr_list_link( const char *path, int attrnamespace, void *data, size_t nbytes); } + SYS_KSEM_TIMEDWAIT = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); } + SYS_THR_SUSPEND = 442 // { int thr_suspend( const struct timespec *timeout); } SYS_THR_WAKE = 443 // { int thr_wake(long id); } SYS_KLDUNLOADF = 444 // { int kldunloadf(int fileid, int flags); } - SYS_AUDIT = 445 // { int audit(const void *record, \ - SYS_AUDITON = 446 // { int auditon(int cmd, void *data, \ + SYS_AUDIT = 445 // { int audit(const void *record, u_int length); } + SYS_AUDITON = 446 // { int auditon(int cmd, void *data, u_int length); } SYS_GETAUID = 447 // { int getauid(uid_t *auid); } SYS_SETAUID = 448 // { int setauid(uid_t *auid); } SYS_GETAUDIT = 449 // { int getaudit(struct auditinfo *auditinfo); } SYS_SETAUDIT = 450 // { int setaudit(struct auditinfo *auditinfo); } - SYS_GETAUDIT_ADDR = 451 // { int getaudit_addr( \ - SYS_SETAUDIT_ADDR = 452 // { int setaudit_addr( \ + SYS_GETAUDIT_ADDR = 451 // { int getaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); } + SYS_SETAUDIT_ADDR = 452 // { int setaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); } SYS_AUDITCTL = 453 // { int auditctl(char *path); } - SYS__UMTX_OP = 454 // { int _umtx_op(void *obj, int op, \ - SYS_THR_NEW = 455 // { int thr_new(struct thr_param *param, \ + SYS__UMTX_OP = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); } + SYS_THR_NEW = 455 // { int thr_new(struct thr_param *param, int param_size); } SYS_SIGQUEUE = 456 // { int sigqueue(pid_t pid, int signum, void *value); } - SYS_KMQ_OPEN = 457 // { int kmq_open(const char *path, int flags, \ - SYS_KMQ_SETATTR = 458 // { int kmq_setattr(int mqd, \ - SYS_KMQ_TIMEDRECEIVE = 459 // { int kmq_timedreceive(int mqd, \ - SYS_KMQ_TIMEDSEND = 460 // { int kmq_timedsend(int mqd, \ - SYS_KMQ_NOTIFY = 461 // { int kmq_notify(int mqd, \ + SYS_KMQ_OPEN = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); } + SYS_KMQ_SETATTR = 458 // { int kmq_setattr(int mqd, const struct mq_attr *attr, struct mq_attr *oattr); } + SYS_KMQ_TIMEDRECEIVE = 459 // { int kmq_timedreceive(int mqd, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); } + SYS_KMQ_TIMEDSEND = 460 // { int kmq_timedsend(int mqd, const char *msg_ptr, size_t msg_len,unsigned msg_prio, const struct timespec *abs_timeout);} + SYS_KMQ_NOTIFY = 461 // { int kmq_notify(int mqd, const struct sigevent *sigev); } SYS_KMQ_UNLINK = 462 // { int kmq_unlink(const char *path); } SYS_ABORT2 = 463 // { int abort2(const char *why, int nargs, void **args); } SYS_THR_SET_NAME = 464 // { int thr_set_name(long id, const char *name); } SYS_AIO_FSYNC = 465 // { int aio_fsync(int op, struct aiocb *aiocbp); } - SYS_RTPRIO_THREAD = 466 // { int rtprio_thread(int function, \ + SYS_RTPRIO_THREAD = 466 // { int rtprio_thread(int function, lwpid_t lwpid, struct rtprio *rtp); } SYS_SCTP_PEELOFF = 471 // { int sctp_peeloff(int sd, uint32_t name); } - SYS_SCTP_GENERIC_SENDMSG = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \ - SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \ - SYS_SCTP_GENERIC_RECVMSG = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \ - SYS_PREAD = 475 // { ssize_t pread(int fd, void *buf, \ - SYS_PWRITE = 476 // { ssize_t pwrite(int fd, const void *buf, \ - SYS_MMAP = 477 // { caddr_t mmap(caddr_t addr, size_t len, \ - SYS_LSEEK = 478 // { off_t lseek(int fd, off_t offset, \ + SYS_SCTP_GENERIC_SENDMSG = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); } + SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); } + SYS_SCTP_GENERIC_RECVMSG = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr * from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); } + SYS_PREAD = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); } + SYS_PWRITE = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); } + SYS_MMAP = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); } + SYS_LSEEK = 478 // { off_t lseek(int fd, off_t offset, int whence); } SYS_TRUNCATE = 479 // { int truncate(char *path, off_t length); } SYS_FTRUNCATE = 480 // { int ftruncate(int fd, off_t length); } SYS_THR_KILL2 = 481 // { int thr_kill2(pid_t pid, long id, int sig); } - SYS_SHM_OPEN = 482 // { int shm_open(const char *path, int flags, \ + SYS_SHM_OPEN = 482 // { int shm_open(const char *path, int flags, mode_t mode); } SYS_SHM_UNLINK = 483 // { int shm_unlink(const char *path); } SYS_CPUSET = 484 // { int cpuset(cpusetid_t *setid); } - SYS_CPUSET_SETID = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \ - SYS_CPUSET_GETID = 486 // { int cpuset_getid(cpulevel_t level, \ - SYS_CPUSET_GETAFFINITY = 487 // { int cpuset_getaffinity(cpulevel_t level, \ - SYS_CPUSET_SETAFFINITY = 488 // { int cpuset_setaffinity(cpulevel_t level, \ - SYS_FACCESSAT = 489 // { int faccessat(int fd, char *path, int amode, \ - SYS_FCHMODAT = 490 // { int fchmodat(int fd, char *path, mode_t mode, \ - SYS_FCHOWNAT = 491 // { int fchownat(int fd, char *path, uid_t uid, \ - SYS_FEXECVE = 492 // { int fexecve(int fd, char **argv, \ - SYS_FSTATAT = 493 // { int fstatat(int fd, char *path, \ - SYS_FUTIMESAT = 494 // { int futimesat(int fd, char *path, \ - SYS_LINKAT = 495 // { int linkat(int fd1, char *path1, int fd2, \ + SYS_CPUSET_SETID = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, cpusetid_t setid); } + SYS_CPUSET_GETID = 486 // { int cpuset_getid(cpulevel_t level, cpuwhich_t which, id_t id, cpusetid_t *setid); } + SYS_CPUSET_GETAFFINITY = 487 // { int cpuset_getaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, cpuset_t *mask); } + SYS_CPUSET_SETAFFINITY = 488 // { int cpuset_setaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, const cpuset_t *mask); } + SYS_FACCESSAT = 489 // { int faccessat(int fd, char *path, int amode, int flag); } + SYS_FCHMODAT = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); } + SYS_FEXECVE = 492 // { int fexecve(int fd, char **argv, char **envv); } + SYS_FSTATAT = 493 // { int fstatat(int fd, char *path, struct stat *buf, int flag); } + SYS_FUTIMESAT = 494 // { int futimesat(int fd, char *path, struct timeval *times); } + SYS_LINKAT = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); } SYS_MKDIRAT = 496 // { int mkdirat(int fd, char *path, mode_t mode); } SYS_MKFIFOAT = 497 // { int mkfifoat(int fd, char *path, mode_t mode); } - SYS_MKNODAT = 498 // { int mknodat(int fd, char *path, mode_t mode, \ - SYS_OPENAT = 499 // { int openat(int fd, char *path, int flag, \ - SYS_READLINKAT = 500 // { int readlinkat(int fd, char *path, char *buf, \ - SYS_RENAMEAT = 501 // { int renameat(int oldfd, char *old, int newfd, \ - SYS_SYMLINKAT = 502 // { int symlinkat(char *path1, int fd, \ + SYS_MKNODAT = 498 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 499 // { int openat(int fd, char *path, int flag, mode_t mode); } + SYS_READLINKAT = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); } + SYS_RENAMEAT = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); } + SYS_SYMLINKAT = 502 // { int symlinkat(char *path1, int fd, char *path2); } SYS_UNLINKAT = 503 // { int unlinkat(int fd, char *path, int flag); } SYS_POSIX_OPENPT = 504 // { int posix_openpt(int flags); } SYS_GSSD_SYSCALL = 505 // { int gssd_syscall(char *path); } - SYS_JAIL_GET = 506 // { int jail_get(struct iovec *iovp, \ - SYS_JAIL_SET = 507 // { int jail_set(struct iovec *iovp, \ + SYS_JAIL_GET = 506 // { int jail_get(struct iovec *iovp, unsigned int iovcnt, int flags); } + SYS_JAIL_SET = 507 // { int jail_set(struct iovec *iovp, unsigned int iovcnt, int flags); } SYS_JAIL_REMOVE = 508 // { int jail_remove(int jid); } SYS_CLOSEFROM = 509 // { int closefrom(int lowfd); } - SYS___SEMCTL = 510 // { int __semctl(int semid, int semnum, \ - SYS_MSGCTL = 511 // { int msgctl(int msqid, int cmd, \ - SYS_SHMCTL = 512 // { int shmctl(int shmid, int cmd, \ + SYS___SEMCTL = 510 // { int __semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_MSGCTL = 511 // { int msgctl(int msqid, int cmd, struct msqid_ds *buf); } + SYS_SHMCTL = 512 // { int shmctl(int shmid, int cmd, struct shmid_ds *buf); } SYS_LPATHCONF = 513 // { int lpathconf(char *path, int name); } - SYS___CAP_RIGHTS_GET = 515 // { int __cap_rights_get(int version, \ + SYS___CAP_RIGHTS_GET = 515 // { int __cap_rights_get(int version, int fd, cap_rights_t *rightsp); } SYS_CAP_ENTER = 516 // { int cap_enter(void); } SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); } SYS_PDFORK = 518 // { int pdfork(int *fdp, int flags); } SYS_PDKILL = 519 // { int pdkill(int fd, int signum); } SYS_PDGETPID = 520 // { int pdgetpid(int fd, pid_t *pidp); } - SYS_PSELECT = 522 // { int pselect(int nd, fd_set *in, \ - SYS_GETLOGINCLASS = 523 // { int getloginclass(char *namebuf, \ + SYS_PSELECT = 522 // { int pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *sm); } + SYS_GETLOGINCLASS = 523 // { int getloginclass(char *namebuf, size_t namelen); } SYS_SETLOGINCLASS = 524 // { int setloginclass(const char *namebuf); } - SYS_RCTL_GET_RACCT = 525 // { int rctl_get_racct(const void *inbufp, \ - SYS_RCTL_GET_RULES = 526 // { int rctl_get_rules(const void *inbufp, \ - SYS_RCTL_GET_LIMITS = 527 // { int rctl_get_limits(const void *inbufp, \ - SYS_RCTL_ADD_RULE = 528 // { int rctl_add_rule(const void *inbufp, \ - SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, \ - SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, \ - SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, \ - SYS_WAIT6 = 532 // { int wait6(idtype_t idtype, id_t id, \ - SYS_CAP_RIGHTS_LIMIT = 533 // { int cap_rights_limit(int fd, \ - SYS_CAP_IOCTLS_LIMIT = 534 // { int cap_ioctls_limit(int fd, \ - SYS_CAP_IOCTLS_GET = 535 // { ssize_t cap_ioctls_get(int fd, \ - SYS_CAP_FCNTLS_LIMIT = 536 // { int cap_fcntls_limit(int fd, \ - SYS_CAP_FCNTLS_GET = 537 // { int cap_fcntls_get(int fd, \ - SYS_BINDAT = 538 // { int bindat(int fd, int s, caddr_t name, \ - SYS_CONNECTAT = 539 // { int connectat(int fd, int s, caddr_t name, \ - SYS_CHFLAGSAT = 540 // { int chflagsat(int fd, const char *path, \ - SYS_ACCEPT4 = 541 // { int accept4(int s, \ + SYS_RCTL_GET_RACCT = 525 // { int rctl_get_racct(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_GET_RULES = 526 // { int rctl_get_rules(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_GET_LIMITS = 527 // { int rctl_get_limits(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_ADD_RULE = 528 // { int rctl_add_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, off_t offset, off_t len); } + SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, off_t len, int advice); } + SYS_WAIT6 = 532 // { int wait6(idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *info); } + SYS_CAP_RIGHTS_LIMIT = 533 // { int cap_rights_limit(int fd, cap_rights_t *rightsp); } + SYS_CAP_IOCTLS_LIMIT = 534 // { int cap_ioctls_limit(int fd, const u_long *cmds, size_t ncmds); } + SYS_CAP_IOCTLS_GET = 535 // { ssize_t cap_ioctls_get(int fd, u_long *cmds, size_t maxcmds); } + SYS_CAP_FCNTLS_LIMIT = 536 // { int cap_fcntls_limit(int fd, uint32_t fcntlrights); } + SYS_CAP_FCNTLS_GET = 537 // { int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); } + SYS_BINDAT = 538 // { int bindat(int fd, int s, caddr_t name, int namelen); } + SYS_CONNECTAT = 539 // { int connectat(int fd, int s, caddr_t name, int namelen); } + SYS_CHFLAGSAT = 540 // { int chflagsat(int fd, const char *path, u_long flags, int atflag); } + SYS_ACCEPT4 = 541 // { int accept4(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen, int flags); } SYS_PIPE2 = 542 // { int pipe2(int *fildes, int flags); } SYS_AIO_MLOCK = 543 // { int aio_mlock(struct aiocb *aiocbp); } - SYS_PROCCTL = 544 // { int procctl(idtype_t idtype, id_t id, \ - SYS_PPOLL = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \ - SYS_FUTIMENS = 546 // { int futimens(int fd, \ - SYS_UTIMENSAT = 547 // { int utimensat(int fd, \ + SYS_PROCCTL = 544 // { int procctl(idtype_t idtype, id_t id, int com, void *data); } + SYS_PPOLL = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); } + SYS_FUTIMENS = 546 // { int futimens(int fd, struct timespec *times); } + SYS_UTIMENSAT = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); } ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go index d61941ba7e00..44ffd4ce5e98 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go @@ -1,4 +1,4 @@ -// mksysnum_freebsd.pl +// go run mksysnum.go https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master // Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,freebsd @@ -7,13 +7,13 @@ package unix const ( // SYS_NOSYS = 0; // { int nosys(void); } syscall nosys_args int - SYS_EXIT = 1 // { void sys_exit(int rval); } exit \ + SYS_EXIT = 1 // { void sys_exit(int rval); } exit sys_exit_args void SYS_FORK = 2 // { int fork(void); } - SYS_READ = 3 // { ssize_t read(int fd, void *buf, \ - SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, \ + SYS_READ = 3 // { ssize_t read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, size_t nbyte); } SYS_OPEN = 5 // { int open(char *path, int flags, int mode); } SYS_CLOSE = 6 // { int close(int fd); } - SYS_WAIT4 = 7 // { int wait4(int pid, int *status, \ + SYS_WAIT4 = 7 // { int wait4(int pid, int *status, int options, struct rusage *rusage); } SYS_LINK = 9 // { int link(char *path, char *link); } SYS_UNLINK = 10 // { int unlink(char *path); } SYS_CHDIR = 12 // { int chdir(char *path); } @@ -21,20 +21,20 @@ const ( SYS_MKNOD = 14 // { int mknod(char *path, int mode, int dev); } SYS_CHMOD = 15 // { int chmod(char *path, int mode); } SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); } - SYS_OBREAK = 17 // { int obreak(char *nsize); } break \ + SYS_OBREAK = 17 // { int obreak(char *nsize); } break obreak_args int SYS_GETPID = 20 // { pid_t getpid(void); } - SYS_MOUNT = 21 // { int mount(char *type, char *path, \ + SYS_MOUNT = 21 // { int mount(char *type, char *path, int flags, caddr_t data); } SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); } SYS_SETUID = 23 // { int setuid(uid_t uid); } SYS_GETUID = 24 // { uid_t getuid(void); } SYS_GETEUID = 25 // { uid_t geteuid(void); } - SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, \ - SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, \ - SYS_SENDMSG = 28 // { int sendmsg(int s, struct msghdr *msg, \ - SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, \ - SYS_ACCEPT = 30 // { int accept(int s, \ - SYS_GETPEERNAME = 31 // { int getpeername(int fdes, \ - SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, \ + SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { int sendmsg(int s, struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, size_t len, int flags, struct sockaddr * __restrict from, __socklen_t * __restrict fromlenaddr); } + SYS_ACCEPT = 30 // { int accept(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen); } + SYS_GETPEERNAME = 31 // { int getpeername(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); } + SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); } SYS_ACCESS = 33 // { int access(char *path, int amode); } SYS_CHFLAGS = 34 // { int chflags(const char *path, u_long flags); } SYS_FCHFLAGS = 35 // { int fchflags(int fd, u_long flags); } @@ -44,55 +44,55 @@ const ( SYS_DUP = 41 // { int dup(u_int fd); } SYS_PIPE = 42 // { int pipe(void); } SYS_GETEGID = 43 // { gid_t getegid(void); } - SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, \ - SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, \ + SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); } + SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, int facs, int pid); } SYS_GETGID = 47 // { gid_t getgid(void); } - SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int \ + SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int namelen); } SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); } SYS_ACCT = 51 // { int acct(char *path); } - SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, \ - SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, \ + SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, stack_t *oss); } + SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, caddr_t data); } SYS_REBOOT = 55 // { int reboot(int opt); } SYS_REVOKE = 56 // { int revoke(char *path); } SYS_SYMLINK = 57 // { int symlink(char *path, char *link); } - SYS_READLINK = 58 // { ssize_t readlink(char *path, char *buf, \ - SYS_EXECVE = 59 // { int execve(char *fname, char **argv, \ - SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args \ + SYS_READLINK = 58 // { ssize_t readlink(char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int execve(char *fname, char **argv, char **envv); } + SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args int SYS_CHROOT = 61 // { int chroot(char *path); } - SYS_MSYNC = 65 // { int msync(void *addr, size_t len, \ + SYS_MSYNC = 65 // { int msync(void *addr, size_t len, int flags); } SYS_VFORK = 66 // { int vfork(void); } SYS_SBRK = 69 // { int sbrk(int incr); } SYS_SSTK = 70 // { int sstk(int incr); } - SYS_OVADVISE = 72 // { int ovadvise(int anom); } vadvise \ + SYS_OVADVISE = 72 // { int ovadvise(int anom); } vadvise ovadvise_args int SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); } - SYS_MPROTECT = 74 // { int mprotect(const void *addr, size_t len, \ - SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, \ - SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, \ - SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, \ - SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, \ + SYS_MPROTECT = 74 // { int mprotect(const void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, int behav); } + SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, char *vec); } + SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, gid_t *gidset); } SYS_GETPGRP = 81 // { int getpgrp(void); } SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); } - SYS_SETITIMER = 83 // { int setitimer(u_int which, struct \ + SYS_SETITIMER = 83 // { int setitimer(u_int which, struct itimerval *itv, struct itimerval *oitv); } SYS_SWAPON = 85 // { int swapon(char *name); } - SYS_GETITIMER = 86 // { int getitimer(u_int which, \ + SYS_GETITIMER = 86 // { int getitimer(u_int which, struct itimerval *itv); } SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); } SYS_DUP2 = 90 // { int dup2(u_int from, u_int to); } SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); } - SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, \ + SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } SYS_FSYNC = 95 // { int fsync(int fd); } - SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, \ - SYS_SOCKET = 97 // { int socket(int domain, int type, \ - SYS_CONNECT = 98 // { int connect(int s, caddr_t name, \ + SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, int prio); } + SYS_SOCKET = 97 // { int socket(int domain, int type, int protocol); } + SYS_CONNECT = 98 // { int connect(int s, caddr_t name, int namelen); } SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); } - SYS_BIND = 104 // { int bind(int s, caddr_t name, \ - SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, \ + SYS_BIND = 104 // { int bind(int s, caddr_t name, int namelen); } + SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, caddr_t val, int valsize); } SYS_LISTEN = 106 // { int listen(int s, int backlog); } - SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, \ - SYS_GETRUSAGE = 117 // { int getrusage(int who, \ - SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, \ - SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, \ - SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, \ - SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, \ + SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_GETRUSAGE = 117 // { int getrusage(int who, struct rusage *rusage); } + SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, caddr_t val, int *avalsize); } + SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, u_int iovcnt); } + SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, struct timezone *tzp); } SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); } SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); } SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); } @@ -100,26 +100,26 @@ const ( SYS_RENAME = 128 // { int rename(char *from, char *to); } SYS_FLOCK = 131 // { int flock(int fd, int how); } SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); } - SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, \ + SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen); } SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); } - SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, \ + SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, int protocol, int *rsv); } SYS_MKDIR = 136 // { int mkdir(char *path, int mode); } SYS_RMDIR = 137 // { int rmdir(char *path); } - SYS_UTIMES = 138 // { int utimes(char *path, \ - SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, \ + SYS_UTIMES = 138 // { int utimes(char *path, struct timeval *tptr); } + SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, struct timeval *olddelta); } SYS_SETSID = 147 // { int setsid(void); } - SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, \ + SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, caddr_t arg); } SYS_NLM_SYSCALL = 154 // { int nlm_syscall(int debug_level, int grace_period, int addr_count, char **addrs); } SYS_NFSSVC = 155 // { int nfssvc(int flag, caddr_t argp); } - SYS_LGETFH = 160 // { int lgetfh(char *fname, \ - SYS_GETFH = 161 // { int getfh(char *fname, \ + SYS_LGETFH = 160 // { int lgetfh(char *fname, struct fhandle *fhp); } + SYS_GETFH = 161 // { int getfh(char *fname, struct fhandle *fhp); } SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); } - SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, \ - SYS_SEMSYS = 169 // { int semsys(int which, int a2, int a3, \ - SYS_MSGSYS = 170 // { int msgsys(int which, int a2, int a3, \ - SYS_SHMSYS = 171 // { int shmsys(int which, int a2, int a3, \ - SYS_FREEBSD6_PREAD = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \ - SYS_FREEBSD6_PWRITE = 174 // { ssize_t freebsd6_pwrite(int fd, \ + SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, struct rtprio *rtp); } + SYS_SEMSYS = 169 // { int semsys(int which, int a2, int a3, int a4, int a5); } + SYS_MSGSYS = 170 // { int msgsys(int which, int a2, int a3, int a4, int a5, int a6); } + SYS_SHMSYS = 171 // { int shmsys(int which, int a2, int a3, int a4); } + SYS_FREEBSD6_PREAD = 173 // { ssize_t freebsd6_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_FREEBSD6_PWRITE = 174 // { ssize_t freebsd6_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } SYS_SETFIB = 175 // { int setfib(int fibnum); } SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); } SYS_SETGID = 181 // { int setgid(gid_t gid); } @@ -130,274 +130,274 @@ const ( SYS_LSTAT = 190 // { int lstat(char *path, struct stat *ub); } SYS_PATHCONF = 191 // { int pathconf(char *path, int name); } SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); } - SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, \ - SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, \ - SYS_GETDIRENTRIES = 196 // { int getdirentries(int fd, char *buf, \ - SYS_FREEBSD6_MMAP = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \ - SYS_FREEBSD6_LSEEK = 199 // { off_t freebsd6_lseek(int fd, int pad, \ - SYS_FREEBSD6_TRUNCATE = 200 // { int freebsd6_truncate(char *path, int pad, \ - SYS_FREEBSD6_FTRUNCATE = 201 // { int freebsd6_ftruncate(int fd, int pad, \ - SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, \ + SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int + SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int + SYS_GETDIRENTRIES = 196 // { int getdirentries(int fd, char *buf, u_int count, long *basep); } + SYS_FREEBSD6_MMAP = 197 // { caddr_t freebsd6_mmap(caddr_t addr, size_t len, int prot, int flags, int fd, int pad, off_t pos); } + SYS_FREEBSD6_LSEEK = 199 // { off_t freebsd6_lseek(int fd, int pad, off_t offset, int whence); } + SYS_FREEBSD6_TRUNCATE = 200 // { int freebsd6_truncate(char *path, int pad, off_t length); } + SYS_FREEBSD6_FTRUNCATE = 201 // { int freebsd6_ftruncate(int fd, int pad, off_t length); } + SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int SYS_MLOCK = 203 // { int mlock(const void *addr, size_t len); } SYS_MUNLOCK = 204 // { int munlock(const void *addr, size_t len); } SYS_UNDELETE = 205 // { int undelete(char *path); } SYS_FUTIMES = 206 // { int futimes(int fd, struct timeval *tptr); } SYS_GETPGID = 207 // { int getpgid(pid_t pid); } - SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, \ - SYS_SEMGET = 221 // { int semget(key_t key, int nsems, \ - SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, \ + SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS_SEMGET = 221 // { int semget(key_t key, int nsems, int semflg); } + SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); } SYS_MSGGET = 225 // { int msgget(key_t key, int msgflg); } - SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, \ - SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, \ - SYS_SHMAT = 228 // { int shmat(int shmid, const void *shmaddr, \ + SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); } SYS_SHMDT = 230 // { int shmdt(const void *shmaddr); } - SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, \ - SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, \ - SYS_CLOCK_SETTIME = 233 // { int clock_settime( \ - SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, \ - SYS_KTIMER_CREATE = 235 // { int ktimer_create(clockid_t clock_id, \ + SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, int shmflg); } + SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 233 // { int clock_settime( clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_KTIMER_CREATE = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); } SYS_KTIMER_DELETE = 236 // { int ktimer_delete(int timerid); } - SYS_KTIMER_SETTIME = 237 // { int ktimer_settime(int timerid, int flags, \ - SYS_KTIMER_GETTIME = 238 // { int ktimer_gettime(int timerid, struct \ + SYS_KTIMER_SETTIME = 237 // { int ktimer_settime(int timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue); } + SYS_KTIMER_GETTIME = 238 // { int ktimer_gettime(int timerid, struct itimerspec *value); } SYS_KTIMER_GETOVERRUN = 239 // { int ktimer_getoverrun(int timerid); } - SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, \ + SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } SYS_FFCLOCK_GETCOUNTER = 241 // { int ffclock_getcounter(ffcounter *ffcount); } - SYS_FFCLOCK_SETESTIMATE = 242 // { int ffclock_setestimate( \ - SYS_FFCLOCK_GETESTIMATE = 243 // { int ffclock_getestimate( \ - SYS_CLOCK_GETCPUCLOCKID2 = 247 // { int clock_getcpuclockid2(id_t id,\ + SYS_FFCLOCK_SETESTIMATE = 242 // { int ffclock_setestimate( struct ffclock_estimate *cest); } + SYS_FFCLOCK_GETESTIMATE = 243 // { int ffclock_getestimate( struct ffclock_estimate *cest); } + SYS_CLOCK_GETCPUCLOCKID2 = 247 // { int clock_getcpuclockid2(id_t id,int which, clockid_t *clock_id); } SYS_NTP_GETTIME = 248 // { int ntp_gettime(struct ntptimeval *ntvp); } - SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, \ + SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, int inherit); } SYS_RFORK = 251 // { int rfork(int flags); } - SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, \ + SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); } SYS_ISSETUGID = 253 // { int issetugid(void); } SYS_LCHOWN = 254 // { int lchown(char *path, int uid, int gid); } SYS_AIO_READ = 255 // { int aio_read(struct aiocb *aiocbp); } SYS_AIO_WRITE = 256 // { int aio_write(struct aiocb *aiocbp); } - SYS_LIO_LISTIO = 257 // { int lio_listio(int mode, \ - SYS_GETDENTS = 272 // { int getdents(int fd, char *buf, \ + SYS_LIO_LISTIO = 257 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); } + SYS_GETDENTS = 272 // { int getdents(int fd, char *buf, size_t count); } SYS_LCHMOD = 274 // { int lchmod(char *path, mode_t mode); } - SYS_LUTIMES = 276 // { int lutimes(char *path, \ + SYS_LUTIMES = 276 // { int lutimes(char *path, struct timeval *tptr); } SYS_NSTAT = 278 // { int nstat(char *path, struct nstat *ub); } SYS_NFSTAT = 279 // { int nfstat(int fd, struct nstat *sb); } SYS_NLSTAT = 280 // { int nlstat(char *path, struct nstat *ub); } - SYS_PREADV = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \ - SYS_PWRITEV = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \ - SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, \ - SYS_FHSTAT = 299 // { int fhstat(const struct fhandle *u_fhp, \ + SYS_PREADV = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); } + SYS_PWRITEV = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); } + SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); } + SYS_FHSTAT = 299 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); } SYS_MODNEXT = 300 // { int modnext(int modid); } - SYS_MODSTAT = 301 // { int modstat(int modid, \ + SYS_MODSTAT = 301 // { int modstat(int modid, struct module_stat *stat); } SYS_MODFNEXT = 302 // { int modfnext(int modid); } SYS_MODFIND = 303 // { int modfind(const char *name); } SYS_KLDLOAD = 304 // { int kldload(const char *file); } SYS_KLDUNLOAD = 305 // { int kldunload(int fileid); } SYS_KLDFIND = 306 // { int kldfind(const char *file); } SYS_KLDNEXT = 307 // { int kldnext(int fileid); } - SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct \ + SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); } SYS_KLDFIRSTMOD = 309 // { int kldfirstmod(int fileid); } SYS_GETSID = 310 // { int getsid(pid_t pid); } - SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, \ - SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, \ + SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); } SYS_AIO_RETURN = 314 // { int aio_return(struct aiocb *aiocbp); } - SYS_AIO_SUSPEND = 315 // { int aio_suspend( \ - SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, \ + SYS_AIO_SUSPEND = 315 // { int aio_suspend( struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); } + SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); } SYS_AIO_ERROR = 317 // { int aio_error(struct aiocb *aiocbp); } SYS_OAIO_READ = 318 // { int oaio_read(struct oaiocb *aiocbp); } SYS_OAIO_WRITE = 319 // { int oaio_write(struct oaiocb *aiocbp); } - SYS_OLIO_LISTIO = 320 // { int olio_listio(int mode, \ + SYS_OLIO_LISTIO = 320 // { int olio_listio(int mode, struct oaiocb * const *acb_list, int nent, struct osigevent *sig); } SYS_YIELD = 321 // { int yield(void); } SYS_MLOCKALL = 324 // { int mlockall(int how); } SYS_MUNLOCKALL = 325 // { int munlockall(void); } SYS___GETCWD = 326 // { int __getcwd(char *buf, u_int buflen); } - SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, \ - SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct \ - SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int \ + SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); } + SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); } + SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); } SYS_SCHED_GETSCHEDULER = 330 // { int sched_getscheduler (pid_t pid); } SYS_SCHED_YIELD = 331 // { int sched_yield (void); } SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); } SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); } - SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, \ + SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, struct timespec *interval); } SYS_UTRACE = 335 // { int utrace(const void *addr, size_t len); } - SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, \ + SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, void *data); } SYS_JAIL = 338 // { int jail(struct jail *jail); } - SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, \ + SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, const sigset_t *set, sigset_t *oset); } SYS_SIGSUSPEND = 341 // { int sigsuspend(const sigset_t *sigmask); } SYS_SIGPENDING = 343 // { int sigpending(sigset_t *set); } - SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set, \ - SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set, \ - SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, \ - SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, \ - SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, \ - SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, \ - SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, \ - SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, \ - SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, \ - SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, \ - SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, \ - SYS_EXTATTR_SET_FILE = 356 // { ssize_t extattr_set_file( \ - SYS_EXTATTR_GET_FILE = 357 // { ssize_t extattr_get_file( \ - SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, \ - SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete( \ - SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \ - SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \ + SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout); } + SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set, siginfo_t *info); } + SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, acl_type_t type); } + SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, acl_type_t type); } + SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); } + SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); } + SYS_EXTATTR_SET_FILE = 356 // { ssize_t extattr_set_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_FILE = 357 // { ssize_t extattr_get_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); } + SYS_AIO_WAITCOMPLETE = 359 // { int aio_waitcomplete( struct aiocb **aiocbp, struct timespec *timeout); } + SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } SYS_KQUEUE = 362 // { int kqueue(void); } - SYS_KEVENT = 363 // { int kevent(int fd, \ - SYS_EXTATTR_SET_FD = 371 // { ssize_t extattr_set_fd(int fd, \ - SYS_EXTATTR_GET_FD = 372 // { ssize_t extattr_get_fd(int fd, \ - SYS_EXTATTR_DELETE_FD = 373 // { int extattr_delete_fd(int fd, \ + SYS_KEVENT = 363 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } + SYS_EXTATTR_SET_FD = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_FD = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FD = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); } SYS___SETUGID = 374 // { int __setugid(int flag); } SYS_EACCESS = 376 // { int eaccess(char *path, int amode); } - SYS_NMOUNT = 378 // { int nmount(struct iovec *iovp, \ + SYS_NMOUNT = 378 // { int nmount(struct iovec *iovp, unsigned int iovcnt, int flags); } SYS___MAC_GET_PROC = 384 // { int __mac_get_proc(struct mac *mac_p); } SYS___MAC_SET_PROC = 385 // { int __mac_set_proc(struct mac *mac_p); } - SYS___MAC_GET_FD = 386 // { int __mac_get_fd(int fd, \ - SYS___MAC_GET_FILE = 387 // { int __mac_get_file(const char *path_p, \ - SYS___MAC_SET_FD = 388 // { int __mac_set_fd(int fd, \ - SYS___MAC_SET_FILE = 389 // { int __mac_set_file(const char *path_p, \ - SYS_KENV = 390 // { int kenv(int what, const char *name, \ - SYS_LCHFLAGS = 391 // { int lchflags(const char *path, \ - SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, \ - SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, \ - SYS_MAC_SYSCALL = 394 // { int mac_syscall(const char *policy, \ - SYS_GETFSSTAT = 395 // { int getfsstat(struct statfs *buf, \ - SYS_STATFS = 396 // { int statfs(char *path, \ + SYS___MAC_GET_FD = 386 // { int __mac_get_fd(int fd, struct mac *mac_p); } + SYS___MAC_GET_FILE = 387 // { int __mac_get_file(const char *path_p, struct mac *mac_p); } + SYS___MAC_SET_FD = 388 // { int __mac_set_fd(int fd, struct mac *mac_p); } + SYS___MAC_SET_FILE = 389 // { int __mac_set_file(const char *path_p, struct mac *mac_p); } + SYS_KENV = 390 // { int kenv(int what, const char *name, char *value, int len); } + SYS_LCHFLAGS = 391 // { int lchflags(const char *path, u_long flags); } + SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, int count); } + SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); } + SYS_MAC_SYSCALL = 394 // { int mac_syscall(const char *policy, int call, void *arg); } + SYS_GETFSSTAT = 395 // { int getfsstat(struct statfs *buf, long bufsize, int flags); } + SYS_STATFS = 396 // { int statfs(char *path, struct statfs *buf); } SYS_FSTATFS = 397 // { int fstatfs(int fd, struct statfs *buf); } - SYS_FHSTATFS = 398 // { int fhstatfs(const struct fhandle *u_fhp, \ + SYS_FHSTATFS = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); } SYS_KSEM_CLOSE = 400 // { int ksem_close(semid_t id); } SYS_KSEM_POST = 401 // { int ksem_post(semid_t id); } SYS_KSEM_WAIT = 402 // { int ksem_wait(semid_t id); } SYS_KSEM_TRYWAIT = 403 // { int ksem_trywait(semid_t id); } - SYS_KSEM_INIT = 404 // { int ksem_init(semid_t *idp, \ - SYS_KSEM_OPEN = 405 // { int ksem_open(semid_t *idp, \ + SYS_KSEM_INIT = 404 // { int ksem_init(semid_t *idp, unsigned int value); } + SYS_KSEM_OPEN = 405 // { int ksem_open(semid_t *idp, const char *name, int oflag, mode_t mode, unsigned int value); } SYS_KSEM_UNLINK = 406 // { int ksem_unlink(const char *name); } SYS_KSEM_GETVALUE = 407 // { int ksem_getvalue(semid_t id, int *val); } SYS_KSEM_DESTROY = 408 // { int ksem_destroy(semid_t id); } - SYS___MAC_GET_PID = 409 // { int __mac_get_pid(pid_t pid, \ - SYS___MAC_GET_LINK = 410 // { int __mac_get_link(const char *path_p, \ - SYS___MAC_SET_LINK = 411 // { int __mac_set_link(const char *path_p, \ - SYS_EXTATTR_SET_LINK = 412 // { ssize_t extattr_set_link( \ - SYS_EXTATTR_GET_LINK = 413 // { ssize_t extattr_get_link( \ - SYS_EXTATTR_DELETE_LINK = 414 // { int extattr_delete_link( \ - SYS___MAC_EXECVE = 415 // { int __mac_execve(char *fname, char **argv, \ - SYS_SIGACTION = 416 // { int sigaction(int sig, \ - SYS_SIGRETURN = 417 // { int sigreturn( \ + SYS___MAC_GET_PID = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); } + SYS___MAC_GET_LINK = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); } + SYS___MAC_SET_LINK = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); } + SYS_EXTATTR_SET_LINK = 412 // { ssize_t extattr_set_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_GET_LINK = 413 // { ssize_t extattr_get_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_LINK = 414 // { int extattr_delete_link( const char *path, int attrnamespace, const char *attrname); } + SYS___MAC_EXECVE = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); } + SYS_SIGACTION = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); } + SYS_SIGRETURN = 417 // { int sigreturn( const struct __ucontext *sigcntxp); } SYS_GETCONTEXT = 421 // { int getcontext(struct __ucontext *ucp); } - SYS_SETCONTEXT = 422 // { int setcontext( \ - SYS_SWAPCONTEXT = 423 // { int swapcontext(struct __ucontext *oucp, \ + SYS_SETCONTEXT = 422 // { int setcontext( const struct __ucontext *ucp); } + SYS_SWAPCONTEXT = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); } SYS_SWAPOFF = 424 // { int swapoff(const char *name); } - SYS___ACL_GET_LINK = 425 // { int __acl_get_link(const char *path, \ - SYS___ACL_SET_LINK = 426 // { int __acl_set_link(const char *path, \ - SYS___ACL_DELETE_LINK = 427 // { int __acl_delete_link(const char *path, \ - SYS___ACL_ACLCHECK_LINK = 428 // { int __acl_aclcheck_link(const char *path, \ - SYS_SIGWAIT = 429 // { int sigwait(const sigset_t *set, \ - SYS_THR_CREATE = 430 // { int thr_create(ucontext_t *ctx, long *id, \ + SYS___ACL_GET_LINK = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_SET_LINK = 426 // { int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS___ACL_DELETE_LINK = 427 // { int __acl_delete_link(const char *path, acl_type_t type); } + SYS___ACL_ACLCHECK_LINK = 428 // { int __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); } + SYS_SIGWAIT = 429 // { int sigwait(const sigset_t *set, int *sig); } + SYS_THR_CREATE = 430 // { int thr_create(ucontext_t *ctx, long *id, int flags); } SYS_THR_EXIT = 431 // { void thr_exit(long *state); } SYS_THR_SELF = 432 // { int thr_self(long *id); } SYS_THR_KILL = 433 // { int thr_kill(long id, int sig); } SYS__UMTX_LOCK = 434 // { int _umtx_lock(struct umtx *umtx); } SYS__UMTX_UNLOCK = 435 // { int _umtx_unlock(struct umtx *umtx); } SYS_JAIL_ATTACH = 436 // { int jail_attach(int jid); } - SYS_EXTATTR_LIST_FD = 437 // { ssize_t extattr_list_fd(int fd, \ - SYS_EXTATTR_LIST_FILE = 438 // { ssize_t extattr_list_file( \ - SYS_EXTATTR_LIST_LINK = 439 // { ssize_t extattr_list_link( \ - SYS_KSEM_TIMEDWAIT = 441 // { int ksem_timedwait(semid_t id, \ - SYS_THR_SUSPEND = 442 // { int thr_suspend( \ + SYS_EXTATTR_LIST_FD = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); } + SYS_EXTATTR_LIST_FILE = 438 // { ssize_t extattr_list_file( const char *path, int attrnamespace, void *data, size_t nbytes); } + SYS_EXTATTR_LIST_LINK = 439 // { ssize_t extattr_list_link( const char *path, int attrnamespace, void *data, size_t nbytes); } + SYS_KSEM_TIMEDWAIT = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); } + SYS_THR_SUSPEND = 442 // { int thr_suspend( const struct timespec *timeout); } SYS_THR_WAKE = 443 // { int thr_wake(long id); } SYS_KLDUNLOADF = 444 // { int kldunloadf(int fileid, int flags); } - SYS_AUDIT = 445 // { int audit(const void *record, \ - SYS_AUDITON = 446 // { int auditon(int cmd, void *data, \ + SYS_AUDIT = 445 // { int audit(const void *record, u_int length); } + SYS_AUDITON = 446 // { int auditon(int cmd, void *data, u_int length); } SYS_GETAUID = 447 // { int getauid(uid_t *auid); } SYS_SETAUID = 448 // { int setauid(uid_t *auid); } SYS_GETAUDIT = 449 // { int getaudit(struct auditinfo *auditinfo); } SYS_SETAUDIT = 450 // { int setaudit(struct auditinfo *auditinfo); } - SYS_GETAUDIT_ADDR = 451 // { int getaudit_addr( \ - SYS_SETAUDIT_ADDR = 452 // { int setaudit_addr( \ + SYS_GETAUDIT_ADDR = 451 // { int getaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); } + SYS_SETAUDIT_ADDR = 452 // { int setaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); } SYS_AUDITCTL = 453 // { int auditctl(char *path); } - SYS__UMTX_OP = 454 // { int _umtx_op(void *obj, int op, \ - SYS_THR_NEW = 455 // { int thr_new(struct thr_param *param, \ + SYS__UMTX_OP = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); } + SYS_THR_NEW = 455 // { int thr_new(struct thr_param *param, int param_size); } SYS_SIGQUEUE = 456 // { int sigqueue(pid_t pid, int signum, void *value); } - SYS_KMQ_OPEN = 457 // { int kmq_open(const char *path, int flags, \ - SYS_KMQ_SETATTR = 458 // { int kmq_setattr(int mqd, \ - SYS_KMQ_TIMEDRECEIVE = 459 // { int kmq_timedreceive(int mqd, \ - SYS_KMQ_TIMEDSEND = 460 // { int kmq_timedsend(int mqd, \ - SYS_KMQ_NOTIFY = 461 // { int kmq_notify(int mqd, \ + SYS_KMQ_OPEN = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); } + SYS_KMQ_SETATTR = 458 // { int kmq_setattr(int mqd, const struct mq_attr *attr, struct mq_attr *oattr); } + SYS_KMQ_TIMEDRECEIVE = 459 // { int kmq_timedreceive(int mqd, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); } + SYS_KMQ_TIMEDSEND = 460 // { int kmq_timedsend(int mqd, const char *msg_ptr, size_t msg_len,unsigned msg_prio, const struct timespec *abs_timeout);} + SYS_KMQ_NOTIFY = 461 // { int kmq_notify(int mqd, const struct sigevent *sigev); } SYS_KMQ_UNLINK = 462 // { int kmq_unlink(const char *path); } SYS_ABORT2 = 463 // { int abort2(const char *why, int nargs, void **args); } SYS_THR_SET_NAME = 464 // { int thr_set_name(long id, const char *name); } SYS_AIO_FSYNC = 465 // { int aio_fsync(int op, struct aiocb *aiocbp); } - SYS_RTPRIO_THREAD = 466 // { int rtprio_thread(int function, \ + SYS_RTPRIO_THREAD = 466 // { int rtprio_thread(int function, lwpid_t lwpid, struct rtprio *rtp); } SYS_SCTP_PEELOFF = 471 // { int sctp_peeloff(int sd, uint32_t name); } - SYS_SCTP_GENERIC_SENDMSG = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \ - SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \ - SYS_SCTP_GENERIC_RECVMSG = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \ - SYS_PREAD = 475 // { ssize_t pread(int fd, void *buf, \ - SYS_PWRITE = 476 // { ssize_t pwrite(int fd, const void *buf, \ - SYS_MMAP = 477 // { caddr_t mmap(caddr_t addr, size_t len, \ - SYS_LSEEK = 478 // { off_t lseek(int fd, off_t offset, \ + SYS_SCTP_GENERIC_SENDMSG = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); } + SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); } + SYS_SCTP_GENERIC_RECVMSG = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr * from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); } + SYS_PREAD = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); } + SYS_PWRITE = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); } + SYS_MMAP = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); } + SYS_LSEEK = 478 // { off_t lseek(int fd, off_t offset, int whence); } SYS_TRUNCATE = 479 // { int truncate(char *path, off_t length); } SYS_FTRUNCATE = 480 // { int ftruncate(int fd, off_t length); } SYS_THR_KILL2 = 481 // { int thr_kill2(pid_t pid, long id, int sig); } - SYS_SHM_OPEN = 482 // { int shm_open(const char *path, int flags, \ + SYS_SHM_OPEN = 482 // { int shm_open(const char *path, int flags, mode_t mode); } SYS_SHM_UNLINK = 483 // { int shm_unlink(const char *path); } SYS_CPUSET = 484 // { int cpuset(cpusetid_t *setid); } - SYS_CPUSET_SETID = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \ - SYS_CPUSET_GETID = 486 // { int cpuset_getid(cpulevel_t level, \ - SYS_CPUSET_GETAFFINITY = 487 // { int cpuset_getaffinity(cpulevel_t level, \ - SYS_CPUSET_SETAFFINITY = 488 // { int cpuset_setaffinity(cpulevel_t level, \ - SYS_FACCESSAT = 489 // { int faccessat(int fd, char *path, int amode, \ - SYS_FCHMODAT = 490 // { int fchmodat(int fd, char *path, mode_t mode, \ - SYS_FCHOWNAT = 491 // { int fchownat(int fd, char *path, uid_t uid, \ - SYS_FEXECVE = 492 // { int fexecve(int fd, char **argv, \ - SYS_FSTATAT = 493 // { int fstatat(int fd, char *path, \ - SYS_FUTIMESAT = 494 // { int futimesat(int fd, char *path, \ - SYS_LINKAT = 495 // { int linkat(int fd1, char *path1, int fd2, \ + SYS_CPUSET_SETID = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, cpusetid_t setid); } + SYS_CPUSET_GETID = 486 // { int cpuset_getid(cpulevel_t level, cpuwhich_t which, id_t id, cpusetid_t *setid); } + SYS_CPUSET_GETAFFINITY = 487 // { int cpuset_getaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, cpuset_t *mask); } + SYS_CPUSET_SETAFFINITY = 488 // { int cpuset_setaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, const cpuset_t *mask); } + SYS_FACCESSAT = 489 // { int faccessat(int fd, char *path, int amode, int flag); } + SYS_FCHMODAT = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); } + SYS_FEXECVE = 492 // { int fexecve(int fd, char **argv, char **envv); } + SYS_FSTATAT = 493 // { int fstatat(int fd, char *path, struct stat *buf, int flag); } + SYS_FUTIMESAT = 494 // { int futimesat(int fd, char *path, struct timeval *times); } + SYS_LINKAT = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); } SYS_MKDIRAT = 496 // { int mkdirat(int fd, char *path, mode_t mode); } SYS_MKFIFOAT = 497 // { int mkfifoat(int fd, char *path, mode_t mode); } - SYS_MKNODAT = 498 // { int mknodat(int fd, char *path, mode_t mode, \ - SYS_OPENAT = 499 // { int openat(int fd, char *path, int flag, \ - SYS_READLINKAT = 500 // { int readlinkat(int fd, char *path, char *buf, \ - SYS_RENAMEAT = 501 // { int renameat(int oldfd, char *old, int newfd, \ - SYS_SYMLINKAT = 502 // { int symlinkat(char *path1, int fd, \ + SYS_MKNODAT = 498 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 499 // { int openat(int fd, char *path, int flag, mode_t mode); } + SYS_READLINKAT = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); } + SYS_RENAMEAT = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); } + SYS_SYMLINKAT = 502 // { int symlinkat(char *path1, int fd, char *path2); } SYS_UNLINKAT = 503 // { int unlinkat(int fd, char *path, int flag); } SYS_POSIX_OPENPT = 504 // { int posix_openpt(int flags); } SYS_GSSD_SYSCALL = 505 // { int gssd_syscall(char *path); } - SYS_JAIL_GET = 506 // { int jail_get(struct iovec *iovp, \ - SYS_JAIL_SET = 507 // { int jail_set(struct iovec *iovp, \ + SYS_JAIL_GET = 506 // { int jail_get(struct iovec *iovp, unsigned int iovcnt, int flags); } + SYS_JAIL_SET = 507 // { int jail_set(struct iovec *iovp, unsigned int iovcnt, int flags); } SYS_JAIL_REMOVE = 508 // { int jail_remove(int jid); } SYS_CLOSEFROM = 509 // { int closefrom(int lowfd); } - SYS___SEMCTL = 510 // { int __semctl(int semid, int semnum, \ - SYS_MSGCTL = 511 // { int msgctl(int msqid, int cmd, \ - SYS_SHMCTL = 512 // { int shmctl(int shmid, int cmd, \ + SYS___SEMCTL = 510 // { int __semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_MSGCTL = 511 // { int msgctl(int msqid, int cmd, struct msqid_ds *buf); } + SYS_SHMCTL = 512 // { int shmctl(int shmid, int cmd, struct shmid_ds *buf); } SYS_LPATHCONF = 513 // { int lpathconf(char *path, int name); } - SYS___CAP_RIGHTS_GET = 515 // { int __cap_rights_get(int version, \ + SYS___CAP_RIGHTS_GET = 515 // { int __cap_rights_get(int version, int fd, cap_rights_t *rightsp); } SYS_CAP_ENTER = 516 // { int cap_enter(void); } SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); } SYS_PDFORK = 518 // { int pdfork(int *fdp, int flags); } SYS_PDKILL = 519 // { int pdkill(int fd, int signum); } SYS_PDGETPID = 520 // { int pdgetpid(int fd, pid_t *pidp); } - SYS_PSELECT = 522 // { int pselect(int nd, fd_set *in, \ - SYS_GETLOGINCLASS = 523 // { int getloginclass(char *namebuf, \ + SYS_PSELECT = 522 // { int pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *sm); } + SYS_GETLOGINCLASS = 523 // { int getloginclass(char *namebuf, size_t namelen); } SYS_SETLOGINCLASS = 524 // { int setloginclass(const char *namebuf); } - SYS_RCTL_GET_RACCT = 525 // { int rctl_get_racct(const void *inbufp, \ - SYS_RCTL_GET_RULES = 526 // { int rctl_get_rules(const void *inbufp, \ - SYS_RCTL_GET_LIMITS = 527 // { int rctl_get_limits(const void *inbufp, \ - SYS_RCTL_ADD_RULE = 528 // { int rctl_add_rule(const void *inbufp, \ - SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, \ - SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, \ - SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, \ - SYS_WAIT6 = 532 // { int wait6(idtype_t idtype, id_t id, \ - SYS_CAP_RIGHTS_LIMIT = 533 // { int cap_rights_limit(int fd, \ - SYS_CAP_IOCTLS_LIMIT = 534 // { int cap_ioctls_limit(int fd, \ - SYS_CAP_IOCTLS_GET = 535 // { ssize_t cap_ioctls_get(int fd, \ - SYS_CAP_FCNTLS_LIMIT = 536 // { int cap_fcntls_limit(int fd, \ - SYS_CAP_FCNTLS_GET = 537 // { int cap_fcntls_get(int fd, \ - SYS_BINDAT = 538 // { int bindat(int fd, int s, caddr_t name, \ - SYS_CONNECTAT = 539 // { int connectat(int fd, int s, caddr_t name, \ - SYS_CHFLAGSAT = 540 // { int chflagsat(int fd, const char *path, \ - SYS_ACCEPT4 = 541 // { int accept4(int s, \ + SYS_RCTL_GET_RACCT = 525 // { int rctl_get_racct(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_GET_RULES = 526 // { int rctl_get_rules(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_GET_LIMITS = 527 // { int rctl_get_limits(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_ADD_RULE = 528 // { int rctl_add_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); } + SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, off_t offset, off_t len); } + SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, off_t len, int advice); } + SYS_WAIT6 = 532 // { int wait6(idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *info); } + SYS_CAP_RIGHTS_LIMIT = 533 // { int cap_rights_limit(int fd, cap_rights_t *rightsp); } + SYS_CAP_IOCTLS_LIMIT = 534 // { int cap_ioctls_limit(int fd, const u_long *cmds, size_t ncmds); } + SYS_CAP_IOCTLS_GET = 535 // { ssize_t cap_ioctls_get(int fd, u_long *cmds, size_t maxcmds); } + SYS_CAP_FCNTLS_LIMIT = 536 // { int cap_fcntls_limit(int fd, uint32_t fcntlrights); } + SYS_CAP_FCNTLS_GET = 537 // { int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); } + SYS_BINDAT = 538 // { int bindat(int fd, int s, caddr_t name, int namelen); } + SYS_CONNECTAT = 539 // { int connectat(int fd, int s, caddr_t name, int namelen); } + SYS_CHFLAGSAT = 540 // { int chflagsat(int fd, const char *path, u_long flags, int atflag); } + SYS_ACCEPT4 = 541 // { int accept4(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen, int flags); } SYS_PIPE2 = 542 // { int pipe2(int *fildes, int flags); } SYS_AIO_MLOCK = 543 // { int aio_mlock(struct aiocb *aiocbp); } - SYS_PROCCTL = 544 // { int procctl(idtype_t idtype, id_t id, \ - SYS_PPOLL = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \ - SYS_FUTIMENS = 546 // { int futimens(int fd, \ - SYS_UTIMENSAT = 547 // { int utimensat(int fd, \ + SYS_PROCCTL = 544 // { int procctl(idtype_t idtype, id_t id, int com, void *data); } + SYS_PPOLL = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); } + SYS_FUTIMENS = 546 // { int futimens(int fd, struct timespec *times); } + SYS_UTIMENSAT = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); } ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go new file mode 100644 index 000000000000..9f21e9550edd --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go @@ -0,0 +1,395 @@ +// go run mksysnum.go https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build arm64,freebsd + +package unix + +const ( + // SYS_NOSYS = 0; // { int nosys(void); } syscall nosys_args int + SYS_EXIT = 1 // { void sys_exit(int rval); } exit \ + SYS_FORK = 2 // { int fork(void); } + SYS_READ = 3 // { ssize_t read(int fd, void *buf, \ + SYS_WRITE = 4 // { ssize_t write(int fd, const void *buf, \ + SYS_OPEN = 5 // { int open(char *path, int flags, int mode); } + SYS_CLOSE = 6 // { int close(int fd); } + SYS_WAIT4 = 7 // { int wait4(int pid, int *status, \ + SYS_LINK = 9 // { int link(char *path, char *link); } + SYS_UNLINK = 10 // { int unlink(char *path); } + SYS_CHDIR = 12 // { int chdir(char *path); } + SYS_FCHDIR = 13 // { int fchdir(int fd); } + SYS_MKNOD = 14 // { int mknod(char *path, int mode, int dev); } + SYS_CHMOD = 15 // { int chmod(char *path, int mode); } + SYS_CHOWN = 16 // { int chown(char *path, int uid, int gid); } + SYS_OBREAK = 17 // { int obreak(char *nsize); } break \ + SYS_GETPID = 20 // { pid_t getpid(void); } + SYS_MOUNT = 21 // { int mount(char *type, char *path, \ + SYS_UNMOUNT = 22 // { int unmount(char *path, int flags); } + SYS_SETUID = 23 // { int setuid(uid_t uid); } + SYS_GETUID = 24 // { uid_t getuid(void); } + SYS_GETEUID = 25 // { uid_t geteuid(void); } + SYS_PTRACE = 26 // { int ptrace(int req, pid_t pid, \ + SYS_RECVMSG = 27 // { int recvmsg(int s, struct msghdr *msg, \ + SYS_SENDMSG = 28 // { int sendmsg(int s, struct msghdr *msg, \ + SYS_RECVFROM = 29 // { int recvfrom(int s, caddr_t buf, \ + SYS_ACCEPT = 30 // { int accept(int s, \ + SYS_GETPEERNAME = 31 // { int getpeername(int fdes, \ + SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, \ + SYS_ACCESS = 33 // { int access(char *path, int amode); } + SYS_CHFLAGS = 34 // { int chflags(const char *path, u_long flags); } + SYS_FCHFLAGS = 35 // { int fchflags(int fd, u_long flags); } + SYS_SYNC = 36 // { int sync(void); } + SYS_KILL = 37 // { int kill(int pid, int signum); } + SYS_GETPPID = 39 // { pid_t getppid(void); } + SYS_DUP = 41 // { int dup(u_int fd); } + SYS_GETEGID = 43 // { gid_t getegid(void); } + SYS_PROFIL = 44 // { int profil(caddr_t samples, size_t size, \ + SYS_KTRACE = 45 // { int ktrace(const char *fname, int ops, \ + SYS_GETGID = 47 // { gid_t getgid(void); } + SYS_GETLOGIN = 49 // { int getlogin(char *namebuf, u_int \ + SYS_SETLOGIN = 50 // { int setlogin(char *namebuf); } + SYS_ACCT = 51 // { int acct(char *path); } + SYS_SIGALTSTACK = 53 // { int sigaltstack(stack_t *ss, \ + SYS_IOCTL = 54 // { int ioctl(int fd, u_long com, \ + SYS_REBOOT = 55 // { int reboot(int opt); } + SYS_REVOKE = 56 // { int revoke(char *path); } + SYS_SYMLINK = 57 // { int symlink(char *path, char *link); } + SYS_READLINK = 58 // { ssize_t readlink(char *path, char *buf, \ + SYS_EXECVE = 59 // { int execve(char *fname, char **argv, \ + SYS_UMASK = 60 // { int umask(int newmask); } umask umask_args \ + SYS_CHROOT = 61 // { int chroot(char *path); } + SYS_MSYNC = 65 // { int msync(void *addr, size_t len, \ + SYS_VFORK = 66 // { int vfork(void); } + SYS_SBRK = 69 // { int sbrk(int incr); } + SYS_SSTK = 70 // { int sstk(int incr); } + SYS_OVADVISE = 72 // { int ovadvise(int anom); } vadvise \ + SYS_MUNMAP = 73 // { int munmap(void *addr, size_t len); } + SYS_MPROTECT = 74 // { int mprotect(const void *addr, size_t len, \ + SYS_MADVISE = 75 // { int madvise(void *addr, size_t len, \ + SYS_MINCORE = 78 // { int mincore(const void *addr, size_t len, \ + SYS_GETGROUPS = 79 // { int getgroups(u_int gidsetsize, \ + SYS_SETGROUPS = 80 // { int setgroups(u_int gidsetsize, \ + SYS_GETPGRP = 81 // { int getpgrp(void); } + SYS_SETPGID = 82 // { int setpgid(int pid, int pgid); } + SYS_SETITIMER = 83 // { int setitimer(u_int which, struct \ + SYS_SWAPON = 85 // { int swapon(char *name); } + SYS_GETITIMER = 86 // { int getitimer(u_int which, \ + SYS_GETDTABLESIZE = 89 // { int getdtablesize(void); } + SYS_DUP2 = 90 // { int dup2(u_int from, u_int to); } + SYS_FCNTL = 92 // { int fcntl(int fd, int cmd, long arg); } + SYS_SELECT = 93 // { int select(int nd, fd_set *in, fd_set *ou, \ + SYS_FSYNC = 95 // { int fsync(int fd); } + SYS_SETPRIORITY = 96 // { int setpriority(int which, int who, \ + SYS_SOCKET = 97 // { int socket(int domain, int type, \ + SYS_CONNECT = 98 // { int connect(int s, caddr_t name, \ + SYS_GETPRIORITY = 100 // { int getpriority(int which, int who); } + SYS_BIND = 104 // { int bind(int s, caddr_t name, \ + SYS_SETSOCKOPT = 105 // { int setsockopt(int s, int level, int name, \ + SYS_LISTEN = 106 // { int listen(int s, int backlog); } + SYS_GETTIMEOFDAY = 116 // { int gettimeofday(struct timeval *tp, \ + SYS_GETRUSAGE = 117 // { int getrusage(int who, \ + SYS_GETSOCKOPT = 118 // { int getsockopt(int s, int level, int name, \ + SYS_READV = 120 // { int readv(int fd, struct iovec *iovp, \ + SYS_WRITEV = 121 // { int writev(int fd, struct iovec *iovp, \ + SYS_SETTIMEOFDAY = 122 // { int settimeofday(struct timeval *tv, \ + SYS_FCHOWN = 123 // { int fchown(int fd, int uid, int gid); } + SYS_FCHMOD = 124 // { int fchmod(int fd, int mode); } + SYS_SETREUID = 126 // { int setreuid(int ruid, int euid); } + SYS_SETREGID = 127 // { int setregid(int rgid, int egid); } + SYS_RENAME = 128 // { int rename(char *from, char *to); } + SYS_FLOCK = 131 // { int flock(int fd, int how); } + SYS_MKFIFO = 132 // { int mkfifo(char *path, int mode); } + SYS_SENDTO = 133 // { int sendto(int s, caddr_t buf, size_t len, \ + SYS_SHUTDOWN = 134 // { int shutdown(int s, int how); } + SYS_SOCKETPAIR = 135 // { int socketpair(int domain, int type, \ + SYS_MKDIR = 136 // { int mkdir(char *path, int mode); } + SYS_RMDIR = 137 // { int rmdir(char *path); } + SYS_UTIMES = 138 // { int utimes(char *path, \ + SYS_ADJTIME = 140 // { int adjtime(struct timeval *delta, \ + SYS_SETSID = 147 // { int setsid(void); } + SYS_QUOTACTL = 148 // { int quotactl(char *path, int cmd, int uid, \ + SYS_NLM_SYSCALL = 154 // { int nlm_syscall(int debug_level, int grace_period, int addr_count, char **addrs); } + SYS_NFSSVC = 155 // { int nfssvc(int flag, caddr_t argp); } + SYS_LGETFH = 160 // { int lgetfh(char *fname, \ + SYS_GETFH = 161 // { int getfh(char *fname, \ + SYS_SYSARCH = 165 // { int sysarch(int op, char *parms); } + SYS_RTPRIO = 166 // { int rtprio(int function, pid_t pid, \ + SYS_SEMSYS = 169 // { int semsys(int which, int a2, int a3, \ + SYS_MSGSYS = 170 // { int msgsys(int which, int a2, int a3, \ + SYS_SHMSYS = 171 // { int shmsys(int which, int a2, int a3, \ + SYS_SETFIB = 175 // { int setfib(int fibnum); } + SYS_NTP_ADJTIME = 176 // { int ntp_adjtime(struct timex *tp); } + SYS_SETGID = 181 // { int setgid(gid_t gid); } + SYS_SETEGID = 182 // { int setegid(gid_t egid); } + SYS_SETEUID = 183 // { int seteuid(uid_t euid); } + SYS_STAT = 188 // { int stat(char *path, struct stat *ub); } + SYS_FSTAT = 189 // { int fstat(int fd, struct stat *sb); } + SYS_LSTAT = 190 // { int lstat(char *path, struct stat *ub); } + SYS_PATHCONF = 191 // { int pathconf(char *path, int name); } + SYS_FPATHCONF = 192 // { int fpathconf(int fd, int name); } + SYS_GETRLIMIT = 194 // { int getrlimit(u_int which, \ + SYS_SETRLIMIT = 195 // { int setrlimit(u_int which, \ + SYS_GETDIRENTRIES = 196 // { int getdirentries(int fd, char *buf, \ + SYS___SYSCTL = 202 // { int __sysctl(int *name, u_int namelen, \ + SYS_MLOCK = 203 // { int mlock(const void *addr, size_t len); } + SYS_MUNLOCK = 204 // { int munlock(const void *addr, size_t len); } + SYS_UNDELETE = 205 // { int undelete(char *path); } + SYS_FUTIMES = 206 // { int futimes(int fd, struct timeval *tptr); } + SYS_GETPGID = 207 // { int getpgid(pid_t pid); } + SYS_POLL = 209 // { int poll(struct pollfd *fds, u_int nfds, \ + SYS_SEMGET = 221 // { int semget(key_t key, int nsems, \ + SYS_SEMOP = 222 // { int semop(int semid, struct sembuf *sops, \ + SYS_MSGGET = 225 // { int msgget(key_t key, int msgflg); } + SYS_MSGSND = 226 // { int msgsnd(int msqid, const void *msgp, \ + SYS_MSGRCV = 227 // { int msgrcv(int msqid, void *msgp, \ + SYS_SHMAT = 228 // { int shmat(int shmid, const void *shmaddr, \ + SYS_SHMDT = 230 // { int shmdt(const void *shmaddr); } + SYS_SHMGET = 231 // { int shmget(key_t key, size_t size, \ + SYS_CLOCK_GETTIME = 232 // { int clock_gettime(clockid_t clock_id, \ + SYS_CLOCK_SETTIME = 233 // { int clock_settime( \ + SYS_CLOCK_GETRES = 234 // { int clock_getres(clockid_t clock_id, \ + SYS_KTIMER_CREATE = 235 // { int ktimer_create(clockid_t clock_id, \ + SYS_KTIMER_DELETE = 236 // { int ktimer_delete(int timerid); } + SYS_KTIMER_SETTIME = 237 // { int ktimer_settime(int timerid, int flags, \ + SYS_KTIMER_GETTIME = 238 // { int ktimer_gettime(int timerid, struct \ + SYS_KTIMER_GETOVERRUN = 239 // { int ktimer_getoverrun(int timerid); } + SYS_NANOSLEEP = 240 // { int nanosleep(const struct timespec *rqtp, \ + SYS_FFCLOCK_GETCOUNTER = 241 // { int ffclock_getcounter(ffcounter *ffcount); } + SYS_FFCLOCK_SETESTIMATE = 242 // { int ffclock_setestimate( \ + SYS_FFCLOCK_GETESTIMATE = 243 // { int ffclock_getestimate( \ + SYS_CLOCK_NANOSLEEP = 244 // { int clock_nanosleep(clockid_t clock_id, \ + SYS_CLOCK_GETCPUCLOCKID2 = 247 // { int clock_getcpuclockid2(id_t id,\ + SYS_NTP_GETTIME = 248 // { int ntp_gettime(struct ntptimeval *ntvp); } + SYS_MINHERIT = 250 // { int minherit(void *addr, size_t len, \ + SYS_RFORK = 251 // { int rfork(int flags); } + SYS_OPENBSD_POLL = 252 // { int openbsd_poll(struct pollfd *fds, \ + SYS_ISSETUGID = 253 // { int issetugid(void); } + SYS_LCHOWN = 254 // { int lchown(char *path, int uid, int gid); } + SYS_AIO_READ = 255 // { int aio_read(struct aiocb *aiocbp); } + SYS_AIO_WRITE = 256 // { int aio_write(struct aiocb *aiocbp); } + SYS_LIO_LISTIO = 257 // { int lio_listio(int mode, \ + SYS_GETDENTS = 272 // { int getdents(int fd, char *buf, \ + SYS_LCHMOD = 274 // { int lchmod(char *path, mode_t mode); } + SYS_LUTIMES = 276 // { int lutimes(char *path, \ + SYS_NSTAT = 278 // { int nstat(char *path, struct nstat *ub); } + SYS_NFSTAT = 279 // { int nfstat(int fd, struct nstat *sb); } + SYS_NLSTAT = 280 // { int nlstat(char *path, struct nstat *ub); } + SYS_PREADV = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \ + SYS_PWRITEV = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \ + SYS_FHOPEN = 298 // { int fhopen(const struct fhandle *u_fhp, \ + SYS_FHSTAT = 299 // { int fhstat(const struct fhandle *u_fhp, \ + SYS_MODNEXT = 300 // { int modnext(int modid); } + SYS_MODSTAT = 301 // { int modstat(int modid, \ + SYS_MODFNEXT = 302 // { int modfnext(int modid); } + SYS_MODFIND = 303 // { int modfind(const char *name); } + SYS_KLDLOAD = 304 // { int kldload(const char *file); } + SYS_KLDUNLOAD = 305 // { int kldunload(int fileid); } + SYS_KLDFIND = 306 // { int kldfind(const char *file); } + SYS_KLDNEXT = 307 // { int kldnext(int fileid); } + SYS_KLDSTAT = 308 // { int kldstat(int fileid, struct \ + SYS_KLDFIRSTMOD = 309 // { int kldfirstmod(int fileid); } + SYS_GETSID = 310 // { int getsid(pid_t pid); } + SYS_SETRESUID = 311 // { int setresuid(uid_t ruid, uid_t euid, \ + SYS_SETRESGID = 312 // { int setresgid(gid_t rgid, gid_t egid, \ + SYS_AIO_RETURN = 314 // { ssize_t aio_return(struct aiocb *aiocbp); } + SYS_AIO_SUSPEND = 315 // { int aio_suspend( \ + SYS_AIO_CANCEL = 316 // { int aio_cancel(int fd, \ + SYS_AIO_ERROR = 317 // { int aio_error(struct aiocb *aiocbp); } + SYS_YIELD = 321 // { int yield(void); } + SYS_MLOCKALL = 324 // { int mlockall(int how); } + SYS_MUNLOCKALL = 325 // { int munlockall(void); } + SYS___GETCWD = 326 // { int __getcwd(char *buf, u_int buflen); } + SYS_SCHED_SETPARAM = 327 // { int sched_setparam (pid_t pid, \ + SYS_SCHED_GETPARAM = 328 // { int sched_getparam (pid_t pid, struct \ + SYS_SCHED_SETSCHEDULER = 329 // { int sched_setscheduler (pid_t pid, int \ + SYS_SCHED_GETSCHEDULER = 330 // { int sched_getscheduler (pid_t pid); } + SYS_SCHED_YIELD = 331 // { int sched_yield (void); } + SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); } + SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); } + SYS_SCHED_RR_GET_INTERVAL = 334 // { int sched_rr_get_interval (pid_t pid, \ + SYS_UTRACE = 335 // { int utrace(const void *addr, size_t len); } + SYS_KLDSYM = 337 // { int kldsym(int fileid, int cmd, \ + SYS_JAIL = 338 // { int jail(struct jail *jail); } + SYS_SIGPROCMASK = 340 // { int sigprocmask(int how, \ + SYS_SIGSUSPEND = 341 // { int sigsuspend(const sigset_t *sigmask); } + SYS_SIGPENDING = 343 // { int sigpending(sigset_t *set); } + SYS_SIGTIMEDWAIT = 345 // { int sigtimedwait(const sigset_t *set, \ + SYS_SIGWAITINFO = 346 // { int sigwaitinfo(const sigset_t *set, \ + SYS___ACL_GET_FILE = 347 // { int __acl_get_file(const char *path, \ + SYS___ACL_SET_FILE = 348 // { int __acl_set_file(const char *path, \ + SYS___ACL_GET_FD = 349 // { int __acl_get_fd(int filedes, \ + SYS___ACL_SET_FD = 350 // { int __acl_set_fd(int filedes, \ + SYS___ACL_DELETE_FILE = 351 // { int __acl_delete_file(const char *path, \ + SYS___ACL_DELETE_FD = 352 // { int __acl_delete_fd(int filedes, \ + SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, \ + SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, \ + SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, \ + SYS_EXTATTR_SET_FILE = 356 // { ssize_t extattr_set_file( \ + SYS_EXTATTR_GET_FILE = 357 // { ssize_t extattr_get_file( \ + SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, \ + SYS_AIO_WAITCOMPLETE = 359 // { ssize_t aio_waitcomplete( \ + SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \ + SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \ + SYS_KQUEUE = 362 // { int kqueue(void); } + SYS_KEVENT = 363 // { int kevent(int fd, \ + SYS_EXTATTR_SET_FD = 371 // { ssize_t extattr_set_fd(int fd, \ + SYS_EXTATTR_GET_FD = 372 // { ssize_t extattr_get_fd(int fd, \ + SYS_EXTATTR_DELETE_FD = 373 // { int extattr_delete_fd(int fd, \ + SYS___SETUGID = 374 // { int __setugid(int flag); } + SYS_EACCESS = 376 // { int eaccess(char *path, int amode); } + SYS_NMOUNT = 378 // { int nmount(struct iovec *iovp, \ + SYS___MAC_GET_PROC = 384 // { int __mac_get_proc(struct mac *mac_p); } + SYS___MAC_SET_PROC = 385 // { int __mac_set_proc(struct mac *mac_p); } + SYS___MAC_GET_FD = 386 // { int __mac_get_fd(int fd, \ + SYS___MAC_GET_FILE = 387 // { int __mac_get_file(const char *path_p, \ + SYS___MAC_SET_FD = 388 // { int __mac_set_fd(int fd, \ + SYS___MAC_SET_FILE = 389 // { int __mac_set_file(const char *path_p, \ + SYS_KENV = 390 // { int kenv(int what, const char *name, \ + SYS_LCHFLAGS = 391 // { int lchflags(const char *path, \ + SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, \ + SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, \ + SYS_MAC_SYSCALL = 394 // { int mac_syscall(const char *policy, \ + SYS_GETFSSTAT = 395 // { int getfsstat(struct statfs *buf, \ + SYS_STATFS = 396 // { int statfs(char *path, \ + SYS_FSTATFS = 397 // { int fstatfs(int fd, struct statfs *buf); } + SYS_FHSTATFS = 398 // { int fhstatfs(const struct fhandle *u_fhp, \ + SYS_KSEM_CLOSE = 400 // { int ksem_close(semid_t id); } + SYS_KSEM_POST = 401 // { int ksem_post(semid_t id); } + SYS_KSEM_WAIT = 402 // { int ksem_wait(semid_t id); } + SYS_KSEM_TRYWAIT = 403 // { int ksem_trywait(semid_t id); } + SYS_KSEM_INIT = 404 // { int ksem_init(semid_t *idp, \ + SYS_KSEM_OPEN = 405 // { int ksem_open(semid_t *idp, \ + SYS_KSEM_UNLINK = 406 // { int ksem_unlink(const char *name); } + SYS_KSEM_GETVALUE = 407 // { int ksem_getvalue(semid_t id, int *val); } + SYS_KSEM_DESTROY = 408 // { int ksem_destroy(semid_t id); } + SYS___MAC_GET_PID = 409 // { int __mac_get_pid(pid_t pid, \ + SYS___MAC_GET_LINK = 410 // { int __mac_get_link(const char *path_p, \ + SYS___MAC_SET_LINK = 411 // { int __mac_set_link(const char *path_p, \ + SYS_EXTATTR_SET_LINK = 412 // { ssize_t extattr_set_link( \ + SYS_EXTATTR_GET_LINK = 413 // { ssize_t extattr_get_link( \ + SYS_EXTATTR_DELETE_LINK = 414 // { int extattr_delete_link( \ + SYS___MAC_EXECVE = 415 // { int __mac_execve(char *fname, char **argv, \ + SYS_SIGACTION = 416 // { int sigaction(int sig, \ + SYS_SIGRETURN = 417 // { int sigreturn( \ + SYS_GETCONTEXT = 421 // { int getcontext(struct __ucontext *ucp); } + SYS_SETCONTEXT = 422 // { int setcontext( \ + SYS_SWAPCONTEXT = 423 // { int swapcontext(struct __ucontext *oucp, \ + SYS_SWAPOFF = 424 // { int swapoff(const char *name); } + SYS___ACL_GET_LINK = 425 // { int __acl_get_link(const char *path, \ + SYS___ACL_SET_LINK = 426 // { int __acl_set_link(const char *path, \ + SYS___ACL_DELETE_LINK = 427 // { int __acl_delete_link(const char *path, \ + SYS___ACL_ACLCHECK_LINK = 428 // { int __acl_aclcheck_link(const char *path, \ + SYS_SIGWAIT = 429 // { int sigwait(const sigset_t *set, \ + SYS_THR_CREATE = 430 // { int thr_create(ucontext_t *ctx, long *id, \ + SYS_THR_EXIT = 431 // { void thr_exit(long *state); } + SYS_THR_SELF = 432 // { int thr_self(long *id); } + SYS_THR_KILL = 433 // { int thr_kill(long id, int sig); } + SYS_JAIL_ATTACH = 436 // { int jail_attach(int jid); } + SYS_EXTATTR_LIST_FD = 437 // { ssize_t extattr_list_fd(int fd, \ + SYS_EXTATTR_LIST_FILE = 438 // { ssize_t extattr_list_file( \ + SYS_EXTATTR_LIST_LINK = 439 // { ssize_t extattr_list_link( \ + SYS_KSEM_TIMEDWAIT = 441 // { int ksem_timedwait(semid_t id, \ + SYS_THR_SUSPEND = 442 // { int thr_suspend( \ + SYS_THR_WAKE = 443 // { int thr_wake(long id); } + SYS_KLDUNLOADF = 444 // { int kldunloadf(int fileid, int flags); } + SYS_AUDIT = 445 // { int audit(const void *record, \ + SYS_AUDITON = 446 // { int auditon(int cmd, void *data, \ + SYS_GETAUID = 447 // { int getauid(uid_t *auid); } + SYS_SETAUID = 448 // { int setauid(uid_t *auid); } + SYS_GETAUDIT = 449 // { int getaudit(struct auditinfo *auditinfo); } + SYS_SETAUDIT = 450 // { int setaudit(struct auditinfo *auditinfo); } + SYS_GETAUDIT_ADDR = 451 // { int getaudit_addr( \ + SYS_SETAUDIT_ADDR = 452 // { int setaudit_addr( \ + SYS_AUDITCTL = 453 // { int auditctl(char *path); } + SYS__UMTX_OP = 454 // { int _umtx_op(void *obj, int op, \ + SYS_THR_NEW = 455 // { int thr_new(struct thr_param *param, \ + SYS_SIGQUEUE = 456 // { int sigqueue(pid_t pid, int signum, void *value); } + SYS_KMQ_OPEN = 457 // { int kmq_open(const char *path, int flags, \ + SYS_KMQ_SETATTR = 458 // { int kmq_setattr(int mqd, \ + SYS_KMQ_TIMEDRECEIVE = 459 // { int kmq_timedreceive(int mqd, \ + SYS_KMQ_TIMEDSEND = 460 // { int kmq_timedsend(int mqd, \ + SYS_KMQ_NOTIFY = 461 // { int kmq_notify(int mqd, \ + SYS_KMQ_UNLINK = 462 // { int kmq_unlink(const char *path); } + SYS_ABORT2 = 463 // { int abort2(const char *why, int nargs, void **args); } + SYS_THR_SET_NAME = 464 // { int thr_set_name(long id, const char *name); } + SYS_AIO_FSYNC = 465 // { int aio_fsync(int op, struct aiocb *aiocbp); } + SYS_RTPRIO_THREAD = 466 // { int rtprio_thread(int function, \ + SYS_SCTP_PEELOFF = 471 // { int sctp_peeloff(int sd, uint32_t name); } + SYS_SCTP_GENERIC_SENDMSG = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \ + SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \ + SYS_SCTP_GENERIC_RECVMSG = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \ + SYS_PREAD = 475 // { ssize_t pread(int fd, void *buf, \ + SYS_PWRITE = 476 // { ssize_t pwrite(int fd, const void *buf, \ + SYS_MMAP = 477 // { caddr_t mmap(caddr_t addr, size_t len, \ + SYS_LSEEK = 478 // { off_t lseek(int fd, off_t offset, \ + SYS_TRUNCATE = 479 // { int truncate(char *path, off_t length); } + SYS_FTRUNCATE = 480 // { int ftruncate(int fd, off_t length); } + SYS_THR_KILL2 = 481 // { int thr_kill2(pid_t pid, long id, int sig); } + SYS_SHM_OPEN = 482 // { int shm_open(const char *path, int flags, \ + SYS_SHM_UNLINK = 483 // { int shm_unlink(const char *path); } + SYS_CPUSET = 484 // { int cpuset(cpusetid_t *setid); } + SYS_CPUSET_SETID = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \ + SYS_CPUSET_GETID = 486 // { int cpuset_getid(cpulevel_t level, \ + SYS_CPUSET_GETAFFINITY = 487 // { int cpuset_getaffinity(cpulevel_t level, \ + SYS_CPUSET_SETAFFINITY = 488 // { int cpuset_setaffinity(cpulevel_t level, \ + SYS_FACCESSAT = 489 // { int faccessat(int fd, char *path, int amode, \ + SYS_FCHMODAT = 490 // { int fchmodat(int fd, char *path, mode_t mode, \ + SYS_FCHOWNAT = 491 // { int fchownat(int fd, char *path, uid_t uid, \ + SYS_FEXECVE = 492 // { int fexecve(int fd, char **argv, \ + SYS_FSTATAT = 493 // { int fstatat(int fd, char *path, \ + SYS_FUTIMESAT = 494 // { int futimesat(int fd, char *path, \ + SYS_LINKAT = 495 // { int linkat(int fd1, char *path1, int fd2, \ + SYS_MKDIRAT = 496 // { int mkdirat(int fd, char *path, mode_t mode); } + SYS_MKFIFOAT = 497 // { int mkfifoat(int fd, char *path, mode_t mode); } + SYS_MKNODAT = 498 // { int mknodat(int fd, char *path, mode_t mode, \ + SYS_OPENAT = 499 // { int openat(int fd, char *path, int flag, \ + SYS_READLINKAT = 500 // { int readlinkat(int fd, char *path, char *buf, \ + SYS_RENAMEAT = 501 // { int renameat(int oldfd, char *old, int newfd, \ + SYS_SYMLINKAT = 502 // { int symlinkat(char *path1, int fd, \ + SYS_UNLINKAT = 503 // { int unlinkat(int fd, char *path, int flag); } + SYS_POSIX_OPENPT = 504 // { int posix_openpt(int flags); } + SYS_GSSD_SYSCALL = 505 // { int gssd_syscall(char *path); } + SYS_JAIL_GET = 506 // { int jail_get(struct iovec *iovp, \ + SYS_JAIL_SET = 507 // { int jail_set(struct iovec *iovp, \ + SYS_JAIL_REMOVE = 508 // { int jail_remove(int jid); } + SYS_CLOSEFROM = 509 // { int closefrom(int lowfd); } + SYS___SEMCTL = 510 // { int __semctl(int semid, int semnum, \ + SYS_MSGCTL = 511 // { int msgctl(int msqid, int cmd, \ + SYS_SHMCTL = 512 // { int shmctl(int shmid, int cmd, \ + SYS_LPATHCONF = 513 // { int lpathconf(char *path, int name); } + SYS___CAP_RIGHTS_GET = 515 // { int __cap_rights_get(int version, \ + SYS_CAP_ENTER = 516 // { int cap_enter(void); } + SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); } + SYS_PDFORK = 518 // { int pdfork(int *fdp, int flags); } + SYS_PDKILL = 519 // { int pdkill(int fd, int signum); } + SYS_PDGETPID = 520 // { int pdgetpid(int fd, pid_t *pidp); } + SYS_PSELECT = 522 // { int pselect(int nd, fd_set *in, \ + SYS_GETLOGINCLASS = 523 // { int getloginclass(char *namebuf, \ + SYS_SETLOGINCLASS = 524 // { int setloginclass(const char *namebuf); } + SYS_RCTL_GET_RACCT = 525 // { int rctl_get_racct(const void *inbufp, \ + SYS_RCTL_GET_RULES = 526 // { int rctl_get_rules(const void *inbufp, \ + SYS_RCTL_GET_LIMITS = 527 // { int rctl_get_limits(const void *inbufp, \ + SYS_RCTL_ADD_RULE = 528 // { int rctl_add_rule(const void *inbufp, \ + SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, \ + SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, \ + SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, \ + SYS_WAIT6 = 532 // { int wait6(idtype_t idtype, id_t id, \ + SYS_CAP_RIGHTS_LIMIT = 533 // { int cap_rights_limit(int fd, \ + SYS_CAP_IOCTLS_LIMIT = 534 // { int cap_ioctls_limit(int fd, \ + SYS_CAP_IOCTLS_GET = 535 // { ssize_t cap_ioctls_get(int fd, \ + SYS_CAP_FCNTLS_LIMIT = 536 // { int cap_fcntls_limit(int fd, \ + SYS_CAP_FCNTLS_GET = 537 // { int cap_fcntls_get(int fd, \ + SYS_BINDAT = 538 // { int bindat(int fd, int s, caddr_t name, \ + SYS_CONNECTAT = 539 // { int connectat(int fd, int s, caddr_t name, \ + SYS_CHFLAGSAT = 540 // { int chflagsat(int fd, const char *path, \ + SYS_ACCEPT4 = 541 // { int accept4(int s, \ + SYS_PIPE2 = 542 // { int pipe2(int *fildes, int flags); } + SYS_AIO_MLOCK = 543 // { int aio_mlock(struct aiocb *aiocbp); } + SYS_PROCCTL = 544 // { int procctl(idtype_t idtype, id_t id, \ + SYS_PPOLL = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \ + SYS_FUTIMENS = 546 // { int futimens(int fd, \ + SYS_UTIMENSAT = 547 // { int utimensat(int fd, \ + SYS_NUMA_GETAFFINITY = 548 // { int numa_getaffinity(cpuwhich_t which, \ + SYS_NUMA_SETAFFINITY = 549 // { int numa_setaffinity(cpuwhich_t which, \ + SYS_FDATASYNC = 550 // { int fdatasync(int fd); } +) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 3206967896af..b81d508a730f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -285,4 +285,5 @@ const ( SYS_STATX = 291 SYS_IO_PGETEVENTS = 292 SYS_RSEQ = 293 + SYS_KEXEC_FILE_LOAD = 294 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 473c74613f64..2c8c46a2fc15 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -284,4 +284,5 @@ const ( SYS_STATX = 291 SYS_IO_PGETEVENTS = 292 SYS_RSEQ = 293 + SYS_KEXEC_FILE_LOAD = 294 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 93480fcb1683..6ed306370a5e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -253,6 +253,7 @@ const ( SYS_TIMER_GETOVERRUN = 264 SYS_TIMER_DELETE = 265 SYS_TIMER_CREATE = 266 + SYS_VSERVER = 267 SYS_IO_SETUP = 268 SYS_IO_DESTROY = 269 SYS_IO_SUBMIT = 270 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go index f0daa05a9cbf..e66a8c9d39ea 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go @@ -1,5 +1,5 @@ -// mksysnum_netbsd.pl -// Code generated by the command above; DO NOT EDIT. +// go run mksysnum.go http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master +// Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,netbsd diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go index ddb25b94f36d..42c788f2490c 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go @@ -1,5 +1,5 @@ -// mksysnum_netbsd.pl -// Code generated by the command above; DO NOT EDIT. +// go run mksysnum.go http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master +// Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,netbsd diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go index 315bd63f8904..0a0757179ba4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go @@ -1,5 +1,5 @@ -// mksysnum_netbsd.pl -// Code generated by the command above; DO NOT EDIT. +// go run mksysnum.go http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master +// Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,netbsd diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go new file mode 100644 index 000000000000..0291c0931b4f --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go @@ -0,0 +1,274 @@ +// go run mksysnum.go http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master +// Code generated by the command above; DO NOT EDIT. + +// +build arm64,netbsd + +package unix + +const ( + SYS_EXIT = 1 // { void|sys||exit(int rval); } + SYS_FORK = 2 // { int|sys||fork(void); } + SYS_READ = 3 // { ssize_t|sys||read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t|sys||write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int|sys||open(const char *path, int flags, ... mode_t mode); } + SYS_CLOSE = 6 // { int|sys||close(int fd); } + SYS_LINK = 9 // { int|sys||link(const char *path, const char *link); } + SYS_UNLINK = 10 // { int|sys||unlink(const char *path); } + SYS_CHDIR = 12 // { int|sys||chdir(const char *path); } + SYS_FCHDIR = 13 // { int|sys||fchdir(int fd); } + SYS_CHMOD = 15 // { int|sys||chmod(const char *path, mode_t mode); } + SYS_CHOWN = 16 // { int|sys||chown(const char *path, uid_t uid, gid_t gid); } + SYS_BREAK = 17 // { int|sys||obreak(char *nsize); } + SYS_GETPID = 20 // { pid_t|sys||getpid_with_ppid(void); } + SYS_UNMOUNT = 22 // { int|sys||unmount(const char *path, int flags); } + SYS_SETUID = 23 // { int|sys||setuid(uid_t uid); } + SYS_GETUID = 24 // { uid_t|sys||getuid_with_euid(void); } + SYS_GETEUID = 25 // { uid_t|sys||geteuid(void); } + SYS_PTRACE = 26 // { int|sys||ptrace(int req, pid_t pid, void *addr, int data); } + SYS_RECVMSG = 27 // { ssize_t|sys||recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { ssize_t|sys||sendmsg(int s, const struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { ssize_t|sys||recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); } + SYS_ACCEPT = 30 // { int|sys||accept(int s, struct sockaddr *name, socklen_t *anamelen); } + SYS_GETPEERNAME = 31 // { int|sys||getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_GETSOCKNAME = 32 // { int|sys||getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_ACCESS = 33 // { int|sys||access(const char *path, int flags); } + SYS_CHFLAGS = 34 // { int|sys||chflags(const char *path, u_long flags); } + SYS_FCHFLAGS = 35 // { int|sys||fchflags(int fd, u_long flags); } + SYS_SYNC = 36 // { void|sys||sync(void); } + SYS_KILL = 37 // { int|sys||kill(pid_t pid, int signum); } + SYS_GETPPID = 39 // { pid_t|sys||getppid(void); } + SYS_DUP = 41 // { int|sys||dup(int fd); } + SYS_PIPE = 42 // { int|sys||pipe(void); } + SYS_GETEGID = 43 // { gid_t|sys||getegid(void); } + SYS_PROFIL = 44 // { int|sys||profil(char *samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int|sys||ktrace(const char *fname, int ops, int facs, pid_t pid); } + SYS_GETGID = 47 // { gid_t|sys||getgid_with_egid(void); } + SYS___GETLOGIN = 49 // { int|sys||__getlogin(char *namebuf, size_t namelen); } + SYS___SETLOGIN = 50 // { int|sys||__setlogin(const char *namebuf); } + SYS_ACCT = 51 // { int|sys||acct(const char *path); } + SYS_IOCTL = 54 // { int|sys||ioctl(int fd, u_long com, ... void *data); } + SYS_REVOKE = 56 // { int|sys||revoke(const char *path); } + SYS_SYMLINK = 57 // { int|sys||symlink(const char *path, const char *link); } + SYS_READLINK = 58 // { ssize_t|sys||readlink(const char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int|sys||execve(const char *path, char * const *argp, char * const *envp); } + SYS_UMASK = 60 // { mode_t|sys||umask(mode_t newmask); } + SYS_CHROOT = 61 // { int|sys||chroot(const char *path); } + SYS_VFORK = 66 // { int|sys||vfork(void); } + SYS_SBRK = 69 // { int|sys||sbrk(intptr_t incr); } + SYS_SSTK = 70 // { int|sys||sstk(int incr); } + SYS_VADVISE = 72 // { int|sys||ovadvise(int anom); } + SYS_MUNMAP = 73 // { int|sys||munmap(void *addr, size_t len); } + SYS_MPROTECT = 74 // { int|sys||mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int|sys||madvise(void *addr, size_t len, int behav); } + SYS_MINCORE = 78 // { int|sys||mincore(void *addr, size_t len, char *vec); } + SYS_GETGROUPS = 79 // { int|sys||getgroups(int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int|sys||setgroups(int gidsetsize, const gid_t *gidset); } + SYS_GETPGRP = 81 // { int|sys||getpgrp(void); } + SYS_SETPGID = 82 // { int|sys||setpgid(pid_t pid, pid_t pgid); } + SYS_DUP2 = 90 // { int|sys||dup2(int from, int to); } + SYS_FCNTL = 92 // { int|sys||fcntl(int fd, int cmd, ... void *arg); } + SYS_FSYNC = 95 // { int|sys||fsync(int fd); } + SYS_SETPRIORITY = 96 // { int|sys||setpriority(int which, id_t who, int prio); } + SYS_CONNECT = 98 // { int|sys||connect(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_GETPRIORITY = 100 // { int|sys||getpriority(int which, id_t who); } + SYS_BIND = 104 // { int|sys||bind(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_SETSOCKOPT = 105 // { int|sys||setsockopt(int s, int level, int name, const void *val, socklen_t valsize); } + SYS_LISTEN = 106 // { int|sys||listen(int s, int backlog); } + SYS_GETSOCKOPT = 118 // { int|sys||getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); } + SYS_READV = 120 // { ssize_t|sys||readv(int fd, const struct iovec *iovp, int iovcnt); } + SYS_WRITEV = 121 // { ssize_t|sys||writev(int fd, const struct iovec *iovp, int iovcnt); } + SYS_FCHOWN = 123 // { int|sys||fchown(int fd, uid_t uid, gid_t gid); } + SYS_FCHMOD = 124 // { int|sys||fchmod(int fd, mode_t mode); } + SYS_SETREUID = 126 // { int|sys||setreuid(uid_t ruid, uid_t euid); } + SYS_SETREGID = 127 // { int|sys||setregid(gid_t rgid, gid_t egid); } + SYS_RENAME = 128 // { int|sys||rename(const char *from, const char *to); } + SYS_FLOCK = 131 // { int|sys||flock(int fd, int how); } + SYS_MKFIFO = 132 // { int|sys||mkfifo(const char *path, mode_t mode); } + SYS_SENDTO = 133 // { ssize_t|sys||sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); } + SYS_SHUTDOWN = 134 // { int|sys||shutdown(int s, int how); } + SYS_SOCKETPAIR = 135 // { int|sys||socketpair(int domain, int type, int protocol, int *rsv); } + SYS_MKDIR = 136 // { int|sys||mkdir(const char *path, mode_t mode); } + SYS_RMDIR = 137 // { int|sys||rmdir(const char *path); } + SYS_SETSID = 147 // { int|sys||setsid(void); } + SYS_SYSARCH = 165 // { int|sys||sysarch(int op, void *parms); } + SYS_PREAD = 173 // { ssize_t|sys||pread(int fd, void *buf, size_t nbyte, int PAD, off_t offset); } + SYS_PWRITE = 174 // { ssize_t|sys||pwrite(int fd, const void *buf, size_t nbyte, int PAD, off_t offset); } + SYS_NTP_ADJTIME = 176 // { int|sys||ntp_adjtime(struct timex *tp); } + SYS_SETGID = 181 // { int|sys||setgid(gid_t gid); } + SYS_SETEGID = 182 // { int|sys||setegid(gid_t egid); } + SYS_SETEUID = 183 // { int|sys||seteuid(uid_t euid); } + SYS_PATHCONF = 191 // { long|sys||pathconf(const char *path, int name); } + SYS_FPATHCONF = 192 // { long|sys||fpathconf(int fd, int name); } + SYS_GETRLIMIT = 194 // { int|sys||getrlimit(int which, struct rlimit *rlp); } + SYS_SETRLIMIT = 195 // { int|sys||setrlimit(int which, const struct rlimit *rlp); } + SYS_MMAP = 197 // { void *|sys||mmap(void *addr, size_t len, int prot, int flags, int fd, long PAD, off_t pos); } + SYS_LSEEK = 199 // { off_t|sys||lseek(int fd, int PAD, off_t offset, int whence); } + SYS_TRUNCATE = 200 // { int|sys||truncate(const char *path, int PAD, off_t length); } + SYS_FTRUNCATE = 201 // { int|sys||ftruncate(int fd, int PAD, off_t length); } + SYS___SYSCTL = 202 // { int|sys||__sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, const void *new, size_t newlen); } + SYS_MLOCK = 203 // { int|sys||mlock(const void *addr, size_t len); } + SYS_MUNLOCK = 204 // { int|sys||munlock(const void *addr, size_t len); } + SYS_UNDELETE = 205 // { int|sys||undelete(const char *path); } + SYS_GETPGID = 207 // { pid_t|sys||getpgid(pid_t pid); } + SYS_REBOOT = 208 // { int|sys||reboot(int opt, char *bootstr); } + SYS_POLL = 209 // { int|sys||poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS_SEMGET = 221 // { int|sys||semget(key_t key, int nsems, int semflg); } + SYS_SEMOP = 222 // { int|sys||semop(int semid, struct sembuf *sops, size_t nsops); } + SYS_SEMCONFIG = 223 // { int|sys||semconfig(int flag); } + SYS_MSGGET = 225 // { int|sys||msgget(key_t key, int msgflg); } + SYS_MSGSND = 226 // { int|sys||msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { ssize_t|sys||msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { void *|sys||shmat(int shmid, const void *shmaddr, int shmflg); } + SYS_SHMDT = 230 // { int|sys||shmdt(const void *shmaddr); } + SYS_SHMGET = 231 // { int|sys||shmget(key_t key, size_t size, int shmflg); } + SYS_TIMER_CREATE = 235 // { int|sys||timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid); } + SYS_TIMER_DELETE = 236 // { int|sys||timer_delete(timer_t timerid); } + SYS_TIMER_GETOVERRUN = 239 // { int|sys||timer_getoverrun(timer_t timerid); } + SYS_FDATASYNC = 241 // { int|sys||fdatasync(int fd); } + SYS_MLOCKALL = 242 // { int|sys||mlockall(int flags); } + SYS_MUNLOCKALL = 243 // { int|sys||munlockall(void); } + SYS_SIGQUEUEINFO = 245 // { int|sys||sigqueueinfo(pid_t pid, const siginfo_t *info); } + SYS_MODCTL = 246 // { int|sys||modctl(int cmd, void *arg); } + SYS___POSIX_RENAME = 270 // { int|sys||__posix_rename(const char *from, const char *to); } + SYS_SWAPCTL = 271 // { int|sys||swapctl(int cmd, void *arg, int misc); } + SYS_MINHERIT = 273 // { int|sys||minherit(void *addr, size_t len, int inherit); } + SYS_LCHMOD = 274 // { int|sys||lchmod(const char *path, mode_t mode); } + SYS_LCHOWN = 275 // { int|sys||lchown(const char *path, uid_t uid, gid_t gid); } + SYS_MSYNC = 277 // { int|sys|13|msync(void *addr, size_t len, int flags); } + SYS___POSIX_CHOWN = 283 // { int|sys||__posix_chown(const char *path, uid_t uid, gid_t gid); } + SYS___POSIX_FCHOWN = 284 // { int|sys||__posix_fchown(int fd, uid_t uid, gid_t gid); } + SYS___POSIX_LCHOWN = 285 // { int|sys||__posix_lchown(const char *path, uid_t uid, gid_t gid); } + SYS_GETSID = 286 // { pid_t|sys||getsid(pid_t pid); } + SYS___CLONE = 287 // { pid_t|sys||__clone(int flags, void *stack); } + SYS_FKTRACE = 288 // { int|sys||fktrace(int fd, int ops, int facs, pid_t pid); } + SYS_PREADV = 289 // { ssize_t|sys||preadv(int fd, const struct iovec *iovp, int iovcnt, int PAD, off_t offset); } + SYS_PWRITEV = 290 // { ssize_t|sys||pwritev(int fd, const struct iovec *iovp, int iovcnt, int PAD, off_t offset); } + SYS___GETCWD = 296 // { int|sys||__getcwd(char *bufp, size_t length); } + SYS_FCHROOT = 297 // { int|sys||fchroot(int fd); } + SYS_LCHFLAGS = 304 // { int|sys||lchflags(const char *path, u_long flags); } + SYS_ISSETUGID = 305 // { int|sys||issetugid(void); } + SYS_UTRACE = 306 // { int|sys||utrace(const char *label, void *addr, size_t len); } + SYS_GETCONTEXT = 307 // { int|sys||getcontext(struct __ucontext *ucp); } + SYS_SETCONTEXT = 308 // { int|sys||setcontext(const struct __ucontext *ucp); } + SYS__LWP_CREATE = 309 // { int|sys||_lwp_create(const struct __ucontext *ucp, u_long flags, lwpid_t *new_lwp); } + SYS__LWP_EXIT = 310 // { int|sys||_lwp_exit(void); } + SYS__LWP_SELF = 311 // { lwpid_t|sys||_lwp_self(void); } + SYS__LWP_WAIT = 312 // { int|sys||_lwp_wait(lwpid_t wait_for, lwpid_t *departed); } + SYS__LWP_SUSPEND = 313 // { int|sys||_lwp_suspend(lwpid_t target); } + SYS__LWP_CONTINUE = 314 // { int|sys||_lwp_continue(lwpid_t target); } + SYS__LWP_WAKEUP = 315 // { int|sys||_lwp_wakeup(lwpid_t target); } + SYS__LWP_GETPRIVATE = 316 // { void *|sys||_lwp_getprivate(void); } + SYS__LWP_SETPRIVATE = 317 // { void|sys||_lwp_setprivate(void *ptr); } + SYS__LWP_KILL = 318 // { int|sys||_lwp_kill(lwpid_t target, int signo); } + SYS__LWP_DETACH = 319 // { int|sys||_lwp_detach(lwpid_t target); } + SYS__LWP_UNPARK = 321 // { int|sys||_lwp_unpark(lwpid_t target, const void *hint); } + SYS__LWP_UNPARK_ALL = 322 // { ssize_t|sys||_lwp_unpark_all(const lwpid_t *targets, size_t ntargets, const void *hint); } + SYS__LWP_SETNAME = 323 // { int|sys||_lwp_setname(lwpid_t target, const char *name); } + SYS__LWP_GETNAME = 324 // { int|sys||_lwp_getname(lwpid_t target, char *name, size_t len); } + SYS__LWP_CTL = 325 // { int|sys||_lwp_ctl(int features, struct lwpctl **address); } + SYS___SIGACTION_SIGTRAMP = 340 // { int|sys||__sigaction_sigtramp(int signum, const struct sigaction *nsa, struct sigaction *osa, const void *tramp, int vers); } + SYS_PMC_GET_INFO = 341 // { int|sys||pmc_get_info(int ctr, int op, void *args); } + SYS_PMC_CONTROL = 342 // { int|sys||pmc_control(int ctr, int op, void *args); } + SYS_RASCTL = 343 // { int|sys||rasctl(void *addr, size_t len, int op); } + SYS_KQUEUE = 344 // { int|sys||kqueue(void); } + SYS__SCHED_SETPARAM = 346 // { int|sys||_sched_setparam(pid_t pid, lwpid_t lid, int policy, const struct sched_param *params); } + SYS__SCHED_GETPARAM = 347 // { int|sys||_sched_getparam(pid_t pid, lwpid_t lid, int *policy, struct sched_param *params); } + SYS__SCHED_SETAFFINITY = 348 // { int|sys||_sched_setaffinity(pid_t pid, lwpid_t lid, size_t size, const cpuset_t *cpuset); } + SYS__SCHED_GETAFFINITY = 349 // { int|sys||_sched_getaffinity(pid_t pid, lwpid_t lid, size_t size, cpuset_t *cpuset); } + SYS_SCHED_YIELD = 350 // { int|sys||sched_yield(void); } + SYS_FSYNC_RANGE = 354 // { int|sys||fsync_range(int fd, int flags, off_t start, off_t length); } + SYS_UUIDGEN = 355 // { int|sys||uuidgen(struct uuid *store, int count); } + SYS_GETVFSSTAT = 356 // { int|sys||getvfsstat(struct statvfs *buf, size_t bufsize, int flags); } + SYS_STATVFS1 = 357 // { int|sys||statvfs1(const char *path, struct statvfs *buf, int flags); } + SYS_FSTATVFS1 = 358 // { int|sys||fstatvfs1(int fd, struct statvfs *buf, int flags); } + SYS_EXTATTRCTL = 360 // { int|sys||extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); } + SYS_EXTATTR_SET_FILE = 361 // { int|sys||extattr_set_file(const char *path, int attrnamespace, const char *attrname, const void *data, size_t nbytes); } + SYS_EXTATTR_GET_FILE = 362 // { ssize_t|sys||extattr_get_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FILE = 363 // { int|sys||extattr_delete_file(const char *path, int attrnamespace, const char *attrname); } + SYS_EXTATTR_SET_FD = 364 // { int|sys||extattr_set_fd(int fd, int attrnamespace, const char *attrname, const void *data, size_t nbytes); } + SYS_EXTATTR_GET_FD = 365 // { ssize_t|sys||extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_FD = 366 // { int|sys||extattr_delete_fd(int fd, int attrnamespace, const char *attrname); } + SYS_EXTATTR_SET_LINK = 367 // { int|sys||extattr_set_link(const char *path, int attrnamespace, const char *attrname, const void *data, size_t nbytes); } + SYS_EXTATTR_GET_LINK = 368 // { ssize_t|sys||extattr_get_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); } + SYS_EXTATTR_DELETE_LINK = 369 // { int|sys||extattr_delete_link(const char *path, int attrnamespace, const char *attrname); } + SYS_EXTATTR_LIST_FD = 370 // { ssize_t|sys||extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); } + SYS_EXTATTR_LIST_FILE = 371 // { ssize_t|sys||extattr_list_file(const char *path, int attrnamespace, void *data, size_t nbytes); } + SYS_EXTATTR_LIST_LINK = 372 // { ssize_t|sys||extattr_list_link(const char *path, int attrnamespace, void *data, size_t nbytes); } + SYS_SETXATTR = 375 // { int|sys||setxattr(const char *path, const char *name, const void *value, size_t size, int flags); } + SYS_LSETXATTR = 376 // { int|sys||lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags); } + SYS_FSETXATTR = 377 // { int|sys||fsetxattr(int fd, const char *name, const void *value, size_t size, int flags); } + SYS_GETXATTR = 378 // { int|sys||getxattr(const char *path, const char *name, void *value, size_t size); } + SYS_LGETXATTR = 379 // { int|sys||lgetxattr(const char *path, const char *name, void *value, size_t size); } + SYS_FGETXATTR = 380 // { int|sys||fgetxattr(int fd, const char *name, void *value, size_t size); } + SYS_LISTXATTR = 381 // { int|sys||listxattr(const char *path, char *list, size_t size); } + SYS_LLISTXATTR = 382 // { int|sys||llistxattr(const char *path, char *list, size_t size); } + SYS_FLISTXATTR = 383 // { int|sys||flistxattr(int fd, char *list, size_t size); } + SYS_REMOVEXATTR = 384 // { int|sys||removexattr(const char *path, const char *name); } + SYS_LREMOVEXATTR = 385 // { int|sys||lremovexattr(const char *path, const char *name); } + SYS_FREMOVEXATTR = 386 // { int|sys||fremovexattr(int fd, const char *name); } + SYS_GETDENTS = 390 // { int|sys|30|getdents(int fd, char *buf, size_t count); } + SYS_SOCKET = 394 // { int|sys|30|socket(int domain, int type, int protocol); } + SYS_GETFH = 395 // { int|sys|30|getfh(const char *fname, void *fhp, size_t *fh_size); } + SYS_MOUNT = 410 // { int|sys|50|mount(const char *type, const char *path, int flags, void *data, size_t data_len); } + SYS_MREMAP = 411 // { void *|sys||mremap(void *old_address, size_t old_size, void *new_address, size_t new_size, int flags); } + SYS_PSET_CREATE = 412 // { int|sys||pset_create(psetid_t *psid); } + SYS_PSET_DESTROY = 413 // { int|sys||pset_destroy(psetid_t psid); } + SYS_PSET_ASSIGN = 414 // { int|sys||pset_assign(psetid_t psid, cpuid_t cpuid, psetid_t *opsid); } + SYS__PSET_BIND = 415 // { int|sys||_pset_bind(idtype_t idtype, id_t first_id, id_t second_id, psetid_t psid, psetid_t *opsid); } + SYS_POSIX_FADVISE = 416 // { int|sys|50|posix_fadvise(int fd, int PAD, off_t offset, off_t len, int advice); } + SYS_SELECT = 417 // { int|sys|50|select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_GETTIMEOFDAY = 418 // { int|sys|50|gettimeofday(struct timeval *tp, void *tzp); } + SYS_SETTIMEOFDAY = 419 // { int|sys|50|settimeofday(const struct timeval *tv, const void *tzp); } + SYS_UTIMES = 420 // { int|sys|50|utimes(const char *path, const struct timeval *tptr); } + SYS_ADJTIME = 421 // { int|sys|50|adjtime(const struct timeval *delta, struct timeval *olddelta); } + SYS_FUTIMES = 423 // { int|sys|50|futimes(int fd, const struct timeval *tptr); } + SYS_LUTIMES = 424 // { int|sys|50|lutimes(const char *path, const struct timeval *tptr); } + SYS_SETITIMER = 425 // { int|sys|50|setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); } + SYS_GETITIMER = 426 // { int|sys|50|getitimer(int which, struct itimerval *itv); } + SYS_CLOCK_GETTIME = 427 // { int|sys|50|clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 428 // { int|sys|50|clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 429 // { int|sys|50|clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_NANOSLEEP = 430 // { int|sys|50|nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } + SYS___SIGTIMEDWAIT = 431 // { int|sys|50|__sigtimedwait(const sigset_t *set, siginfo_t *info, struct timespec *timeout); } + SYS__LWP_PARK = 434 // { int|sys|50|_lwp_park(const struct timespec *ts, lwpid_t unpark, const void *hint, const void *unparkhint); } + SYS_KEVENT = 435 // { int|sys|50|kevent(int fd, const struct kevent *changelist, size_t nchanges, struct kevent *eventlist, size_t nevents, const struct timespec *timeout); } + SYS_PSELECT = 436 // { int|sys|50|pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); } + SYS_POLLTS = 437 // { int|sys|50|pollts(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); } + SYS_STAT = 439 // { int|sys|50|stat(const char *path, struct stat *ub); } + SYS_FSTAT = 440 // { int|sys|50|fstat(int fd, struct stat *sb); } + SYS_LSTAT = 441 // { int|sys|50|lstat(const char *path, struct stat *ub); } + SYS___SEMCTL = 442 // { int|sys|50|__semctl(int semid, int semnum, int cmd, ... union __semun *arg); } + SYS_SHMCTL = 443 // { int|sys|50|shmctl(int shmid, int cmd, struct shmid_ds *buf); } + SYS_MSGCTL = 444 // { int|sys|50|msgctl(int msqid, int cmd, struct msqid_ds *buf); } + SYS_GETRUSAGE = 445 // { int|sys|50|getrusage(int who, struct rusage *rusage); } + SYS_TIMER_SETTIME = 446 // { int|sys|50|timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue); } + SYS_TIMER_GETTIME = 447 // { int|sys|50|timer_gettime(timer_t timerid, struct itimerspec *value); } + SYS_NTP_GETTIME = 448 // { int|sys|50|ntp_gettime(struct ntptimeval *ntvp); } + SYS_WAIT4 = 449 // { int|sys|50|wait4(pid_t pid, int *status, int options, struct rusage *rusage); } + SYS_MKNOD = 450 // { int|sys|50|mknod(const char *path, mode_t mode, dev_t dev); } + SYS_FHSTAT = 451 // { int|sys|50|fhstat(const void *fhp, size_t fh_size, struct stat *sb); } + SYS_PIPE2 = 453 // { int|sys||pipe2(int *fildes, int flags); } + SYS_DUP3 = 454 // { int|sys||dup3(int from, int to, int flags); } + SYS_KQUEUE1 = 455 // { int|sys||kqueue1(int flags); } + SYS_PACCEPT = 456 // { int|sys||paccept(int s, struct sockaddr *name, socklen_t *anamelen, const sigset_t *mask, int flags); } + SYS_LINKAT = 457 // { int|sys||linkat(int fd1, const char *name1, int fd2, const char *name2, int flags); } + SYS_RENAMEAT = 458 // { int|sys||renameat(int fromfd, const char *from, int tofd, const char *to); } + SYS_MKFIFOAT = 459 // { int|sys||mkfifoat(int fd, const char *path, mode_t mode); } + SYS_MKNODAT = 460 // { int|sys||mknodat(int fd, const char *path, mode_t mode, uint32_t dev); } + SYS_MKDIRAT = 461 // { int|sys||mkdirat(int fd, const char *path, mode_t mode); } + SYS_FACCESSAT = 462 // { int|sys||faccessat(int fd, const char *path, int amode, int flag); } + SYS_FCHMODAT = 463 // { int|sys||fchmodat(int fd, const char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 464 // { int|sys||fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag); } + SYS_FEXECVE = 465 // { int|sys||fexecve(int fd, char * const *argp, char * const *envp); } + SYS_FSTATAT = 466 // { int|sys||fstatat(int fd, const char *path, struct stat *buf, int flag); } + SYS_UTIMENSAT = 467 // { int|sys||utimensat(int fd, const char *path, const struct timespec *tptr, int flag); } + SYS_OPENAT = 468 // { int|sys||openat(int fd, const char *path, int oflags, ... mode_t mode); } + SYS_READLINKAT = 469 // { int|sys||readlinkat(int fd, const char *path, char *buf, size_t bufsize); } + SYS_SYMLINKAT = 470 // { int|sys||symlinkat(const char *path1, int fd, const char *path2); } + SYS_UNLINKAT = 471 // { int|sys||unlinkat(int fd, const char *path, int flag); } + SYS_FUTIMENS = 472 // { int|sys||futimens(int fd, const struct timespec *tptr); } + SYS___QUOTACTL = 473 // { int|sys||__quotactl(const char *path, struct quotactl_args *args); } + SYS_POSIX_SPAWN = 474 // { int|sys||posix_spawn(pid_t *pid, const char *path, const struct posix_spawn_file_actions *file_actions, const struct posix_spawnattr *attrp, char *const *argv, char *const *envp); } + SYS_RECVMMSG = 475 // { int|sys||recvmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); } + SYS_SENDMMSG = 476 // { int|sys||sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, unsigned int flags); } +) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go index f93f391d26be..b0207d1c9bbc 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go @@ -1,4 +1,4 @@ -// mksysnum_openbsd.pl +// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master // Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,openbsd @@ -9,35 +9,35 @@ const ( SYS_EXIT = 1 // { void sys_exit(int rval); } SYS_FORK = 2 // { int sys_fork(void); } SYS_READ = 3 // { ssize_t sys_read(int fd, void *buf, size_t nbyte); } - SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, \ - SYS_OPEN = 5 // { int sys_open(const char *path, \ + SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int sys_open(const char *path, int flags, ... mode_t mode); } SYS_CLOSE = 6 // { int sys_close(int fd); } SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); } - SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, \ + SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, size_t psize); } SYS_LINK = 9 // { int sys_link(const char *path, const char *link); } SYS_UNLINK = 10 // { int sys_unlink(const char *path); } - SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, \ + SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); } SYS_CHDIR = 12 // { int sys_chdir(const char *path); } SYS_FCHDIR = 13 // { int sys_fchdir(int fd); } - SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, \ + SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, dev_t dev); } SYS_CHMOD = 15 // { int sys_chmod(const char *path, mode_t mode); } - SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, \ + SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, gid_t gid); } SYS_OBREAK = 17 // { int sys_obreak(char *nsize); } break SYS_GETDTABLECOUNT = 18 // { int sys_getdtablecount(void); } - SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, \ + SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, struct rusage *rusage); } SYS_GETPID = 20 // { pid_t sys_getpid(void); } - SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, \ + SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, int flags, void *data); } SYS_UNMOUNT = 22 // { int sys_unmount(const char *path, int flags); } SYS_SETUID = 23 // { int sys_setuid(uid_t uid); } SYS_GETUID = 24 // { uid_t sys_getuid(void); } SYS_GETEUID = 25 // { uid_t sys_geteuid(void); } - SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, \ - SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, \ - SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, \ - SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, \ - SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, \ - SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, \ - SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, \ + SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); } + SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); } + SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); } SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); } SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); } SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); } @@ -46,81 +46,81 @@ const ( SYS_GETPPID = 39 // { pid_t sys_getppid(void); } SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); } SYS_DUP = 41 // { int sys_dup(int fd); } - SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, \ + SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); } SYS_GETEGID = 43 // { gid_t sys_getegid(void); } - SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, \ - SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, \ - SYS_SIGACTION = 46 // { int sys_sigaction(int signum, \ + SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); } + SYS_SIGACTION = 46 // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); } SYS_GETGID = 47 // { gid_t sys_getgid(void); } SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); } SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); } SYS_ACCT = 51 // { int sys_acct(const char *path); } SYS_SIGPENDING = 52 // { int sys_sigpending(void); } SYS_FSTAT = 53 // { int sys_fstat(int fd, struct stat *sb); } - SYS_IOCTL = 54 // { int sys_ioctl(int fd, \ + SYS_IOCTL = 54 // { int sys_ioctl(int fd, u_long com, ... void *data); } SYS_REBOOT = 55 // { int sys_reboot(int opt); } SYS_REVOKE = 56 // { int sys_revoke(const char *path); } - SYS_SYMLINK = 57 // { int sys_symlink(const char *path, \ - SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, \ - SYS_EXECVE = 59 // { int sys_execve(const char *path, \ + SYS_SYMLINK = 57 // { int sys_symlink(const char *path, const char *link); } + SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int sys_execve(const char *path, char * const *argp, char * const *envp); } SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); } SYS_CHROOT = 61 // { int sys_chroot(const char *path); } - SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, \ - SYS_STATFS = 63 // { int sys_statfs(const char *path, \ + SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); } + SYS_STATFS = 63 // { int sys_statfs(const char *path, struct statfs *buf); } SYS_FSTATFS = 64 // { int sys_fstatfs(int fd, struct statfs *buf); } - SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, \ + SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); } SYS_VFORK = 66 // { int sys_vfork(void); } - SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, \ - SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, \ - SYS_SETITIMER = 69 // { int sys_setitimer(int which, \ - SYS_GETITIMER = 70 // { int sys_getitimer(int which, \ - SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, \ - SYS_KEVENT = 72 // { int sys_kevent(int fd, \ + SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); } + SYS_SETITIMER = 69 // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); } + SYS_GETITIMER = 70 // { int sys_getitimer(int which, struct itimerval *itv); } + SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_KEVENT = 72 // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } SYS_MUNMAP = 73 // { int sys_munmap(void *addr, size_t len); } - SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, \ - SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, \ - SYS_UTIMES = 76 // { int sys_utimes(const char *path, \ - SYS_FUTIMES = 77 // { int sys_futimes(int fd, \ - SYS_MINCORE = 78 // { int sys_mincore(void *addr, size_t len, \ - SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, \ - SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, \ + SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, int behav); } + SYS_UTIMES = 76 // { int sys_utimes(const char *path, const struct timeval *tptr); } + SYS_FUTIMES = 77 // { int sys_futimes(int fd, const struct timeval *tptr); } + SYS_MINCORE = 78 // { int sys_mincore(void *addr, size_t len, char *vec); } + SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, const gid_t *gidset); } SYS_GETPGRP = 81 // { int sys_getpgrp(void); } SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); } - SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, \ - SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, \ - SYS_FUTIMENS = 85 // { int sys_futimens(int fd, \ - SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, \ - SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, \ - SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, \ - SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, \ + SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); } + SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); } + SYS_FUTIMENS = 85 // { int sys_futimens(int fd, const struct timespec *times); } + SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); } + SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); } SYS_DUP2 = 90 // { int sys_dup2(int from, int to); } - SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, \ + SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); } - SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, \ - SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, \ + SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); } + SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); } SYS_FSYNC = 95 // { int sys_fsync(int fd); } SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); } SYS_SOCKET = 97 // { int sys_socket(int domain, int type, int protocol); } - SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, \ + SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); } SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); } SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); } SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); } SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); } SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); } - SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, \ - SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, \ + SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); } SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); } - SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, \ - SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, \ - SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, \ - SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, \ + SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); } + SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, const char *execpromises); } + SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); } + SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); } SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); } - SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, \ - SYS_UNVEIL = 114 // { int sys_unveil(const char *path, \ - SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, \ + SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); } + SYS_UNVEIL = 114 // { int sys_unveil(const char *path, const char *permissions); } + SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); } SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); } - SYS_READV = 120 // { ssize_t sys_readv(int fd, \ - SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, \ + SYS_READV = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); } + SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); } SYS_KILL = 122 // { int sys_kill(int pid, int signum); } SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); } SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); } @@ -129,90 +129,90 @@ const ( SYS_RENAME = 128 // { int sys_rename(const char *from, const char *to); } SYS_FLOCK = 131 // { int sys_flock(int fd, int how); } SYS_MKFIFO = 132 // { int sys_mkfifo(const char *path, mode_t mode); } - SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, \ + SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); } SYS_SHUTDOWN = 134 // { int sys_shutdown(int s, int how); } - SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, \ + SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); } SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); } SYS_RMDIR = 137 // { int sys_rmdir(const char *path); } - SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, \ + SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); } SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); } SYS_SETSID = 147 // { int sys_setsid(void); } - SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, \ + SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); } SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); } SYS_GETFH = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); } SYS_SYSARCH = 165 // { int sys_sysarch(int op, void *parms); } - SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, \ - SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, \ + SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } SYS_SETGID = 181 // { int sys_setgid(gid_t gid); } SYS_SETEGID = 182 // { int sys_setegid(gid_t egid); } SYS_SETEUID = 183 // { int sys_seteuid(uid_t euid); } SYS_PATHCONF = 191 // { long sys_pathconf(const char *path, int name); } SYS_FPATHCONF = 192 // { long sys_fpathconf(int fd, int name); } SYS_SWAPCTL = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); } - SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, \ - SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, \ - SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, \ - SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, \ - SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, \ + SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); } + SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); } + SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); } + SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, off_t length); } SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); } - SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, \ + SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); } SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); } SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); } - SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, \ + SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); } SYS_SEMGET = 221 // { int sys_semget(key_t key, int nsems, int semflg); } SYS_MSGGET = 225 // { int sys_msgget(key_t key, int msgflg); } - SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, \ - SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, \ - SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, \ + SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); } SYS_SHMDT = 230 // { int sys_shmdt(const void *shmaddr); } - SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, \ - SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, \ + SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, int inherit); } + SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); } SYS_ISSETUGID = 253 // { int sys_issetugid(void); } SYS_LCHOWN = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); } SYS_GETSID = 255 // { pid_t sys_getsid(pid_t pid); } SYS_MSYNC = 256 // { int sys_msync(void *addr, size_t len, int flags); } SYS_PIPE = 263 // { int sys_pipe(int *fdp); } SYS_FHOPEN = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); } - SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, \ - SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, \ + SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } SYS_KQUEUE = 269 // { int sys_kqueue(void); } SYS_MLOCKALL = 271 // { int sys_mlockall(int flags); } SYS_MUNLOCKALL = 272 // { int sys_munlockall(void); } - SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, \ - SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, \ - SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, \ - SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, \ - SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, \ + SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } + SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); } + SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } SYS_CLOSEFROM = 287 // { int sys_closefrom(int fd); } - SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, \ + SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); } SYS_SHMGET = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); } - SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, \ - SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, \ - SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, \ - SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, \ - SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, \ + SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); } + SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); } + SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); } + SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); } SYS_SCHED_YIELD = 298 // { int sys_sched_yield(void); } SYS_GETTHRID = 299 // { pid_t sys_getthrid(void); } - SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, \ + SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, int n); } SYS___THREXIT = 302 // { void sys___threxit(pid_t *notdead); } - SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, \ + SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); } SYS___GETCWD = 304 // { int sys___getcwd(char *buf, size_t len); } - SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, \ + SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); } SYS_SETRTABLE = 310 // { int sys_setrtable(int rtableid); } SYS_GETRTABLE = 311 // { int sys_getrtable(void); } - SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, \ - SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, \ - SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, \ - SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, \ - SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, \ - SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, \ - SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, \ - SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, \ - SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, \ - SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, \ - SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, \ - SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, \ + SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); } + SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); } + SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); } + SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); } + SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); } + SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); } + SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); } + SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); } + SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); } + SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, int flag); } SYS___SET_TCB = 329 // { void sys___set_tcb(void *tcb); } SYS___GET_TCB = 330 // { void *sys___get_tcb(void); } ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go index bc7fa57956a9..f0dec6f0b43c 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go @@ -1,4 +1,4 @@ -// mksysnum_openbsd.pl +// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master // Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,openbsd @@ -9,35 +9,35 @@ const ( SYS_EXIT = 1 // { void sys_exit(int rval); } SYS_FORK = 2 // { int sys_fork(void); } SYS_READ = 3 // { ssize_t sys_read(int fd, void *buf, size_t nbyte); } - SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, \ - SYS_OPEN = 5 // { int sys_open(const char *path, \ + SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int sys_open(const char *path, int flags, ... mode_t mode); } SYS_CLOSE = 6 // { int sys_close(int fd); } SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); } - SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, \ + SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, size_t psize); } SYS_LINK = 9 // { int sys_link(const char *path, const char *link); } SYS_UNLINK = 10 // { int sys_unlink(const char *path); } - SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, \ + SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); } SYS_CHDIR = 12 // { int sys_chdir(const char *path); } SYS_FCHDIR = 13 // { int sys_fchdir(int fd); } - SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, \ + SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, dev_t dev); } SYS_CHMOD = 15 // { int sys_chmod(const char *path, mode_t mode); } - SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, \ + SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, gid_t gid); } SYS_OBREAK = 17 // { int sys_obreak(char *nsize); } break SYS_GETDTABLECOUNT = 18 // { int sys_getdtablecount(void); } - SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, \ + SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, struct rusage *rusage); } SYS_GETPID = 20 // { pid_t sys_getpid(void); } - SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, \ + SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, int flags, void *data); } SYS_UNMOUNT = 22 // { int sys_unmount(const char *path, int flags); } SYS_SETUID = 23 // { int sys_setuid(uid_t uid); } SYS_GETUID = 24 // { uid_t sys_getuid(void); } SYS_GETEUID = 25 // { uid_t sys_geteuid(void); } - SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, \ - SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, \ - SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, \ - SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, \ - SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, \ - SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, \ - SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, \ + SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); } + SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); } + SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); } SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); } SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); } SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); } @@ -46,81 +46,81 @@ const ( SYS_GETPPID = 39 // { pid_t sys_getppid(void); } SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); } SYS_DUP = 41 // { int sys_dup(int fd); } - SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, \ + SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); } SYS_GETEGID = 43 // { gid_t sys_getegid(void); } - SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, \ - SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, \ - SYS_SIGACTION = 46 // { int sys_sigaction(int signum, \ + SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); } + SYS_SIGACTION = 46 // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); } SYS_GETGID = 47 // { gid_t sys_getgid(void); } SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); } SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); } SYS_ACCT = 51 // { int sys_acct(const char *path); } SYS_SIGPENDING = 52 // { int sys_sigpending(void); } SYS_FSTAT = 53 // { int sys_fstat(int fd, struct stat *sb); } - SYS_IOCTL = 54 // { int sys_ioctl(int fd, \ + SYS_IOCTL = 54 // { int sys_ioctl(int fd, u_long com, ... void *data); } SYS_REBOOT = 55 // { int sys_reboot(int opt); } SYS_REVOKE = 56 // { int sys_revoke(const char *path); } - SYS_SYMLINK = 57 // { int sys_symlink(const char *path, \ - SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, \ - SYS_EXECVE = 59 // { int sys_execve(const char *path, \ + SYS_SYMLINK = 57 // { int sys_symlink(const char *path, const char *link); } + SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int sys_execve(const char *path, char * const *argp, char * const *envp); } SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); } SYS_CHROOT = 61 // { int sys_chroot(const char *path); } - SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, \ - SYS_STATFS = 63 // { int sys_statfs(const char *path, \ + SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); } + SYS_STATFS = 63 // { int sys_statfs(const char *path, struct statfs *buf); } SYS_FSTATFS = 64 // { int sys_fstatfs(int fd, struct statfs *buf); } - SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, \ + SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); } SYS_VFORK = 66 // { int sys_vfork(void); } - SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, \ - SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, \ - SYS_SETITIMER = 69 // { int sys_setitimer(int which, \ - SYS_GETITIMER = 70 // { int sys_getitimer(int which, \ - SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, \ - SYS_KEVENT = 72 // { int sys_kevent(int fd, \ + SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); } + SYS_SETITIMER = 69 // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); } + SYS_GETITIMER = 70 // { int sys_getitimer(int which, struct itimerval *itv); } + SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_KEVENT = 72 // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } SYS_MUNMAP = 73 // { int sys_munmap(void *addr, size_t len); } - SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, \ - SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, \ - SYS_UTIMES = 76 // { int sys_utimes(const char *path, \ - SYS_FUTIMES = 77 // { int sys_futimes(int fd, \ - SYS_MINCORE = 78 // { int sys_mincore(void *addr, size_t len, \ - SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, \ - SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, \ + SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, int behav); } + SYS_UTIMES = 76 // { int sys_utimes(const char *path, const struct timeval *tptr); } + SYS_FUTIMES = 77 // { int sys_futimes(int fd, const struct timeval *tptr); } + SYS_MINCORE = 78 // { int sys_mincore(void *addr, size_t len, char *vec); } + SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, const gid_t *gidset); } SYS_GETPGRP = 81 // { int sys_getpgrp(void); } SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); } - SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, \ - SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, \ - SYS_FUTIMENS = 85 // { int sys_futimens(int fd, \ - SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, \ - SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, \ - SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, \ - SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, \ + SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); } + SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); } + SYS_FUTIMENS = 85 // { int sys_futimens(int fd, const struct timespec *times); } + SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); } + SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); } SYS_DUP2 = 90 // { int sys_dup2(int from, int to); } - SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, \ + SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); } - SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, \ - SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, \ + SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); } + SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); } SYS_FSYNC = 95 // { int sys_fsync(int fd); } SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); } SYS_SOCKET = 97 // { int sys_socket(int domain, int type, int protocol); } - SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, \ + SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); } SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); } SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); } SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); } SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); } SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); } - SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, \ - SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, \ + SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); } SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); } - SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, \ - SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, \ - SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, \ - SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, \ + SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); } + SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, const char *execpromises); } + SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); } + SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); } SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); } - SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, \ - SYS_UNVEIL = 114 // { int sys_unveil(const char *path, \ - SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, \ + SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); } + SYS_UNVEIL = 114 // { int sys_unveil(const char *path, const char *permissions); } + SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); } SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); } - SYS_READV = 120 // { ssize_t sys_readv(int fd, \ - SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, \ + SYS_READV = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); } + SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); } SYS_KILL = 122 // { int sys_kill(int pid, int signum); } SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); } SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); } @@ -129,90 +129,90 @@ const ( SYS_RENAME = 128 // { int sys_rename(const char *from, const char *to); } SYS_FLOCK = 131 // { int sys_flock(int fd, int how); } SYS_MKFIFO = 132 // { int sys_mkfifo(const char *path, mode_t mode); } - SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, \ + SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); } SYS_SHUTDOWN = 134 // { int sys_shutdown(int s, int how); } - SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, \ + SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); } SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); } SYS_RMDIR = 137 // { int sys_rmdir(const char *path); } - SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, \ + SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); } SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); } SYS_SETSID = 147 // { int sys_setsid(void); } - SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, \ + SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); } SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); } SYS_GETFH = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); } SYS_SYSARCH = 165 // { int sys_sysarch(int op, void *parms); } - SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, \ - SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, \ + SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } SYS_SETGID = 181 // { int sys_setgid(gid_t gid); } SYS_SETEGID = 182 // { int sys_setegid(gid_t egid); } SYS_SETEUID = 183 // { int sys_seteuid(uid_t euid); } SYS_PATHCONF = 191 // { long sys_pathconf(const char *path, int name); } SYS_FPATHCONF = 192 // { long sys_fpathconf(int fd, int name); } SYS_SWAPCTL = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); } - SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, \ - SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, \ - SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, \ - SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, \ - SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, \ + SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); } + SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); } + SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); } + SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, off_t length); } SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); } - SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, \ + SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); } SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); } SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); } - SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, \ + SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); } SYS_SEMGET = 221 // { int sys_semget(key_t key, int nsems, int semflg); } SYS_MSGGET = 225 // { int sys_msgget(key_t key, int msgflg); } - SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, \ - SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, \ - SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, \ + SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); } SYS_SHMDT = 230 // { int sys_shmdt(const void *shmaddr); } - SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, \ - SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, \ + SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, int inherit); } + SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); } SYS_ISSETUGID = 253 // { int sys_issetugid(void); } SYS_LCHOWN = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); } SYS_GETSID = 255 // { pid_t sys_getsid(pid_t pid); } SYS_MSYNC = 256 // { int sys_msync(void *addr, size_t len, int flags); } SYS_PIPE = 263 // { int sys_pipe(int *fdp); } SYS_FHOPEN = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); } - SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, \ - SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, \ + SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } SYS_KQUEUE = 269 // { int sys_kqueue(void); } SYS_MLOCKALL = 271 // { int sys_mlockall(int flags); } SYS_MUNLOCKALL = 272 // { int sys_munlockall(void); } - SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, \ - SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, \ - SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, \ - SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, \ - SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, \ + SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } + SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); } + SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } SYS_CLOSEFROM = 287 // { int sys_closefrom(int fd); } - SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, \ + SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); } SYS_SHMGET = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); } - SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, \ - SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, \ - SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, \ - SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, \ - SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, \ + SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); } + SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); } + SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); } + SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); } SYS_SCHED_YIELD = 298 // { int sys_sched_yield(void); } SYS_GETTHRID = 299 // { pid_t sys_getthrid(void); } - SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, \ + SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, int n); } SYS___THREXIT = 302 // { void sys___threxit(pid_t *notdead); } - SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, \ + SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); } SYS___GETCWD = 304 // { int sys___getcwd(char *buf, size_t len); } - SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, \ + SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); } SYS_SETRTABLE = 310 // { int sys_setrtable(int rtableid); } SYS_GETRTABLE = 311 // { int sys_getrtable(void); } - SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, \ - SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, \ - SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, \ - SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, \ - SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, \ - SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, \ - SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, \ - SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, \ - SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, \ - SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, \ - SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, \ - SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, \ + SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); } + SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); } + SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); } + SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); } + SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); } + SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); } + SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); } + SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); } + SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); } + SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, int flag); } SYS___SET_TCB = 329 // { void sys___set_tcb(void *tcb); } SYS___GET_TCB = 330 // { void *sys___get_tcb(void); } ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go index be1198d91633..33d1dc5404e4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go @@ -1,4 +1,4 @@ -// mksysnum_openbsd.pl +// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master // Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,openbsd @@ -9,35 +9,35 @@ const ( SYS_EXIT = 1 // { void sys_exit(int rval); } SYS_FORK = 2 // { int sys_fork(void); } SYS_READ = 3 // { ssize_t sys_read(int fd, void *buf, size_t nbyte); } - SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, \ - SYS_OPEN = 5 // { int sys_open(const char *path, \ + SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int sys_open(const char *path, int flags, ... mode_t mode); } SYS_CLOSE = 6 // { int sys_close(int fd); } SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); } - SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, \ + SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, size_t psize); } SYS_LINK = 9 // { int sys_link(const char *path, const char *link); } SYS_UNLINK = 10 // { int sys_unlink(const char *path); } - SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, \ + SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); } SYS_CHDIR = 12 // { int sys_chdir(const char *path); } SYS_FCHDIR = 13 // { int sys_fchdir(int fd); } - SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, \ + SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, dev_t dev); } SYS_CHMOD = 15 // { int sys_chmod(const char *path, mode_t mode); } - SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, \ + SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, gid_t gid); } SYS_OBREAK = 17 // { int sys_obreak(char *nsize); } break SYS_GETDTABLECOUNT = 18 // { int sys_getdtablecount(void); } - SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, \ + SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, struct rusage *rusage); } SYS_GETPID = 20 // { pid_t sys_getpid(void); } - SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, \ + SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, int flags, void *data); } SYS_UNMOUNT = 22 // { int sys_unmount(const char *path, int flags); } SYS_SETUID = 23 // { int sys_setuid(uid_t uid); } SYS_GETUID = 24 // { uid_t sys_getuid(void); } SYS_GETEUID = 25 // { uid_t sys_geteuid(void); } - SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, \ - SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, \ - SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, \ - SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, \ - SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, \ - SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, \ - SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, \ + SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); } + SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); } + SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); } SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); } SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); } SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); } @@ -46,81 +46,81 @@ const ( SYS_GETPPID = 39 // { pid_t sys_getppid(void); } SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); } SYS_DUP = 41 // { int sys_dup(int fd); } - SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, \ + SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); } SYS_GETEGID = 43 // { gid_t sys_getegid(void); } - SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, \ - SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, \ - SYS_SIGACTION = 46 // { int sys_sigaction(int signum, \ + SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); } + SYS_SIGACTION = 46 // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); } SYS_GETGID = 47 // { gid_t sys_getgid(void); } SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); } SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); } SYS_ACCT = 51 // { int sys_acct(const char *path); } SYS_SIGPENDING = 52 // { int sys_sigpending(void); } SYS_FSTAT = 53 // { int sys_fstat(int fd, struct stat *sb); } - SYS_IOCTL = 54 // { int sys_ioctl(int fd, \ + SYS_IOCTL = 54 // { int sys_ioctl(int fd, u_long com, ... void *data); } SYS_REBOOT = 55 // { int sys_reboot(int opt); } SYS_REVOKE = 56 // { int sys_revoke(const char *path); } - SYS_SYMLINK = 57 // { int sys_symlink(const char *path, \ - SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, \ - SYS_EXECVE = 59 // { int sys_execve(const char *path, \ + SYS_SYMLINK = 57 // { int sys_symlink(const char *path, const char *link); } + SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int sys_execve(const char *path, char * const *argp, char * const *envp); } SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); } SYS_CHROOT = 61 // { int sys_chroot(const char *path); } - SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, \ - SYS_STATFS = 63 // { int sys_statfs(const char *path, \ + SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); } + SYS_STATFS = 63 // { int sys_statfs(const char *path, struct statfs *buf); } SYS_FSTATFS = 64 // { int sys_fstatfs(int fd, struct statfs *buf); } - SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, \ + SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); } SYS_VFORK = 66 // { int sys_vfork(void); } - SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, \ - SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, \ - SYS_SETITIMER = 69 // { int sys_setitimer(int which, \ - SYS_GETITIMER = 70 // { int sys_getitimer(int which, \ - SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, \ - SYS_KEVENT = 72 // { int sys_kevent(int fd, \ + SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); } + SYS_SETITIMER = 69 // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); } + SYS_GETITIMER = 70 // { int sys_getitimer(int which, struct itimerval *itv); } + SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_KEVENT = 72 // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } SYS_MUNMAP = 73 // { int sys_munmap(void *addr, size_t len); } - SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, \ - SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, \ - SYS_UTIMES = 76 // { int sys_utimes(const char *path, \ - SYS_FUTIMES = 77 // { int sys_futimes(int fd, \ - SYS_MINCORE = 78 // { int sys_mincore(void *addr, size_t len, \ - SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, \ - SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, \ + SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, int behav); } + SYS_UTIMES = 76 // { int sys_utimes(const char *path, const struct timeval *tptr); } + SYS_FUTIMES = 77 // { int sys_futimes(int fd, const struct timeval *tptr); } + SYS_MINCORE = 78 // { int sys_mincore(void *addr, size_t len, char *vec); } + SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, const gid_t *gidset); } SYS_GETPGRP = 81 // { int sys_getpgrp(void); } SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); } - SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, \ - SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, \ - SYS_FUTIMENS = 85 // { int sys_futimens(int fd, \ - SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, \ - SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, \ - SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, \ - SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, \ + SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); } + SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); } + SYS_FUTIMENS = 85 // { int sys_futimens(int fd, const struct timespec *times); } + SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); } + SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); } SYS_DUP2 = 90 // { int sys_dup2(int from, int to); } - SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, \ + SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); } - SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, \ - SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, \ + SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); } + SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); } SYS_FSYNC = 95 // { int sys_fsync(int fd); } SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); } SYS_SOCKET = 97 // { int sys_socket(int domain, int type, int protocol); } - SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, \ + SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); } SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); } SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); } SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); } SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); } SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); } - SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, \ - SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, \ + SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); } SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); } - SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, \ - SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, \ - SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, \ - SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, \ + SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); } + SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, const char *execpromises); } + SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); } + SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); } SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); } - SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, \ - SYS_UNVEIL = 114 // { int sys_unveil(const char *path, \ - SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, \ + SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); } + SYS_UNVEIL = 114 // { int sys_unveil(const char *path, const char *permissions); } + SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); } SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); } - SYS_READV = 120 // { ssize_t sys_readv(int fd, \ - SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, \ + SYS_READV = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); } + SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); } SYS_KILL = 122 // { int sys_kill(int pid, int signum); } SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); } SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); } @@ -129,90 +129,90 @@ const ( SYS_RENAME = 128 // { int sys_rename(const char *from, const char *to); } SYS_FLOCK = 131 // { int sys_flock(int fd, int how); } SYS_MKFIFO = 132 // { int sys_mkfifo(const char *path, mode_t mode); } - SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, \ + SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); } SYS_SHUTDOWN = 134 // { int sys_shutdown(int s, int how); } - SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, \ + SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); } SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); } SYS_RMDIR = 137 // { int sys_rmdir(const char *path); } - SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, \ + SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); } SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); } SYS_SETSID = 147 // { int sys_setsid(void); } - SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, \ + SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); } SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); } SYS_GETFH = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); } SYS_SYSARCH = 165 // { int sys_sysarch(int op, void *parms); } - SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, \ - SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, \ + SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } SYS_SETGID = 181 // { int sys_setgid(gid_t gid); } SYS_SETEGID = 182 // { int sys_setegid(gid_t egid); } SYS_SETEUID = 183 // { int sys_seteuid(uid_t euid); } SYS_PATHCONF = 191 // { long sys_pathconf(const char *path, int name); } SYS_FPATHCONF = 192 // { long sys_fpathconf(int fd, int name); } SYS_SWAPCTL = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); } - SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, \ - SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, \ - SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, \ - SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, \ - SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, \ + SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); } + SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); } + SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); } + SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, off_t length); } SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); } - SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, \ + SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); } SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); } SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); } - SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, \ + SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); } SYS_SEMGET = 221 // { int sys_semget(key_t key, int nsems, int semflg); } SYS_MSGGET = 225 // { int sys_msgget(key_t key, int msgflg); } - SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, \ - SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, \ - SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, \ + SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); } SYS_SHMDT = 230 // { int sys_shmdt(const void *shmaddr); } - SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, \ - SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, \ + SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, int inherit); } + SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); } SYS_ISSETUGID = 253 // { int sys_issetugid(void); } SYS_LCHOWN = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); } SYS_GETSID = 255 // { pid_t sys_getsid(pid_t pid); } SYS_MSYNC = 256 // { int sys_msync(void *addr, size_t len, int flags); } SYS_PIPE = 263 // { int sys_pipe(int *fdp); } SYS_FHOPEN = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); } - SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, \ - SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, \ + SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } SYS_KQUEUE = 269 // { int sys_kqueue(void); } SYS_MLOCKALL = 271 // { int sys_mlockall(int flags); } SYS_MUNLOCKALL = 272 // { int sys_munlockall(void); } - SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, \ - SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, \ - SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, \ - SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, \ - SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, \ + SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } + SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); } + SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } SYS_CLOSEFROM = 287 // { int sys_closefrom(int fd); } - SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, \ + SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); } SYS_SHMGET = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); } - SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, \ - SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, \ - SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, \ - SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, \ - SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, \ + SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); } + SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); } + SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); } + SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); } SYS_SCHED_YIELD = 298 // { int sys_sched_yield(void); } SYS_GETTHRID = 299 // { pid_t sys_getthrid(void); } - SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, \ + SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, int n); } SYS___THREXIT = 302 // { void sys___threxit(pid_t *notdead); } - SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, \ + SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); } SYS___GETCWD = 304 // { int sys___getcwd(char *buf, size_t len); } - SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, \ + SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); } SYS_SETRTABLE = 310 // { int sys_setrtable(int rtableid); } SYS_GETRTABLE = 311 // { int sys_getrtable(void); } - SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, \ - SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, \ - SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, \ - SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, \ - SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, \ - SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, \ - SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, \ - SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, \ - SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, \ - SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, \ - SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, \ - SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, \ + SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); } + SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); } + SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); } + SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); } + SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); } + SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); } + SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); } + SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); } + SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); } + SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, int flag); } SYS___SET_TCB = 329 // { void sys___set_tcb(void *tcb); } SYS___GET_TCB = 330 // { void *sys___get_tcb(void); } ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go new file mode 100644 index 000000000000..fe2b689b6375 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go @@ -0,0 +1,217 @@ +// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build arm64,openbsd + +package unix + +const ( + SYS_EXIT = 1 // { void sys_exit(int rval); } + SYS_FORK = 2 // { int sys_fork(void); } + SYS_READ = 3 // { ssize_t sys_read(int fd, void *buf, size_t nbyte); } + SYS_WRITE = 4 // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); } + SYS_OPEN = 5 // { int sys_open(const char *path, int flags, ... mode_t mode); } + SYS_CLOSE = 6 // { int sys_close(int fd); } + SYS_GETENTROPY = 7 // { int sys_getentropy(void *buf, size_t nbyte); } + SYS___TFORK = 8 // { int sys___tfork(const struct __tfork *param, size_t psize); } + SYS_LINK = 9 // { int sys_link(const char *path, const char *link); } + SYS_UNLINK = 10 // { int sys_unlink(const char *path); } + SYS_WAIT4 = 11 // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); } + SYS_CHDIR = 12 // { int sys_chdir(const char *path); } + SYS_FCHDIR = 13 // { int sys_fchdir(int fd); } + SYS_MKNOD = 14 // { int sys_mknod(const char *path, mode_t mode, dev_t dev); } + SYS_CHMOD = 15 // { int sys_chmod(const char *path, mode_t mode); } + SYS_CHOWN = 16 // { int sys_chown(const char *path, uid_t uid, gid_t gid); } + SYS_OBREAK = 17 // { int sys_obreak(char *nsize); } break + SYS_GETDTABLECOUNT = 18 // { int sys_getdtablecount(void); } + SYS_GETRUSAGE = 19 // { int sys_getrusage(int who, struct rusage *rusage); } + SYS_GETPID = 20 // { pid_t sys_getpid(void); } + SYS_MOUNT = 21 // { int sys_mount(const char *type, const char *path, int flags, void *data); } + SYS_UNMOUNT = 22 // { int sys_unmount(const char *path, int flags); } + SYS_SETUID = 23 // { int sys_setuid(uid_t uid); } + SYS_GETUID = 24 // { uid_t sys_getuid(void); } + SYS_GETEUID = 25 // { uid_t sys_geteuid(void); } + SYS_PTRACE = 26 // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); } + SYS_RECVMSG = 27 // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); } + SYS_SENDMSG = 28 // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); } + SYS_RECVFROM = 29 // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); } + SYS_ACCEPT = 30 // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); } + SYS_GETPEERNAME = 31 // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_GETSOCKNAME = 32 // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); } + SYS_ACCESS = 33 // { int sys_access(const char *path, int amode); } + SYS_CHFLAGS = 34 // { int sys_chflags(const char *path, u_int flags); } + SYS_FCHFLAGS = 35 // { int sys_fchflags(int fd, u_int flags); } + SYS_SYNC = 36 // { void sys_sync(void); } + SYS_STAT = 38 // { int sys_stat(const char *path, struct stat *ub); } + SYS_GETPPID = 39 // { pid_t sys_getppid(void); } + SYS_LSTAT = 40 // { int sys_lstat(const char *path, struct stat *ub); } + SYS_DUP = 41 // { int sys_dup(int fd); } + SYS_FSTATAT = 42 // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); } + SYS_GETEGID = 43 // { gid_t sys_getegid(void); } + SYS_PROFIL = 44 // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); } + SYS_KTRACE = 45 // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); } + SYS_SIGACTION = 46 // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); } + SYS_GETGID = 47 // { gid_t sys_getgid(void); } + SYS_SIGPROCMASK = 48 // { int sys_sigprocmask(int how, sigset_t mask); } + SYS_SETLOGIN = 50 // { int sys_setlogin(const char *namebuf); } + SYS_ACCT = 51 // { int sys_acct(const char *path); } + SYS_SIGPENDING = 52 // { int sys_sigpending(void); } + SYS_FSTAT = 53 // { int sys_fstat(int fd, struct stat *sb); } + SYS_IOCTL = 54 // { int sys_ioctl(int fd, u_long com, ... void *data); } + SYS_REBOOT = 55 // { int sys_reboot(int opt); } + SYS_REVOKE = 56 // { int sys_revoke(const char *path); } + SYS_SYMLINK = 57 // { int sys_symlink(const char *path, const char *link); } + SYS_READLINK = 58 // { ssize_t sys_readlink(const char *path, char *buf, size_t count); } + SYS_EXECVE = 59 // { int sys_execve(const char *path, char * const *argp, char * const *envp); } + SYS_UMASK = 60 // { mode_t sys_umask(mode_t newmask); } + SYS_CHROOT = 61 // { int sys_chroot(const char *path); } + SYS_GETFSSTAT = 62 // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); } + SYS_STATFS = 63 // { int sys_statfs(const char *path, struct statfs *buf); } + SYS_FSTATFS = 64 // { int sys_fstatfs(int fd, struct statfs *buf); } + SYS_FHSTATFS = 65 // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); } + SYS_VFORK = 66 // { int sys_vfork(void); } + SYS_GETTIMEOFDAY = 67 // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); } + SYS_SETTIMEOFDAY = 68 // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); } + SYS_SETITIMER = 69 // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); } + SYS_GETITIMER = 70 // { int sys_getitimer(int which, struct itimerval *itv); } + SYS_SELECT = 71 // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); } + SYS_KEVENT = 72 // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } + SYS_MUNMAP = 73 // { int sys_munmap(void *addr, size_t len); } + SYS_MPROTECT = 74 // { int sys_mprotect(void *addr, size_t len, int prot); } + SYS_MADVISE = 75 // { int sys_madvise(void *addr, size_t len, int behav); } + SYS_UTIMES = 76 // { int sys_utimes(const char *path, const struct timeval *tptr); } + SYS_FUTIMES = 77 // { int sys_futimes(int fd, const struct timeval *tptr); } + SYS_GETGROUPS = 79 // { int sys_getgroups(int gidsetsize, gid_t *gidset); } + SYS_SETGROUPS = 80 // { int sys_setgroups(int gidsetsize, const gid_t *gidset); } + SYS_GETPGRP = 81 // { int sys_getpgrp(void); } + SYS_SETPGID = 82 // { int sys_setpgid(pid_t pid, pid_t pgid); } + SYS_FUTEX = 83 // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); } + SYS_UTIMENSAT = 84 // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); } + SYS_FUTIMENS = 85 // { int sys_futimens(int fd, const struct timespec *times); } + SYS_KBIND = 86 // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); } + SYS_CLOCK_GETTIME = 87 // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); } + SYS_CLOCK_SETTIME = 88 // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); } + SYS_CLOCK_GETRES = 89 // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); } + SYS_DUP2 = 90 // { int sys_dup2(int from, int to); } + SYS_NANOSLEEP = 91 // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); } + SYS_FCNTL = 92 // { int sys_fcntl(int fd, int cmd, ... void *arg); } + SYS_ACCEPT4 = 93 // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); } + SYS___THRSLEEP = 94 // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); } + SYS_FSYNC = 95 // { int sys_fsync(int fd); } + SYS_SETPRIORITY = 96 // { int sys_setpriority(int which, id_t who, int prio); } + SYS_SOCKET = 97 // { int sys_socket(int domain, int type, int protocol); } + SYS_CONNECT = 98 // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_GETDENTS = 99 // { int sys_getdents(int fd, void *buf, size_t buflen); } + SYS_GETPRIORITY = 100 // { int sys_getpriority(int which, id_t who); } + SYS_PIPE2 = 101 // { int sys_pipe2(int *fdp, int flags); } + SYS_DUP3 = 102 // { int sys_dup3(int from, int to, int flags); } + SYS_SIGRETURN = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); } + SYS_BIND = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); } + SYS_SETSOCKOPT = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); } + SYS_LISTEN = 106 // { int sys_listen(int s, int backlog); } + SYS_CHFLAGSAT = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); } + SYS_PLEDGE = 108 // { int sys_pledge(const char *promises, const char *execpromises); } + SYS_PPOLL = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); } + SYS_PSELECT = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); } + SYS_SIGSUSPEND = 111 // { int sys_sigsuspend(int mask); } + SYS_SENDSYSLOG = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); } + SYS_UNVEIL = 114 // { int sys_unveil(const char *path, const char *permissions); } + SYS_GETSOCKOPT = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); } + SYS_THRKILL = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); } + SYS_READV = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); } + SYS_WRITEV = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); } + SYS_KILL = 122 // { int sys_kill(int pid, int signum); } + SYS_FCHOWN = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); } + SYS_FCHMOD = 124 // { int sys_fchmod(int fd, mode_t mode); } + SYS_SETREUID = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); } + SYS_SETREGID = 127 // { int sys_setregid(gid_t rgid, gid_t egid); } + SYS_RENAME = 128 // { int sys_rename(const char *from, const char *to); } + SYS_FLOCK = 131 // { int sys_flock(int fd, int how); } + SYS_MKFIFO = 132 // { int sys_mkfifo(const char *path, mode_t mode); } + SYS_SENDTO = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); } + SYS_SHUTDOWN = 134 // { int sys_shutdown(int s, int how); } + SYS_SOCKETPAIR = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); } + SYS_MKDIR = 136 // { int sys_mkdir(const char *path, mode_t mode); } + SYS_RMDIR = 137 // { int sys_rmdir(const char *path); } + SYS_ADJTIME = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); } + SYS_GETLOGIN_R = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); } + SYS_SETSID = 147 // { int sys_setsid(void); } + SYS_QUOTACTL = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); } + SYS_NFSSVC = 155 // { int sys_nfssvc(int flag, void *argp); } + SYS_GETFH = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); } + SYS_SYSARCH = 165 // { int sys_sysarch(int op, void *parms); } + SYS_PREAD = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); } + SYS_PWRITE = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); } + SYS_SETGID = 181 // { int sys_setgid(gid_t gid); } + SYS_SETEGID = 182 // { int sys_setegid(gid_t egid); } + SYS_SETEUID = 183 // { int sys_seteuid(uid_t euid); } + SYS_PATHCONF = 191 // { long sys_pathconf(const char *path, int name); } + SYS_FPATHCONF = 192 // { long sys_fpathconf(int fd, int name); } + SYS_SWAPCTL = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); } + SYS_GETRLIMIT = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); } + SYS_SETRLIMIT = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); } + SYS_MMAP = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_LSEEK = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); } + SYS_TRUNCATE = 200 // { int sys_truncate(const char *path, int pad, off_t length); } + SYS_FTRUNCATE = 201 // { int sys_ftruncate(int fd, int pad, off_t length); } + SYS_SYSCTL = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } + SYS_MLOCK = 203 // { int sys_mlock(const void *addr, size_t len); } + SYS_MUNLOCK = 204 // { int sys_munlock(const void *addr, size_t len); } + SYS_GETPGID = 207 // { pid_t sys_getpgid(pid_t pid); } + SYS_UTRACE = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); } + SYS_SEMGET = 221 // { int sys_semget(key_t key, int nsems, int semflg); } + SYS_MSGGET = 225 // { int sys_msgget(key_t key, int msgflg); } + SYS_MSGSND = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); } + SYS_MSGRCV = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); } + SYS_SHMAT = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); } + SYS_SHMDT = 230 // { int sys_shmdt(const void *shmaddr); } + SYS_MINHERIT = 250 // { int sys_minherit(void *addr, size_t len, int inherit); } + SYS_POLL = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); } + SYS_ISSETUGID = 253 // { int sys_issetugid(void); } + SYS_LCHOWN = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); } + SYS_GETSID = 255 // { pid_t sys_getsid(pid_t pid); } + SYS_MSYNC = 256 // { int sys_msync(void *addr, size_t len, int flags); } + SYS_PIPE = 263 // { int sys_pipe(int *fdp); } + SYS_FHOPEN = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); } + SYS_PREADV = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_PWRITEV = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); } + SYS_KQUEUE = 269 // { int sys_kqueue(void); } + SYS_MLOCKALL = 271 // { int sys_mlockall(int flags); } + SYS_MUNLOCKALL = 272 // { int sys_munlockall(void); } + SYS_GETRESUID = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } + SYS_SETRESUID = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); } + SYS_GETRESGID = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } + SYS_SETRESGID = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); } + SYS_MQUERY = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); } + SYS_CLOSEFROM = 287 // { int sys_closefrom(int fd); } + SYS_SIGALTSTACK = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); } + SYS_SHMGET = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); } + SYS_SEMOP = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); } + SYS_FHSTAT = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); } + SYS___SEMCTL = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); } + SYS_SHMCTL = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); } + SYS_MSGCTL = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); } + SYS_SCHED_YIELD = 298 // { int sys_sched_yield(void); } + SYS_GETTHRID = 299 // { pid_t sys_getthrid(void); } + SYS___THRWAKEUP = 301 // { int sys___thrwakeup(const volatile void *ident, int n); } + SYS___THREXIT = 302 // { void sys___threxit(pid_t *notdead); } + SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); } + SYS___GETCWD = 304 // { int sys___getcwd(char *buf, size_t len); } + SYS_ADJFREQ = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); } + SYS_SETRTABLE = 310 // { int sys_setrtable(int rtableid); } + SYS_GETRTABLE = 311 // { int sys_getrtable(void); } + SYS_FACCESSAT = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); } + SYS_FCHMODAT = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); } + SYS_FCHOWNAT = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); } + SYS_LINKAT = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); } + SYS_MKDIRAT = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); } + SYS_MKFIFOAT = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); } + SYS_MKNODAT = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); } + SYS_OPENAT = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); } + SYS_READLINKAT = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); } + SYS_RENAMEAT = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); } + SYS_SYMLINKAT = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); } + SYS_UNLINKAT = 325 // { int sys_unlinkat(int fd, const char *path, int flag); } + SYS___SET_TCB = 329 // { void sys___set_tcb(void *tcb); } + SYS___GET_TCB = 330 // { void *sys___get_tcb(void); } +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go index f46482d272e6..904359f69f31 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go @@ -103,7 +103,6 @@ type Stat_t struct { Gid uint32 Rdev uint64 Ssize int32 - _ [4]byte Atim StTimespec Mtim StTimespec Ctim StTimespec @@ -205,10 +204,8 @@ type Linger struct { type Msghdr struct { Name *byte Namelen uint32 - _ [4]byte Iov *Iovec Iovlen int32 - _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -339,7 +336,6 @@ type Statfs_t struct { Ffree uint64 Fsid Fsid64_t Vfstype int32 - _ [4]byte Fsize uint64 Vfsnumber int32 Vfsoff int32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go index 2aeb52a886de..cefe2f8eaeb1 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go @@ -487,3 +487,13 @@ type Utsname struct { Version [256]byte Machine [256]byte } + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 0d0d9f2ccb7a..c6bb883c3962 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -497,3 +497,13 @@ type Utsname struct { Version [256]byte Machine [256]byte } + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go index 04e344b78d88..94c23bc2d4ae 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go @@ -488,3 +488,13 @@ type Utsname struct { Version [256]byte Machine [256]byte } + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 9fec185c180f..c82a930cdc59 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -497,3 +497,13 @@ type Utsname struct { Version [256]byte Machine [256]byte } + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go new file mode 100644 index 000000000000..2aadc1a4d8ff --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go @@ -0,0 +1,602 @@ +// cgo -godefs types_freebsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build arm64,freebsd + +package unix + +const ( + SizeofPtr = 0x8 + SizeofShort = 0x2 + SizeofInt = 0x4 + SizeofLong = 0x8 + SizeofLongLong = 0x8 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int64 +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} + +type Rlimit struct { + Cur int64 + Max int64 +} + +type _Gid_t uint32 + +const ( + _statfsVersion = 0x20140518 + _dirblksiz = 0x400 +) + +type Stat_t struct { + Dev uint64 + Ino uint64 + Nlink uint64 + Mode uint16 + _0 int16 + Uid uint32 + Gid uint32 + _1 int32 + Rdev uint64 + Atim Timespec + Mtim Timespec + Ctim Timespec + Birthtim Timespec + Size int64 + Blocks int64 + Blksize int32 + Flags uint32 + Gen uint64 + Spare [10]uint64 +} + +type stat_freebsd11_t struct { + Dev uint32 + Ino uint32 + Mode uint16 + Nlink uint16 + Uid uint32 + Gid uint32 + Rdev uint32 + Atim Timespec + Mtim Timespec + Ctim Timespec + Size int64 + Blocks int64 + Blksize int32 + Flags uint32 + Gen uint32 + Lspare int32 + Birthtim Timespec +} + +type Statfs_t struct { + Version uint32 + Type uint32 + Flags uint64 + Bsize uint64 + Iosize uint64 + Blocks uint64 + Bfree uint64 + Bavail int64 + Files uint64 + Ffree int64 + Syncwrites uint64 + Asyncwrites uint64 + Syncreads uint64 + Asyncreads uint64 + Spare [10]uint64 + Namemax uint32 + Owner uint32 + Fsid Fsid + Charspare [80]int8 + Fstypename [16]int8 + Mntfromname [1024]int8 + Mntonname [1024]int8 +} + +type statfs_freebsd11_t struct { + Version uint32 + Type uint32 + Flags uint64 + Bsize uint64 + Iosize uint64 + Blocks uint64 + Bfree uint64 + Bavail int64 + Files uint64 + Ffree int64 + Syncwrites uint64 + Asyncwrites uint64 + Syncreads uint64 + Asyncreads uint64 + Spare [10]uint64 + Namemax uint32 + Owner uint32 + Fsid Fsid + Charspare [80]int8 + Fstypename [16]int8 + Mntfromname [88]int8 + Mntonname [88]int8 +} + +type Flock_t struct { + Start int64 + Len int64 + Pid int32 + Type int16 + Whence int16 + Sysid int32 + _ [4]byte +} + +type Dirent struct { + Fileno uint64 + Off int64 + Reclen uint16 + Type uint8 + Pad0 uint8 + Namlen uint16 + Pad1 uint16 + Name [256]int8 +} + +type dirent_freebsd11 struct { + Fileno uint32 + Reclen uint16 + Type uint8 + Namlen uint8 + Name [256]int8 +} + +type Fsid struct { + Val [2]int32 +} + +const ( + PathMax = 0x400 +) + +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + +type RawSockaddrInet4 struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type RawSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddrUnix struct { + Len uint8 + Family uint8 + Path [104]int8 +} + +type RawSockaddrDatalink struct { + Len uint8 + Family uint8 + Index uint16 + Type uint8 + Nlen uint8 + Alen uint8 + Slen uint8 + Data [46]int8 +} + +type RawSockaddr struct { + Len uint8 + Family uint8 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [92]int8 +} + +type _Socklen uint32 + +type Linger struct { + Onoff int32 + Linger int32 +} + +type Iovec struct { + Base *byte + Len uint64 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type Msghdr struct { + Name *byte + Namelen uint32 + _ [4]byte + Iov *Iovec + Iovlen int32 + _ [4]byte + Control *byte + Controllen uint32 + Flags int32 +} + +type Cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type Inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type IPv6MTUInfo struct { + Addr RawSockaddrInet6 + Mtu uint32 +} + +type ICMPv6Filter struct { + Filt [8]uint32 +} + +const ( + SizeofSockaddrInet4 = 0x10 + SizeofSockaddrInet6 = 0x1c + SizeofSockaddrAny = 0x6c + SizeofSockaddrUnix = 0x6a + SizeofSockaddrDatalink = 0x36 + SizeofLinger = 0x8 + SizeofIPMreq = 0x8 + SizeofIPMreqn = 0xc + SizeofIPv6Mreq = 0x14 + SizeofMsghdr = 0x30 + SizeofCmsghdr = 0xc + SizeofInet6Pktinfo = 0x14 + SizeofIPv6MTUInfo = 0x20 + SizeofICMPv6Filter = 0x20 +) + +const ( + PTRACE_TRACEME = 0x0 + PTRACE_CONT = 0x7 + PTRACE_KILL = 0x8 +) + +type Kevent_t struct { + Ident uint64 + Filter int16 + Flags uint16 + Fflags uint32 + Data int64 + Udata *byte +} + +type FdSet struct { + Bits [16]uint64 +} + +const ( + sizeofIfMsghdr = 0xa8 + SizeofIfMsghdr = 0xa8 + sizeofIfData = 0x98 + SizeofIfData = 0x98 + SizeofIfaMsghdr = 0x14 + SizeofIfmaMsghdr = 0x10 + SizeofIfAnnounceMsghdr = 0x18 + SizeofRtMsghdr = 0x98 + SizeofRtMetrics = 0x70 +) + +type ifMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data ifData +} + +type IfMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData +} + +type ifData struct { + Type uint8 + Physical uint8 + Addrlen uint8 + Hdrlen uint8 + Link_state uint8 + Vhid uint8 + Datalen uint16 + Mtu uint32 + Metric uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Oqdrops uint64 + Noproto uint64 + Hwassist uint64 + _ [8]byte + _ [16]byte +} + +type IfData struct { + Type uint8 + Physical uint8 + Addrlen uint8 + Hdrlen uint8 + Link_state uint8 + Spare_char1 uint8 + Spare_char2 uint8 + Datalen uint8 + Mtu uint64 + Metric uint64 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Noproto uint64 + Hwassist uint64 + Epoch int64 + Lastchange Timeval +} + +type IfaMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 +} + +type IfmaMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte +} + +type IfAnnounceMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Name [16]int8 + What uint16 +} + +type RtMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Fmask int32 + Inits uint64 + Rmx RtMetrics +} + +type RtMetrics struct { + Locks uint64 + Mtu uint64 + Hopcount uint64 + Expire uint64 + Recvpipe uint64 + Sendpipe uint64 + Ssthresh uint64 + Rtt uint64 + Rttvar uint64 + Pksent uint64 + Weight uint64 + Filler [3]uint64 +} + +const ( + SizeofBpfVersion = 0x4 + SizeofBpfStat = 0x8 + SizeofBpfZbuf = 0x18 + SizeofBpfProgram = 0x10 + SizeofBpfInsn = 0x8 + SizeofBpfHdr = 0x20 + SizeofBpfZbufHeader = 0x20 +) + +type BpfVersion struct { + Major uint16 + Minor uint16 +} + +type BpfStat struct { + Recv uint32 + Drop uint32 +} + +type BpfZbuf struct { + Bufa *byte + Bufb *byte + Buflen uint64 +} + +type BpfProgram struct { + Len uint32 + _ [4]byte + Insns *BpfInsn +} + +type BpfInsn struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} + +type BpfHdr struct { + Tstamp Timeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [6]byte +} + +type BpfZbufHeader struct { + Kernel_gen uint32 + Kernel_len uint32 + User_gen uint32 + _ [5]uint32 +} + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed uint32 + Ospeed uint32 +} + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_REMOVEDIR = 0x800 + AT_SYMLINK_FOLLOW = 0x400 + AT_SYMLINK_NOFOLLOW = 0x200 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLINIGNEOF = 0x2000 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type CapRights struct { + Rights [2]uint64 +} + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index 8ee54ec329e8..06471afa360c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -405,6 +405,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -434,141 +439,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -634,6 +683,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x8 @@ -759,7 +829,30 @@ type Sigset_t struct { Val [32]uint32 } -const RNDGETENTCNT = 0x80045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -828,6 +921,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -930,7 +1025,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1033,6 +1129,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1054,21 +1151,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1081,6 +1195,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1337,6 +1452,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1385,6 +1515,9 @@ const ( SizeofTpacketHdr = 0x18 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1962,6 +2095,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1981,4 +2118,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index dcfe39124355..6bba58ed2545 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -406,6 +406,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -435,141 +440,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -635,6 +684,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -772,7 +842,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x80045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -839,6 +932,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -941,7 +1036,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1044,6 +1140,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1065,21 +1162,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1092,6 +1206,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1349,6 +1464,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1397,6 +1527,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1975,6 +2108,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1994,4 +2131,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index 692f2966de31..07aa92b29d1c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -409,6 +409,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -438,141 +443,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -638,6 +687,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x8 @@ -748,7 +818,30 @@ type Sigset_t struct { Val [32]uint32 } -const RNDGETENTCNT = 0x80045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -817,6 +910,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -919,7 +1014,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1022,6 +1118,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1043,21 +1140,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1070,6 +1184,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1327,6 +1442,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1375,6 +1505,9 @@ const ( SizeofTpacketHdr = 0x18 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1953,6 +2086,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1972,4 +2109,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]uint8 + Driver_name [64]uint8 + Module_name [64]uint8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]uint8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]uint8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]uint8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]uint8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]uint8 +} + +type CryptoReportLarval struct { + Type [64]uint8 +} + +type CryptoReportHash struct { + Type [64]uint8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]uint8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]uint8 + Geniv [64]uint8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]uint8 + Geniv [64]uint8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]uint8 +} + +type CryptoReportRNG struct { + Type [64]uint8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]uint8 +} + +type CryptoReportKPP struct { + Type [64]uint8 +} + +type CryptoReportAcomp struct { + Type [64]uint8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index 54ff596c50ba..66dba9aab6d2 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -407,6 +407,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -436,141 +441,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -636,6 +685,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -751,7 +821,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x80045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -818,6 +911,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -920,7 +1015,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1023,6 +1119,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1044,21 +1141,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1071,6 +1185,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1328,6 +1443,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1376,6 +1506,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1954,6 +2087,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1973,4 +2110,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 5dbe0c3186c1..b11b77d3ba4e 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -408,6 +408,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -437,141 +442,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -637,6 +686,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x8 @@ -753,7 +823,30 @@ type Sigset_t struct { Val [32]uint32 } -const RNDGETENTCNT = 0x40045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -822,6 +915,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -924,7 +1019,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1027,6 +1123,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1048,21 +1145,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1075,6 +1189,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1333,6 +1448,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1381,6 +1511,9 @@ const ( SizeofTpacketHdr = 0x18 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1959,6 +2092,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1978,4 +2115,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 26766ee37afe..ccfd9522ebcd 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -407,6 +407,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -436,141 +441,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -636,6 +685,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -753,7 +823,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x40045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -820,6 +913,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -922,7 +1017,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1025,6 +1121,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1046,21 +1143,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1073,6 +1187,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1330,6 +1445,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1378,6 +1508,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1956,6 +2089,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1975,4 +2112,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index 2d23ed17a3a0..95374fd9b50d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -407,6 +407,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -436,141 +441,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -636,6 +685,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -753,7 +823,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x40045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -820,6 +913,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -922,7 +1017,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1025,6 +1121,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1046,21 +1143,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1073,6 +1187,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1330,6 +1445,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1378,6 +1508,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1956,6 +2089,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1975,4 +2112,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index dac6168ebac6..9d4953daf53d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -408,6 +408,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -437,141 +442,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -637,6 +686,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x8 @@ -753,7 +823,30 @@ type Sigset_t struct { Val [32]uint32 } -const RNDGETENTCNT = 0x40045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -822,6 +915,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -924,7 +1019,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1027,6 +1123,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1048,21 +1145,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1075,6 +1189,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1333,6 +1448,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1381,6 +1511,9 @@ const ( SizeofTpacketHdr = 0x18 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1959,6 +2092,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1978,4 +2115,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index d79111c36642..a436410d621a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -408,6 +408,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -437,141 +442,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -637,6 +686,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -761,7 +831,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x40045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -828,6 +921,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -930,7 +1025,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1033,6 +1129,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1054,21 +1151,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1081,6 +1195,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1338,6 +1453,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1386,6 +1516,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1964,6 +2097,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1983,4 +2120,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]uint8 + Driver_name [64]uint8 + Module_name [64]uint8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]uint8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]uint8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]uint8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]uint8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]uint8 +} + +type CryptoReportLarval struct { + Type [64]uint8 +} + +type CryptoReportHash struct { + Type [64]uint8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]uint8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]uint8 + Geniv [64]uint8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]uint8 + Geniv [64]uint8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]uint8 +} + +type CryptoReportRNG struct { + Type [64]uint8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]uint8 +} + +type CryptoReportKPP struct { + Type [64]uint8 +} + +type CryptoReportAcomp struct { + Type [64]uint8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index f58b691b4530..dbe32bb3035d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -408,6 +408,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -437,141 +442,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -637,6 +686,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -761,7 +831,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x40045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -828,6 +921,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -930,7 +1025,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1033,6 +1129,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1054,21 +1151,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1081,6 +1195,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1338,6 +1453,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1386,6 +1516,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1964,6 +2097,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1983,4 +2120,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]uint8 + Driver_name [64]uint8 + Module_name [64]uint8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]uint8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]uint8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]uint8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]uint8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]uint8 +} + +type CryptoReportLarval struct { + Type [64]uint8 +} + +type CryptoReportHash struct { + Type [64]uint8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]uint8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]uint8 + Geniv [64]uint8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]uint8 + Geniv [64]uint8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]uint8 +} + +type CryptoReportRNG struct { + Type [64]uint8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]uint8 +} + +type CryptoReportKPP struct { + Type [64]uint8 +} + +type CryptoReportAcomp struct { + Type [64]uint8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 2a493b5528c6..774d5c3eb73f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -212,7 +212,7 @@ type RawSockaddrInet6 struct { type RawSockaddrUnix struct { Family uint16 - Path [108]uint8 + Path [108]int8 } type RawSockaddrLinklayer struct { @@ -407,6 +407,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -436,141 +441,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -636,6 +685,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -778,7 +848,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x80045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -845,6 +938,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -947,7 +1042,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1050,6 +1146,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1071,21 +1168,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1098,6 +1212,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1355,6 +1470,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1403,6 +1533,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1981,6 +2114,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -2000,4 +2137,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]uint8 + Driver_name [64]uint8 + Module_name [64]uint8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]uint8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]uint8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]uint8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]uint8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]uint8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]uint8 +} + +type CryptoReportLarval struct { + Type [64]uint8 +} + +type CryptoReportHash struct { + Type [64]uint8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]uint8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]uint8 + Geniv [64]uint8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]uint8 + Geniv [64]uint8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]uint8 +} + +type CryptoReportRNG struct { + Type [64]uint8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]uint8 +} + +type CryptoReportKPP struct { + Type [64]uint8 +} + +type CryptoReportAcomp struct { + Type [64]uint8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index 4ff4097c216d..3b7747ed968a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -406,6 +406,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -435,141 +440,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -635,6 +684,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -774,7 +844,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x80045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -841,6 +934,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -943,7 +1038,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1046,6 +1142,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1067,21 +1164,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1094,6 +1208,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1352,6 +1467,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1400,6 +1530,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1978,6 +2111,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1997,4 +2134,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index ec980c1ab654..c606f4776b05 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -410,6 +410,11 @@ type TCPInfo struct { Total_retrans uint32 } +type CanFilter struct { + Id uint32 + Mask uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -439,141 +444,185 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0x68 + SizeofCanFilter = 0x8 ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_INFO_KIND = 0x1 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_NUM_VF = 0x15 - IFLA_VFINFO_LIST = 0x16 - IFLA_STATS64 = 0x17 - IFLA_VF_PORTS = 0x18 - IFLA_PORT_SELF = 0x19 - IFLA_AF_SPEC = 0x1a - IFLA_GROUP = 0x1b - IFLA_NET_NS_FD = 0x1c - IFLA_EXT_MASK = 0x1d - IFLA_PROMISCUITY = 0x1e - IFLA_NUM_TX_QUEUES = 0x1f - IFLA_NUM_RX_QUEUES = 0x20 - IFLA_CARRIER = 0x21 - IFLA_PHYS_PORT_ID = 0x22 - IFLA_CARRIER_CHANGES = 0x23 - IFLA_PHYS_SWITCH_ID = 0x24 - IFLA_LINK_NETNSID = 0x25 - IFLA_PHYS_PORT_NAME = 0x26 - IFLA_PROTO_DOWN = 0x27 - IFLA_GSO_MAX_SEGS = 0x28 - IFLA_GSO_MAX_SIZE = 0x29 - IFLA_PAD = 0x2a - IFLA_XDP = 0x2b - IFLA_EVENT = 0x2c - IFLA_NEW_NETNSID = 0x2d - IFLA_IF_NETNSID = 0x2e - IFLA_MAX = 0x33 - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTA_MARK = 0x10 - RTA_MFC_STATS = 0x11 - RTA_VIA = 0x12 - RTA_NEWDST = 0x13 - RTA_PREF = 0x14 - RTA_ENCAP_TYPE = 0x15 - RTA_ENCAP = 0x16 - RTA_EXPIRES = 0x17 - RTA_PAD = 0x18 - RTA_UID = 0x19 - RTA_TTL_PROPAGATE = 0x1a - RTA_IP_PROTO = 0x1b - RTA_SPORT = 0x1c - RTA_DPORT = 0x1d - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + NDA_UNSPEC = 0x0 + NDA_DST = 0x1 + NDA_LLADDR = 0x2 + NDA_CACHEINFO = 0x3 + NDA_PROBES = 0x4 + NDA_VLAN = 0x5 + NDA_PORT = 0x6 + NDA_VNI = 0x7 + NDA_IFINDEX = 0x8 + NDA_MASTER = 0x9 + NDA_LINK_NETNSID = 0xa + NDA_SRC_VNI = 0xb + NTF_USE = 0x1 + NTF_SELF = 0x2 + NTF_MASTER = 0x4 + NTF_PROXY = 0x8 + NTF_EXT_LEARNED = 0x10 + NTF_OFFLOADED = 0x20 + NTF_ROUTER = 0x80 + NUD_INCOMPLETE = 0x1 + NUD_REACHABLE = 0x2 + NUD_STALE = 0x4 + NUD_DELAY = 0x8 + NUD_PROBE = 0x10 + NUD_FAILED = 0x20 + NUD_NOARP = 0x40 + NUD_PERMANENT = 0x80 + NUD_NONE = 0x0 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFA_FLAGS = 0x8 + IFA_RT_PRIORITY = 0x9 + IFA_TARGET_NETNSID = 0xa + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_TARGET_NETNSID = 0x2e + IFLA_CARRIER_UP_COUNT = 0x2f + IFLA_CARRIER_DOWN_COUNT = 0x30 + IFLA_NEW_IFINDEX = 0x31 + IFLA_MIN_MTU = 0x32 + IFLA_MAX_MTU = 0x33 + IFLA_MAX = 0x33 + IFLA_INFO_KIND = 0x1 + IFLA_INFO_DATA = 0x2 + IFLA_INFO_XSTATS = 0x3 + IFLA_INFO_SLAVE_KIND = 0x4 + IFLA_INFO_SLAVE_DATA = 0x5 + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTA_MARK = 0x10 + RTA_MFC_STATS = 0x11 + RTA_VIA = 0x12 + RTA_NEWDST = 0x13 + RTA_PREF = 0x14 + RTA_ENCAP_TYPE = 0x15 + RTA_ENCAP = 0x16 + RTA_EXPIRES = 0x17 + RTA_PAD = 0x18 + RTA_UID = 0x19 + RTA_TTL_PROPAGATE = 0x1a + RTA_IP_PROTO = 0x1b + RTA_SPORT = 0x1c + RTA_DPORT = 0x1d + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 + SizeofNdUseroptmsg = 0x10 + SizeofNdMsg = 0xc ) type NlMsghdr struct { @@ -639,6 +688,27 @@ type RtNexthop struct { Ifindex int32 } +type NdUseroptmsg struct { + Family uint8 + Pad1 uint8 + Opts_len uint16 + Ifindex int32 + Icmp_type uint8 + Icmp_code uint8 + Pad2 uint16 + Pad3 uint32 +} + +type NdMsg struct { + Family uint8 + Pad1 uint8 + Pad2 uint16 + Ifindex int32 + State uint16 + Flags uint8 + Type uint8 +} + const ( SizeofSockFilter = 0x8 SizeofSockFprog = 0x10 @@ -756,7 +826,30 @@ type Sigset_t struct { Val [16]uint64 } -const RNDGETENTCNT = 0x40045200 +type SignalfdSiginfo struct { + Signo uint32 + Errno int32 + Code int32 + Pid uint32 + Uid uint32 + Fd int32 + Tid uint32 + Band uint32 + Overrun uint32 + Trapno uint32 + Status int32 + Int int32 + Ptr uint64 + Utime uint64 + Stime uint64 + Addr uint64 + Addr_lsb uint16 + _ uint16 + Syscall int32 + Call_addr uint64 + Arch uint32 + _ [28]uint8 +} const PERF_IOC_FLAG_GROUP = 0x1 @@ -823,6 +916,8 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Thrashing_count uint64 + Thrashing_delay_total uint64 } const ( @@ -925,7 +1020,8 @@ type PerfEventAttr struct { Clockid int32 Sample_regs_intr uint64 Aux_watermark uint32 - _ uint32 + Sample_max_stack uint16 + _ uint16 } type PerfEventMmapPage struct { @@ -1028,6 +1124,7 @@ const ( PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 PERF_COUNT_SW_EMULATION_FAULTS = 0x8 PERF_COUNT_SW_DUMMY = 0x9 + PERF_COUNT_SW_BPF_OUTPUT = 0xa PERF_SAMPLE_IP = 0x1 PERF_SAMPLE_TID = 0x2 @@ -1049,21 +1146,38 @@ const ( PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 PERF_SAMPLE_BRANCH_IND_CALL = 0x40 + PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 + PERF_SAMPLE_BRANCH_IN_TX = 0x100 + PERF_SAMPLE_BRANCH_NO_TX = 0x200 + PERF_SAMPLE_BRANCH_COND = 0x400 + PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 + PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 + PERF_SAMPLE_BRANCH_CALL = 0x2000 + PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 + PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 + PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 PERF_FORMAT_ID = 0x4 PERF_FORMAT_GROUP = 0x8 - PERF_RECORD_MMAP = 0x1 - PERF_RECORD_LOST = 0x2 - PERF_RECORD_COMM = 0x3 - PERF_RECORD_EXIT = 0x4 - PERF_RECORD_THROTTLE = 0x5 - PERF_RECORD_UNTHROTTLE = 0x6 - PERF_RECORD_FORK = 0x7 - PERF_RECORD_READ = 0x8 - PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP = 0x1 + PERF_RECORD_LOST = 0x2 + PERF_RECORD_COMM = 0x3 + PERF_RECORD_EXIT = 0x4 + PERF_RECORD_THROTTLE = 0x5 + PERF_RECORD_UNTHROTTLE = 0x6 + PERF_RECORD_FORK = 0x7 + PERF_RECORD_READ = 0x8 + PERF_RECORD_SAMPLE = 0x9 + PERF_RECORD_MMAP2 = 0xa + PERF_RECORD_AUX = 0xb + PERF_RECORD_ITRACE_START = 0xc + PERF_RECORD_LOST_SAMPLES = 0xd + PERF_RECORD_SWITCH = 0xe + PERF_RECORD_SWITCH_CPU_WIDE = 0xf + PERF_RECORD_NAMESPACES = 0x10 PERF_CONTEXT_HV = -0x20 PERF_CONTEXT_KERNEL = -0x80 @@ -1076,6 +1190,7 @@ const ( PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_PID_CGROUP = 0x4 + PERF_FLAG_FD_CLOEXEC = 0x8 ) const ( @@ -1333,6 +1448,21 @@ type TpacketBlockDesc struct { Hdr [40]byte } +type TpacketBDTS struct { + Sec uint32 + Usec uint32 +} + +type TpacketHdrV1 struct { + Block_status uint32 + Num_pkts uint32 + Offset_to_first_pkt uint32 + Blk_len uint32 + Seq_num uint64 + Ts_first_pkt TpacketBDTS + Ts_last_pkt TpacketBDTS +} + type TpacketReq struct { Block_size uint32 Block_nr uint32 @@ -1381,6 +1511,9 @@ const ( SizeofTpacketHdr = 0x20 SizeofTpacket2Hdr = 0x20 SizeofTpacket3Hdr = 0x30 + + SizeofTpacketStats = 0x8 + SizeofTpacketStatsV3 = 0xc ) const ( @@ -1959,6 +2092,10 @@ const ( NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ) +type ScmTimestamping struct { + Ts [3]Timespec +} + const ( SOF_TIMESTAMPING_TX_HARDWARE = 0x1 SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 @@ -1978,4 +2115,198 @@ const ( SOF_TIMESTAMPING_LAST = 0x4000 SOF_TIMESTAMPING_MASK = 0x7fff + + SCM_TSTAMP_SND = 0x0 + SCM_TSTAMP_SCHED = 0x1 + SCM_TSTAMP_ACK = 0x2 +) + +type SockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type FanotifyEventMetadata struct { + Event_len uint32 + Vers uint8 + Reserved uint8 + Metadata_len uint16 + Mask uint64 + Fd int32 + Pid int32 +} + +type FanotifyResponse struct { + Fd int32 + Response uint32 +} + +const ( + CRYPTO_MSG_BASE = 0x10 + CRYPTO_MSG_NEWALG = 0x10 + CRYPTO_MSG_DELALG = 0x11 + CRYPTO_MSG_UPDATEALG = 0x12 + CRYPTO_MSG_GETALG = 0x13 + CRYPTO_MSG_DELRNG = 0x14 + CRYPTO_MSG_GETSTAT = 0x15 ) + +const ( + CRYPTOCFGA_UNSPEC = 0x0 + CRYPTOCFGA_PRIORITY_VAL = 0x1 + CRYPTOCFGA_REPORT_LARVAL = 0x2 + CRYPTOCFGA_REPORT_HASH = 0x3 + CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 + CRYPTOCFGA_REPORT_AEAD = 0x5 + CRYPTOCFGA_REPORT_COMPRESS = 0x6 + CRYPTOCFGA_REPORT_RNG = 0x7 + CRYPTOCFGA_REPORT_CIPHER = 0x8 + CRYPTOCFGA_REPORT_AKCIPHER = 0x9 + CRYPTOCFGA_REPORT_KPP = 0xa + CRYPTOCFGA_REPORT_ACOMP = 0xb + CRYPTOCFGA_STAT_LARVAL = 0xc + CRYPTOCFGA_STAT_HASH = 0xd + CRYPTOCFGA_STAT_BLKCIPHER = 0xe + CRYPTOCFGA_STAT_AEAD = 0xf + CRYPTOCFGA_STAT_COMPRESS = 0x10 + CRYPTOCFGA_STAT_RNG = 0x11 + CRYPTOCFGA_STAT_CIPHER = 0x12 + CRYPTOCFGA_STAT_AKCIPHER = 0x13 + CRYPTOCFGA_STAT_KPP = 0x14 + CRYPTOCFGA_STAT_ACOMP = 0x15 +) + +type CryptoUserAlg struct { + Name [64]int8 + Driver_name [64]int8 + Module_name [64]int8 + Type uint32 + Mask uint32 + Refcnt uint32 + Flags uint32 +} + +type CryptoStatAEAD struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatAKCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Verify_cnt uint64 + Sign_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatCipher struct { + Type [64]int8 + Encrypt_cnt uint64 + Encrypt_tlen uint64 + Decrypt_cnt uint64 + Decrypt_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatCompress struct { + Type [64]int8 + Compress_cnt uint64 + Compress_tlen uint64 + Decompress_cnt uint64 + Decompress_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatHash struct { + Type [64]int8 + Hash_cnt uint64 + Hash_tlen uint64 + Err_cnt uint64 +} + +type CryptoStatKPP struct { + Type [64]int8 + Setsecret_cnt uint64 + Generate_public_key_cnt uint64 + Compute_shared_secret_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatRNG struct { + Type [64]int8 + Generate_cnt uint64 + Generate_tlen uint64 + Seed_cnt uint64 + Err_cnt uint64 +} + +type CryptoStatLarval struct { + Type [64]int8 +} + +type CryptoReportLarval struct { + Type [64]int8 +} + +type CryptoReportHash struct { + Type [64]int8 + Blocksize uint32 + Digestsize uint32 +} + +type CryptoReportCipher struct { + Type [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 +} + +type CryptoReportBlkCipher struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Min_keysize uint32 + Max_keysize uint32 + Ivsize uint32 +} + +type CryptoReportAEAD struct { + Type [64]int8 + Geniv [64]int8 + Blocksize uint32 + Maxauthsize uint32 + Ivsize uint32 +} + +type CryptoReportComp struct { + Type [64]int8 +} + +type CryptoReportRNG struct { + Type [64]int8 + Seedsize uint32 +} + +type CryptoReportAKCipher struct { + Type [64]int8 +} + +type CryptoReportKPP struct { + Type [64]int8 +} + +type CryptoReportAcomp struct { + Type [64]int8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go new file mode 100644 index 000000000000..43da2c41c503 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go @@ -0,0 +1,472 @@ +// cgo -godefs types_netbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build arm64,netbsd + +package unix + +const ( + SizeofPtr = 0x8 + SizeofShort = 0x2 + SizeofInt = 0x4 + SizeofLong = 0x8 + SizeofLongLong = 0x8 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int32 + Pad_cgo_0 [4]byte +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} + +type Rlimit struct { + Cur uint64 + Max uint64 +} + +type _Gid_t uint32 + +type Stat_t struct { + Dev uint64 + Mode uint32 + Pad_cgo_0 [4]byte + Ino uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Pad_cgo_1 [4]byte + Rdev uint64 + Atimespec Timespec + Mtimespec Timespec + Ctimespec Timespec + Birthtimespec Timespec + Size int64 + Blocks int64 + Blksize uint32 + Flags uint32 + Gen uint32 + Spare [2]uint32 + Pad_cgo_2 [4]byte +} + +type Statfs_t [0]byte + +type Flock_t struct { + Start int64 + Len int64 + Pid int32 + Type int16 + Whence int16 +} + +type Dirent struct { + Fileno uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [512]int8 + Pad_cgo_0 [3]byte +} + +type Fsid struct { + X__fsid_val [2]int32 +} + +const ( + PathMax = 0x400 +) + +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + +type RawSockaddrInet4 struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type RawSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddrUnix struct { + Len uint8 + Family uint8 + Path [104]int8 +} + +type RawSockaddrDatalink struct { + Len uint8 + Family uint8 + Index uint16 + Type uint8 + Nlen uint8 + Alen uint8 + Slen uint8 + Data [12]int8 +} + +type RawSockaddr struct { + Len uint8 + Family uint8 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [92]int8 +} + +type _Socklen uint32 + +type Linger struct { + Onoff int32 + Linger int32 +} + +type Iovec struct { + Base *byte + Len uint64 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type Msghdr struct { + Name *byte + Namelen uint32 + Pad_cgo_0 [4]byte + Iov *Iovec + Iovlen int32 + Pad_cgo_1 [4]byte + Control *byte + Controllen uint32 + Flags int32 +} + +type Cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type Inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type IPv6MTUInfo struct { + Addr RawSockaddrInet6 + Mtu uint32 +} + +type ICMPv6Filter struct { + Filt [8]uint32 +} + +const ( + SizeofSockaddrInet4 = 0x10 + SizeofSockaddrInet6 = 0x1c + SizeofSockaddrAny = 0x6c + SizeofSockaddrUnix = 0x6a + SizeofSockaddrDatalink = 0x14 + SizeofLinger = 0x8 + SizeofIPMreq = 0x8 + SizeofIPv6Mreq = 0x14 + SizeofMsghdr = 0x30 + SizeofCmsghdr = 0xc + SizeofInet6Pktinfo = 0x14 + SizeofIPv6MTUInfo = 0x20 + SizeofICMPv6Filter = 0x20 +) + +const ( + PTRACE_TRACEME = 0x0 + PTRACE_CONT = 0x7 + PTRACE_KILL = 0x8 +) + +type Kevent_t struct { + Ident uint64 + Filter uint32 + Flags uint32 + Fflags uint32 + Pad_cgo_0 [4]byte + Data int64 + Udata int64 +} + +type FdSet struct { + Bits [8]uint32 +} + +const ( + SizeofIfMsghdr = 0x98 + SizeofIfData = 0x88 + SizeofIfaMsghdr = 0x18 + SizeofIfAnnounceMsghdr = 0x18 + SizeofRtMsghdr = 0x78 + SizeofRtMetrics = 0x50 +) + +type IfMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + Pad_cgo_0 [2]byte + Data IfData +} + +type IfData struct { + Type uint8 + Addrlen uint8 + Hdrlen uint8 + Pad_cgo_0 [1]byte + Link_state int32 + Mtu uint64 + Metric uint64 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Noproto uint64 + Lastchange Timespec +} + +type IfaMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Metric int32 + Index uint16 + Pad_cgo_0 [6]byte +} + +type IfAnnounceMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Name [16]int8 + What uint16 +} + +type RtMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Pad_cgo_0 [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits int32 + Pad_cgo_1 [4]byte + Rmx RtMetrics +} + +type RtMetrics struct { + Locks uint64 + Mtu uint64 + Hopcount uint64 + Recvpipe uint64 + Sendpipe uint64 + Ssthresh uint64 + Rtt uint64 + Rttvar uint64 + Expire int64 + Pksent int64 +} + +type Mclpool [0]byte + +const ( + SizeofBpfVersion = 0x4 + SizeofBpfStat = 0x80 + SizeofBpfProgram = 0x10 + SizeofBpfInsn = 0x8 + SizeofBpfHdr = 0x20 +) + +type BpfVersion struct { + Major uint16 + Minor uint16 +} + +type BpfStat struct { + Recv uint64 + Drop uint64 + Capt uint64 + Padding [13]uint64 +} + +type BpfProgram struct { + Len uint32 + Pad_cgo_0 [4]byte + Insns *BpfInsn +} + +type BpfInsn struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} + +type BpfHdr struct { + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + Pad_cgo_0 [6]byte +} + +type BpfTimeval struct { + Sec int64 + Usec int64 +} + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed int32 + Ospeed int32 +} + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +type Ptmget struct { + Cfd int32 + Sfd int32 + Cn [1024]byte + Sn [1024]byte +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x200 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Sysctlnode struct { + Flags uint32 + Num int32 + Name [32]int8 + Ver uint32 + X__rsvd uint32 + Un [16]byte + X_sysctl_size [8]byte + X_sysctl_func [8]byte + X_sysctl_parent [8]byte + X_sysctl_desc [8]byte +} + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go index 8b37d83992b6..900fb44622f3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go @@ -558,3 +558,13 @@ type Uvmexp struct { Fpswtch int32 Kmapent int32 } + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go index 6efea463559f..028fa78d74af 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go @@ -558,3 +558,13 @@ type Uvmexp struct { Fpswtch int32 Kmapent int32 } + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go index 510efc3eaac6..b45d5eedffe9 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go @@ -559,3 +559,13 @@ type Uvmexp struct { Fpswtch int32 Kmapent int32 } + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go new file mode 100644 index 000000000000..fa369a32a2df --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go @@ -0,0 +1,564 @@ +// cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +// +build arm64,openbsd + +package unix + +const ( + SizeofPtr = 0x8 + SizeofShort = 0x2 + SizeofInt = 0x4 + SizeofLong = 0x8 + SizeofLongLong = 0x8 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int64 +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} + +type Rlimit struct { + Cur uint64 + Max uint64 +} + +type _Gid_t uint32 + +type Stat_t struct { + Mode uint32 + Dev int32 + Ino uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev int32 + Atim Timespec + Mtim Timespec + Ctim Timespec + Size int64 + Blocks int64 + Blksize int32 + Flags uint32 + Gen uint32 + _ Timespec +} + +type Statfs_t struct { + F_flags uint32 + F_bsize uint32 + F_iosize uint32 + F_blocks uint64 + F_bfree uint64 + F_bavail int64 + F_files uint64 + F_ffree uint64 + F_favail int64 + F_syncwrites uint64 + F_syncreads uint64 + F_asyncwrites uint64 + F_asyncreads uint64 + F_fsid Fsid + F_namemax uint32 + F_owner uint32 + F_ctime uint64 + F_fstypename [16]int8 + F_mntonname [90]int8 + F_mntfromname [90]int8 + F_mntfromspec [90]int8 + _ [2]byte + Mount_info [160]byte +} + +type Flock_t struct { + Start int64 + Len int64 + Pid int32 + Type int16 + Whence int16 +} + +type Dirent struct { + Fileno uint64 + Off int64 + Reclen uint16 + Type uint8 + Namlen uint8 + _ [4]uint8 + Name [256]int8 +} + +type Fsid struct { + Val [2]int32 +} + +const ( + PathMax = 0x400 +) + +type RawSockaddrInet4 struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type RawSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddrUnix struct { + Len uint8 + Family uint8 + Path [104]int8 +} + +type RawSockaddrDatalink struct { + Len uint8 + Family uint8 + Index uint16 + Type uint8 + Nlen uint8 + Alen uint8 + Slen uint8 + Data [24]int8 +} + +type RawSockaddr struct { + Len uint8 + Family uint8 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [92]int8 +} + +type _Socklen uint32 + +type Linger struct { + Onoff int32 + Linger int32 +} + +type Iovec struct { + Base *byte + Len uint64 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type Msghdr struct { + Name *byte + Namelen uint32 + Iov *Iovec + Iovlen uint32 + Control *byte + Controllen uint32 + Flags int32 +} + +type Cmsghdr struct { + Len uint32 + Level int32 + Type int32 +} + +type Inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type IPv6MTUInfo struct { + Addr RawSockaddrInet6 + Mtu uint32 +} + +type ICMPv6Filter struct { + Filt [8]uint32 +} + +const ( + SizeofSockaddrInet4 = 0x10 + SizeofSockaddrInet6 = 0x1c + SizeofSockaddrAny = 0x6c + SizeofSockaddrUnix = 0x6a + SizeofSockaddrDatalink = 0x20 + SizeofLinger = 0x8 + SizeofIPMreq = 0x8 + SizeofIPv6Mreq = 0x14 + SizeofMsghdr = 0x30 + SizeofCmsghdr = 0xc + SizeofInet6Pktinfo = 0x14 + SizeofIPv6MTUInfo = 0x20 + SizeofICMPv6Filter = 0x20 +) + +const ( + PTRACE_TRACEME = 0x0 + PTRACE_CONT = 0x7 + PTRACE_KILL = 0x8 +) + +type Kevent_t struct { + Ident uint64 + Filter int16 + Flags uint16 + Fflags uint32 + Data int64 + Udata *byte +} + +type FdSet struct { + Bits [32]uint32 +} + +const ( + SizeofIfMsghdr = 0xa8 + SizeofIfData = 0x90 + SizeofIfaMsghdr = 0x18 + SizeofIfAnnounceMsghdr = 0x1a + SizeofRtMsghdr = 0x60 + SizeofRtMetrics = 0x38 +) + +type IfMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Pad1 uint8 + Pad2 uint8 + Addrs int32 + Flags int32 + Xflags int32 + Data IfData +} + +type IfData struct { + Type uint8 + Addrlen uint8 + Hdrlen uint8 + Link_state uint8 + Mtu uint32 + Metric uint32 + Rdomain uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Oqdrops uint64 + Noproto uint64 + Capabilities uint32 + Lastchange Timeval +} + +type IfaMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Pad1 uint8 + Pad2 uint8 + Addrs int32 + Flags int32 + Metric int32 +} + +type IfAnnounceMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + What uint16 + Name [16]int8 +} + +type RtMsghdr struct { + Msglen uint16 + Version uint8 + Type uint8 + Hdrlen uint16 + Index uint16 + Tableid uint16 + Priority uint8 + Mpls uint8 + Addrs int32 + Flags int32 + Fmask int32 + Pid int32 + Seq int32 + Errno int32 + Inits uint32 + Rmx RtMetrics +} + +type RtMetrics struct { + Pksent uint64 + Expire int64 + Locks uint32 + Mtu uint32 + Refcnt uint32 + Hopcount uint32 + Recvpipe uint32 + Sendpipe uint32 + Ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Pad uint32 +} + +type Mclpool struct{} + +const ( + SizeofBpfVersion = 0x4 + SizeofBpfStat = 0x8 + SizeofBpfProgram = 0x10 + SizeofBpfInsn = 0x8 + SizeofBpfHdr = 0x14 +) + +type BpfVersion struct { + Major uint16 + Minor uint16 +} + +type BpfStat struct { + Recv uint32 + Drop uint32 +} + +type BpfProgram struct { + Len uint32 + Insns *BpfInsn +} + +type BpfInsn struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} + +type BpfHdr struct { + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte +} + +type BpfTimeval struct { + Sec uint32 + Usec uint32 +} + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed int32 + Ospeed int32 +} + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x2 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Sigset_t uint32 + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} + +const SizeofUvmexp = 0x158 + +type Uvmexp struct { + Pagesize int32 + Pagemask int32 + Pageshift int32 + Npages int32 + Free int32 + Active int32 + Inactive int32 + Paging int32 + Wired int32 + Zeropages int32 + Reserve_pagedaemon int32 + Reserve_kernel int32 + Unused01 int32 + Vnodepages int32 + Vtextpages int32 + Freemin int32 + Freetarg int32 + Inactarg int32 + Wiredmax int32 + Anonmin int32 + Vtextmin int32 + Vnodemin int32 + Anonminpct int32 + Vtextminpct int32 + Vnodeminpct int32 + Nswapdev int32 + Swpages int32 + Swpginuse int32 + Swpgonly int32 + Nswget int32 + Nanon int32 + Unused05 int32 + Unused06 int32 + Faults int32 + Traps int32 + Intrs int32 + Swtch int32 + Softs int32 + Syscalls int32 + Pageins int32 + Unused07 int32 + Unused08 int32 + Pgswapin int32 + Pgswapout int32 + Forks int32 + Forks_ppwait int32 + Forks_sharevm int32 + Pga_zerohit int32 + Pga_zeromiss int32 + Unused09 int32 + Fltnoram int32 + Fltnoanon int32 + Fltnoamap int32 + Fltpgwait int32 + Fltpgrele int32 + Fltrelck int32 + Fltrelckok int32 + Fltanget int32 + Fltanretry int32 + Fltamcopy int32 + Fltnamap int32 + Fltnomap int32 + Fltlget int32 + Fltget int32 + Flt_anon int32 + Flt_acow int32 + Flt_obj int32 + Flt_prcopy int32 + Flt_przero int32 + Pdwoke int32 + Pdrevs int32 + Pdswout int32 + Pdfreed int32 + Pdscans int32 + Pdanscan int32 + Pdobscan int32 + Pdreact int32 + Pdbusy int32 + Pdpageouts int32 + Pdpending int32 + Pddeact int32 + Unused11 int32 + Unused12 int32 + Unused13 int32 + Fpswtch int32 + Kmapent int32 +} + +const SizeofClockinfo = 0x14 + +type Clockinfo struct { + Hz int32 + Tick int32 + Tickadj int32 + Stathz int32 + Profhz int32 +} diff --git a/vendor/golang.org/x/text/transform/transform.go b/vendor/golang.org/x/text/transform/transform.go index fe47b9b35f05..520b9ada0e28 100644 --- a/vendor/golang.org/x/text/transform/transform.go +++ b/vendor/golang.org/x/text/transform/transform.go @@ -78,8 +78,8 @@ type SpanningTransformer interface { // considering the error err. // // A nil error means that all input bytes are known to be identical to the - // output produced by the Transformer. A nil error can be be returned - // regardless of whether atEOF is true. If err is nil, then then n must + // output produced by the Transformer. A nil error can be returned + // regardless of whether atEOF is true. If err is nil, then n must // equal len(src); the converse is not necessarily true. // // ErrEndOfSpan means that the Transformer output may differ from the @@ -493,7 +493,7 @@ func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err erro return dstL.n, srcL.p, err } -// Deprecated: use runes.Remove instead. +// Deprecated: Use runes.Remove instead. func RemoveFunc(f func(r rune) bool) Transformer { return removeF(f) } diff --git a/vendor/golang.org/x/text/unicode/bidi/bidi.go b/vendor/golang.org/x/text/unicode/bidi/bidi.go index 3fc4a62521a4..e8edc54cc28d 100644 --- a/vendor/golang.org/x/text/unicode/bidi/bidi.go +++ b/vendor/golang.org/x/text/unicode/bidi/bidi.go @@ -6,7 +6,7 @@ // Package bidi contains functionality for bidirectional text support. // -// See http://www.unicode.org/reports/tr9. +// See https://www.unicode.org/reports/tr9. // // NOTE: UNDER CONSTRUCTION. This API may change in backwards incompatible ways // and without notice. diff --git a/vendor/golang.org/x/text/unicode/bidi/bracket.go b/vendor/golang.org/x/text/unicode/bidi/bracket.go index 601e259203eb..18539397914b 100644 --- a/vendor/golang.org/x/text/unicode/bidi/bracket.go +++ b/vendor/golang.org/x/text/unicode/bidi/bracket.go @@ -12,7 +12,7 @@ import ( // This file contains a port of the reference implementation of the // Bidi Parentheses Algorithm: -// http://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/BidiPBAReference.java +// https://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/BidiPBAReference.java // // The implementation in this file covers definitions BD14-BD16 and rule N0 // of UAX#9. @@ -246,7 +246,7 @@ func (p *bracketPairer) getStrongTypeN0(index int) Class { // assuming the given embedding direction. // // It returns ON if no strong type is found. If a single strong type is found, -// it returns this this type. Otherwise it returns the embedding direction. +// it returns this type. Otherwise it returns the embedding direction. // // TODO: use separate type for "strong" directionality. func (p *bracketPairer) classifyPairContent(loc bracketPair, dirEmbed Class) Class { diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index d4c1399f0da0..48d144008aa9 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -7,7 +7,7 @@ package bidi import "log" // This implementation is a port based on the reference implementation found at: -// http://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/ +// https://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/ // // described in Unicode Bidirectional Algorithm (UAX #9). // diff --git a/vendor/golang.org/x/text/unicode/bidi/gen.go b/vendor/golang.org/x/text/unicode/bidi/gen.go index 4e1c7ba0bf4d..987fc169cc04 100644 --- a/vendor/golang.org/x/text/unicode/bidi/gen.go +++ b/vendor/golang.org/x/text/unicode/bidi/gen.go @@ -26,7 +26,7 @@ func main() { } // bidiClass names and codes taken from class "bc" in -// http://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt +// https://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt var bidiClass = map[string]Class{ "AL": AL, // ArabicLetter "AN": AN, // ArabicNumber diff --git a/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go b/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go index 51bd68fa7f38..02c3b505d640 100644 --- a/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go +++ b/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go @@ -15,7 +15,7 @@ import ( ) // These tables are hand-extracted from: -// http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt +// https://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt func visitDefaults(fn func(r rune, c Class)) { // first write default values for ranges listed above. visitRunes(fn, AL, []rune{ diff --git a/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go b/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go index 2e1ff19599dc..d8c94e1bd1a6 100644 --- a/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go +++ b/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go @@ -1,6 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. -// +build go1.10 +// +build go1.10,!go1.13 package bidi diff --git a/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go b/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go new file mode 100644 index 000000000000..022e3c69092d --- /dev/null +++ b/vendor/golang.org/x/text/unicode/bidi/tables11.0.0.go @@ -0,0 +1,1887 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.13 + +package bidi + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "11.0.0" + +// xorMasks contains masks to be xor-ed with brackets to get the reverse +// version. +var xorMasks = []int32{ // 8 elements + 0, 1, 6, 7, 3, 15, 29, 63, +} // Size: 56 bytes + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *bidiTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return bidiValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *bidiTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return bidiValues[c0] + } + i := bidiIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *bidiTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return bidiValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *bidiTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return bidiValues[c0] + } + i := bidiIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// bidiTrie. Total size: 16512 bytes (16.12 KiB). Checksum: 2a9cf1317f2ffaa. +type bidiTrie struct{} + +func newBidiTrie(i int) *bidiTrie { + return &bidiTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *bidiTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(bidiValues[n<<6+uint32(b)]) + } +} + +// bidiValues: 234 blocks, 14976 entries, 14976 bytes +// The third block is the zero block. +var bidiValues = [14976]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x000b, 0x01: 0x000b, 0x02: 0x000b, 0x03: 0x000b, 0x04: 0x000b, 0x05: 0x000b, + 0x06: 0x000b, 0x07: 0x000b, 0x08: 0x000b, 0x09: 0x0008, 0x0a: 0x0007, 0x0b: 0x0008, + 0x0c: 0x0009, 0x0d: 0x0007, 0x0e: 0x000b, 0x0f: 0x000b, 0x10: 0x000b, 0x11: 0x000b, + 0x12: 0x000b, 0x13: 0x000b, 0x14: 0x000b, 0x15: 0x000b, 0x16: 0x000b, 0x17: 0x000b, + 0x18: 0x000b, 0x19: 0x000b, 0x1a: 0x000b, 0x1b: 0x000b, 0x1c: 0x0007, 0x1d: 0x0007, + 0x1e: 0x0007, 0x1f: 0x0008, 0x20: 0x0009, 0x21: 0x000a, 0x22: 0x000a, 0x23: 0x0004, + 0x24: 0x0004, 0x25: 0x0004, 0x26: 0x000a, 0x27: 0x000a, 0x28: 0x003a, 0x29: 0x002a, + 0x2a: 0x000a, 0x2b: 0x0003, 0x2c: 0x0006, 0x2d: 0x0003, 0x2e: 0x0006, 0x2f: 0x0006, + 0x30: 0x0002, 0x31: 0x0002, 0x32: 0x0002, 0x33: 0x0002, 0x34: 0x0002, 0x35: 0x0002, + 0x36: 0x0002, 0x37: 0x0002, 0x38: 0x0002, 0x39: 0x0002, 0x3a: 0x0006, 0x3b: 0x000a, + 0x3c: 0x000a, 0x3d: 0x000a, 0x3e: 0x000a, 0x3f: 0x000a, + // Block 0x1, offset 0x40 + 0x40: 0x000a, + 0x5b: 0x005a, 0x5c: 0x000a, 0x5d: 0x004a, + 0x5e: 0x000a, 0x5f: 0x000a, 0x60: 0x000a, + 0x7b: 0x005a, + 0x7c: 0x000a, 0x7d: 0x004a, 0x7e: 0x000a, 0x7f: 0x000b, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x000b, 0xc1: 0x000b, 0xc2: 0x000b, 0xc3: 0x000b, 0xc4: 0x000b, 0xc5: 0x0007, + 0xc6: 0x000b, 0xc7: 0x000b, 0xc8: 0x000b, 0xc9: 0x000b, 0xca: 0x000b, 0xcb: 0x000b, + 0xcc: 0x000b, 0xcd: 0x000b, 0xce: 0x000b, 0xcf: 0x000b, 0xd0: 0x000b, 0xd1: 0x000b, + 0xd2: 0x000b, 0xd3: 0x000b, 0xd4: 0x000b, 0xd5: 0x000b, 0xd6: 0x000b, 0xd7: 0x000b, + 0xd8: 0x000b, 0xd9: 0x000b, 0xda: 0x000b, 0xdb: 0x000b, 0xdc: 0x000b, 0xdd: 0x000b, + 0xde: 0x000b, 0xdf: 0x000b, 0xe0: 0x0006, 0xe1: 0x000a, 0xe2: 0x0004, 0xe3: 0x0004, + 0xe4: 0x0004, 0xe5: 0x0004, 0xe6: 0x000a, 0xe7: 0x000a, 0xe8: 0x000a, 0xe9: 0x000a, + 0xeb: 0x000a, 0xec: 0x000a, 0xed: 0x000b, 0xee: 0x000a, 0xef: 0x000a, + 0xf0: 0x0004, 0xf1: 0x0004, 0xf2: 0x0002, 0xf3: 0x0002, 0xf4: 0x000a, + 0xf6: 0x000a, 0xf7: 0x000a, 0xf8: 0x000a, 0xf9: 0x0002, 0xfb: 0x000a, + 0xfc: 0x000a, 0xfd: 0x000a, 0xfe: 0x000a, 0xff: 0x000a, + // Block 0x4, offset 0x100 + 0x117: 0x000a, + 0x137: 0x000a, + // Block 0x5, offset 0x140 + 0x179: 0x000a, 0x17a: 0x000a, + // Block 0x6, offset 0x180 + 0x182: 0x000a, 0x183: 0x000a, 0x184: 0x000a, 0x185: 0x000a, + 0x186: 0x000a, 0x187: 0x000a, 0x188: 0x000a, 0x189: 0x000a, 0x18a: 0x000a, 0x18b: 0x000a, + 0x18c: 0x000a, 0x18d: 0x000a, 0x18e: 0x000a, 0x18f: 0x000a, + 0x192: 0x000a, 0x193: 0x000a, 0x194: 0x000a, 0x195: 0x000a, 0x196: 0x000a, 0x197: 0x000a, + 0x198: 0x000a, 0x199: 0x000a, 0x19a: 0x000a, 0x19b: 0x000a, 0x19c: 0x000a, 0x19d: 0x000a, + 0x19e: 0x000a, 0x19f: 0x000a, + 0x1a5: 0x000a, 0x1a6: 0x000a, 0x1a7: 0x000a, 0x1a8: 0x000a, 0x1a9: 0x000a, + 0x1aa: 0x000a, 0x1ab: 0x000a, 0x1ac: 0x000a, 0x1ad: 0x000a, 0x1af: 0x000a, + 0x1b0: 0x000a, 0x1b1: 0x000a, 0x1b2: 0x000a, 0x1b3: 0x000a, 0x1b4: 0x000a, 0x1b5: 0x000a, + 0x1b6: 0x000a, 0x1b7: 0x000a, 0x1b8: 0x000a, 0x1b9: 0x000a, 0x1ba: 0x000a, 0x1bb: 0x000a, + 0x1bc: 0x000a, 0x1bd: 0x000a, 0x1be: 0x000a, 0x1bf: 0x000a, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x000c, 0x1c1: 0x000c, 0x1c2: 0x000c, 0x1c3: 0x000c, 0x1c4: 0x000c, 0x1c5: 0x000c, + 0x1c6: 0x000c, 0x1c7: 0x000c, 0x1c8: 0x000c, 0x1c9: 0x000c, 0x1ca: 0x000c, 0x1cb: 0x000c, + 0x1cc: 0x000c, 0x1cd: 0x000c, 0x1ce: 0x000c, 0x1cf: 0x000c, 0x1d0: 0x000c, 0x1d1: 0x000c, + 0x1d2: 0x000c, 0x1d3: 0x000c, 0x1d4: 0x000c, 0x1d5: 0x000c, 0x1d6: 0x000c, 0x1d7: 0x000c, + 0x1d8: 0x000c, 0x1d9: 0x000c, 0x1da: 0x000c, 0x1db: 0x000c, 0x1dc: 0x000c, 0x1dd: 0x000c, + 0x1de: 0x000c, 0x1df: 0x000c, 0x1e0: 0x000c, 0x1e1: 0x000c, 0x1e2: 0x000c, 0x1e3: 0x000c, + 0x1e4: 0x000c, 0x1e5: 0x000c, 0x1e6: 0x000c, 0x1e7: 0x000c, 0x1e8: 0x000c, 0x1e9: 0x000c, + 0x1ea: 0x000c, 0x1eb: 0x000c, 0x1ec: 0x000c, 0x1ed: 0x000c, 0x1ee: 0x000c, 0x1ef: 0x000c, + 0x1f0: 0x000c, 0x1f1: 0x000c, 0x1f2: 0x000c, 0x1f3: 0x000c, 0x1f4: 0x000c, 0x1f5: 0x000c, + 0x1f6: 0x000c, 0x1f7: 0x000c, 0x1f8: 0x000c, 0x1f9: 0x000c, 0x1fa: 0x000c, 0x1fb: 0x000c, + 0x1fc: 0x000c, 0x1fd: 0x000c, 0x1fe: 0x000c, 0x1ff: 0x000c, + // Block 0x8, offset 0x200 + 0x200: 0x000c, 0x201: 0x000c, 0x202: 0x000c, 0x203: 0x000c, 0x204: 0x000c, 0x205: 0x000c, + 0x206: 0x000c, 0x207: 0x000c, 0x208: 0x000c, 0x209: 0x000c, 0x20a: 0x000c, 0x20b: 0x000c, + 0x20c: 0x000c, 0x20d: 0x000c, 0x20e: 0x000c, 0x20f: 0x000c, 0x210: 0x000c, 0x211: 0x000c, + 0x212: 0x000c, 0x213: 0x000c, 0x214: 0x000c, 0x215: 0x000c, 0x216: 0x000c, 0x217: 0x000c, + 0x218: 0x000c, 0x219: 0x000c, 0x21a: 0x000c, 0x21b: 0x000c, 0x21c: 0x000c, 0x21d: 0x000c, + 0x21e: 0x000c, 0x21f: 0x000c, 0x220: 0x000c, 0x221: 0x000c, 0x222: 0x000c, 0x223: 0x000c, + 0x224: 0x000c, 0x225: 0x000c, 0x226: 0x000c, 0x227: 0x000c, 0x228: 0x000c, 0x229: 0x000c, + 0x22a: 0x000c, 0x22b: 0x000c, 0x22c: 0x000c, 0x22d: 0x000c, 0x22e: 0x000c, 0x22f: 0x000c, + 0x234: 0x000a, 0x235: 0x000a, + 0x23e: 0x000a, + // Block 0x9, offset 0x240 + 0x244: 0x000a, 0x245: 0x000a, + 0x247: 0x000a, + // Block 0xa, offset 0x280 + 0x2b6: 0x000a, + // Block 0xb, offset 0x2c0 + 0x2c3: 0x000c, 0x2c4: 0x000c, 0x2c5: 0x000c, + 0x2c6: 0x000c, 0x2c7: 0x000c, 0x2c8: 0x000c, 0x2c9: 0x000c, + // Block 0xc, offset 0x300 + 0x30a: 0x000a, + 0x30d: 0x000a, 0x30e: 0x000a, 0x30f: 0x0004, 0x310: 0x0001, 0x311: 0x000c, + 0x312: 0x000c, 0x313: 0x000c, 0x314: 0x000c, 0x315: 0x000c, 0x316: 0x000c, 0x317: 0x000c, + 0x318: 0x000c, 0x319: 0x000c, 0x31a: 0x000c, 0x31b: 0x000c, 0x31c: 0x000c, 0x31d: 0x000c, + 0x31e: 0x000c, 0x31f: 0x000c, 0x320: 0x000c, 0x321: 0x000c, 0x322: 0x000c, 0x323: 0x000c, + 0x324: 0x000c, 0x325: 0x000c, 0x326: 0x000c, 0x327: 0x000c, 0x328: 0x000c, 0x329: 0x000c, + 0x32a: 0x000c, 0x32b: 0x000c, 0x32c: 0x000c, 0x32d: 0x000c, 0x32e: 0x000c, 0x32f: 0x000c, + 0x330: 0x000c, 0x331: 0x000c, 0x332: 0x000c, 0x333: 0x000c, 0x334: 0x000c, 0x335: 0x000c, + 0x336: 0x000c, 0x337: 0x000c, 0x338: 0x000c, 0x339: 0x000c, 0x33a: 0x000c, 0x33b: 0x000c, + 0x33c: 0x000c, 0x33d: 0x000c, 0x33e: 0x0001, 0x33f: 0x000c, + // Block 0xd, offset 0x340 + 0x340: 0x0001, 0x341: 0x000c, 0x342: 0x000c, 0x343: 0x0001, 0x344: 0x000c, 0x345: 0x000c, + 0x346: 0x0001, 0x347: 0x000c, 0x348: 0x0001, 0x349: 0x0001, 0x34a: 0x0001, 0x34b: 0x0001, + 0x34c: 0x0001, 0x34d: 0x0001, 0x34e: 0x0001, 0x34f: 0x0001, 0x350: 0x0001, 0x351: 0x0001, + 0x352: 0x0001, 0x353: 0x0001, 0x354: 0x0001, 0x355: 0x0001, 0x356: 0x0001, 0x357: 0x0001, + 0x358: 0x0001, 0x359: 0x0001, 0x35a: 0x0001, 0x35b: 0x0001, 0x35c: 0x0001, 0x35d: 0x0001, + 0x35e: 0x0001, 0x35f: 0x0001, 0x360: 0x0001, 0x361: 0x0001, 0x362: 0x0001, 0x363: 0x0001, + 0x364: 0x0001, 0x365: 0x0001, 0x366: 0x0001, 0x367: 0x0001, 0x368: 0x0001, 0x369: 0x0001, + 0x36a: 0x0001, 0x36b: 0x0001, 0x36c: 0x0001, 0x36d: 0x0001, 0x36e: 0x0001, 0x36f: 0x0001, + 0x370: 0x0001, 0x371: 0x0001, 0x372: 0x0001, 0x373: 0x0001, 0x374: 0x0001, 0x375: 0x0001, + 0x376: 0x0001, 0x377: 0x0001, 0x378: 0x0001, 0x379: 0x0001, 0x37a: 0x0001, 0x37b: 0x0001, + 0x37c: 0x0001, 0x37d: 0x0001, 0x37e: 0x0001, 0x37f: 0x0001, + // Block 0xe, offset 0x380 + 0x380: 0x0005, 0x381: 0x0005, 0x382: 0x0005, 0x383: 0x0005, 0x384: 0x0005, 0x385: 0x0005, + 0x386: 0x000a, 0x387: 0x000a, 0x388: 0x000d, 0x389: 0x0004, 0x38a: 0x0004, 0x38b: 0x000d, + 0x38c: 0x0006, 0x38d: 0x000d, 0x38e: 0x000a, 0x38f: 0x000a, 0x390: 0x000c, 0x391: 0x000c, + 0x392: 0x000c, 0x393: 0x000c, 0x394: 0x000c, 0x395: 0x000c, 0x396: 0x000c, 0x397: 0x000c, + 0x398: 0x000c, 0x399: 0x000c, 0x39a: 0x000c, 0x39b: 0x000d, 0x39c: 0x000d, 0x39d: 0x000d, + 0x39e: 0x000d, 0x39f: 0x000d, 0x3a0: 0x000d, 0x3a1: 0x000d, 0x3a2: 0x000d, 0x3a3: 0x000d, + 0x3a4: 0x000d, 0x3a5: 0x000d, 0x3a6: 0x000d, 0x3a7: 0x000d, 0x3a8: 0x000d, 0x3a9: 0x000d, + 0x3aa: 0x000d, 0x3ab: 0x000d, 0x3ac: 0x000d, 0x3ad: 0x000d, 0x3ae: 0x000d, 0x3af: 0x000d, + 0x3b0: 0x000d, 0x3b1: 0x000d, 0x3b2: 0x000d, 0x3b3: 0x000d, 0x3b4: 0x000d, 0x3b5: 0x000d, + 0x3b6: 0x000d, 0x3b7: 0x000d, 0x3b8: 0x000d, 0x3b9: 0x000d, 0x3ba: 0x000d, 0x3bb: 0x000d, + 0x3bc: 0x000d, 0x3bd: 0x000d, 0x3be: 0x000d, 0x3bf: 0x000d, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x000d, 0x3c1: 0x000d, 0x3c2: 0x000d, 0x3c3: 0x000d, 0x3c4: 0x000d, 0x3c5: 0x000d, + 0x3c6: 0x000d, 0x3c7: 0x000d, 0x3c8: 0x000d, 0x3c9: 0x000d, 0x3ca: 0x000d, 0x3cb: 0x000c, + 0x3cc: 0x000c, 0x3cd: 0x000c, 0x3ce: 0x000c, 0x3cf: 0x000c, 0x3d0: 0x000c, 0x3d1: 0x000c, + 0x3d2: 0x000c, 0x3d3: 0x000c, 0x3d4: 0x000c, 0x3d5: 0x000c, 0x3d6: 0x000c, 0x3d7: 0x000c, + 0x3d8: 0x000c, 0x3d9: 0x000c, 0x3da: 0x000c, 0x3db: 0x000c, 0x3dc: 0x000c, 0x3dd: 0x000c, + 0x3de: 0x000c, 0x3df: 0x000c, 0x3e0: 0x0005, 0x3e1: 0x0005, 0x3e2: 0x0005, 0x3e3: 0x0005, + 0x3e4: 0x0005, 0x3e5: 0x0005, 0x3e6: 0x0005, 0x3e7: 0x0005, 0x3e8: 0x0005, 0x3e9: 0x0005, + 0x3ea: 0x0004, 0x3eb: 0x0005, 0x3ec: 0x0005, 0x3ed: 0x000d, 0x3ee: 0x000d, 0x3ef: 0x000d, + 0x3f0: 0x000c, 0x3f1: 0x000d, 0x3f2: 0x000d, 0x3f3: 0x000d, 0x3f4: 0x000d, 0x3f5: 0x000d, + 0x3f6: 0x000d, 0x3f7: 0x000d, 0x3f8: 0x000d, 0x3f9: 0x000d, 0x3fa: 0x000d, 0x3fb: 0x000d, + 0x3fc: 0x000d, 0x3fd: 0x000d, 0x3fe: 0x000d, 0x3ff: 0x000d, + // Block 0x10, offset 0x400 + 0x400: 0x000d, 0x401: 0x000d, 0x402: 0x000d, 0x403: 0x000d, 0x404: 0x000d, 0x405: 0x000d, + 0x406: 0x000d, 0x407: 0x000d, 0x408: 0x000d, 0x409: 0x000d, 0x40a: 0x000d, 0x40b: 0x000d, + 0x40c: 0x000d, 0x40d: 0x000d, 0x40e: 0x000d, 0x40f: 0x000d, 0x410: 0x000d, 0x411: 0x000d, + 0x412: 0x000d, 0x413: 0x000d, 0x414: 0x000d, 0x415: 0x000d, 0x416: 0x000d, 0x417: 0x000d, + 0x418: 0x000d, 0x419: 0x000d, 0x41a: 0x000d, 0x41b: 0x000d, 0x41c: 0x000d, 0x41d: 0x000d, + 0x41e: 0x000d, 0x41f: 0x000d, 0x420: 0x000d, 0x421: 0x000d, 0x422: 0x000d, 0x423: 0x000d, + 0x424: 0x000d, 0x425: 0x000d, 0x426: 0x000d, 0x427: 0x000d, 0x428: 0x000d, 0x429: 0x000d, + 0x42a: 0x000d, 0x42b: 0x000d, 0x42c: 0x000d, 0x42d: 0x000d, 0x42e: 0x000d, 0x42f: 0x000d, + 0x430: 0x000d, 0x431: 0x000d, 0x432: 0x000d, 0x433: 0x000d, 0x434: 0x000d, 0x435: 0x000d, + 0x436: 0x000d, 0x437: 0x000d, 0x438: 0x000d, 0x439: 0x000d, 0x43a: 0x000d, 0x43b: 0x000d, + 0x43c: 0x000d, 0x43d: 0x000d, 0x43e: 0x000d, 0x43f: 0x000d, + // Block 0x11, offset 0x440 + 0x440: 0x000d, 0x441: 0x000d, 0x442: 0x000d, 0x443: 0x000d, 0x444: 0x000d, 0x445: 0x000d, + 0x446: 0x000d, 0x447: 0x000d, 0x448: 0x000d, 0x449: 0x000d, 0x44a: 0x000d, 0x44b: 0x000d, + 0x44c: 0x000d, 0x44d: 0x000d, 0x44e: 0x000d, 0x44f: 0x000d, 0x450: 0x000d, 0x451: 0x000d, + 0x452: 0x000d, 0x453: 0x000d, 0x454: 0x000d, 0x455: 0x000d, 0x456: 0x000c, 0x457: 0x000c, + 0x458: 0x000c, 0x459: 0x000c, 0x45a: 0x000c, 0x45b: 0x000c, 0x45c: 0x000c, 0x45d: 0x0005, + 0x45e: 0x000a, 0x45f: 0x000c, 0x460: 0x000c, 0x461: 0x000c, 0x462: 0x000c, 0x463: 0x000c, + 0x464: 0x000c, 0x465: 0x000d, 0x466: 0x000d, 0x467: 0x000c, 0x468: 0x000c, 0x469: 0x000a, + 0x46a: 0x000c, 0x46b: 0x000c, 0x46c: 0x000c, 0x46d: 0x000c, 0x46e: 0x000d, 0x46f: 0x000d, + 0x470: 0x0002, 0x471: 0x0002, 0x472: 0x0002, 0x473: 0x0002, 0x474: 0x0002, 0x475: 0x0002, + 0x476: 0x0002, 0x477: 0x0002, 0x478: 0x0002, 0x479: 0x0002, 0x47a: 0x000d, 0x47b: 0x000d, + 0x47c: 0x000d, 0x47d: 0x000d, 0x47e: 0x000d, 0x47f: 0x000d, + // Block 0x12, offset 0x480 + 0x480: 0x000d, 0x481: 0x000d, 0x482: 0x000d, 0x483: 0x000d, 0x484: 0x000d, 0x485: 0x000d, + 0x486: 0x000d, 0x487: 0x000d, 0x488: 0x000d, 0x489: 0x000d, 0x48a: 0x000d, 0x48b: 0x000d, + 0x48c: 0x000d, 0x48d: 0x000d, 0x48e: 0x000d, 0x48f: 0x000d, 0x490: 0x000d, 0x491: 0x000c, + 0x492: 0x000d, 0x493: 0x000d, 0x494: 0x000d, 0x495: 0x000d, 0x496: 0x000d, 0x497: 0x000d, + 0x498: 0x000d, 0x499: 0x000d, 0x49a: 0x000d, 0x49b: 0x000d, 0x49c: 0x000d, 0x49d: 0x000d, + 0x49e: 0x000d, 0x49f: 0x000d, 0x4a0: 0x000d, 0x4a1: 0x000d, 0x4a2: 0x000d, 0x4a3: 0x000d, + 0x4a4: 0x000d, 0x4a5: 0x000d, 0x4a6: 0x000d, 0x4a7: 0x000d, 0x4a8: 0x000d, 0x4a9: 0x000d, + 0x4aa: 0x000d, 0x4ab: 0x000d, 0x4ac: 0x000d, 0x4ad: 0x000d, 0x4ae: 0x000d, 0x4af: 0x000d, + 0x4b0: 0x000c, 0x4b1: 0x000c, 0x4b2: 0x000c, 0x4b3: 0x000c, 0x4b4: 0x000c, 0x4b5: 0x000c, + 0x4b6: 0x000c, 0x4b7: 0x000c, 0x4b8: 0x000c, 0x4b9: 0x000c, 0x4ba: 0x000c, 0x4bb: 0x000c, + 0x4bc: 0x000c, 0x4bd: 0x000c, 0x4be: 0x000c, 0x4bf: 0x000c, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x000c, 0x4c1: 0x000c, 0x4c2: 0x000c, 0x4c3: 0x000c, 0x4c4: 0x000c, 0x4c5: 0x000c, + 0x4c6: 0x000c, 0x4c7: 0x000c, 0x4c8: 0x000c, 0x4c9: 0x000c, 0x4ca: 0x000c, 0x4cb: 0x000d, + 0x4cc: 0x000d, 0x4cd: 0x000d, 0x4ce: 0x000d, 0x4cf: 0x000d, 0x4d0: 0x000d, 0x4d1: 0x000d, + 0x4d2: 0x000d, 0x4d3: 0x000d, 0x4d4: 0x000d, 0x4d5: 0x000d, 0x4d6: 0x000d, 0x4d7: 0x000d, + 0x4d8: 0x000d, 0x4d9: 0x000d, 0x4da: 0x000d, 0x4db: 0x000d, 0x4dc: 0x000d, 0x4dd: 0x000d, + 0x4de: 0x000d, 0x4df: 0x000d, 0x4e0: 0x000d, 0x4e1: 0x000d, 0x4e2: 0x000d, 0x4e3: 0x000d, + 0x4e4: 0x000d, 0x4e5: 0x000d, 0x4e6: 0x000d, 0x4e7: 0x000d, 0x4e8: 0x000d, 0x4e9: 0x000d, + 0x4ea: 0x000d, 0x4eb: 0x000d, 0x4ec: 0x000d, 0x4ed: 0x000d, 0x4ee: 0x000d, 0x4ef: 0x000d, + 0x4f0: 0x000d, 0x4f1: 0x000d, 0x4f2: 0x000d, 0x4f3: 0x000d, 0x4f4: 0x000d, 0x4f5: 0x000d, + 0x4f6: 0x000d, 0x4f7: 0x000d, 0x4f8: 0x000d, 0x4f9: 0x000d, 0x4fa: 0x000d, 0x4fb: 0x000d, + 0x4fc: 0x000d, 0x4fd: 0x000d, 0x4fe: 0x000d, 0x4ff: 0x000d, + // Block 0x14, offset 0x500 + 0x500: 0x000d, 0x501: 0x000d, 0x502: 0x000d, 0x503: 0x000d, 0x504: 0x000d, 0x505: 0x000d, + 0x506: 0x000d, 0x507: 0x000d, 0x508: 0x000d, 0x509: 0x000d, 0x50a: 0x000d, 0x50b: 0x000d, + 0x50c: 0x000d, 0x50d: 0x000d, 0x50e: 0x000d, 0x50f: 0x000d, 0x510: 0x000d, 0x511: 0x000d, + 0x512: 0x000d, 0x513: 0x000d, 0x514: 0x000d, 0x515: 0x000d, 0x516: 0x000d, 0x517: 0x000d, + 0x518: 0x000d, 0x519: 0x000d, 0x51a: 0x000d, 0x51b: 0x000d, 0x51c: 0x000d, 0x51d: 0x000d, + 0x51e: 0x000d, 0x51f: 0x000d, 0x520: 0x000d, 0x521: 0x000d, 0x522: 0x000d, 0x523: 0x000d, + 0x524: 0x000d, 0x525: 0x000d, 0x526: 0x000c, 0x527: 0x000c, 0x528: 0x000c, 0x529: 0x000c, + 0x52a: 0x000c, 0x52b: 0x000c, 0x52c: 0x000c, 0x52d: 0x000c, 0x52e: 0x000c, 0x52f: 0x000c, + 0x530: 0x000c, 0x531: 0x000d, 0x532: 0x000d, 0x533: 0x000d, 0x534: 0x000d, 0x535: 0x000d, + 0x536: 0x000d, 0x537: 0x000d, 0x538: 0x000d, 0x539: 0x000d, 0x53a: 0x000d, 0x53b: 0x000d, + 0x53c: 0x000d, 0x53d: 0x000d, 0x53e: 0x000d, 0x53f: 0x000d, + // Block 0x15, offset 0x540 + 0x540: 0x0001, 0x541: 0x0001, 0x542: 0x0001, 0x543: 0x0001, 0x544: 0x0001, 0x545: 0x0001, + 0x546: 0x0001, 0x547: 0x0001, 0x548: 0x0001, 0x549: 0x0001, 0x54a: 0x0001, 0x54b: 0x0001, + 0x54c: 0x0001, 0x54d: 0x0001, 0x54e: 0x0001, 0x54f: 0x0001, 0x550: 0x0001, 0x551: 0x0001, + 0x552: 0x0001, 0x553: 0x0001, 0x554: 0x0001, 0x555: 0x0001, 0x556: 0x0001, 0x557: 0x0001, + 0x558: 0x0001, 0x559: 0x0001, 0x55a: 0x0001, 0x55b: 0x0001, 0x55c: 0x0001, 0x55d: 0x0001, + 0x55e: 0x0001, 0x55f: 0x0001, 0x560: 0x0001, 0x561: 0x0001, 0x562: 0x0001, 0x563: 0x0001, + 0x564: 0x0001, 0x565: 0x0001, 0x566: 0x0001, 0x567: 0x0001, 0x568: 0x0001, 0x569: 0x0001, + 0x56a: 0x0001, 0x56b: 0x000c, 0x56c: 0x000c, 0x56d: 0x000c, 0x56e: 0x000c, 0x56f: 0x000c, + 0x570: 0x000c, 0x571: 0x000c, 0x572: 0x000c, 0x573: 0x000c, 0x574: 0x0001, 0x575: 0x0001, + 0x576: 0x000a, 0x577: 0x000a, 0x578: 0x000a, 0x579: 0x000a, 0x57a: 0x0001, 0x57b: 0x0001, + 0x57c: 0x0001, 0x57d: 0x000c, 0x57e: 0x0001, 0x57f: 0x0001, + // Block 0x16, offset 0x580 + 0x580: 0x0001, 0x581: 0x0001, 0x582: 0x0001, 0x583: 0x0001, 0x584: 0x0001, 0x585: 0x0001, + 0x586: 0x0001, 0x587: 0x0001, 0x588: 0x0001, 0x589: 0x0001, 0x58a: 0x0001, 0x58b: 0x0001, + 0x58c: 0x0001, 0x58d: 0x0001, 0x58e: 0x0001, 0x58f: 0x0001, 0x590: 0x0001, 0x591: 0x0001, + 0x592: 0x0001, 0x593: 0x0001, 0x594: 0x0001, 0x595: 0x0001, 0x596: 0x000c, 0x597: 0x000c, + 0x598: 0x000c, 0x599: 0x000c, 0x59a: 0x0001, 0x59b: 0x000c, 0x59c: 0x000c, 0x59d: 0x000c, + 0x59e: 0x000c, 0x59f: 0x000c, 0x5a0: 0x000c, 0x5a1: 0x000c, 0x5a2: 0x000c, 0x5a3: 0x000c, + 0x5a4: 0x0001, 0x5a5: 0x000c, 0x5a6: 0x000c, 0x5a7: 0x000c, 0x5a8: 0x0001, 0x5a9: 0x000c, + 0x5aa: 0x000c, 0x5ab: 0x000c, 0x5ac: 0x000c, 0x5ad: 0x000c, 0x5ae: 0x0001, 0x5af: 0x0001, + 0x5b0: 0x0001, 0x5b1: 0x0001, 0x5b2: 0x0001, 0x5b3: 0x0001, 0x5b4: 0x0001, 0x5b5: 0x0001, + 0x5b6: 0x0001, 0x5b7: 0x0001, 0x5b8: 0x0001, 0x5b9: 0x0001, 0x5ba: 0x0001, 0x5bb: 0x0001, + 0x5bc: 0x0001, 0x5bd: 0x0001, 0x5be: 0x0001, 0x5bf: 0x0001, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0001, 0x5c1: 0x0001, 0x5c2: 0x0001, 0x5c3: 0x0001, 0x5c4: 0x0001, 0x5c5: 0x0001, + 0x5c6: 0x0001, 0x5c7: 0x0001, 0x5c8: 0x0001, 0x5c9: 0x0001, 0x5ca: 0x0001, 0x5cb: 0x0001, + 0x5cc: 0x0001, 0x5cd: 0x0001, 0x5ce: 0x0001, 0x5cf: 0x0001, 0x5d0: 0x0001, 0x5d1: 0x0001, + 0x5d2: 0x0001, 0x5d3: 0x0001, 0x5d4: 0x0001, 0x5d5: 0x0001, 0x5d6: 0x0001, 0x5d7: 0x0001, + 0x5d8: 0x0001, 0x5d9: 0x000c, 0x5da: 0x000c, 0x5db: 0x000c, 0x5dc: 0x0001, 0x5dd: 0x0001, + 0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x000d, 0x5e1: 0x000d, 0x5e2: 0x000d, 0x5e3: 0x000d, + 0x5e4: 0x000d, 0x5e5: 0x000d, 0x5e6: 0x000d, 0x5e7: 0x000d, 0x5e8: 0x000d, 0x5e9: 0x000d, + 0x5ea: 0x000d, 0x5eb: 0x000d, 0x5ec: 0x000d, 0x5ed: 0x000d, 0x5ee: 0x000d, 0x5ef: 0x000d, + 0x5f0: 0x0001, 0x5f1: 0x0001, 0x5f2: 0x0001, 0x5f3: 0x0001, 0x5f4: 0x0001, 0x5f5: 0x0001, + 0x5f6: 0x0001, 0x5f7: 0x0001, 0x5f8: 0x0001, 0x5f9: 0x0001, 0x5fa: 0x0001, 0x5fb: 0x0001, + 0x5fc: 0x0001, 0x5fd: 0x0001, 0x5fe: 0x0001, 0x5ff: 0x0001, + // Block 0x18, offset 0x600 + 0x600: 0x0001, 0x601: 0x0001, 0x602: 0x0001, 0x603: 0x0001, 0x604: 0x0001, 0x605: 0x0001, + 0x606: 0x0001, 0x607: 0x0001, 0x608: 0x0001, 0x609: 0x0001, 0x60a: 0x0001, 0x60b: 0x0001, + 0x60c: 0x0001, 0x60d: 0x0001, 0x60e: 0x0001, 0x60f: 0x0001, 0x610: 0x0001, 0x611: 0x0001, + 0x612: 0x0001, 0x613: 0x0001, 0x614: 0x0001, 0x615: 0x0001, 0x616: 0x0001, 0x617: 0x0001, + 0x618: 0x0001, 0x619: 0x0001, 0x61a: 0x0001, 0x61b: 0x0001, 0x61c: 0x0001, 0x61d: 0x0001, + 0x61e: 0x0001, 0x61f: 0x0001, 0x620: 0x000d, 0x621: 0x000d, 0x622: 0x000d, 0x623: 0x000d, + 0x624: 0x000d, 0x625: 0x000d, 0x626: 0x000d, 0x627: 0x000d, 0x628: 0x000d, 0x629: 0x000d, + 0x62a: 0x000d, 0x62b: 0x000d, 0x62c: 0x000d, 0x62d: 0x000d, 0x62e: 0x000d, 0x62f: 0x000d, + 0x630: 0x000d, 0x631: 0x000d, 0x632: 0x000d, 0x633: 0x000d, 0x634: 0x000d, 0x635: 0x000d, + 0x636: 0x000d, 0x637: 0x000d, 0x638: 0x000d, 0x639: 0x000d, 0x63a: 0x000d, 0x63b: 0x000d, + 0x63c: 0x000d, 0x63d: 0x000d, 0x63e: 0x000d, 0x63f: 0x000d, + // Block 0x19, offset 0x640 + 0x640: 0x000d, 0x641: 0x000d, 0x642: 0x000d, 0x643: 0x000d, 0x644: 0x000d, 0x645: 0x000d, + 0x646: 0x000d, 0x647: 0x000d, 0x648: 0x000d, 0x649: 0x000d, 0x64a: 0x000d, 0x64b: 0x000d, + 0x64c: 0x000d, 0x64d: 0x000d, 0x64e: 0x000d, 0x64f: 0x000d, 0x650: 0x000d, 0x651: 0x000d, + 0x652: 0x000d, 0x653: 0x000c, 0x654: 0x000c, 0x655: 0x000c, 0x656: 0x000c, 0x657: 0x000c, + 0x658: 0x000c, 0x659: 0x000c, 0x65a: 0x000c, 0x65b: 0x000c, 0x65c: 0x000c, 0x65d: 0x000c, + 0x65e: 0x000c, 0x65f: 0x000c, 0x660: 0x000c, 0x661: 0x000c, 0x662: 0x0005, 0x663: 0x000c, + 0x664: 0x000c, 0x665: 0x000c, 0x666: 0x000c, 0x667: 0x000c, 0x668: 0x000c, 0x669: 0x000c, + 0x66a: 0x000c, 0x66b: 0x000c, 0x66c: 0x000c, 0x66d: 0x000c, 0x66e: 0x000c, 0x66f: 0x000c, + 0x670: 0x000c, 0x671: 0x000c, 0x672: 0x000c, 0x673: 0x000c, 0x674: 0x000c, 0x675: 0x000c, + 0x676: 0x000c, 0x677: 0x000c, 0x678: 0x000c, 0x679: 0x000c, 0x67a: 0x000c, 0x67b: 0x000c, + 0x67c: 0x000c, 0x67d: 0x000c, 0x67e: 0x000c, 0x67f: 0x000c, + // Block 0x1a, offset 0x680 + 0x680: 0x000c, 0x681: 0x000c, 0x682: 0x000c, + 0x6ba: 0x000c, + 0x6bc: 0x000c, + // Block 0x1b, offset 0x6c0 + 0x6c1: 0x000c, 0x6c2: 0x000c, 0x6c3: 0x000c, 0x6c4: 0x000c, 0x6c5: 0x000c, + 0x6c6: 0x000c, 0x6c7: 0x000c, 0x6c8: 0x000c, + 0x6cd: 0x000c, 0x6d1: 0x000c, + 0x6d2: 0x000c, 0x6d3: 0x000c, 0x6d4: 0x000c, 0x6d5: 0x000c, 0x6d6: 0x000c, 0x6d7: 0x000c, + 0x6e2: 0x000c, 0x6e3: 0x000c, + // Block 0x1c, offset 0x700 + 0x701: 0x000c, + 0x73c: 0x000c, + // Block 0x1d, offset 0x740 + 0x741: 0x000c, 0x742: 0x000c, 0x743: 0x000c, 0x744: 0x000c, + 0x74d: 0x000c, + 0x762: 0x000c, 0x763: 0x000c, + 0x772: 0x0004, 0x773: 0x0004, + 0x77b: 0x0004, + 0x77e: 0x000c, + // Block 0x1e, offset 0x780 + 0x781: 0x000c, 0x782: 0x000c, + 0x7bc: 0x000c, + // Block 0x1f, offset 0x7c0 + 0x7c1: 0x000c, 0x7c2: 0x000c, + 0x7c7: 0x000c, 0x7c8: 0x000c, 0x7cb: 0x000c, + 0x7cc: 0x000c, 0x7cd: 0x000c, 0x7d1: 0x000c, + 0x7f0: 0x000c, 0x7f1: 0x000c, 0x7f5: 0x000c, + // Block 0x20, offset 0x800 + 0x801: 0x000c, 0x802: 0x000c, 0x803: 0x000c, 0x804: 0x000c, 0x805: 0x000c, + 0x807: 0x000c, 0x808: 0x000c, + 0x80d: 0x000c, + 0x822: 0x000c, 0x823: 0x000c, + 0x831: 0x0004, + 0x83a: 0x000c, 0x83b: 0x000c, + 0x83c: 0x000c, 0x83d: 0x000c, 0x83e: 0x000c, 0x83f: 0x000c, + // Block 0x21, offset 0x840 + 0x841: 0x000c, + 0x87c: 0x000c, 0x87f: 0x000c, + // Block 0x22, offset 0x880 + 0x881: 0x000c, 0x882: 0x000c, 0x883: 0x000c, 0x884: 0x000c, + 0x88d: 0x000c, + 0x896: 0x000c, + 0x8a2: 0x000c, 0x8a3: 0x000c, + // Block 0x23, offset 0x8c0 + 0x8c2: 0x000c, + // Block 0x24, offset 0x900 + 0x900: 0x000c, + 0x90d: 0x000c, + 0x933: 0x000a, 0x934: 0x000a, 0x935: 0x000a, + 0x936: 0x000a, 0x937: 0x000a, 0x938: 0x000a, 0x939: 0x0004, 0x93a: 0x000a, + // Block 0x25, offset 0x940 + 0x940: 0x000c, 0x944: 0x000c, + 0x97e: 0x000c, 0x97f: 0x000c, + // Block 0x26, offset 0x980 + 0x980: 0x000c, + 0x986: 0x000c, 0x987: 0x000c, 0x988: 0x000c, 0x98a: 0x000c, 0x98b: 0x000c, + 0x98c: 0x000c, 0x98d: 0x000c, + 0x995: 0x000c, 0x996: 0x000c, + 0x9a2: 0x000c, 0x9a3: 0x000c, + 0x9b8: 0x000a, 0x9b9: 0x000a, 0x9ba: 0x000a, 0x9bb: 0x000a, + 0x9bc: 0x000a, 0x9bd: 0x000a, 0x9be: 0x000a, + // Block 0x27, offset 0x9c0 + 0x9cc: 0x000c, 0x9cd: 0x000c, + 0x9e2: 0x000c, 0x9e3: 0x000c, + // Block 0x28, offset 0xa00 + 0xa00: 0x000c, 0xa01: 0x000c, + 0xa3b: 0x000c, + 0xa3c: 0x000c, + // Block 0x29, offset 0xa40 + 0xa41: 0x000c, 0xa42: 0x000c, 0xa43: 0x000c, 0xa44: 0x000c, + 0xa4d: 0x000c, + 0xa62: 0x000c, 0xa63: 0x000c, + // Block 0x2a, offset 0xa80 + 0xa8a: 0x000c, + 0xa92: 0x000c, 0xa93: 0x000c, 0xa94: 0x000c, 0xa96: 0x000c, + // Block 0x2b, offset 0xac0 + 0xaf1: 0x000c, 0xaf4: 0x000c, 0xaf5: 0x000c, + 0xaf6: 0x000c, 0xaf7: 0x000c, 0xaf8: 0x000c, 0xaf9: 0x000c, 0xafa: 0x000c, + 0xaff: 0x0004, + // Block 0x2c, offset 0xb00 + 0xb07: 0x000c, 0xb08: 0x000c, 0xb09: 0x000c, 0xb0a: 0x000c, 0xb0b: 0x000c, + 0xb0c: 0x000c, 0xb0d: 0x000c, 0xb0e: 0x000c, + // Block 0x2d, offset 0xb40 + 0xb71: 0x000c, 0xb74: 0x000c, 0xb75: 0x000c, + 0xb76: 0x000c, 0xb77: 0x000c, 0xb78: 0x000c, 0xb79: 0x000c, 0xb7b: 0x000c, + 0xb7c: 0x000c, + // Block 0x2e, offset 0xb80 + 0xb88: 0x000c, 0xb89: 0x000c, 0xb8a: 0x000c, 0xb8b: 0x000c, + 0xb8c: 0x000c, 0xb8d: 0x000c, + // Block 0x2f, offset 0xbc0 + 0xbd8: 0x000c, 0xbd9: 0x000c, + 0xbf5: 0x000c, + 0xbf7: 0x000c, 0xbf9: 0x000c, 0xbfa: 0x003a, 0xbfb: 0x002a, + 0xbfc: 0x003a, 0xbfd: 0x002a, + // Block 0x30, offset 0xc00 + 0xc31: 0x000c, 0xc32: 0x000c, 0xc33: 0x000c, 0xc34: 0x000c, 0xc35: 0x000c, + 0xc36: 0x000c, 0xc37: 0x000c, 0xc38: 0x000c, 0xc39: 0x000c, 0xc3a: 0x000c, 0xc3b: 0x000c, + 0xc3c: 0x000c, 0xc3d: 0x000c, 0xc3e: 0x000c, + // Block 0x31, offset 0xc40 + 0xc40: 0x000c, 0xc41: 0x000c, 0xc42: 0x000c, 0xc43: 0x000c, 0xc44: 0x000c, + 0xc46: 0x000c, 0xc47: 0x000c, + 0xc4d: 0x000c, 0xc4e: 0x000c, 0xc4f: 0x000c, 0xc50: 0x000c, 0xc51: 0x000c, + 0xc52: 0x000c, 0xc53: 0x000c, 0xc54: 0x000c, 0xc55: 0x000c, 0xc56: 0x000c, 0xc57: 0x000c, + 0xc59: 0x000c, 0xc5a: 0x000c, 0xc5b: 0x000c, 0xc5c: 0x000c, 0xc5d: 0x000c, + 0xc5e: 0x000c, 0xc5f: 0x000c, 0xc60: 0x000c, 0xc61: 0x000c, 0xc62: 0x000c, 0xc63: 0x000c, + 0xc64: 0x000c, 0xc65: 0x000c, 0xc66: 0x000c, 0xc67: 0x000c, 0xc68: 0x000c, 0xc69: 0x000c, + 0xc6a: 0x000c, 0xc6b: 0x000c, 0xc6c: 0x000c, 0xc6d: 0x000c, 0xc6e: 0x000c, 0xc6f: 0x000c, + 0xc70: 0x000c, 0xc71: 0x000c, 0xc72: 0x000c, 0xc73: 0x000c, 0xc74: 0x000c, 0xc75: 0x000c, + 0xc76: 0x000c, 0xc77: 0x000c, 0xc78: 0x000c, 0xc79: 0x000c, 0xc7a: 0x000c, 0xc7b: 0x000c, + 0xc7c: 0x000c, + // Block 0x32, offset 0xc80 + 0xc86: 0x000c, + // Block 0x33, offset 0xcc0 + 0xced: 0x000c, 0xcee: 0x000c, 0xcef: 0x000c, + 0xcf0: 0x000c, 0xcf2: 0x000c, 0xcf3: 0x000c, 0xcf4: 0x000c, 0xcf5: 0x000c, + 0xcf6: 0x000c, 0xcf7: 0x000c, 0xcf9: 0x000c, 0xcfa: 0x000c, + 0xcfd: 0x000c, 0xcfe: 0x000c, + // Block 0x34, offset 0xd00 + 0xd18: 0x000c, 0xd19: 0x000c, + 0xd1e: 0x000c, 0xd1f: 0x000c, 0xd20: 0x000c, + 0xd31: 0x000c, 0xd32: 0x000c, 0xd33: 0x000c, 0xd34: 0x000c, + // Block 0x35, offset 0xd40 + 0xd42: 0x000c, 0xd45: 0x000c, + 0xd46: 0x000c, + 0xd4d: 0x000c, + 0xd5d: 0x000c, + // Block 0x36, offset 0xd80 + 0xd9d: 0x000c, + 0xd9e: 0x000c, 0xd9f: 0x000c, + // Block 0x37, offset 0xdc0 + 0xdd0: 0x000a, 0xdd1: 0x000a, + 0xdd2: 0x000a, 0xdd3: 0x000a, 0xdd4: 0x000a, 0xdd5: 0x000a, 0xdd6: 0x000a, 0xdd7: 0x000a, + 0xdd8: 0x000a, 0xdd9: 0x000a, + // Block 0x38, offset 0xe00 + 0xe00: 0x000a, + // Block 0x39, offset 0xe40 + 0xe40: 0x0009, + 0xe5b: 0x007a, 0xe5c: 0x006a, + // Block 0x3a, offset 0xe80 + 0xe92: 0x000c, 0xe93: 0x000c, 0xe94: 0x000c, + 0xeb2: 0x000c, 0xeb3: 0x000c, 0xeb4: 0x000c, + // Block 0x3b, offset 0xec0 + 0xed2: 0x000c, 0xed3: 0x000c, + 0xef2: 0x000c, 0xef3: 0x000c, + // Block 0x3c, offset 0xf00 + 0xf34: 0x000c, 0xf35: 0x000c, + 0xf37: 0x000c, 0xf38: 0x000c, 0xf39: 0x000c, 0xf3a: 0x000c, 0xf3b: 0x000c, + 0xf3c: 0x000c, 0xf3d: 0x000c, + // Block 0x3d, offset 0xf40 + 0xf46: 0x000c, 0xf49: 0x000c, 0xf4a: 0x000c, 0xf4b: 0x000c, + 0xf4c: 0x000c, 0xf4d: 0x000c, 0xf4e: 0x000c, 0xf4f: 0x000c, 0xf50: 0x000c, 0xf51: 0x000c, + 0xf52: 0x000c, 0xf53: 0x000c, + 0xf5b: 0x0004, 0xf5d: 0x000c, + 0xf70: 0x000a, 0xf71: 0x000a, 0xf72: 0x000a, 0xf73: 0x000a, 0xf74: 0x000a, 0xf75: 0x000a, + 0xf76: 0x000a, 0xf77: 0x000a, 0xf78: 0x000a, 0xf79: 0x000a, + // Block 0x3e, offset 0xf80 + 0xf80: 0x000a, 0xf81: 0x000a, 0xf82: 0x000a, 0xf83: 0x000a, 0xf84: 0x000a, 0xf85: 0x000a, + 0xf86: 0x000a, 0xf87: 0x000a, 0xf88: 0x000a, 0xf89: 0x000a, 0xf8a: 0x000a, 0xf8b: 0x000c, + 0xf8c: 0x000c, 0xf8d: 0x000c, 0xf8e: 0x000b, + // Block 0x3f, offset 0xfc0 + 0xfc5: 0x000c, + 0xfc6: 0x000c, + 0xfe9: 0x000c, + // Block 0x40, offset 0x1000 + 0x1020: 0x000c, 0x1021: 0x000c, 0x1022: 0x000c, + 0x1027: 0x000c, 0x1028: 0x000c, + 0x1032: 0x000c, + 0x1039: 0x000c, 0x103a: 0x000c, 0x103b: 0x000c, + // Block 0x41, offset 0x1040 + 0x1040: 0x000a, 0x1044: 0x000a, 0x1045: 0x000a, + // Block 0x42, offset 0x1080 + 0x109e: 0x000a, 0x109f: 0x000a, 0x10a0: 0x000a, 0x10a1: 0x000a, 0x10a2: 0x000a, 0x10a3: 0x000a, + 0x10a4: 0x000a, 0x10a5: 0x000a, 0x10a6: 0x000a, 0x10a7: 0x000a, 0x10a8: 0x000a, 0x10a9: 0x000a, + 0x10aa: 0x000a, 0x10ab: 0x000a, 0x10ac: 0x000a, 0x10ad: 0x000a, 0x10ae: 0x000a, 0x10af: 0x000a, + 0x10b0: 0x000a, 0x10b1: 0x000a, 0x10b2: 0x000a, 0x10b3: 0x000a, 0x10b4: 0x000a, 0x10b5: 0x000a, + 0x10b6: 0x000a, 0x10b7: 0x000a, 0x10b8: 0x000a, 0x10b9: 0x000a, 0x10ba: 0x000a, 0x10bb: 0x000a, + 0x10bc: 0x000a, 0x10bd: 0x000a, 0x10be: 0x000a, 0x10bf: 0x000a, + // Block 0x43, offset 0x10c0 + 0x10d7: 0x000c, + 0x10d8: 0x000c, 0x10db: 0x000c, + // Block 0x44, offset 0x1100 + 0x1116: 0x000c, + 0x1118: 0x000c, 0x1119: 0x000c, 0x111a: 0x000c, 0x111b: 0x000c, 0x111c: 0x000c, 0x111d: 0x000c, + 0x111e: 0x000c, 0x1120: 0x000c, 0x1122: 0x000c, + 0x1125: 0x000c, 0x1126: 0x000c, 0x1127: 0x000c, 0x1128: 0x000c, 0x1129: 0x000c, + 0x112a: 0x000c, 0x112b: 0x000c, 0x112c: 0x000c, + 0x1133: 0x000c, 0x1134: 0x000c, 0x1135: 0x000c, + 0x1136: 0x000c, 0x1137: 0x000c, 0x1138: 0x000c, 0x1139: 0x000c, 0x113a: 0x000c, 0x113b: 0x000c, + 0x113c: 0x000c, 0x113f: 0x000c, + // Block 0x45, offset 0x1140 + 0x1170: 0x000c, 0x1171: 0x000c, 0x1172: 0x000c, 0x1173: 0x000c, 0x1174: 0x000c, 0x1175: 0x000c, + 0x1176: 0x000c, 0x1177: 0x000c, 0x1178: 0x000c, 0x1179: 0x000c, 0x117a: 0x000c, 0x117b: 0x000c, + 0x117c: 0x000c, 0x117d: 0x000c, 0x117e: 0x000c, + // Block 0x46, offset 0x1180 + 0x1180: 0x000c, 0x1181: 0x000c, 0x1182: 0x000c, 0x1183: 0x000c, + 0x11b4: 0x000c, + 0x11b6: 0x000c, 0x11b7: 0x000c, 0x11b8: 0x000c, 0x11b9: 0x000c, 0x11ba: 0x000c, + 0x11bc: 0x000c, + // Block 0x47, offset 0x11c0 + 0x11c2: 0x000c, + 0x11eb: 0x000c, 0x11ec: 0x000c, 0x11ed: 0x000c, 0x11ee: 0x000c, 0x11ef: 0x000c, + 0x11f0: 0x000c, 0x11f1: 0x000c, 0x11f2: 0x000c, 0x11f3: 0x000c, + // Block 0x48, offset 0x1200 + 0x1200: 0x000c, 0x1201: 0x000c, + 0x1222: 0x000c, 0x1223: 0x000c, + 0x1224: 0x000c, 0x1225: 0x000c, 0x1228: 0x000c, 0x1229: 0x000c, + 0x122b: 0x000c, 0x122c: 0x000c, 0x122d: 0x000c, + // Block 0x49, offset 0x1240 + 0x1266: 0x000c, 0x1268: 0x000c, 0x1269: 0x000c, + 0x126d: 0x000c, 0x126f: 0x000c, + 0x1270: 0x000c, 0x1271: 0x000c, + // Block 0x4a, offset 0x1280 + 0x12ac: 0x000c, 0x12ad: 0x000c, 0x12ae: 0x000c, 0x12af: 0x000c, + 0x12b0: 0x000c, 0x12b1: 0x000c, 0x12b2: 0x000c, 0x12b3: 0x000c, + 0x12b6: 0x000c, 0x12b7: 0x000c, + // Block 0x4b, offset 0x12c0 + 0x12d0: 0x000c, 0x12d1: 0x000c, + 0x12d2: 0x000c, 0x12d4: 0x000c, 0x12d5: 0x000c, 0x12d6: 0x000c, 0x12d7: 0x000c, + 0x12d8: 0x000c, 0x12d9: 0x000c, 0x12da: 0x000c, 0x12db: 0x000c, 0x12dc: 0x000c, 0x12dd: 0x000c, + 0x12de: 0x000c, 0x12df: 0x000c, 0x12e0: 0x000c, 0x12e2: 0x000c, 0x12e3: 0x000c, + 0x12e4: 0x000c, 0x12e5: 0x000c, 0x12e6: 0x000c, 0x12e7: 0x000c, 0x12e8: 0x000c, + 0x12ed: 0x000c, + 0x12f4: 0x000c, + 0x12f8: 0x000c, 0x12f9: 0x000c, + // Block 0x4c, offset 0x1300 + 0x1300: 0x000c, 0x1301: 0x000c, 0x1302: 0x000c, 0x1303: 0x000c, 0x1304: 0x000c, 0x1305: 0x000c, + 0x1306: 0x000c, 0x1307: 0x000c, 0x1308: 0x000c, 0x1309: 0x000c, 0x130a: 0x000c, 0x130b: 0x000c, + 0x130c: 0x000c, 0x130d: 0x000c, 0x130e: 0x000c, 0x130f: 0x000c, 0x1310: 0x000c, 0x1311: 0x000c, + 0x1312: 0x000c, 0x1313: 0x000c, 0x1314: 0x000c, 0x1315: 0x000c, 0x1316: 0x000c, 0x1317: 0x000c, + 0x1318: 0x000c, 0x1319: 0x000c, 0x131a: 0x000c, 0x131b: 0x000c, 0x131c: 0x000c, 0x131d: 0x000c, + 0x131e: 0x000c, 0x131f: 0x000c, 0x1320: 0x000c, 0x1321: 0x000c, 0x1322: 0x000c, 0x1323: 0x000c, + 0x1324: 0x000c, 0x1325: 0x000c, 0x1326: 0x000c, 0x1327: 0x000c, 0x1328: 0x000c, 0x1329: 0x000c, + 0x132a: 0x000c, 0x132b: 0x000c, 0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c, + 0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c, 0x1334: 0x000c, 0x1335: 0x000c, + 0x1336: 0x000c, 0x1337: 0x000c, 0x1338: 0x000c, 0x1339: 0x000c, 0x133b: 0x000c, + 0x133c: 0x000c, 0x133d: 0x000c, 0x133e: 0x000c, 0x133f: 0x000c, + // Block 0x4d, offset 0x1340 + 0x137d: 0x000a, 0x137f: 0x000a, + // Block 0x4e, offset 0x1380 + 0x1380: 0x000a, 0x1381: 0x000a, + 0x138d: 0x000a, 0x138e: 0x000a, 0x138f: 0x000a, + 0x139d: 0x000a, + 0x139e: 0x000a, 0x139f: 0x000a, + 0x13ad: 0x000a, 0x13ae: 0x000a, 0x13af: 0x000a, + 0x13bd: 0x000a, 0x13be: 0x000a, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x0009, 0x13c1: 0x0009, 0x13c2: 0x0009, 0x13c3: 0x0009, 0x13c4: 0x0009, 0x13c5: 0x0009, + 0x13c6: 0x0009, 0x13c7: 0x0009, 0x13c8: 0x0009, 0x13c9: 0x0009, 0x13ca: 0x0009, 0x13cb: 0x000b, + 0x13cc: 0x000b, 0x13cd: 0x000b, 0x13cf: 0x0001, 0x13d0: 0x000a, 0x13d1: 0x000a, + 0x13d2: 0x000a, 0x13d3: 0x000a, 0x13d4: 0x000a, 0x13d5: 0x000a, 0x13d6: 0x000a, 0x13d7: 0x000a, + 0x13d8: 0x000a, 0x13d9: 0x000a, 0x13da: 0x000a, 0x13db: 0x000a, 0x13dc: 0x000a, 0x13dd: 0x000a, + 0x13de: 0x000a, 0x13df: 0x000a, 0x13e0: 0x000a, 0x13e1: 0x000a, 0x13e2: 0x000a, 0x13e3: 0x000a, + 0x13e4: 0x000a, 0x13e5: 0x000a, 0x13e6: 0x000a, 0x13e7: 0x000a, 0x13e8: 0x0009, 0x13e9: 0x0007, + 0x13ea: 0x000e, 0x13eb: 0x000e, 0x13ec: 0x000e, 0x13ed: 0x000e, 0x13ee: 0x000e, 0x13ef: 0x0006, + 0x13f0: 0x0004, 0x13f1: 0x0004, 0x13f2: 0x0004, 0x13f3: 0x0004, 0x13f4: 0x0004, 0x13f5: 0x000a, + 0x13f6: 0x000a, 0x13f7: 0x000a, 0x13f8: 0x000a, 0x13f9: 0x000a, 0x13fa: 0x000a, 0x13fb: 0x000a, + 0x13fc: 0x000a, 0x13fd: 0x000a, 0x13fe: 0x000a, 0x13ff: 0x000a, + // Block 0x50, offset 0x1400 + 0x1400: 0x000a, 0x1401: 0x000a, 0x1402: 0x000a, 0x1403: 0x000a, 0x1404: 0x0006, 0x1405: 0x009a, + 0x1406: 0x008a, 0x1407: 0x000a, 0x1408: 0x000a, 0x1409: 0x000a, 0x140a: 0x000a, 0x140b: 0x000a, + 0x140c: 0x000a, 0x140d: 0x000a, 0x140e: 0x000a, 0x140f: 0x000a, 0x1410: 0x000a, 0x1411: 0x000a, + 0x1412: 0x000a, 0x1413: 0x000a, 0x1414: 0x000a, 0x1415: 0x000a, 0x1416: 0x000a, 0x1417: 0x000a, + 0x1418: 0x000a, 0x1419: 0x000a, 0x141a: 0x000a, 0x141b: 0x000a, 0x141c: 0x000a, 0x141d: 0x000a, + 0x141e: 0x000a, 0x141f: 0x0009, 0x1420: 0x000b, 0x1421: 0x000b, 0x1422: 0x000b, 0x1423: 0x000b, + 0x1424: 0x000b, 0x1425: 0x000b, 0x1426: 0x000e, 0x1427: 0x000e, 0x1428: 0x000e, 0x1429: 0x000e, + 0x142a: 0x000b, 0x142b: 0x000b, 0x142c: 0x000b, 0x142d: 0x000b, 0x142e: 0x000b, 0x142f: 0x000b, + 0x1430: 0x0002, 0x1434: 0x0002, 0x1435: 0x0002, + 0x1436: 0x0002, 0x1437: 0x0002, 0x1438: 0x0002, 0x1439: 0x0002, 0x143a: 0x0003, 0x143b: 0x0003, + 0x143c: 0x000a, 0x143d: 0x009a, 0x143e: 0x008a, + // Block 0x51, offset 0x1440 + 0x1440: 0x0002, 0x1441: 0x0002, 0x1442: 0x0002, 0x1443: 0x0002, 0x1444: 0x0002, 0x1445: 0x0002, + 0x1446: 0x0002, 0x1447: 0x0002, 0x1448: 0x0002, 0x1449: 0x0002, 0x144a: 0x0003, 0x144b: 0x0003, + 0x144c: 0x000a, 0x144d: 0x009a, 0x144e: 0x008a, + 0x1460: 0x0004, 0x1461: 0x0004, 0x1462: 0x0004, 0x1463: 0x0004, + 0x1464: 0x0004, 0x1465: 0x0004, 0x1466: 0x0004, 0x1467: 0x0004, 0x1468: 0x0004, 0x1469: 0x0004, + 0x146a: 0x0004, 0x146b: 0x0004, 0x146c: 0x0004, 0x146d: 0x0004, 0x146e: 0x0004, 0x146f: 0x0004, + 0x1470: 0x0004, 0x1471: 0x0004, 0x1472: 0x0004, 0x1473: 0x0004, 0x1474: 0x0004, 0x1475: 0x0004, + 0x1476: 0x0004, 0x1477: 0x0004, 0x1478: 0x0004, 0x1479: 0x0004, 0x147a: 0x0004, 0x147b: 0x0004, + 0x147c: 0x0004, 0x147d: 0x0004, 0x147e: 0x0004, 0x147f: 0x0004, + // Block 0x52, offset 0x1480 + 0x1480: 0x0004, 0x1481: 0x0004, 0x1482: 0x0004, 0x1483: 0x0004, 0x1484: 0x0004, 0x1485: 0x0004, + 0x1486: 0x0004, 0x1487: 0x0004, 0x1488: 0x0004, 0x1489: 0x0004, 0x148a: 0x0004, 0x148b: 0x0004, + 0x148c: 0x0004, 0x148d: 0x0004, 0x148e: 0x0004, 0x148f: 0x0004, 0x1490: 0x000c, 0x1491: 0x000c, + 0x1492: 0x000c, 0x1493: 0x000c, 0x1494: 0x000c, 0x1495: 0x000c, 0x1496: 0x000c, 0x1497: 0x000c, + 0x1498: 0x000c, 0x1499: 0x000c, 0x149a: 0x000c, 0x149b: 0x000c, 0x149c: 0x000c, 0x149d: 0x000c, + 0x149e: 0x000c, 0x149f: 0x000c, 0x14a0: 0x000c, 0x14a1: 0x000c, 0x14a2: 0x000c, 0x14a3: 0x000c, + 0x14a4: 0x000c, 0x14a5: 0x000c, 0x14a6: 0x000c, 0x14a7: 0x000c, 0x14a8: 0x000c, 0x14a9: 0x000c, + 0x14aa: 0x000c, 0x14ab: 0x000c, 0x14ac: 0x000c, 0x14ad: 0x000c, 0x14ae: 0x000c, 0x14af: 0x000c, + 0x14b0: 0x000c, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x000a, 0x14c1: 0x000a, 0x14c3: 0x000a, 0x14c4: 0x000a, 0x14c5: 0x000a, + 0x14c6: 0x000a, 0x14c8: 0x000a, 0x14c9: 0x000a, + 0x14d4: 0x000a, 0x14d6: 0x000a, 0x14d7: 0x000a, + 0x14d8: 0x000a, + 0x14de: 0x000a, 0x14df: 0x000a, 0x14e0: 0x000a, 0x14e1: 0x000a, 0x14e2: 0x000a, 0x14e3: 0x000a, + 0x14e5: 0x000a, 0x14e7: 0x000a, 0x14e9: 0x000a, + 0x14ee: 0x0004, + 0x14fa: 0x000a, 0x14fb: 0x000a, + // Block 0x54, offset 0x1500 + 0x1500: 0x000a, 0x1501: 0x000a, 0x1502: 0x000a, 0x1503: 0x000a, 0x1504: 0x000a, + 0x150a: 0x000a, 0x150b: 0x000a, + 0x150c: 0x000a, 0x150d: 0x000a, 0x1510: 0x000a, 0x1511: 0x000a, + 0x1512: 0x000a, 0x1513: 0x000a, 0x1514: 0x000a, 0x1515: 0x000a, 0x1516: 0x000a, 0x1517: 0x000a, + 0x1518: 0x000a, 0x1519: 0x000a, 0x151a: 0x000a, 0x151b: 0x000a, 0x151c: 0x000a, 0x151d: 0x000a, + 0x151e: 0x000a, 0x151f: 0x000a, + // Block 0x55, offset 0x1540 + 0x1549: 0x000a, 0x154a: 0x000a, 0x154b: 0x000a, + 0x1550: 0x000a, 0x1551: 0x000a, + 0x1552: 0x000a, 0x1553: 0x000a, 0x1554: 0x000a, 0x1555: 0x000a, 0x1556: 0x000a, 0x1557: 0x000a, + 0x1558: 0x000a, 0x1559: 0x000a, 0x155a: 0x000a, 0x155b: 0x000a, 0x155c: 0x000a, 0x155d: 0x000a, + 0x155e: 0x000a, 0x155f: 0x000a, 0x1560: 0x000a, 0x1561: 0x000a, 0x1562: 0x000a, 0x1563: 0x000a, + 0x1564: 0x000a, 0x1565: 0x000a, 0x1566: 0x000a, 0x1567: 0x000a, 0x1568: 0x000a, 0x1569: 0x000a, + 0x156a: 0x000a, 0x156b: 0x000a, 0x156c: 0x000a, 0x156d: 0x000a, 0x156e: 0x000a, 0x156f: 0x000a, + 0x1570: 0x000a, 0x1571: 0x000a, 0x1572: 0x000a, 0x1573: 0x000a, 0x1574: 0x000a, 0x1575: 0x000a, + 0x1576: 0x000a, 0x1577: 0x000a, 0x1578: 0x000a, 0x1579: 0x000a, 0x157a: 0x000a, 0x157b: 0x000a, + 0x157c: 0x000a, 0x157d: 0x000a, 0x157e: 0x000a, 0x157f: 0x000a, + // Block 0x56, offset 0x1580 + 0x1580: 0x000a, 0x1581: 0x000a, 0x1582: 0x000a, 0x1583: 0x000a, 0x1584: 0x000a, 0x1585: 0x000a, + 0x1586: 0x000a, 0x1587: 0x000a, 0x1588: 0x000a, 0x1589: 0x000a, 0x158a: 0x000a, 0x158b: 0x000a, + 0x158c: 0x000a, 0x158d: 0x000a, 0x158e: 0x000a, 0x158f: 0x000a, 0x1590: 0x000a, 0x1591: 0x000a, + 0x1592: 0x000a, 0x1593: 0x000a, 0x1594: 0x000a, 0x1595: 0x000a, 0x1596: 0x000a, 0x1597: 0x000a, + 0x1598: 0x000a, 0x1599: 0x000a, 0x159a: 0x000a, 0x159b: 0x000a, 0x159c: 0x000a, 0x159d: 0x000a, + 0x159e: 0x000a, 0x159f: 0x000a, 0x15a0: 0x000a, 0x15a1: 0x000a, 0x15a2: 0x000a, 0x15a3: 0x000a, + 0x15a4: 0x000a, 0x15a5: 0x000a, 0x15a6: 0x000a, 0x15a7: 0x000a, 0x15a8: 0x000a, 0x15a9: 0x000a, + 0x15aa: 0x000a, 0x15ab: 0x000a, 0x15ac: 0x000a, 0x15ad: 0x000a, 0x15ae: 0x000a, 0x15af: 0x000a, + 0x15b0: 0x000a, 0x15b1: 0x000a, 0x15b2: 0x000a, 0x15b3: 0x000a, 0x15b4: 0x000a, 0x15b5: 0x000a, + 0x15b6: 0x000a, 0x15b7: 0x000a, 0x15b8: 0x000a, 0x15b9: 0x000a, 0x15ba: 0x000a, 0x15bb: 0x000a, + 0x15bc: 0x000a, 0x15bd: 0x000a, 0x15be: 0x000a, 0x15bf: 0x000a, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x000a, 0x15c1: 0x000a, 0x15c2: 0x000a, 0x15c3: 0x000a, 0x15c4: 0x000a, 0x15c5: 0x000a, + 0x15c6: 0x000a, 0x15c7: 0x000a, 0x15c8: 0x000a, 0x15c9: 0x000a, 0x15ca: 0x000a, 0x15cb: 0x000a, + 0x15cc: 0x000a, 0x15cd: 0x000a, 0x15ce: 0x000a, 0x15cf: 0x000a, 0x15d0: 0x000a, 0x15d1: 0x000a, + 0x15d2: 0x0003, 0x15d3: 0x0004, 0x15d4: 0x000a, 0x15d5: 0x000a, 0x15d6: 0x000a, 0x15d7: 0x000a, + 0x15d8: 0x000a, 0x15d9: 0x000a, 0x15da: 0x000a, 0x15db: 0x000a, 0x15dc: 0x000a, 0x15dd: 0x000a, + 0x15de: 0x000a, 0x15df: 0x000a, 0x15e0: 0x000a, 0x15e1: 0x000a, 0x15e2: 0x000a, 0x15e3: 0x000a, + 0x15e4: 0x000a, 0x15e5: 0x000a, 0x15e6: 0x000a, 0x15e7: 0x000a, 0x15e8: 0x000a, 0x15e9: 0x000a, + 0x15ea: 0x000a, 0x15eb: 0x000a, 0x15ec: 0x000a, 0x15ed: 0x000a, 0x15ee: 0x000a, 0x15ef: 0x000a, + 0x15f0: 0x000a, 0x15f1: 0x000a, 0x15f2: 0x000a, 0x15f3: 0x000a, 0x15f4: 0x000a, 0x15f5: 0x000a, + 0x15f6: 0x000a, 0x15f7: 0x000a, 0x15f8: 0x000a, 0x15f9: 0x000a, 0x15fa: 0x000a, 0x15fb: 0x000a, + 0x15fc: 0x000a, 0x15fd: 0x000a, 0x15fe: 0x000a, 0x15ff: 0x000a, + // Block 0x58, offset 0x1600 + 0x1600: 0x000a, 0x1601: 0x000a, 0x1602: 0x000a, 0x1603: 0x000a, 0x1604: 0x000a, 0x1605: 0x000a, + 0x1606: 0x000a, 0x1607: 0x000a, 0x1608: 0x003a, 0x1609: 0x002a, 0x160a: 0x003a, 0x160b: 0x002a, + 0x160c: 0x000a, 0x160d: 0x000a, 0x160e: 0x000a, 0x160f: 0x000a, 0x1610: 0x000a, 0x1611: 0x000a, + 0x1612: 0x000a, 0x1613: 0x000a, 0x1614: 0x000a, 0x1615: 0x000a, 0x1616: 0x000a, 0x1617: 0x000a, + 0x1618: 0x000a, 0x1619: 0x000a, 0x161a: 0x000a, 0x161b: 0x000a, 0x161c: 0x000a, 0x161d: 0x000a, + 0x161e: 0x000a, 0x161f: 0x000a, 0x1620: 0x000a, 0x1621: 0x000a, 0x1622: 0x000a, 0x1623: 0x000a, + 0x1624: 0x000a, 0x1625: 0x000a, 0x1626: 0x000a, 0x1627: 0x000a, 0x1628: 0x000a, 0x1629: 0x009a, + 0x162a: 0x008a, 0x162b: 0x000a, 0x162c: 0x000a, 0x162d: 0x000a, 0x162e: 0x000a, 0x162f: 0x000a, + 0x1630: 0x000a, 0x1631: 0x000a, 0x1632: 0x000a, 0x1633: 0x000a, 0x1634: 0x000a, 0x1635: 0x000a, + // Block 0x59, offset 0x1640 + 0x167b: 0x000a, + 0x167c: 0x000a, 0x167d: 0x000a, 0x167e: 0x000a, 0x167f: 0x000a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x000a, 0x1681: 0x000a, 0x1682: 0x000a, 0x1683: 0x000a, 0x1684: 0x000a, 0x1685: 0x000a, + 0x1686: 0x000a, 0x1687: 0x000a, 0x1688: 0x000a, 0x1689: 0x000a, 0x168a: 0x000a, 0x168b: 0x000a, + 0x168c: 0x000a, 0x168d: 0x000a, 0x168e: 0x000a, 0x168f: 0x000a, 0x1690: 0x000a, 0x1691: 0x000a, + 0x1692: 0x000a, 0x1693: 0x000a, 0x1694: 0x000a, 0x1696: 0x000a, 0x1697: 0x000a, + 0x1698: 0x000a, 0x1699: 0x000a, 0x169a: 0x000a, 0x169b: 0x000a, 0x169c: 0x000a, 0x169d: 0x000a, + 0x169e: 0x000a, 0x169f: 0x000a, 0x16a0: 0x000a, 0x16a1: 0x000a, 0x16a2: 0x000a, 0x16a3: 0x000a, + 0x16a4: 0x000a, 0x16a5: 0x000a, 0x16a6: 0x000a, 0x16a7: 0x000a, 0x16a8: 0x000a, 0x16a9: 0x000a, + 0x16aa: 0x000a, 0x16ab: 0x000a, 0x16ac: 0x000a, 0x16ad: 0x000a, 0x16ae: 0x000a, 0x16af: 0x000a, + 0x16b0: 0x000a, 0x16b1: 0x000a, 0x16b2: 0x000a, 0x16b3: 0x000a, 0x16b4: 0x000a, 0x16b5: 0x000a, + 0x16b6: 0x000a, 0x16b7: 0x000a, 0x16b8: 0x000a, 0x16b9: 0x000a, 0x16ba: 0x000a, 0x16bb: 0x000a, + 0x16bc: 0x000a, 0x16bd: 0x000a, 0x16be: 0x000a, 0x16bf: 0x000a, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x000a, 0x16c1: 0x000a, 0x16c2: 0x000a, 0x16c3: 0x000a, 0x16c4: 0x000a, 0x16c5: 0x000a, + 0x16c6: 0x000a, 0x16c7: 0x000a, 0x16c8: 0x000a, 0x16c9: 0x000a, 0x16ca: 0x000a, 0x16cb: 0x000a, + 0x16cc: 0x000a, 0x16cd: 0x000a, 0x16ce: 0x000a, 0x16cf: 0x000a, 0x16d0: 0x000a, 0x16d1: 0x000a, + 0x16d2: 0x000a, 0x16d3: 0x000a, 0x16d4: 0x000a, 0x16d5: 0x000a, 0x16d6: 0x000a, 0x16d7: 0x000a, + 0x16d8: 0x000a, 0x16d9: 0x000a, 0x16da: 0x000a, 0x16db: 0x000a, 0x16dc: 0x000a, 0x16dd: 0x000a, + 0x16de: 0x000a, 0x16df: 0x000a, 0x16e0: 0x000a, 0x16e1: 0x000a, 0x16e2: 0x000a, 0x16e3: 0x000a, + 0x16e4: 0x000a, 0x16e5: 0x000a, 0x16e6: 0x000a, + // Block 0x5c, offset 0x1700 + 0x1700: 0x000a, 0x1701: 0x000a, 0x1702: 0x000a, 0x1703: 0x000a, 0x1704: 0x000a, 0x1705: 0x000a, + 0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a, + 0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a, + 0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a, 0x1727: 0x000a, 0x1728: 0x000a, 0x1729: 0x000a, + 0x172a: 0x000a, 0x172b: 0x000a, 0x172c: 0x000a, 0x172d: 0x000a, 0x172e: 0x000a, 0x172f: 0x000a, + 0x1730: 0x000a, 0x1731: 0x000a, 0x1732: 0x000a, 0x1733: 0x000a, 0x1734: 0x000a, 0x1735: 0x000a, + 0x1736: 0x000a, 0x1737: 0x000a, 0x1738: 0x000a, 0x1739: 0x000a, 0x173a: 0x000a, 0x173b: 0x000a, + 0x173c: 0x000a, 0x173d: 0x000a, 0x173e: 0x000a, 0x173f: 0x000a, + // Block 0x5d, offset 0x1740 + 0x1740: 0x000a, 0x1741: 0x000a, 0x1742: 0x000a, 0x1743: 0x000a, 0x1744: 0x000a, 0x1745: 0x000a, + 0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x0002, 0x1749: 0x0002, 0x174a: 0x0002, 0x174b: 0x0002, + 0x174c: 0x0002, 0x174d: 0x0002, 0x174e: 0x0002, 0x174f: 0x0002, 0x1750: 0x0002, 0x1751: 0x0002, + 0x1752: 0x0002, 0x1753: 0x0002, 0x1754: 0x0002, 0x1755: 0x0002, 0x1756: 0x0002, 0x1757: 0x0002, + 0x1758: 0x0002, 0x1759: 0x0002, 0x175a: 0x0002, 0x175b: 0x0002, + // Block 0x5e, offset 0x1780 + 0x17aa: 0x000a, 0x17ab: 0x000a, 0x17ac: 0x000a, 0x17ad: 0x000a, 0x17ae: 0x000a, 0x17af: 0x000a, + 0x17b0: 0x000a, 0x17b1: 0x000a, 0x17b2: 0x000a, 0x17b3: 0x000a, 0x17b4: 0x000a, 0x17b5: 0x000a, + 0x17b6: 0x000a, 0x17b7: 0x000a, 0x17b8: 0x000a, 0x17b9: 0x000a, 0x17ba: 0x000a, 0x17bb: 0x000a, + 0x17bc: 0x000a, 0x17bd: 0x000a, 0x17be: 0x000a, 0x17bf: 0x000a, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x000a, 0x17c1: 0x000a, 0x17c2: 0x000a, 0x17c3: 0x000a, 0x17c4: 0x000a, 0x17c5: 0x000a, + 0x17c6: 0x000a, 0x17c7: 0x000a, 0x17c8: 0x000a, 0x17c9: 0x000a, 0x17ca: 0x000a, 0x17cb: 0x000a, + 0x17cc: 0x000a, 0x17cd: 0x000a, 0x17ce: 0x000a, 0x17cf: 0x000a, 0x17d0: 0x000a, 0x17d1: 0x000a, + 0x17d2: 0x000a, 0x17d3: 0x000a, 0x17d4: 0x000a, 0x17d5: 0x000a, 0x17d6: 0x000a, 0x17d7: 0x000a, + 0x17d8: 0x000a, 0x17d9: 0x000a, 0x17da: 0x000a, 0x17db: 0x000a, 0x17dc: 0x000a, 0x17dd: 0x000a, + 0x17de: 0x000a, 0x17df: 0x000a, 0x17e0: 0x000a, 0x17e1: 0x000a, 0x17e2: 0x000a, 0x17e3: 0x000a, + 0x17e4: 0x000a, 0x17e5: 0x000a, 0x17e6: 0x000a, 0x17e7: 0x000a, 0x17e8: 0x000a, 0x17e9: 0x000a, + 0x17ea: 0x000a, 0x17eb: 0x000a, 0x17ed: 0x000a, 0x17ee: 0x000a, 0x17ef: 0x000a, + 0x17f0: 0x000a, 0x17f1: 0x000a, 0x17f2: 0x000a, 0x17f3: 0x000a, 0x17f4: 0x000a, 0x17f5: 0x000a, + 0x17f6: 0x000a, 0x17f7: 0x000a, 0x17f8: 0x000a, 0x17f9: 0x000a, 0x17fa: 0x000a, 0x17fb: 0x000a, + 0x17fc: 0x000a, 0x17fd: 0x000a, 0x17fe: 0x000a, 0x17ff: 0x000a, + // Block 0x60, offset 0x1800 + 0x1800: 0x000a, 0x1801: 0x000a, 0x1802: 0x000a, 0x1803: 0x000a, 0x1804: 0x000a, 0x1805: 0x000a, + 0x1806: 0x000a, 0x1807: 0x000a, 0x1808: 0x000a, 0x1809: 0x000a, 0x180a: 0x000a, 0x180b: 0x000a, + 0x180c: 0x000a, 0x180d: 0x000a, 0x180e: 0x000a, 0x180f: 0x000a, 0x1810: 0x000a, 0x1811: 0x000a, + 0x1812: 0x000a, 0x1813: 0x000a, 0x1814: 0x000a, 0x1815: 0x000a, 0x1816: 0x000a, 0x1817: 0x000a, + 0x1818: 0x000a, 0x1819: 0x000a, 0x181a: 0x000a, 0x181b: 0x000a, 0x181c: 0x000a, 0x181d: 0x000a, + 0x181e: 0x000a, 0x181f: 0x000a, 0x1820: 0x000a, 0x1821: 0x000a, 0x1822: 0x000a, 0x1823: 0x000a, + 0x1824: 0x000a, 0x1825: 0x000a, 0x1826: 0x000a, 0x1827: 0x000a, 0x1828: 0x003a, 0x1829: 0x002a, + 0x182a: 0x003a, 0x182b: 0x002a, 0x182c: 0x003a, 0x182d: 0x002a, 0x182e: 0x003a, 0x182f: 0x002a, + 0x1830: 0x003a, 0x1831: 0x002a, 0x1832: 0x003a, 0x1833: 0x002a, 0x1834: 0x003a, 0x1835: 0x002a, + 0x1836: 0x000a, 0x1837: 0x000a, 0x1838: 0x000a, 0x1839: 0x000a, 0x183a: 0x000a, 0x183b: 0x000a, + 0x183c: 0x000a, 0x183d: 0x000a, 0x183e: 0x000a, 0x183f: 0x000a, + // Block 0x61, offset 0x1840 + 0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x009a, + 0x1846: 0x008a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a, + 0x184c: 0x000a, 0x184d: 0x000a, 0x184e: 0x000a, 0x184f: 0x000a, 0x1850: 0x000a, 0x1851: 0x000a, + 0x1852: 0x000a, 0x1853: 0x000a, 0x1854: 0x000a, 0x1855: 0x000a, 0x1856: 0x000a, 0x1857: 0x000a, + 0x1858: 0x000a, 0x1859: 0x000a, 0x185a: 0x000a, 0x185b: 0x000a, 0x185c: 0x000a, 0x185d: 0x000a, + 0x185e: 0x000a, 0x185f: 0x000a, 0x1860: 0x000a, 0x1861: 0x000a, 0x1862: 0x000a, 0x1863: 0x000a, + 0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x003a, 0x1867: 0x002a, 0x1868: 0x003a, 0x1869: 0x002a, + 0x186a: 0x003a, 0x186b: 0x002a, 0x186c: 0x003a, 0x186d: 0x002a, 0x186e: 0x003a, 0x186f: 0x002a, + 0x1870: 0x000a, 0x1871: 0x000a, 0x1872: 0x000a, 0x1873: 0x000a, 0x1874: 0x000a, 0x1875: 0x000a, + 0x1876: 0x000a, 0x1877: 0x000a, 0x1878: 0x000a, 0x1879: 0x000a, 0x187a: 0x000a, 0x187b: 0x000a, + 0x187c: 0x000a, 0x187d: 0x000a, 0x187e: 0x000a, 0x187f: 0x000a, + // Block 0x62, offset 0x1880 + 0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x007a, 0x1884: 0x006a, 0x1885: 0x009a, + 0x1886: 0x008a, 0x1887: 0x00ba, 0x1888: 0x00aa, 0x1889: 0x009a, 0x188a: 0x008a, 0x188b: 0x007a, + 0x188c: 0x006a, 0x188d: 0x00da, 0x188e: 0x002a, 0x188f: 0x003a, 0x1890: 0x00ca, 0x1891: 0x009a, + 0x1892: 0x008a, 0x1893: 0x007a, 0x1894: 0x006a, 0x1895: 0x009a, 0x1896: 0x008a, 0x1897: 0x00ba, + 0x1898: 0x00aa, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a, + 0x189e: 0x000a, 0x189f: 0x000a, 0x18a0: 0x000a, 0x18a1: 0x000a, 0x18a2: 0x000a, 0x18a3: 0x000a, + 0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x000a, 0x18a7: 0x000a, 0x18a8: 0x000a, 0x18a9: 0x000a, + 0x18aa: 0x000a, 0x18ab: 0x000a, 0x18ac: 0x000a, 0x18ad: 0x000a, 0x18ae: 0x000a, 0x18af: 0x000a, + 0x18b0: 0x000a, 0x18b1: 0x000a, 0x18b2: 0x000a, 0x18b3: 0x000a, 0x18b4: 0x000a, 0x18b5: 0x000a, + 0x18b6: 0x000a, 0x18b7: 0x000a, 0x18b8: 0x000a, 0x18b9: 0x000a, 0x18ba: 0x000a, 0x18bb: 0x000a, + 0x18bc: 0x000a, 0x18bd: 0x000a, 0x18be: 0x000a, 0x18bf: 0x000a, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x000a, 0x18c4: 0x000a, 0x18c5: 0x000a, + 0x18c6: 0x000a, 0x18c7: 0x000a, 0x18c8: 0x000a, 0x18c9: 0x000a, 0x18ca: 0x000a, 0x18cb: 0x000a, + 0x18cc: 0x000a, 0x18cd: 0x000a, 0x18ce: 0x000a, 0x18cf: 0x000a, 0x18d0: 0x000a, 0x18d1: 0x000a, + 0x18d2: 0x000a, 0x18d3: 0x000a, 0x18d4: 0x000a, 0x18d5: 0x000a, 0x18d6: 0x000a, 0x18d7: 0x000a, + 0x18d8: 0x003a, 0x18d9: 0x002a, 0x18da: 0x003a, 0x18db: 0x002a, 0x18dc: 0x000a, 0x18dd: 0x000a, + 0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a, + 0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x000a, 0x18e7: 0x000a, 0x18e8: 0x000a, 0x18e9: 0x000a, + 0x18ea: 0x000a, 0x18eb: 0x000a, 0x18ec: 0x000a, 0x18ed: 0x000a, 0x18ee: 0x000a, 0x18ef: 0x000a, + 0x18f0: 0x000a, 0x18f1: 0x000a, 0x18f2: 0x000a, 0x18f3: 0x000a, 0x18f4: 0x000a, 0x18f5: 0x000a, + 0x18f6: 0x000a, 0x18f7: 0x000a, 0x18f8: 0x000a, 0x18f9: 0x000a, 0x18fa: 0x000a, 0x18fb: 0x000a, + 0x18fc: 0x003a, 0x18fd: 0x002a, 0x18fe: 0x000a, 0x18ff: 0x000a, + // Block 0x64, offset 0x1900 + 0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x000a, 0x1904: 0x000a, 0x1905: 0x000a, + 0x1906: 0x000a, 0x1907: 0x000a, 0x1908: 0x000a, 0x1909: 0x000a, 0x190a: 0x000a, 0x190b: 0x000a, + 0x190c: 0x000a, 0x190d: 0x000a, 0x190e: 0x000a, 0x190f: 0x000a, 0x1910: 0x000a, 0x1911: 0x000a, + 0x1912: 0x000a, 0x1913: 0x000a, 0x1914: 0x000a, 0x1915: 0x000a, 0x1916: 0x000a, 0x1917: 0x000a, + 0x1918: 0x000a, 0x1919: 0x000a, 0x191a: 0x000a, 0x191b: 0x000a, 0x191c: 0x000a, 0x191d: 0x000a, + 0x191e: 0x000a, 0x191f: 0x000a, 0x1920: 0x000a, 0x1921: 0x000a, 0x1922: 0x000a, 0x1923: 0x000a, + 0x1924: 0x000a, 0x1925: 0x000a, 0x1926: 0x000a, 0x1927: 0x000a, 0x1928: 0x000a, 0x1929: 0x000a, + 0x192a: 0x000a, 0x192b: 0x000a, 0x192c: 0x000a, 0x192d: 0x000a, 0x192e: 0x000a, 0x192f: 0x000a, + 0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a, + 0x1936: 0x000a, 0x1937: 0x000a, 0x1938: 0x000a, 0x1939: 0x000a, 0x193a: 0x000a, 0x193b: 0x000a, + 0x193c: 0x000a, 0x193d: 0x000a, 0x193e: 0x000a, 0x193f: 0x000a, + // Block 0x65, offset 0x1940 + 0x1940: 0x000a, 0x1941: 0x000a, 0x1942: 0x000a, 0x1943: 0x000a, 0x1944: 0x000a, 0x1945: 0x000a, + 0x1946: 0x000a, 0x1947: 0x000a, 0x1948: 0x000a, 0x1949: 0x000a, 0x194a: 0x000a, 0x194b: 0x000a, + 0x194c: 0x000a, 0x194d: 0x000a, 0x194e: 0x000a, 0x194f: 0x000a, 0x1950: 0x000a, 0x1951: 0x000a, + 0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a, + 0x1958: 0x000a, 0x1959: 0x000a, 0x195a: 0x000a, 0x195b: 0x000a, 0x195c: 0x000a, 0x195d: 0x000a, + 0x195e: 0x000a, 0x195f: 0x000a, 0x1960: 0x000a, 0x1961: 0x000a, 0x1962: 0x000a, 0x1963: 0x000a, + 0x1964: 0x000a, 0x1965: 0x000a, 0x1966: 0x000a, 0x1967: 0x000a, 0x1968: 0x000a, 0x1969: 0x000a, + 0x196a: 0x000a, 0x196b: 0x000a, 0x196c: 0x000a, 0x196d: 0x000a, 0x196e: 0x000a, 0x196f: 0x000a, + 0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a, 0x1974: 0x000a, 0x1975: 0x000a, + 0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a, 0x197a: 0x000a, 0x197b: 0x000a, + 0x197c: 0x000a, 0x197d: 0x000a, 0x197e: 0x000a, 0x197f: 0x000a, + // Block 0x66, offset 0x1980 + 0x1980: 0x000a, 0x1981: 0x000a, 0x1982: 0x000a, 0x1983: 0x000a, 0x1984: 0x000a, 0x1985: 0x000a, + 0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a, + 0x198c: 0x000a, 0x198d: 0x000a, 0x198e: 0x000a, 0x198f: 0x000a, 0x1990: 0x000a, 0x1991: 0x000a, + 0x1992: 0x000a, 0x1993: 0x000a, 0x1994: 0x000a, 0x1995: 0x000a, 0x1996: 0x000a, 0x1997: 0x000a, + 0x1998: 0x000a, 0x1999: 0x000a, 0x199a: 0x000a, 0x199b: 0x000a, 0x199c: 0x000a, 0x199d: 0x000a, + 0x199e: 0x000a, 0x199f: 0x000a, 0x19a0: 0x000a, 0x19a1: 0x000a, 0x19a2: 0x000a, 0x19a3: 0x000a, + 0x19a4: 0x000a, 0x19a5: 0x000a, 0x19a6: 0x000a, 0x19a7: 0x000a, 0x19a8: 0x000a, 0x19a9: 0x000a, + 0x19aa: 0x000a, 0x19ab: 0x000a, 0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a, + 0x19b0: 0x000a, 0x19b1: 0x000a, 0x19b2: 0x000a, 0x19b3: 0x000a, 0x19b4: 0x000a, 0x19b5: 0x000a, + 0x19b6: 0x000a, 0x19b7: 0x000a, 0x19b8: 0x000a, 0x19b9: 0x000a, 0x19ba: 0x000a, 0x19bb: 0x000a, + 0x19bc: 0x000a, 0x19bd: 0x000a, 0x19be: 0x000a, + // Block 0x67, offset 0x19c0 + 0x19e5: 0x000a, 0x19e6: 0x000a, 0x19e7: 0x000a, 0x19e8: 0x000a, 0x19e9: 0x000a, + 0x19ea: 0x000a, 0x19ef: 0x000c, + 0x19f0: 0x000c, 0x19f1: 0x000c, + 0x19f9: 0x000a, 0x19fa: 0x000a, 0x19fb: 0x000a, + 0x19fc: 0x000a, 0x19fd: 0x000a, 0x19fe: 0x000a, 0x19ff: 0x000a, + // Block 0x68, offset 0x1a00 + 0x1a3f: 0x000c, + // Block 0x69, offset 0x1a40 + 0x1a60: 0x000c, 0x1a61: 0x000c, 0x1a62: 0x000c, 0x1a63: 0x000c, + 0x1a64: 0x000c, 0x1a65: 0x000c, 0x1a66: 0x000c, 0x1a67: 0x000c, 0x1a68: 0x000c, 0x1a69: 0x000c, + 0x1a6a: 0x000c, 0x1a6b: 0x000c, 0x1a6c: 0x000c, 0x1a6d: 0x000c, 0x1a6e: 0x000c, 0x1a6f: 0x000c, + 0x1a70: 0x000c, 0x1a71: 0x000c, 0x1a72: 0x000c, 0x1a73: 0x000c, 0x1a74: 0x000c, 0x1a75: 0x000c, + 0x1a76: 0x000c, 0x1a77: 0x000c, 0x1a78: 0x000c, 0x1a79: 0x000c, 0x1a7a: 0x000c, 0x1a7b: 0x000c, + 0x1a7c: 0x000c, 0x1a7d: 0x000c, 0x1a7e: 0x000c, 0x1a7f: 0x000c, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x000a, 0x1a81: 0x000a, 0x1a82: 0x000a, 0x1a83: 0x000a, 0x1a84: 0x000a, 0x1a85: 0x000a, + 0x1a86: 0x000a, 0x1a87: 0x000a, 0x1a88: 0x000a, 0x1a89: 0x000a, 0x1a8a: 0x000a, 0x1a8b: 0x000a, + 0x1a8c: 0x000a, 0x1a8d: 0x000a, 0x1a8e: 0x000a, 0x1a8f: 0x000a, 0x1a90: 0x000a, 0x1a91: 0x000a, + 0x1a92: 0x000a, 0x1a93: 0x000a, 0x1a94: 0x000a, 0x1a95: 0x000a, 0x1a96: 0x000a, 0x1a97: 0x000a, + 0x1a98: 0x000a, 0x1a99: 0x000a, 0x1a9a: 0x000a, 0x1a9b: 0x000a, 0x1a9c: 0x000a, 0x1a9d: 0x000a, + 0x1a9e: 0x000a, 0x1a9f: 0x000a, 0x1aa0: 0x000a, 0x1aa1: 0x000a, 0x1aa2: 0x003a, 0x1aa3: 0x002a, + 0x1aa4: 0x003a, 0x1aa5: 0x002a, 0x1aa6: 0x003a, 0x1aa7: 0x002a, 0x1aa8: 0x003a, 0x1aa9: 0x002a, + 0x1aaa: 0x000a, 0x1aab: 0x000a, 0x1aac: 0x000a, 0x1aad: 0x000a, 0x1aae: 0x000a, 0x1aaf: 0x000a, + 0x1ab0: 0x000a, 0x1ab1: 0x000a, 0x1ab2: 0x000a, 0x1ab3: 0x000a, 0x1ab4: 0x000a, 0x1ab5: 0x000a, + 0x1ab6: 0x000a, 0x1ab7: 0x000a, 0x1ab8: 0x000a, 0x1ab9: 0x000a, 0x1aba: 0x000a, 0x1abb: 0x000a, + 0x1abc: 0x000a, 0x1abd: 0x000a, 0x1abe: 0x000a, 0x1abf: 0x000a, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x000a, 0x1ac1: 0x000a, 0x1ac2: 0x000a, 0x1ac3: 0x000a, 0x1ac4: 0x000a, 0x1ac5: 0x000a, + 0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a, 0x1aca: 0x000a, 0x1acb: 0x000a, + 0x1acc: 0x000a, 0x1acd: 0x000a, 0x1ace: 0x000a, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a, 0x1b05: 0x000a, + 0x1b06: 0x000a, 0x1b07: 0x000a, 0x1b08: 0x000a, 0x1b09: 0x000a, 0x1b0a: 0x000a, 0x1b0b: 0x000a, + 0x1b0c: 0x000a, 0x1b0d: 0x000a, 0x1b0e: 0x000a, 0x1b0f: 0x000a, 0x1b10: 0x000a, 0x1b11: 0x000a, + 0x1b12: 0x000a, 0x1b13: 0x000a, 0x1b14: 0x000a, 0x1b15: 0x000a, 0x1b16: 0x000a, 0x1b17: 0x000a, + 0x1b18: 0x000a, 0x1b19: 0x000a, 0x1b1b: 0x000a, 0x1b1c: 0x000a, 0x1b1d: 0x000a, + 0x1b1e: 0x000a, 0x1b1f: 0x000a, 0x1b20: 0x000a, 0x1b21: 0x000a, 0x1b22: 0x000a, 0x1b23: 0x000a, + 0x1b24: 0x000a, 0x1b25: 0x000a, 0x1b26: 0x000a, 0x1b27: 0x000a, 0x1b28: 0x000a, 0x1b29: 0x000a, + 0x1b2a: 0x000a, 0x1b2b: 0x000a, 0x1b2c: 0x000a, 0x1b2d: 0x000a, 0x1b2e: 0x000a, 0x1b2f: 0x000a, + 0x1b30: 0x000a, 0x1b31: 0x000a, 0x1b32: 0x000a, 0x1b33: 0x000a, 0x1b34: 0x000a, 0x1b35: 0x000a, + 0x1b36: 0x000a, 0x1b37: 0x000a, 0x1b38: 0x000a, 0x1b39: 0x000a, 0x1b3a: 0x000a, 0x1b3b: 0x000a, + 0x1b3c: 0x000a, 0x1b3d: 0x000a, 0x1b3e: 0x000a, 0x1b3f: 0x000a, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x000a, 0x1b41: 0x000a, 0x1b42: 0x000a, 0x1b43: 0x000a, 0x1b44: 0x000a, 0x1b45: 0x000a, + 0x1b46: 0x000a, 0x1b47: 0x000a, 0x1b48: 0x000a, 0x1b49: 0x000a, 0x1b4a: 0x000a, 0x1b4b: 0x000a, + 0x1b4c: 0x000a, 0x1b4d: 0x000a, 0x1b4e: 0x000a, 0x1b4f: 0x000a, 0x1b50: 0x000a, 0x1b51: 0x000a, + 0x1b52: 0x000a, 0x1b53: 0x000a, 0x1b54: 0x000a, 0x1b55: 0x000a, 0x1b56: 0x000a, 0x1b57: 0x000a, + 0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5a: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a, + 0x1b5e: 0x000a, 0x1b5f: 0x000a, 0x1b60: 0x000a, 0x1b61: 0x000a, 0x1b62: 0x000a, 0x1b63: 0x000a, + 0x1b64: 0x000a, 0x1b65: 0x000a, 0x1b66: 0x000a, 0x1b67: 0x000a, 0x1b68: 0x000a, 0x1b69: 0x000a, + 0x1b6a: 0x000a, 0x1b6b: 0x000a, 0x1b6c: 0x000a, 0x1b6d: 0x000a, 0x1b6e: 0x000a, 0x1b6f: 0x000a, + 0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x000a, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, 0x1b85: 0x000a, + 0x1b86: 0x000a, 0x1b87: 0x000a, 0x1b88: 0x000a, 0x1b89: 0x000a, 0x1b8a: 0x000a, 0x1b8b: 0x000a, + 0x1b8c: 0x000a, 0x1b8d: 0x000a, 0x1b8e: 0x000a, 0x1b8f: 0x000a, 0x1b90: 0x000a, 0x1b91: 0x000a, + 0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a, + 0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a, 0x1bb4: 0x000a, 0x1bb5: 0x000a, + 0x1bb6: 0x000a, 0x1bb7: 0x000a, 0x1bb8: 0x000a, 0x1bb9: 0x000a, 0x1bba: 0x000a, 0x1bbb: 0x000a, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x0009, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a, + 0x1bc8: 0x003a, 0x1bc9: 0x002a, 0x1bca: 0x003a, 0x1bcb: 0x002a, + 0x1bcc: 0x003a, 0x1bcd: 0x002a, 0x1bce: 0x003a, 0x1bcf: 0x002a, 0x1bd0: 0x003a, 0x1bd1: 0x002a, + 0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x003a, 0x1bd5: 0x002a, 0x1bd6: 0x003a, 0x1bd7: 0x002a, + 0x1bd8: 0x003a, 0x1bd9: 0x002a, 0x1bda: 0x003a, 0x1bdb: 0x002a, 0x1bdc: 0x000a, 0x1bdd: 0x000a, + 0x1bde: 0x000a, 0x1bdf: 0x000a, 0x1be0: 0x000a, + 0x1bea: 0x000c, 0x1beb: 0x000c, 0x1bec: 0x000c, 0x1bed: 0x000c, + 0x1bf0: 0x000a, + 0x1bf6: 0x000a, 0x1bf7: 0x000a, + 0x1bfd: 0x000a, 0x1bfe: 0x000a, 0x1bff: 0x000a, + // Block 0x70, offset 0x1c00 + 0x1c19: 0x000c, 0x1c1a: 0x000c, 0x1c1b: 0x000a, 0x1c1c: 0x000a, + 0x1c20: 0x000a, + // Block 0x71, offset 0x1c40 + 0x1c7b: 0x000a, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x000a, 0x1c81: 0x000a, 0x1c82: 0x000a, 0x1c83: 0x000a, 0x1c84: 0x000a, 0x1c85: 0x000a, + 0x1c86: 0x000a, 0x1c87: 0x000a, 0x1c88: 0x000a, 0x1c89: 0x000a, 0x1c8a: 0x000a, 0x1c8b: 0x000a, + 0x1c8c: 0x000a, 0x1c8d: 0x000a, 0x1c8e: 0x000a, 0x1c8f: 0x000a, 0x1c90: 0x000a, 0x1c91: 0x000a, + 0x1c92: 0x000a, 0x1c93: 0x000a, 0x1c94: 0x000a, 0x1c95: 0x000a, 0x1c96: 0x000a, 0x1c97: 0x000a, + 0x1c98: 0x000a, 0x1c99: 0x000a, 0x1c9a: 0x000a, 0x1c9b: 0x000a, 0x1c9c: 0x000a, 0x1c9d: 0x000a, + 0x1c9e: 0x000a, 0x1c9f: 0x000a, 0x1ca0: 0x000a, 0x1ca1: 0x000a, 0x1ca2: 0x000a, 0x1ca3: 0x000a, + // Block 0x73, offset 0x1cc0 + 0x1cdd: 0x000a, + 0x1cde: 0x000a, + // Block 0x74, offset 0x1d00 + 0x1d10: 0x000a, 0x1d11: 0x000a, + 0x1d12: 0x000a, 0x1d13: 0x000a, 0x1d14: 0x000a, 0x1d15: 0x000a, 0x1d16: 0x000a, 0x1d17: 0x000a, + 0x1d18: 0x000a, 0x1d19: 0x000a, 0x1d1a: 0x000a, 0x1d1b: 0x000a, 0x1d1c: 0x000a, 0x1d1d: 0x000a, + 0x1d1e: 0x000a, 0x1d1f: 0x000a, + 0x1d3c: 0x000a, 0x1d3d: 0x000a, 0x1d3e: 0x000a, + // Block 0x75, offset 0x1d40 + 0x1d71: 0x000a, 0x1d72: 0x000a, 0x1d73: 0x000a, 0x1d74: 0x000a, 0x1d75: 0x000a, + 0x1d76: 0x000a, 0x1d77: 0x000a, 0x1d78: 0x000a, 0x1d79: 0x000a, 0x1d7a: 0x000a, 0x1d7b: 0x000a, + 0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a, 0x1d7f: 0x000a, + // Block 0x76, offset 0x1d80 + 0x1d8c: 0x000a, 0x1d8d: 0x000a, 0x1d8e: 0x000a, 0x1d8f: 0x000a, + // Block 0x77, offset 0x1dc0 + 0x1df7: 0x000a, 0x1df8: 0x000a, 0x1df9: 0x000a, 0x1dfa: 0x000a, + // Block 0x78, offset 0x1e00 + 0x1e1e: 0x000a, 0x1e1f: 0x000a, + 0x1e3f: 0x000a, + // Block 0x79, offset 0x1e40 + 0x1e50: 0x000a, 0x1e51: 0x000a, + 0x1e52: 0x000a, 0x1e53: 0x000a, 0x1e54: 0x000a, 0x1e55: 0x000a, 0x1e56: 0x000a, 0x1e57: 0x000a, + 0x1e58: 0x000a, 0x1e59: 0x000a, 0x1e5a: 0x000a, 0x1e5b: 0x000a, 0x1e5c: 0x000a, 0x1e5d: 0x000a, + 0x1e5e: 0x000a, 0x1e5f: 0x000a, 0x1e60: 0x000a, 0x1e61: 0x000a, 0x1e62: 0x000a, 0x1e63: 0x000a, + 0x1e64: 0x000a, 0x1e65: 0x000a, 0x1e66: 0x000a, 0x1e67: 0x000a, 0x1e68: 0x000a, 0x1e69: 0x000a, + 0x1e6a: 0x000a, 0x1e6b: 0x000a, 0x1e6c: 0x000a, 0x1e6d: 0x000a, 0x1e6e: 0x000a, 0x1e6f: 0x000a, + 0x1e70: 0x000a, 0x1e71: 0x000a, 0x1e72: 0x000a, 0x1e73: 0x000a, 0x1e74: 0x000a, 0x1e75: 0x000a, + 0x1e76: 0x000a, 0x1e77: 0x000a, 0x1e78: 0x000a, 0x1e79: 0x000a, 0x1e7a: 0x000a, 0x1e7b: 0x000a, + 0x1e7c: 0x000a, 0x1e7d: 0x000a, 0x1e7e: 0x000a, 0x1e7f: 0x000a, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x000a, 0x1e81: 0x000a, 0x1e82: 0x000a, 0x1e83: 0x000a, 0x1e84: 0x000a, 0x1e85: 0x000a, + 0x1e86: 0x000a, + // Block 0x7b, offset 0x1ec0 + 0x1ecd: 0x000a, 0x1ece: 0x000a, 0x1ecf: 0x000a, + // Block 0x7c, offset 0x1f00 + 0x1f2f: 0x000c, + 0x1f30: 0x000c, 0x1f31: 0x000c, 0x1f32: 0x000c, 0x1f33: 0x000a, 0x1f34: 0x000c, 0x1f35: 0x000c, + 0x1f36: 0x000c, 0x1f37: 0x000c, 0x1f38: 0x000c, 0x1f39: 0x000c, 0x1f3a: 0x000c, 0x1f3b: 0x000c, + 0x1f3c: 0x000c, 0x1f3d: 0x000c, 0x1f3e: 0x000a, 0x1f3f: 0x000a, + // Block 0x7d, offset 0x1f40 + 0x1f5e: 0x000c, 0x1f5f: 0x000c, + // Block 0x7e, offset 0x1f80 + 0x1fb0: 0x000c, 0x1fb1: 0x000c, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0x000a, 0x1fc1: 0x000a, 0x1fc2: 0x000a, 0x1fc3: 0x000a, 0x1fc4: 0x000a, 0x1fc5: 0x000a, + 0x1fc6: 0x000a, 0x1fc7: 0x000a, 0x1fc8: 0x000a, 0x1fc9: 0x000a, 0x1fca: 0x000a, 0x1fcb: 0x000a, + 0x1fcc: 0x000a, 0x1fcd: 0x000a, 0x1fce: 0x000a, 0x1fcf: 0x000a, 0x1fd0: 0x000a, 0x1fd1: 0x000a, + 0x1fd2: 0x000a, 0x1fd3: 0x000a, 0x1fd4: 0x000a, 0x1fd5: 0x000a, 0x1fd6: 0x000a, 0x1fd7: 0x000a, + 0x1fd8: 0x000a, 0x1fd9: 0x000a, 0x1fda: 0x000a, 0x1fdb: 0x000a, 0x1fdc: 0x000a, 0x1fdd: 0x000a, + 0x1fde: 0x000a, 0x1fdf: 0x000a, 0x1fe0: 0x000a, 0x1fe1: 0x000a, + // Block 0x80, offset 0x2000 + 0x2008: 0x000a, + // Block 0x81, offset 0x2040 + 0x2042: 0x000c, + 0x2046: 0x000c, 0x204b: 0x000c, + 0x2065: 0x000c, 0x2066: 0x000c, 0x2068: 0x000a, 0x2069: 0x000a, + 0x206a: 0x000a, 0x206b: 0x000a, + 0x2078: 0x0004, 0x2079: 0x0004, + // Block 0x82, offset 0x2080 + 0x20b4: 0x000a, 0x20b5: 0x000a, + 0x20b6: 0x000a, 0x20b7: 0x000a, + // Block 0x83, offset 0x20c0 + 0x20c4: 0x000c, 0x20c5: 0x000c, + 0x20e0: 0x000c, 0x20e1: 0x000c, 0x20e2: 0x000c, 0x20e3: 0x000c, + 0x20e4: 0x000c, 0x20e5: 0x000c, 0x20e6: 0x000c, 0x20e7: 0x000c, 0x20e8: 0x000c, 0x20e9: 0x000c, + 0x20ea: 0x000c, 0x20eb: 0x000c, 0x20ec: 0x000c, 0x20ed: 0x000c, 0x20ee: 0x000c, 0x20ef: 0x000c, + 0x20f0: 0x000c, 0x20f1: 0x000c, + 0x20ff: 0x000c, + // Block 0x84, offset 0x2100 + 0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c, + 0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c, + // Block 0x85, offset 0x2140 + 0x2147: 0x000c, 0x2148: 0x000c, 0x2149: 0x000c, 0x214a: 0x000c, 0x214b: 0x000c, + 0x214c: 0x000c, 0x214d: 0x000c, 0x214e: 0x000c, 0x214f: 0x000c, 0x2150: 0x000c, 0x2151: 0x000c, + // Block 0x86, offset 0x2180 + 0x2180: 0x000c, 0x2181: 0x000c, 0x2182: 0x000c, + 0x21b3: 0x000c, + 0x21b6: 0x000c, 0x21b7: 0x000c, 0x21b8: 0x000c, 0x21b9: 0x000c, + 0x21bc: 0x000c, + // Block 0x87, offset 0x21c0 + 0x21e5: 0x000c, + // Block 0x88, offset 0x2200 + 0x2229: 0x000c, + 0x222a: 0x000c, 0x222b: 0x000c, 0x222c: 0x000c, 0x222d: 0x000c, 0x222e: 0x000c, + 0x2231: 0x000c, 0x2232: 0x000c, 0x2235: 0x000c, + 0x2236: 0x000c, + // Block 0x89, offset 0x2240 + 0x2243: 0x000c, + 0x224c: 0x000c, + 0x227c: 0x000c, + // Block 0x8a, offset 0x2280 + 0x22b0: 0x000c, 0x22b2: 0x000c, 0x22b3: 0x000c, 0x22b4: 0x000c, + 0x22b7: 0x000c, 0x22b8: 0x000c, + 0x22be: 0x000c, 0x22bf: 0x000c, + // Block 0x8b, offset 0x22c0 + 0x22c1: 0x000c, + 0x22ec: 0x000c, 0x22ed: 0x000c, + 0x22f6: 0x000c, + // Block 0x8c, offset 0x2300 + 0x2325: 0x000c, 0x2328: 0x000c, + 0x232d: 0x000c, + // Block 0x8d, offset 0x2340 + 0x235d: 0x0001, + 0x235e: 0x000c, 0x235f: 0x0001, 0x2360: 0x0001, 0x2361: 0x0001, 0x2362: 0x0001, 0x2363: 0x0001, + 0x2364: 0x0001, 0x2365: 0x0001, 0x2366: 0x0001, 0x2367: 0x0001, 0x2368: 0x0001, 0x2369: 0x0003, + 0x236a: 0x0001, 0x236b: 0x0001, 0x236c: 0x0001, 0x236d: 0x0001, 0x236e: 0x0001, 0x236f: 0x0001, + 0x2370: 0x0001, 0x2371: 0x0001, 0x2372: 0x0001, 0x2373: 0x0001, 0x2374: 0x0001, 0x2375: 0x0001, + 0x2376: 0x0001, 0x2377: 0x0001, 0x2378: 0x0001, 0x2379: 0x0001, 0x237a: 0x0001, 0x237b: 0x0001, + 0x237c: 0x0001, 0x237d: 0x0001, 0x237e: 0x0001, 0x237f: 0x0001, + // Block 0x8e, offset 0x2380 + 0x2380: 0x0001, 0x2381: 0x0001, 0x2382: 0x0001, 0x2383: 0x0001, 0x2384: 0x0001, 0x2385: 0x0001, + 0x2386: 0x0001, 0x2387: 0x0001, 0x2388: 0x0001, 0x2389: 0x0001, 0x238a: 0x0001, 0x238b: 0x0001, + 0x238c: 0x0001, 0x238d: 0x0001, 0x238e: 0x0001, 0x238f: 0x0001, 0x2390: 0x000d, 0x2391: 0x000d, + 0x2392: 0x000d, 0x2393: 0x000d, 0x2394: 0x000d, 0x2395: 0x000d, 0x2396: 0x000d, 0x2397: 0x000d, + 0x2398: 0x000d, 0x2399: 0x000d, 0x239a: 0x000d, 0x239b: 0x000d, 0x239c: 0x000d, 0x239d: 0x000d, + 0x239e: 0x000d, 0x239f: 0x000d, 0x23a0: 0x000d, 0x23a1: 0x000d, 0x23a2: 0x000d, 0x23a3: 0x000d, + 0x23a4: 0x000d, 0x23a5: 0x000d, 0x23a6: 0x000d, 0x23a7: 0x000d, 0x23a8: 0x000d, 0x23a9: 0x000d, + 0x23aa: 0x000d, 0x23ab: 0x000d, 0x23ac: 0x000d, 0x23ad: 0x000d, 0x23ae: 0x000d, 0x23af: 0x000d, + 0x23b0: 0x000d, 0x23b1: 0x000d, 0x23b2: 0x000d, 0x23b3: 0x000d, 0x23b4: 0x000d, 0x23b5: 0x000d, + 0x23b6: 0x000d, 0x23b7: 0x000d, 0x23b8: 0x000d, 0x23b9: 0x000d, 0x23ba: 0x000d, 0x23bb: 0x000d, + 0x23bc: 0x000d, 0x23bd: 0x000d, 0x23be: 0x000d, 0x23bf: 0x000d, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x000d, 0x23c1: 0x000d, 0x23c2: 0x000d, 0x23c3: 0x000d, 0x23c4: 0x000d, 0x23c5: 0x000d, + 0x23c6: 0x000d, 0x23c7: 0x000d, 0x23c8: 0x000d, 0x23c9: 0x000d, 0x23ca: 0x000d, 0x23cb: 0x000d, + 0x23cc: 0x000d, 0x23cd: 0x000d, 0x23ce: 0x000d, 0x23cf: 0x000d, 0x23d0: 0x000d, 0x23d1: 0x000d, + 0x23d2: 0x000d, 0x23d3: 0x000d, 0x23d4: 0x000d, 0x23d5: 0x000d, 0x23d6: 0x000d, 0x23d7: 0x000d, + 0x23d8: 0x000d, 0x23d9: 0x000d, 0x23da: 0x000d, 0x23db: 0x000d, 0x23dc: 0x000d, 0x23dd: 0x000d, + 0x23de: 0x000d, 0x23df: 0x000d, 0x23e0: 0x000d, 0x23e1: 0x000d, 0x23e2: 0x000d, 0x23e3: 0x000d, + 0x23e4: 0x000d, 0x23e5: 0x000d, 0x23e6: 0x000d, 0x23e7: 0x000d, 0x23e8: 0x000d, 0x23e9: 0x000d, + 0x23ea: 0x000d, 0x23eb: 0x000d, 0x23ec: 0x000d, 0x23ed: 0x000d, 0x23ee: 0x000d, 0x23ef: 0x000d, + 0x23f0: 0x000d, 0x23f1: 0x000d, 0x23f2: 0x000d, 0x23f3: 0x000d, 0x23f4: 0x000d, 0x23f5: 0x000d, + 0x23f6: 0x000d, 0x23f7: 0x000d, 0x23f8: 0x000d, 0x23f9: 0x000d, 0x23fa: 0x000d, 0x23fb: 0x000d, + 0x23fc: 0x000d, 0x23fd: 0x000d, 0x23fe: 0x000a, 0x23ff: 0x000a, + // Block 0x90, offset 0x2400 + 0x2400: 0x000d, 0x2401: 0x000d, 0x2402: 0x000d, 0x2403: 0x000d, 0x2404: 0x000d, 0x2405: 0x000d, + 0x2406: 0x000d, 0x2407: 0x000d, 0x2408: 0x000d, 0x2409: 0x000d, 0x240a: 0x000d, 0x240b: 0x000d, + 0x240c: 0x000d, 0x240d: 0x000d, 0x240e: 0x000d, 0x240f: 0x000d, 0x2410: 0x000b, 0x2411: 0x000b, + 0x2412: 0x000b, 0x2413: 0x000b, 0x2414: 0x000b, 0x2415: 0x000b, 0x2416: 0x000b, 0x2417: 0x000b, + 0x2418: 0x000b, 0x2419: 0x000b, 0x241a: 0x000b, 0x241b: 0x000b, 0x241c: 0x000b, 0x241d: 0x000b, + 0x241e: 0x000b, 0x241f: 0x000b, 0x2420: 0x000b, 0x2421: 0x000b, 0x2422: 0x000b, 0x2423: 0x000b, + 0x2424: 0x000b, 0x2425: 0x000b, 0x2426: 0x000b, 0x2427: 0x000b, 0x2428: 0x000b, 0x2429: 0x000b, + 0x242a: 0x000b, 0x242b: 0x000b, 0x242c: 0x000b, 0x242d: 0x000b, 0x242e: 0x000b, 0x242f: 0x000b, + 0x2430: 0x000d, 0x2431: 0x000d, 0x2432: 0x000d, 0x2433: 0x000d, 0x2434: 0x000d, 0x2435: 0x000d, + 0x2436: 0x000d, 0x2437: 0x000d, 0x2438: 0x000d, 0x2439: 0x000d, 0x243a: 0x000d, 0x243b: 0x000d, + 0x243c: 0x000d, 0x243d: 0x000a, 0x243e: 0x000d, 0x243f: 0x000d, + // Block 0x91, offset 0x2440 + 0x2440: 0x000c, 0x2441: 0x000c, 0x2442: 0x000c, 0x2443: 0x000c, 0x2444: 0x000c, 0x2445: 0x000c, + 0x2446: 0x000c, 0x2447: 0x000c, 0x2448: 0x000c, 0x2449: 0x000c, 0x244a: 0x000c, 0x244b: 0x000c, + 0x244c: 0x000c, 0x244d: 0x000c, 0x244e: 0x000c, 0x244f: 0x000c, 0x2450: 0x000a, 0x2451: 0x000a, + 0x2452: 0x000a, 0x2453: 0x000a, 0x2454: 0x000a, 0x2455: 0x000a, 0x2456: 0x000a, 0x2457: 0x000a, + 0x2458: 0x000a, 0x2459: 0x000a, + 0x2460: 0x000c, 0x2461: 0x000c, 0x2462: 0x000c, 0x2463: 0x000c, + 0x2464: 0x000c, 0x2465: 0x000c, 0x2466: 0x000c, 0x2467: 0x000c, 0x2468: 0x000c, 0x2469: 0x000c, + 0x246a: 0x000c, 0x246b: 0x000c, 0x246c: 0x000c, 0x246d: 0x000c, 0x246e: 0x000c, 0x246f: 0x000c, + 0x2470: 0x000a, 0x2471: 0x000a, 0x2472: 0x000a, 0x2473: 0x000a, 0x2474: 0x000a, 0x2475: 0x000a, + 0x2476: 0x000a, 0x2477: 0x000a, 0x2478: 0x000a, 0x2479: 0x000a, 0x247a: 0x000a, 0x247b: 0x000a, + 0x247c: 0x000a, 0x247d: 0x000a, 0x247e: 0x000a, 0x247f: 0x000a, + // Block 0x92, offset 0x2480 + 0x2480: 0x000a, 0x2481: 0x000a, 0x2482: 0x000a, 0x2483: 0x000a, 0x2484: 0x000a, 0x2485: 0x000a, + 0x2486: 0x000a, 0x2487: 0x000a, 0x2488: 0x000a, 0x2489: 0x000a, 0x248a: 0x000a, 0x248b: 0x000a, + 0x248c: 0x000a, 0x248d: 0x000a, 0x248e: 0x000a, 0x248f: 0x000a, 0x2490: 0x0006, 0x2491: 0x000a, + 0x2492: 0x0006, 0x2494: 0x000a, 0x2495: 0x0006, 0x2496: 0x000a, 0x2497: 0x000a, + 0x2498: 0x000a, 0x2499: 0x009a, 0x249a: 0x008a, 0x249b: 0x007a, 0x249c: 0x006a, 0x249d: 0x009a, + 0x249e: 0x008a, 0x249f: 0x0004, 0x24a0: 0x000a, 0x24a1: 0x000a, 0x24a2: 0x0003, 0x24a3: 0x0003, + 0x24a4: 0x000a, 0x24a5: 0x000a, 0x24a6: 0x000a, 0x24a8: 0x000a, 0x24a9: 0x0004, + 0x24aa: 0x0004, 0x24ab: 0x000a, + 0x24b0: 0x000d, 0x24b1: 0x000d, 0x24b2: 0x000d, 0x24b3: 0x000d, 0x24b4: 0x000d, 0x24b5: 0x000d, + 0x24b6: 0x000d, 0x24b7: 0x000d, 0x24b8: 0x000d, 0x24b9: 0x000d, 0x24ba: 0x000d, 0x24bb: 0x000d, + 0x24bc: 0x000d, 0x24bd: 0x000d, 0x24be: 0x000d, 0x24bf: 0x000d, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x000d, 0x24c1: 0x000d, 0x24c2: 0x000d, 0x24c3: 0x000d, 0x24c4: 0x000d, 0x24c5: 0x000d, + 0x24c6: 0x000d, 0x24c7: 0x000d, 0x24c8: 0x000d, 0x24c9: 0x000d, 0x24ca: 0x000d, 0x24cb: 0x000d, + 0x24cc: 0x000d, 0x24cd: 0x000d, 0x24ce: 0x000d, 0x24cf: 0x000d, 0x24d0: 0x000d, 0x24d1: 0x000d, + 0x24d2: 0x000d, 0x24d3: 0x000d, 0x24d4: 0x000d, 0x24d5: 0x000d, 0x24d6: 0x000d, 0x24d7: 0x000d, + 0x24d8: 0x000d, 0x24d9: 0x000d, 0x24da: 0x000d, 0x24db: 0x000d, 0x24dc: 0x000d, 0x24dd: 0x000d, + 0x24de: 0x000d, 0x24df: 0x000d, 0x24e0: 0x000d, 0x24e1: 0x000d, 0x24e2: 0x000d, 0x24e3: 0x000d, + 0x24e4: 0x000d, 0x24e5: 0x000d, 0x24e6: 0x000d, 0x24e7: 0x000d, 0x24e8: 0x000d, 0x24e9: 0x000d, + 0x24ea: 0x000d, 0x24eb: 0x000d, 0x24ec: 0x000d, 0x24ed: 0x000d, 0x24ee: 0x000d, 0x24ef: 0x000d, + 0x24f0: 0x000d, 0x24f1: 0x000d, 0x24f2: 0x000d, 0x24f3: 0x000d, 0x24f4: 0x000d, 0x24f5: 0x000d, + 0x24f6: 0x000d, 0x24f7: 0x000d, 0x24f8: 0x000d, 0x24f9: 0x000d, 0x24fa: 0x000d, 0x24fb: 0x000d, + 0x24fc: 0x000d, 0x24fd: 0x000d, 0x24fe: 0x000d, 0x24ff: 0x000b, + // Block 0x94, offset 0x2500 + 0x2501: 0x000a, 0x2502: 0x000a, 0x2503: 0x0004, 0x2504: 0x0004, 0x2505: 0x0004, + 0x2506: 0x000a, 0x2507: 0x000a, 0x2508: 0x003a, 0x2509: 0x002a, 0x250a: 0x000a, 0x250b: 0x0003, + 0x250c: 0x0006, 0x250d: 0x0003, 0x250e: 0x0006, 0x250f: 0x0006, 0x2510: 0x0002, 0x2511: 0x0002, + 0x2512: 0x0002, 0x2513: 0x0002, 0x2514: 0x0002, 0x2515: 0x0002, 0x2516: 0x0002, 0x2517: 0x0002, + 0x2518: 0x0002, 0x2519: 0x0002, 0x251a: 0x0006, 0x251b: 0x000a, 0x251c: 0x000a, 0x251d: 0x000a, + 0x251e: 0x000a, 0x251f: 0x000a, 0x2520: 0x000a, + 0x253b: 0x005a, + 0x253c: 0x000a, 0x253d: 0x004a, 0x253e: 0x000a, 0x253f: 0x000a, + // Block 0x95, offset 0x2540 + 0x2540: 0x000a, + 0x255b: 0x005a, 0x255c: 0x000a, 0x255d: 0x004a, + 0x255e: 0x000a, 0x255f: 0x00fa, 0x2560: 0x00ea, 0x2561: 0x000a, 0x2562: 0x003a, 0x2563: 0x002a, + 0x2564: 0x000a, 0x2565: 0x000a, + // Block 0x96, offset 0x2580 + 0x25a0: 0x0004, 0x25a1: 0x0004, 0x25a2: 0x000a, 0x25a3: 0x000a, + 0x25a4: 0x000a, 0x25a5: 0x0004, 0x25a6: 0x0004, 0x25a8: 0x000a, 0x25a9: 0x000a, + 0x25aa: 0x000a, 0x25ab: 0x000a, 0x25ac: 0x000a, 0x25ad: 0x000a, 0x25ae: 0x000a, + 0x25b0: 0x000b, 0x25b1: 0x000b, 0x25b2: 0x000b, 0x25b3: 0x000b, 0x25b4: 0x000b, 0x25b5: 0x000b, + 0x25b6: 0x000b, 0x25b7: 0x000b, 0x25b8: 0x000b, 0x25b9: 0x000a, 0x25ba: 0x000a, 0x25bb: 0x000a, + 0x25bc: 0x000a, 0x25bd: 0x000a, 0x25be: 0x000b, 0x25bf: 0x000b, + // Block 0x97, offset 0x25c0 + 0x25c1: 0x000a, + // Block 0x98, offset 0x2600 + 0x2600: 0x000a, 0x2601: 0x000a, 0x2602: 0x000a, 0x2603: 0x000a, 0x2604: 0x000a, 0x2605: 0x000a, + 0x2606: 0x000a, 0x2607: 0x000a, 0x2608: 0x000a, 0x2609: 0x000a, 0x260a: 0x000a, 0x260b: 0x000a, + 0x260c: 0x000a, 0x2610: 0x000a, 0x2611: 0x000a, + 0x2612: 0x000a, 0x2613: 0x000a, 0x2614: 0x000a, 0x2615: 0x000a, 0x2616: 0x000a, 0x2617: 0x000a, + 0x2618: 0x000a, 0x2619: 0x000a, 0x261a: 0x000a, 0x261b: 0x000a, + 0x2620: 0x000a, + // Block 0x99, offset 0x2640 + 0x267d: 0x000c, + // Block 0x9a, offset 0x2680 + 0x26a0: 0x000c, 0x26a1: 0x0002, 0x26a2: 0x0002, 0x26a3: 0x0002, + 0x26a4: 0x0002, 0x26a5: 0x0002, 0x26a6: 0x0002, 0x26a7: 0x0002, 0x26a8: 0x0002, 0x26a9: 0x0002, + 0x26aa: 0x0002, 0x26ab: 0x0002, 0x26ac: 0x0002, 0x26ad: 0x0002, 0x26ae: 0x0002, 0x26af: 0x0002, + 0x26b0: 0x0002, 0x26b1: 0x0002, 0x26b2: 0x0002, 0x26b3: 0x0002, 0x26b4: 0x0002, 0x26b5: 0x0002, + 0x26b6: 0x0002, 0x26b7: 0x0002, 0x26b8: 0x0002, 0x26b9: 0x0002, 0x26ba: 0x0002, 0x26bb: 0x0002, + // Block 0x9b, offset 0x26c0 + 0x26f6: 0x000c, 0x26f7: 0x000c, 0x26f8: 0x000c, 0x26f9: 0x000c, 0x26fa: 0x000c, + // Block 0x9c, offset 0x2700 + 0x2700: 0x0001, 0x2701: 0x0001, 0x2702: 0x0001, 0x2703: 0x0001, 0x2704: 0x0001, 0x2705: 0x0001, + 0x2706: 0x0001, 0x2707: 0x0001, 0x2708: 0x0001, 0x2709: 0x0001, 0x270a: 0x0001, 0x270b: 0x0001, + 0x270c: 0x0001, 0x270d: 0x0001, 0x270e: 0x0001, 0x270f: 0x0001, 0x2710: 0x0001, 0x2711: 0x0001, + 0x2712: 0x0001, 0x2713: 0x0001, 0x2714: 0x0001, 0x2715: 0x0001, 0x2716: 0x0001, 0x2717: 0x0001, + 0x2718: 0x0001, 0x2719: 0x0001, 0x271a: 0x0001, 0x271b: 0x0001, 0x271c: 0x0001, 0x271d: 0x0001, + 0x271e: 0x0001, 0x271f: 0x0001, 0x2720: 0x0001, 0x2721: 0x0001, 0x2722: 0x0001, 0x2723: 0x0001, + 0x2724: 0x0001, 0x2725: 0x0001, 0x2726: 0x0001, 0x2727: 0x0001, 0x2728: 0x0001, 0x2729: 0x0001, + 0x272a: 0x0001, 0x272b: 0x0001, 0x272c: 0x0001, 0x272d: 0x0001, 0x272e: 0x0001, 0x272f: 0x0001, + 0x2730: 0x0001, 0x2731: 0x0001, 0x2732: 0x0001, 0x2733: 0x0001, 0x2734: 0x0001, 0x2735: 0x0001, + 0x2736: 0x0001, 0x2737: 0x0001, 0x2738: 0x0001, 0x2739: 0x0001, 0x273a: 0x0001, 0x273b: 0x0001, + 0x273c: 0x0001, 0x273d: 0x0001, 0x273e: 0x0001, 0x273f: 0x0001, + // Block 0x9d, offset 0x2740 + 0x2740: 0x0001, 0x2741: 0x0001, 0x2742: 0x0001, 0x2743: 0x0001, 0x2744: 0x0001, 0x2745: 0x0001, + 0x2746: 0x0001, 0x2747: 0x0001, 0x2748: 0x0001, 0x2749: 0x0001, 0x274a: 0x0001, 0x274b: 0x0001, + 0x274c: 0x0001, 0x274d: 0x0001, 0x274e: 0x0001, 0x274f: 0x0001, 0x2750: 0x0001, 0x2751: 0x0001, + 0x2752: 0x0001, 0x2753: 0x0001, 0x2754: 0x0001, 0x2755: 0x0001, 0x2756: 0x0001, 0x2757: 0x0001, + 0x2758: 0x0001, 0x2759: 0x0001, 0x275a: 0x0001, 0x275b: 0x0001, 0x275c: 0x0001, 0x275d: 0x0001, + 0x275e: 0x0001, 0x275f: 0x000a, 0x2760: 0x0001, 0x2761: 0x0001, 0x2762: 0x0001, 0x2763: 0x0001, + 0x2764: 0x0001, 0x2765: 0x0001, 0x2766: 0x0001, 0x2767: 0x0001, 0x2768: 0x0001, 0x2769: 0x0001, + 0x276a: 0x0001, 0x276b: 0x0001, 0x276c: 0x0001, 0x276d: 0x0001, 0x276e: 0x0001, 0x276f: 0x0001, + 0x2770: 0x0001, 0x2771: 0x0001, 0x2772: 0x0001, 0x2773: 0x0001, 0x2774: 0x0001, 0x2775: 0x0001, + 0x2776: 0x0001, 0x2777: 0x0001, 0x2778: 0x0001, 0x2779: 0x0001, 0x277a: 0x0001, 0x277b: 0x0001, + 0x277c: 0x0001, 0x277d: 0x0001, 0x277e: 0x0001, 0x277f: 0x0001, + // Block 0x9e, offset 0x2780 + 0x2780: 0x0001, 0x2781: 0x000c, 0x2782: 0x000c, 0x2783: 0x000c, 0x2784: 0x0001, 0x2785: 0x000c, + 0x2786: 0x000c, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001, + 0x278c: 0x000c, 0x278d: 0x000c, 0x278e: 0x000c, 0x278f: 0x000c, 0x2790: 0x0001, 0x2791: 0x0001, + 0x2792: 0x0001, 0x2793: 0x0001, 0x2794: 0x0001, 0x2795: 0x0001, 0x2796: 0x0001, 0x2797: 0x0001, + 0x2798: 0x0001, 0x2799: 0x0001, 0x279a: 0x0001, 0x279b: 0x0001, 0x279c: 0x0001, 0x279d: 0x0001, + 0x279e: 0x0001, 0x279f: 0x0001, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001, + 0x27a4: 0x0001, 0x27a5: 0x0001, 0x27a6: 0x0001, 0x27a7: 0x0001, 0x27a8: 0x0001, 0x27a9: 0x0001, + 0x27aa: 0x0001, 0x27ab: 0x0001, 0x27ac: 0x0001, 0x27ad: 0x0001, 0x27ae: 0x0001, 0x27af: 0x0001, + 0x27b0: 0x0001, 0x27b1: 0x0001, 0x27b2: 0x0001, 0x27b3: 0x0001, 0x27b4: 0x0001, 0x27b5: 0x0001, + 0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x000c, 0x27b9: 0x000c, 0x27ba: 0x000c, 0x27bb: 0x0001, + 0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x000c, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x0001, 0x27c1: 0x0001, 0x27c2: 0x0001, 0x27c3: 0x0001, 0x27c4: 0x0001, 0x27c5: 0x0001, + 0x27c6: 0x0001, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001, + 0x27cc: 0x0001, 0x27cd: 0x0001, 0x27ce: 0x0001, 0x27cf: 0x0001, 0x27d0: 0x0001, 0x27d1: 0x0001, + 0x27d2: 0x0001, 0x27d3: 0x0001, 0x27d4: 0x0001, 0x27d5: 0x0001, 0x27d6: 0x0001, 0x27d7: 0x0001, + 0x27d8: 0x0001, 0x27d9: 0x0001, 0x27da: 0x0001, 0x27db: 0x0001, 0x27dc: 0x0001, 0x27dd: 0x0001, + 0x27de: 0x0001, 0x27df: 0x0001, 0x27e0: 0x0001, 0x27e1: 0x0001, 0x27e2: 0x0001, 0x27e3: 0x0001, + 0x27e4: 0x0001, 0x27e5: 0x000c, 0x27e6: 0x000c, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001, + 0x27ea: 0x0001, 0x27eb: 0x0001, 0x27ec: 0x0001, 0x27ed: 0x0001, 0x27ee: 0x0001, 0x27ef: 0x0001, + 0x27f0: 0x0001, 0x27f1: 0x0001, 0x27f2: 0x0001, 0x27f3: 0x0001, 0x27f4: 0x0001, 0x27f5: 0x0001, + 0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x0001, 0x27f9: 0x0001, 0x27fa: 0x0001, 0x27fb: 0x0001, + 0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x0001, + // Block 0xa0, offset 0x2800 + 0x2800: 0x0001, 0x2801: 0x0001, 0x2802: 0x0001, 0x2803: 0x0001, 0x2804: 0x0001, 0x2805: 0x0001, + 0x2806: 0x0001, 0x2807: 0x0001, 0x2808: 0x0001, 0x2809: 0x0001, 0x280a: 0x0001, 0x280b: 0x0001, + 0x280c: 0x0001, 0x280d: 0x0001, 0x280e: 0x0001, 0x280f: 0x0001, 0x2810: 0x0001, 0x2811: 0x0001, + 0x2812: 0x0001, 0x2813: 0x0001, 0x2814: 0x0001, 0x2815: 0x0001, 0x2816: 0x0001, 0x2817: 0x0001, + 0x2818: 0x0001, 0x2819: 0x0001, 0x281a: 0x0001, 0x281b: 0x0001, 0x281c: 0x0001, 0x281d: 0x0001, + 0x281e: 0x0001, 0x281f: 0x0001, 0x2820: 0x0001, 0x2821: 0x0001, 0x2822: 0x0001, 0x2823: 0x0001, + 0x2824: 0x0001, 0x2825: 0x0001, 0x2826: 0x0001, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001, + 0x282a: 0x0001, 0x282b: 0x0001, 0x282c: 0x0001, 0x282d: 0x0001, 0x282e: 0x0001, 0x282f: 0x0001, + 0x2830: 0x0001, 0x2831: 0x0001, 0x2832: 0x0001, 0x2833: 0x0001, 0x2834: 0x0001, 0x2835: 0x0001, + 0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x0001, 0x2839: 0x000a, 0x283a: 0x000a, 0x283b: 0x000a, + 0x283c: 0x000a, 0x283d: 0x000a, 0x283e: 0x000a, 0x283f: 0x000a, + // Block 0xa1, offset 0x2840 + 0x2840: 0x000d, 0x2841: 0x000d, 0x2842: 0x000d, 0x2843: 0x000d, 0x2844: 0x000d, 0x2845: 0x000d, + 0x2846: 0x000d, 0x2847: 0x000d, 0x2848: 0x000d, 0x2849: 0x000d, 0x284a: 0x000d, 0x284b: 0x000d, + 0x284c: 0x000d, 0x284d: 0x000d, 0x284e: 0x000d, 0x284f: 0x000d, 0x2850: 0x000d, 0x2851: 0x000d, + 0x2852: 0x000d, 0x2853: 0x000d, 0x2854: 0x000d, 0x2855: 0x000d, 0x2856: 0x000d, 0x2857: 0x000d, + 0x2858: 0x000d, 0x2859: 0x000d, 0x285a: 0x000d, 0x285b: 0x000d, 0x285c: 0x000d, 0x285d: 0x000d, + 0x285e: 0x000d, 0x285f: 0x000d, 0x2860: 0x000d, 0x2861: 0x000d, 0x2862: 0x000d, 0x2863: 0x000d, + 0x2864: 0x000c, 0x2865: 0x000c, 0x2866: 0x000c, 0x2867: 0x000c, 0x2868: 0x000d, 0x2869: 0x000d, + 0x286a: 0x000d, 0x286b: 0x000d, 0x286c: 0x000d, 0x286d: 0x000d, 0x286e: 0x000d, 0x286f: 0x000d, + 0x2870: 0x0005, 0x2871: 0x0005, 0x2872: 0x0005, 0x2873: 0x0005, 0x2874: 0x0005, 0x2875: 0x0005, + 0x2876: 0x0005, 0x2877: 0x0005, 0x2878: 0x0005, 0x2879: 0x0005, 0x287a: 0x000d, 0x287b: 0x000d, + 0x287c: 0x000d, 0x287d: 0x000d, 0x287e: 0x000d, 0x287f: 0x000d, + // Block 0xa2, offset 0x2880 + 0x2880: 0x0001, 0x2881: 0x0001, 0x2882: 0x0001, 0x2883: 0x0001, 0x2884: 0x0001, 0x2885: 0x0001, + 0x2886: 0x0001, 0x2887: 0x0001, 0x2888: 0x0001, 0x2889: 0x0001, 0x288a: 0x0001, 0x288b: 0x0001, + 0x288c: 0x0001, 0x288d: 0x0001, 0x288e: 0x0001, 0x288f: 0x0001, 0x2890: 0x0001, 0x2891: 0x0001, + 0x2892: 0x0001, 0x2893: 0x0001, 0x2894: 0x0001, 0x2895: 0x0001, 0x2896: 0x0001, 0x2897: 0x0001, + 0x2898: 0x0001, 0x2899: 0x0001, 0x289a: 0x0001, 0x289b: 0x0001, 0x289c: 0x0001, 0x289d: 0x0001, + 0x289e: 0x0001, 0x289f: 0x0001, 0x28a0: 0x0005, 0x28a1: 0x0005, 0x28a2: 0x0005, 0x28a3: 0x0005, + 0x28a4: 0x0005, 0x28a5: 0x0005, 0x28a6: 0x0005, 0x28a7: 0x0005, 0x28a8: 0x0005, 0x28a9: 0x0005, + 0x28aa: 0x0005, 0x28ab: 0x0005, 0x28ac: 0x0005, 0x28ad: 0x0005, 0x28ae: 0x0005, 0x28af: 0x0005, + 0x28b0: 0x0005, 0x28b1: 0x0005, 0x28b2: 0x0005, 0x28b3: 0x0005, 0x28b4: 0x0005, 0x28b5: 0x0005, + 0x28b6: 0x0005, 0x28b7: 0x0005, 0x28b8: 0x0005, 0x28b9: 0x0005, 0x28ba: 0x0005, 0x28bb: 0x0005, + 0x28bc: 0x0005, 0x28bd: 0x0005, 0x28be: 0x0005, 0x28bf: 0x0001, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x0001, 0x28c1: 0x0001, 0x28c2: 0x0001, 0x28c3: 0x0001, 0x28c4: 0x0001, 0x28c5: 0x0001, + 0x28c6: 0x0001, 0x28c7: 0x0001, 0x28c8: 0x0001, 0x28c9: 0x0001, 0x28ca: 0x0001, 0x28cb: 0x0001, + 0x28cc: 0x0001, 0x28cd: 0x0001, 0x28ce: 0x0001, 0x28cf: 0x0001, 0x28d0: 0x0001, 0x28d1: 0x0001, + 0x28d2: 0x0001, 0x28d3: 0x0001, 0x28d4: 0x0001, 0x28d5: 0x0001, 0x28d6: 0x0001, 0x28d7: 0x0001, + 0x28d8: 0x0001, 0x28d9: 0x0001, 0x28da: 0x0001, 0x28db: 0x0001, 0x28dc: 0x0001, 0x28dd: 0x0001, + 0x28de: 0x0001, 0x28df: 0x0001, 0x28e0: 0x0001, 0x28e1: 0x0001, 0x28e2: 0x0001, 0x28e3: 0x0001, + 0x28e4: 0x0001, 0x28e5: 0x0001, 0x28e6: 0x0001, 0x28e7: 0x0001, 0x28e8: 0x0001, 0x28e9: 0x0001, + 0x28ea: 0x0001, 0x28eb: 0x0001, 0x28ec: 0x0001, 0x28ed: 0x0001, 0x28ee: 0x0001, 0x28ef: 0x0001, + 0x28f0: 0x000d, 0x28f1: 0x000d, 0x28f2: 0x000d, 0x28f3: 0x000d, 0x28f4: 0x000d, 0x28f5: 0x000d, + 0x28f6: 0x000d, 0x28f7: 0x000d, 0x28f8: 0x000d, 0x28f9: 0x000d, 0x28fa: 0x000d, 0x28fb: 0x000d, + 0x28fc: 0x000d, 0x28fd: 0x000d, 0x28fe: 0x000d, 0x28ff: 0x000d, + // Block 0xa4, offset 0x2900 + 0x2900: 0x000d, 0x2901: 0x000d, 0x2902: 0x000d, 0x2903: 0x000d, 0x2904: 0x000d, 0x2905: 0x000d, + 0x2906: 0x000c, 0x2907: 0x000c, 0x2908: 0x000c, 0x2909: 0x000c, 0x290a: 0x000c, 0x290b: 0x000c, + 0x290c: 0x000c, 0x290d: 0x000c, 0x290e: 0x000c, 0x290f: 0x000c, 0x2910: 0x000c, 0x2911: 0x000d, + 0x2912: 0x000d, 0x2913: 0x000d, 0x2914: 0x000d, 0x2915: 0x000d, 0x2916: 0x000d, 0x2917: 0x000d, + 0x2918: 0x000d, 0x2919: 0x000d, 0x291a: 0x000d, 0x291b: 0x000d, 0x291c: 0x000d, 0x291d: 0x000d, + 0x291e: 0x000d, 0x291f: 0x000d, 0x2920: 0x000d, 0x2921: 0x000d, 0x2922: 0x000d, 0x2923: 0x000d, + 0x2924: 0x000d, 0x2925: 0x000d, 0x2926: 0x000d, 0x2927: 0x000d, 0x2928: 0x000d, 0x2929: 0x000d, + 0x292a: 0x000d, 0x292b: 0x000d, 0x292c: 0x000d, 0x292d: 0x000d, 0x292e: 0x000d, 0x292f: 0x000d, + 0x2930: 0x0001, 0x2931: 0x0001, 0x2932: 0x0001, 0x2933: 0x0001, 0x2934: 0x0001, 0x2935: 0x0001, + 0x2936: 0x0001, 0x2937: 0x0001, 0x2938: 0x0001, 0x2939: 0x0001, 0x293a: 0x0001, 0x293b: 0x0001, + 0x293c: 0x0001, 0x293d: 0x0001, 0x293e: 0x0001, 0x293f: 0x0001, + // Block 0xa5, offset 0x2940 + 0x2941: 0x000c, + 0x2978: 0x000c, 0x2979: 0x000c, 0x297a: 0x000c, 0x297b: 0x000c, + 0x297c: 0x000c, 0x297d: 0x000c, 0x297e: 0x000c, 0x297f: 0x000c, + // Block 0xa6, offset 0x2980 + 0x2980: 0x000c, 0x2981: 0x000c, 0x2982: 0x000c, 0x2983: 0x000c, 0x2984: 0x000c, 0x2985: 0x000c, + 0x2986: 0x000c, + 0x2992: 0x000a, 0x2993: 0x000a, 0x2994: 0x000a, 0x2995: 0x000a, 0x2996: 0x000a, 0x2997: 0x000a, + 0x2998: 0x000a, 0x2999: 0x000a, 0x299a: 0x000a, 0x299b: 0x000a, 0x299c: 0x000a, 0x299d: 0x000a, + 0x299e: 0x000a, 0x299f: 0x000a, 0x29a0: 0x000a, 0x29a1: 0x000a, 0x29a2: 0x000a, 0x29a3: 0x000a, + 0x29a4: 0x000a, 0x29a5: 0x000a, + 0x29bf: 0x000c, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x000c, 0x29c1: 0x000c, + 0x29f3: 0x000c, 0x29f4: 0x000c, 0x29f5: 0x000c, + 0x29f6: 0x000c, 0x29f9: 0x000c, 0x29fa: 0x000c, + // Block 0xa8, offset 0x2a00 + 0x2a00: 0x000c, 0x2a01: 0x000c, 0x2a02: 0x000c, + 0x2a27: 0x000c, 0x2a28: 0x000c, 0x2a29: 0x000c, + 0x2a2a: 0x000c, 0x2a2b: 0x000c, 0x2a2d: 0x000c, 0x2a2e: 0x000c, 0x2a2f: 0x000c, + 0x2a30: 0x000c, 0x2a31: 0x000c, 0x2a32: 0x000c, 0x2a33: 0x000c, 0x2a34: 0x000c, + // Block 0xa9, offset 0x2a40 + 0x2a73: 0x000c, + // Block 0xaa, offset 0x2a80 + 0x2a80: 0x000c, 0x2a81: 0x000c, + 0x2ab6: 0x000c, 0x2ab7: 0x000c, 0x2ab8: 0x000c, 0x2ab9: 0x000c, 0x2aba: 0x000c, 0x2abb: 0x000c, + 0x2abc: 0x000c, 0x2abd: 0x000c, 0x2abe: 0x000c, + // Block 0xab, offset 0x2ac0 + 0x2ac9: 0x000c, 0x2aca: 0x000c, 0x2acb: 0x000c, + 0x2acc: 0x000c, + // Block 0xac, offset 0x2b00 + 0x2b2f: 0x000c, + 0x2b30: 0x000c, 0x2b31: 0x000c, 0x2b34: 0x000c, + 0x2b36: 0x000c, 0x2b37: 0x000c, + 0x2b3e: 0x000c, + // Block 0xad, offset 0x2b40 + 0x2b5f: 0x000c, 0x2b63: 0x000c, + 0x2b64: 0x000c, 0x2b65: 0x000c, 0x2b66: 0x000c, 0x2b67: 0x000c, 0x2b68: 0x000c, 0x2b69: 0x000c, + 0x2b6a: 0x000c, + // Block 0xae, offset 0x2b80 + 0x2b80: 0x000c, + 0x2ba6: 0x000c, 0x2ba7: 0x000c, 0x2ba8: 0x000c, 0x2ba9: 0x000c, + 0x2baa: 0x000c, 0x2bab: 0x000c, 0x2bac: 0x000c, + 0x2bb0: 0x000c, 0x2bb1: 0x000c, 0x2bb2: 0x000c, 0x2bb3: 0x000c, 0x2bb4: 0x000c, + // Block 0xaf, offset 0x2bc0 + 0x2bf8: 0x000c, 0x2bf9: 0x000c, 0x2bfa: 0x000c, 0x2bfb: 0x000c, + 0x2bfc: 0x000c, 0x2bfd: 0x000c, 0x2bfe: 0x000c, 0x2bff: 0x000c, + // Block 0xb0, offset 0x2c00 + 0x2c02: 0x000c, 0x2c03: 0x000c, 0x2c04: 0x000c, + 0x2c06: 0x000c, + 0x2c1e: 0x000c, + // Block 0xb1, offset 0x2c40 + 0x2c73: 0x000c, 0x2c74: 0x000c, 0x2c75: 0x000c, + 0x2c76: 0x000c, 0x2c77: 0x000c, 0x2c78: 0x000c, 0x2c7a: 0x000c, + 0x2c7f: 0x000c, + // Block 0xb2, offset 0x2c80 + 0x2c80: 0x000c, 0x2c82: 0x000c, 0x2c83: 0x000c, + // Block 0xb3, offset 0x2cc0 + 0x2cf2: 0x000c, 0x2cf3: 0x000c, 0x2cf4: 0x000c, 0x2cf5: 0x000c, + 0x2cfc: 0x000c, 0x2cfd: 0x000c, 0x2cff: 0x000c, + // Block 0xb4, offset 0x2d00 + 0x2d00: 0x000c, + 0x2d1c: 0x000c, 0x2d1d: 0x000c, + // Block 0xb5, offset 0x2d40 + 0x2d73: 0x000c, 0x2d74: 0x000c, 0x2d75: 0x000c, + 0x2d76: 0x000c, 0x2d77: 0x000c, 0x2d78: 0x000c, 0x2d79: 0x000c, 0x2d7a: 0x000c, + 0x2d7d: 0x000c, 0x2d7f: 0x000c, + // Block 0xb6, offset 0x2d80 + 0x2d80: 0x000c, + 0x2da0: 0x000a, 0x2da1: 0x000a, 0x2da2: 0x000a, 0x2da3: 0x000a, + 0x2da4: 0x000a, 0x2da5: 0x000a, 0x2da6: 0x000a, 0x2da7: 0x000a, 0x2da8: 0x000a, 0x2da9: 0x000a, + 0x2daa: 0x000a, 0x2dab: 0x000a, 0x2dac: 0x000a, + // Block 0xb7, offset 0x2dc0 + 0x2deb: 0x000c, 0x2ded: 0x000c, + 0x2df0: 0x000c, 0x2df1: 0x000c, 0x2df2: 0x000c, 0x2df3: 0x000c, 0x2df4: 0x000c, 0x2df5: 0x000c, + 0x2df7: 0x000c, + // Block 0xb8, offset 0x2e00 + 0x2e1d: 0x000c, + 0x2e1e: 0x000c, 0x2e1f: 0x000c, 0x2e22: 0x000c, 0x2e23: 0x000c, + 0x2e24: 0x000c, 0x2e25: 0x000c, 0x2e27: 0x000c, 0x2e28: 0x000c, 0x2e29: 0x000c, + 0x2e2a: 0x000c, 0x2e2b: 0x000c, + // Block 0xb9, offset 0x2e40 + 0x2e6f: 0x000c, + 0x2e70: 0x000c, 0x2e71: 0x000c, 0x2e72: 0x000c, 0x2e73: 0x000c, 0x2e74: 0x000c, 0x2e75: 0x000c, + 0x2e76: 0x000c, 0x2e77: 0x000c, 0x2e79: 0x000c, 0x2e7a: 0x000c, + // Block 0xba, offset 0x2e80 + 0x2e81: 0x000c, 0x2e82: 0x000c, 0x2e83: 0x000c, 0x2e84: 0x000c, 0x2e85: 0x000c, + 0x2e86: 0x000c, 0x2e89: 0x000c, 0x2e8a: 0x000c, + 0x2eb3: 0x000c, 0x2eb4: 0x000c, 0x2eb5: 0x000c, + 0x2eb6: 0x000c, 0x2eb7: 0x000c, 0x2eb8: 0x000c, 0x2ebb: 0x000c, + 0x2ebc: 0x000c, 0x2ebd: 0x000c, 0x2ebe: 0x000c, + // Block 0xbb, offset 0x2ec0 + 0x2ec7: 0x000c, + 0x2ed1: 0x000c, + 0x2ed2: 0x000c, 0x2ed3: 0x000c, 0x2ed4: 0x000c, 0x2ed5: 0x000c, 0x2ed6: 0x000c, + 0x2ed9: 0x000c, 0x2eda: 0x000c, 0x2edb: 0x000c, + // Block 0xbc, offset 0x2f00 + 0x2f0a: 0x000c, 0x2f0b: 0x000c, + 0x2f0c: 0x000c, 0x2f0d: 0x000c, 0x2f0e: 0x000c, 0x2f0f: 0x000c, 0x2f10: 0x000c, 0x2f11: 0x000c, + 0x2f12: 0x000c, 0x2f13: 0x000c, 0x2f14: 0x000c, 0x2f15: 0x000c, 0x2f16: 0x000c, + 0x2f18: 0x000c, 0x2f19: 0x000c, + // Block 0xbd, offset 0x2f40 + 0x2f70: 0x000c, 0x2f71: 0x000c, 0x2f72: 0x000c, 0x2f73: 0x000c, 0x2f74: 0x000c, 0x2f75: 0x000c, + 0x2f76: 0x000c, 0x2f78: 0x000c, 0x2f79: 0x000c, 0x2f7a: 0x000c, 0x2f7b: 0x000c, + 0x2f7c: 0x000c, 0x2f7d: 0x000c, + // Block 0xbe, offset 0x2f80 + 0x2f92: 0x000c, 0x2f93: 0x000c, 0x2f94: 0x000c, 0x2f95: 0x000c, 0x2f96: 0x000c, 0x2f97: 0x000c, + 0x2f98: 0x000c, 0x2f99: 0x000c, 0x2f9a: 0x000c, 0x2f9b: 0x000c, 0x2f9c: 0x000c, 0x2f9d: 0x000c, + 0x2f9e: 0x000c, 0x2f9f: 0x000c, 0x2fa0: 0x000c, 0x2fa1: 0x000c, 0x2fa2: 0x000c, 0x2fa3: 0x000c, + 0x2fa4: 0x000c, 0x2fa5: 0x000c, 0x2fa6: 0x000c, 0x2fa7: 0x000c, + 0x2faa: 0x000c, 0x2fab: 0x000c, 0x2fac: 0x000c, 0x2fad: 0x000c, 0x2fae: 0x000c, 0x2faf: 0x000c, + 0x2fb0: 0x000c, 0x2fb2: 0x000c, 0x2fb3: 0x000c, 0x2fb5: 0x000c, + 0x2fb6: 0x000c, + // Block 0xbf, offset 0x2fc0 + 0x2ff1: 0x000c, 0x2ff2: 0x000c, 0x2ff3: 0x000c, 0x2ff4: 0x000c, 0x2ff5: 0x000c, + 0x2ff6: 0x000c, 0x2ffa: 0x000c, + 0x2ffc: 0x000c, 0x2ffd: 0x000c, 0x2fff: 0x000c, + // Block 0xc0, offset 0x3000 + 0x3000: 0x000c, 0x3001: 0x000c, 0x3002: 0x000c, 0x3003: 0x000c, 0x3004: 0x000c, 0x3005: 0x000c, + 0x3007: 0x000c, + // Block 0xc1, offset 0x3040 + 0x3050: 0x000c, 0x3051: 0x000c, + 0x3055: 0x000c, 0x3057: 0x000c, + // Block 0xc2, offset 0x3080 + 0x30b3: 0x000c, 0x30b4: 0x000c, + // Block 0xc3, offset 0x30c0 + 0x30f0: 0x000c, 0x30f1: 0x000c, 0x30f2: 0x000c, 0x30f3: 0x000c, 0x30f4: 0x000c, + // Block 0xc4, offset 0x3100 + 0x3130: 0x000c, 0x3131: 0x000c, 0x3132: 0x000c, 0x3133: 0x000c, 0x3134: 0x000c, 0x3135: 0x000c, + 0x3136: 0x000c, + // Block 0xc5, offset 0x3140 + 0x314f: 0x000c, 0x3150: 0x000c, 0x3151: 0x000c, + 0x3152: 0x000c, + // Block 0xc6, offset 0x3180 + 0x319d: 0x000c, + 0x319e: 0x000c, 0x31a0: 0x000b, 0x31a1: 0x000b, 0x31a2: 0x000b, 0x31a3: 0x000b, + // Block 0xc7, offset 0x31c0 + 0x31e7: 0x000c, 0x31e8: 0x000c, 0x31e9: 0x000c, + 0x31f3: 0x000b, 0x31f4: 0x000b, 0x31f5: 0x000b, + 0x31f6: 0x000b, 0x31f7: 0x000b, 0x31f8: 0x000b, 0x31f9: 0x000b, 0x31fa: 0x000b, 0x31fb: 0x000c, + 0x31fc: 0x000c, 0x31fd: 0x000c, 0x31fe: 0x000c, 0x31ff: 0x000c, + // Block 0xc8, offset 0x3200 + 0x3200: 0x000c, 0x3201: 0x000c, 0x3202: 0x000c, 0x3205: 0x000c, + 0x3206: 0x000c, 0x3207: 0x000c, 0x3208: 0x000c, 0x3209: 0x000c, 0x320a: 0x000c, 0x320b: 0x000c, + 0x322a: 0x000c, 0x322b: 0x000c, 0x322c: 0x000c, 0x322d: 0x000c, + // Block 0xc9, offset 0x3240 + 0x3240: 0x000a, 0x3241: 0x000a, 0x3242: 0x000c, 0x3243: 0x000c, 0x3244: 0x000c, 0x3245: 0x000a, + // Block 0xca, offset 0x3280 + 0x3280: 0x000a, 0x3281: 0x000a, 0x3282: 0x000a, 0x3283: 0x000a, 0x3284: 0x000a, 0x3285: 0x000a, + 0x3286: 0x000a, 0x3287: 0x000a, 0x3288: 0x000a, 0x3289: 0x000a, 0x328a: 0x000a, 0x328b: 0x000a, + 0x328c: 0x000a, 0x328d: 0x000a, 0x328e: 0x000a, 0x328f: 0x000a, 0x3290: 0x000a, 0x3291: 0x000a, + 0x3292: 0x000a, 0x3293: 0x000a, 0x3294: 0x000a, 0x3295: 0x000a, 0x3296: 0x000a, + // Block 0xcb, offset 0x32c0 + 0x32db: 0x000a, + // Block 0xcc, offset 0x3300 + 0x3315: 0x000a, + // Block 0xcd, offset 0x3340 + 0x334f: 0x000a, + // Block 0xce, offset 0x3380 + 0x3389: 0x000a, + // Block 0xcf, offset 0x33c0 + 0x33c3: 0x000a, + 0x33ce: 0x0002, 0x33cf: 0x0002, 0x33d0: 0x0002, 0x33d1: 0x0002, + 0x33d2: 0x0002, 0x33d3: 0x0002, 0x33d4: 0x0002, 0x33d5: 0x0002, 0x33d6: 0x0002, 0x33d7: 0x0002, + 0x33d8: 0x0002, 0x33d9: 0x0002, 0x33da: 0x0002, 0x33db: 0x0002, 0x33dc: 0x0002, 0x33dd: 0x0002, + 0x33de: 0x0002, 0x33df: 0x0002, 0x33e0: 0x0002, 0x33e1: 0x0002, 0x33e2: 0x0002, 0x33e3: 0x0002, + 0x33e4: 0x0002, 0x33e5: 0x0002, 0x33e6: 0x0002, 0x33e7: 0x0002, 0x33e8: 0x0002, 0x33e9: 0x0002, + 0x33ea: 0x0002, 0x33eb: 0x0002, 0x33ec: 0x0002, 0x33ed: 0x0002, 0x33ee: 0x0002, 0x33ef: 0x0002, + 0x33f0: 0x0002, 0x33f1: 0x0002, 0x33f2: 0x0002, 0x33f3: 0x0002, 0x33f4: 0x0002, 0x33f5: 0x0002, + 0x33f6: 0x0002, 0x33f7: 0x0002, 0x33f8: 0x0002, 0x33f9: 0x0002, 0x33fa: 0x0002, 0x33fb: 0x0002, + 0x33fc: 0x0002, 0x33fd: 0x0002, 0x33fe: 0x0002, 0x33ff: 0x0002, + // Block 0xd0, offset 0x3400 + 0x3400: 0x000c, 0x3401: 0x000c, 0x3402: 0x000c, 0x3403: 0x000c, 0x3404: 0x000c, 0x3405: 0x000c, + 0x3406: 0x000c, 0x3407: 0x000c, 0x3408: 0x000c, 0x3409: 0x000c, 0x340a: 0x000c, 0x340b: 0x000c, + 0x340c: 0x000c, 0x340d: 0x000c, 0x340e: 0x000c, 0x340f: 0x000c, 0x3410: 0x000c, 0x3411: 0x000c, + 0x3412: 0x000c, 0x3413: 0x000c, 0x3414: 0x000c, 0x3415: 0x000c, 0x3416: 0x000c, 0x3417: 0x000c, + 0x3418: 0x000c, 0x3419: 0x000c, 0x341a: 0x000c, 0x341b: 0x000c, 0x341c: 0x000c, 0x341d: 0x000c, + 0x341e: 0x000c, 0x341f: 0x000c, 0x3420: 0x000c, 0x3421: 0x000c, 0x3422: 0x000c, 0x3423: 0x000c, + 0x3424: 0x000c, 0x3425: 0x000c, 0x3426: 0x000c, 0x3427: 0x000c, 0x3428: 0x000c, 0x3429: 0x000c, + 0x342a: 0x000c, 0x342b: 0x000c, 0x342c: 0x000c, 0x342d: 0x000c, 0x342e: 0x000c, 0x342f: 0x000c, + 0x3430: 0x000c, 0x3431: 0x000c, 0x3432: 0x000c, 0x3433: 0x000c, 0x3434: 0x000c, 0x3435: 0x000c, + 0x3436: 0x000c, 0x343b: 0x000c, + 0x343c: 0x000c, 0x343d: 0x000c, 0x343e: 0x000c, 0x343f: 0x000c, + // Block 0xd1, offset 0x3440 + 0x3440: 0x000c, 0x3441: 0x000c, 0x3442: 0x000c, 0x3443: 0x000c, 0x3444: 0x000c, 0x3445: 0x000c, + 0x3446: 0x000c, 0x3447: 0x000c, 0x3448: 0x000c, 0x3449: 0x000c, 0x344a: 0x000c, 0x344b: 0x000c, + 0x344c: 0x000c, 0x344d: 0x000c, 0x344e: 0x000c, 0x344f: 0x000c, 0x3450: 0x000c, 0x3451: 0x000c, + 0x3452: 0x000c, 0x3453: 0x000c, 0x3454: 0x000c, 0x3455: 0x000c, 0x3456: 0x000c, 0x3457: 0x000c, + 0x3458: 0x000c, 0x3459: 0x000c, 0x345a: 0x000c, 0x345b: 0x000c, 0x345c: 0x000c, 0x345d: 0x000c, + 0x345e: 0x000c, 0x345f: 0x000c, 0x3460: 0x000c, 0x3461: 0x000c, 0x3462: 0x000c, 0x3463: 0x000c, + 0x3464: 0x000c, 0x3465: 0x000c, 0x3466: 0x000c, 0x3467: 0x000c, 0x3468: 0x000c, 0x3469: 0x000c, + 0x346a: 0x000c, 0x346b: 0x000c, 0x346c: 0x000c, + 0x3475: 0x000c, + // Block 0xd2, offset 0x3480 + 0x3484: 0x000c, + 0x349b: 0x000c, 0x349c: 0x000c, 0x349d: 0x000c, + 0x349e: 0x000c, 0x349f: 0x000c, 0x34a1: 0x000c, 0x34a2: 0x000c, 0x34a3: 0x000c, + 0x34a4: 0x000c, 0x34a5: 0x000c, 0x34a6: 0x000c, 0x34a7: 0x000c, 0x34a8: 0x000c, 0x34a9: 0x000c, + 0x34aa: 0x000c, 0x34ab: 0x000c, 0x34ac: 0x000c, 0x34ad: 0x000c, 0x34ae: 0x000c, 0x34af: 0x000c, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x000c, 0x34c1: 0x000c, 0x34c2: 0x000c, 0x34c3: 0x000c, 0x34c4: 0x000c, 0x34c5: 0x000c, + 0x34c6: 0x000c, 0x34c8: 0x000c, 0x34c9: 0x000c, 0x34ca: 0x000c, 0x34cb: 0x000c, + 0x34cc: 0x000c, 0x34cd: 0x000c, 0x34ce: 0x000c, 0x34cf: 0x000c, 0x34d0: 0x000c, 0x34d1: 0x000c, + 0x34d2: 0x000c, 0x34d3: 0x000c, 0x34d4: 0x000c, 0x34d5: 0x000c, 0x34d6: 0x000c, 0x34d7: 0x000c, + 0x34d8: 0x000c, 0x34db: 0x000c, 0x34dc: 0x000c, 0x34dd: 0x000c, + 0x34de: 0x000c, 0x34df: 0x000c, 0x34e0: 0x000c, 0x34e1: 0x000c, 0x34e3: 0x000c, + 0x34e4: 0x000c, 0x34e6: 0x000c, 0x34e7: 0x000c, 0x34e8: 0x000c, 0x34e9: 0x000c, + 0x34ea: 0x000c, + // Block 0xd4, offset 0x3500 + 0x3500: 0x0001, 0x3501: 0x0001, 0x3502: 0x0001, 0x3503: 0x0001, 0x3504: 0x0001, 0x3505: 0x0001, + 0x3506: 0x0001, 0x3507: 0x0001, 0x3508: 0x0001, 0x3509: 0x0001, 0x350a: 0x0001, 0x350b: 0x0001, + 0x350c: 0x0001, 0x350d: 0x0001, 0x350e: 0x0001, 0x350f: 0x0001, 0x3510: 0x000c, 0x3511: 0x000c, + 0x3512: 0x000c, 0x3513: 0x000c, 0x3514: 0x000c, 0x3515: 0x000c, 0x3516: 0x000c, 0x3517: 0x0001, + 0x3518: 0x0001, 0x3519: 0x0001, 0x351a: 0x0001, 0x351b: 0x0001, 0x351c: 0x0001, 0x351d: 0x0001, + 0x351e: 0x0001, 0x351f: 0x0001, 0x3520: 0x0001, 0x3521: 0x0001, 0x3522: 0x0001, 0x3523: 0x0001, + 0x3524: 0x0001, 0x3525: 0x0001, 0x3526: 0x0001, 0x3527: 0x0001, 0x3528: 0x0001, 0x3529: 0x0001, + 0x352a: 0x0001, 0x352b: 0x0001, 0x352c: 0x0001, 0x352d: 0x0001, 0x352e: 0x0001, 0x352f: 0x0001, + 0x3530: 0x0001, 0x3531: 0x0001, 0x3532: 0x0001, 0x3533: 0x0001, 0x3534: 0x0001, 0x3535: 0x0001, + 0x3536: 0x0001, 0x3537: 0x0001, 0x3538: 0x0001, 0x3539: 0x0001, 0x353a: 0x0001, 0x353b: 0x0001, + 0x353c: 0x0001, 0x353d: 0x0001, 0x353e: 0x0001, 0x353f: 0x0001, + // Block 0xd5, offset 0x3540 + 0x3540: 0x0001, 0x3541: 0x0001, 0x3542: 0x0001, 0x3543: 0x0001, 0x3544: 0x000c, 0x3545: 0x000c, + 0x3546: 0x000c, 0x3547: 0x000c, 0x3548: 0x000c, 0x3549: 0x000c, 0x354a: 0x000c, 0x354b: 0x0001, + 0x354c: 0x0001, 0x354d: 0x0001, 0x354e: 0x0001, 0x354f: 0x0001, 0x3550: 0x0001, 0x3551: 0x0001, + 0x3552: 0x0001, 0x3553: 0x0001, 0x3554: 0x0001, 0x3555: 0x0001, 0x3556: 0x0001, 0x3557: 0x0001, + 0x3558: 0x0001, 0x3559: 0x0001, 0x355a: 0x0001, 0x355b: 0x0001, 0x355c: 0x0001, 0x355d: 0x0001, + 0x355e: 0x0001, 0x355f: 0x0001, 0x3560: 0x0001, 0x3561: 0x0001, 0x3562: 0x0001, 0x3563: 0x0001, + 0x3564: 0x0001, 0x3565: 0x0001, 0x3566: 0x0001, 0x3567: 0x0001, 0x3568: 0x0001, 0x3569: 0x0001, + 0x356a: 0x0001, 0x356b: 0x0001, 0x356c: 0x0001, 0x356d: 0x0001, 0x356e: 0x0001, 0x356f: 0x0001, + 0x3570: 0x0001, 0x3571: 0x0001, 0x3572: 0x0001, 0x3573: 0x0001, 0x3574: 0x0001, 0x3575: 0x0001, + 0x3576: 0x0001, 0x3577: 0x0001, 0x3578: 0x0001, 0x3579: 0x0001, 0x357a: 0x0001, 0x357b: 0x0001, + 0x357c: 0x0001, 0x357d: 0x0001, 0x357e: 0x0001, 0x357f: 0x0001, + // Block 0xd6, offset 0x3580 + 0x3580: 0x000d, 0x3581: 0x000d, 0x3582: 0x000d, 0x3583: 0x000d, 0x3584: 0x000d, 0x3585: 0x000d, + 0x3586: 0x000d, 0x3587: 0x000d, 0x3588: 0x000d, 0x3589: 0x000d, 0x358a: 0x000d, 0x358b: 0x000d, + 0x358c: 0x000d, 0x358d: 0x000d, 0x358e: 0x000d, 0x358f: 0x000d, 0x3590: 0x000d, 0x3591: 0x000d, + 0x3592: 0x000d, 0x3593: 0x000d, 0x3594: 0x000d, 0x3595: 0x000d, 0x3596: 0x000d, 0x3597: 0x000d, + 0x3598: 0x000d, 0x3599: 0x000d, 0x359a: 0x000d, 0x359b: 0x000d, 0x359c: 0x000d, 0x359d: 0x000d, + 0x359e: 0x000d, 0x359f: 0x000d, 0x35a0: 0x000d, 0x35a1: 0x000d, 0x35a2: 0x000d, 0x35a3: 0x000d, + 0x35a4: 0x000d, 0x35a5: 0x000d, 0x35a6: 0x000d, 0x35a7: 0x000d, 0x35a8: 0x000d, 0x35a9: 0x000d, + 0x35aa: 0x000d, 0x35ab: 0x000d, 0x35ac: 0x000d, 0x35ad: 0x000d, 0x35ae: 0x000d, 0x35af: 0x000d, + 0x35b0: 0x000a, 0x35b1: 0x000a, 0x35b2: 0x000d, 0x35b3: 0x000d, 0x35b4: 0x000d, 0x35b5: 0x000d, + 0x35b6: 0x000d, 0x35b7: 0x000d, 0x35b8: 0x000d, 0x35b9: 0x000d, 0x35ba: 0x000d, 0x35bb: 0x000d, + 0x35bc: 0x000d, 0x35bd: 0x000d, 0x35be: 0x000d, 0x35bf: 0x000d, + // Block 0xd7, offset 0x35c0 + 0x35c0: 0x000a, 0x35c1: 0x000a, 0x35c2: 0x000a, 0x35c3: 0x000a, 0x35c4: 0x000a, 0x35c5: 0x000a, + 0x35c6: 0x000a, 0x35c7: 0x000a, 0x35c8: 0x000a, 0x35c9: 0x000a, 0x35ca: 0x000a, 0x35cb: 0x000a, + 0x35cc: 0x000a, 0x35cd: 0x000a, 0x35ce: 0x000a, 0x35cf: 0x000a, 0x35d0: 0x000a, 0x35d1: 0x000a, + 0x35d2: 0x000a, 0x35d3: 0x000a, 0x35d4: 0x000a, 0x35d5: 0x000a, 0x35d6: 0x000a, 0x35d7: 0x000a, + 0x35d8: 0x000a, 0x35d9: 0x000a, 0x35da: 0x000a, 0x35db: 0x000a, 0x35dc: 0x000a, 0x35dd: 0x000a, + 0x35de: 0x000a, 0x35df: 0x000a, 0x35e0: 0x000a, 0x35e1: 0x000a, 0x35e2: 0x000a, 0x35e3: 0x000a, + 0x35e4: 0x000a, 0x35e5: 0x000a, 0x35e6: 0x000a, 0x35e7: 0x000a, 0x35e8: 0x000a, 0x35e9: 0x000a, + 0x35ea: 0x000a, 0x35eb: 0x000a, + 0x35f0: 0x000a, 0x35f1: 0x000a, 0x35f2: 0x000a, 0x35f3: 0x000a, 0x35f4: 0x000a, 0x35f5: 0x000a, + 0x35f6: 0x000a, 0x35f7: 0x000a, 0x35f8: 0x000a, 0x35f9: 0x000a, 0x35fa: 0x000a, 0x35fb: 0x000a, + 0x35fc: 0x000a, 0x35fd: 0x000a, 0x35fe: 0x000a, 0x35ff: 0x000a, + // Block 0xd8, offset 0x3600 + 0x3600: 0x000a, 0x3601: 0x000a, 0x3602: 0x000a, 0x3603: 0x000a, 0x3604: 0x000a, 0x3605: 0x000a, + 0x3606: 0x000a, 0x3607: 0x000a, 0x3608: 0x000a, 0x3609: 0x000a, 0x360a: 0x000a, 0x360b: 0x000a, + 0x360c: 0x000a, 0x360d: 0x000a, 0x360e: 0x000a, 0x360f: 0x000a, 0x3610: 0x000a, 0x3611: 0x000a, + 0x3612: 0x000a, 0x3613: 0x000a, + 0x3620: 0x000a, 0x3621: 0x000a, 0x3622: 0x000a, 0x3623: 0x000a, + 0x3624: 0x000a, 0x3625: 0x000a, 0x3626: 0x000a, 0x3627: 0x000a, 0x3628: 0x000a, 0x3629: 0x000a, + 0x362a: 0x000a, 0x362b: 0x000a, 0x362c: 0x000a, 0x362d: 0x000a, 0x362e: 0x000a, + 0x3631: 0x000a, 0x3632: 0x000a, 0x3633: 0x000a, 0x3634: 0x000a, 0x3635: 0x000a, + 0x3636: 0x000a, 0x3637: 0x000a, 0x3638: 0x000a, 0x3639: 0x000a, 0x363a: 0x000a, 0x363b: 0x000a, + 0x363c: 0x000a, 0x363d: 0x000a, 0x363e: 0x000a, 0x363f: 0x000a, + // Block 0xd9, offset 0x3640 + 0x3641: 0x000a, 0x3642: 0x000a, 0x3643: 0x000a, 0x3644: 0x000a, 0x3645: 0x000a, + 0x3646: 0x000a, 0x3647: 0x000a, 0x3648: 0x000a, 0x3649: 0x000a, 0x364a: 0x000a, 0x364b: 0x000a, + 0x364c: 0x000a, 0x364d: 0x000a, 0x364e: 0x000a, 0x364f: 0x000a, 0x3651: 0x000a, + 0x3652: 0x000a, 0x3653: 0x000a, 0x3654: 0x000a, 0x3655: 0x000a, 0x3656: 0x000a, 0x3657: 0x000a, + 0x3658: 0x000a, 0x3659: 0x000a, 0x365a: 0x000a, 0x365b: 0x000a, 0x365c: 0x000a, 0x365d: 0x000a, + 0x365e: 0x000a, 0x365f: 0x000a, 0x3660: 0x000a, 0x3661: 0x000a, 0x3662: 0x000a, 0x3663: 0x000a, + 0x3664: 0x000a, 0x3665: 0x000a, 0x3666: 0x000a, 0x3667: 0x000a, 0x3668: 0x000a, 0x3669: 0x000a, + 0x366a: 0x000a, 0x366b: 0x000a, 0x366c: 0x000a, 0x366d: 0x000a, 0x366e: 0x000a, 0x366f: 0x000a, + 0x3670: 0x000a, 0x3671: 0x000a, 0x3672: 0x000a, 0x3673: 0x000a, 0x3674: 0x000a, 0x3675: 0x000a, + // Block 0xda, offset 0x3680 + 0x3680: 0x0002, 0x3681: 0x0002, 0x3682: 0x0002, 0x3683: 0x0002, 0x3684: 0x0002, 0x3685: 0x0002, + 0x3686: 0x0002, 0x3687: 0x0002, 0x3688: 0x0002, 0x3689: 0x0002, 0x368a: 0x0002, 0x368b: 0x000a, + 0x368c: 0x000a, + 0x36af: 0x000a, + // Block 0xdb, offset 0x36c0 + 0x36ea: 0x000a, 0x36eb: 0x000a, + // Block 0xdc, offset 0x3700 + 0x3720: 0x000a, 0x3721: 0x000a, 0x3722: 0x000a, 0x3723: 0x000a, + 0x3724: 0x000a, 0x3725: 0x000a, + // Block 0xdd, offset 0x3740 + 0x3740: 0x000a, 0x3741: 0x000a, 0x3742: 0x000a, 0x3743: 0x000a, 0x3744: 0x000a, 0x3745: 0x000a, + 0x3746: 0x000a, 0x3747: 0x000a, 0x3748: 0x000a, 0x3749: 0x000a, 0x374a: 0x000a, 0x374b: 0x000a, + 0x374c: 0x000a, 0x374d: 0x000a, 0x374e: 0x000a, 0x374f: 0x000a, 0x3750: 0x000a, 0x3751: 0x000a, + 0x3752: 0x000a, 0x3753: 0x000a, 0x3754: 0x000a, + 0x3760: 0x000a, 0x3761: 0x000a, 0x3762: 0x000a, 0x3763: 0x000a, + 0x3764: 0x000a, 0x3765: 0x000a, 0x3766: 0x000a, 0x3767: 0x000a, 0x3768: 0x000a, 0x3769: 0x000a, + 0x376a: 0x000a, 0x376b: 0x000a, 0x376c: 0x000a, + 0x3770: 0x000a, 0x3771: 0x000a, 0x3772: 0x000a, 0x3773: 0x000a, 0x3774: 0x000a, 0x3775: 0x000a, + 0x3776: 0x000a, 0x3777: 0x000a, 0x3778: 0x000a, 0x3779: 0x000a, + // Block 0xde, offset 0x3780 + 0x3780: 0x000a, 0x3781: 0x000a, 0x3782: 0x000a, 0x3783: 0x000a, 0x3784: 0x000a, 0x3785: 0x000a, + 0x3786: 0x000a, 0x3787: 0x000a, 0x3788: 0x000a, 0x3789: 0x000a, 0x378a: 0x000a, 0x378b: 0x000a, + 0x378c: 0x000a, 0x378d: 0x000a, 0x378e: 0x000a, 0x378f: 0x000a, 0x3790: 0x000a, 0x3791: 0x000a, + 0x3792: 0x000a, 0x3793: 0x000a, 0x3794: 0x000a, 0x3795: 0x000a, 0x3796: 0x000a, 0x3797: 0x000a, + 0x3798: 0x000a, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x000a, 0x37c1: 0x000a, 0x37c2: 0x000a, 0x37c3: 0x000a, 0x37c4: 0x000a, 0x37c5: 0x000a, + 0x37c6: 0x000a, 0x37c7: 0x000a, 0x37c8: 0x000a, 0x37c9: 0x000a, 0x37ca: 0x000a, 0x37cb: 0x000a, + 0x37d0: 0x000a, 0x37d1: 0x000a, + 0x37d2: 0x000a, 0x37d3: 0x000a, 0x37d4: 0x000a, 0x37d5: 0x000a, 0x37d6: 0x000a, 0x37d7: 0x000a, + 0x37d8: 0x000a, 0x37d9: 0x000a, 0x37da: 0x000a, 0x37db: 0x000a, 0x37dc: 0x000a, 0x37dd: 0x000a, + 0x37de: 0x000a, 0x37df: 0x000a, 0x37e0: 0x000a, 0x37e1: 0x000a, 0x37e2: 0x000a, 0x37e3: 0x000a, + 0x37e4: 0x000a, 0x37e5: 0x000a, 0x37e6: 0x000a, 0x37e7: 0x000a, 0x37e8: 0x000a, 0x37e9: 0x000a, + 0x37ea: 0x000a, 0x37eb: 0x000a, 0x37ec: 0x000a, 0x37ed: 0x000a, 0x37ee: 0x000a, 0x37ef: 0x000a, + 0x37f0: 0x000a, 0x37f1: 0x000a, 0x37f2: 0x000a, 0x37f3: 0x000a, 0x37f4: 0x000a, 0x37f5: 0x000a, + 0x37f6: 0x000a, 0x37f7: 0x000a, 0x37f8: 0x000a, 0x37f9: 0x000a, 0x37fa: 0x000a, 0x37fb: 0x000a, + 0x37fc: 0x000a, 0x37fd: 0x000a, 0x37fe: 0x000a, 0x37ff: 0x000a, + // Block 0xe0, offset 0x3800 + 0x3800: 0x000a, 0x3801: 0x000a, 0x3802: 0x000a, 0x3803: 0x000a, 0x3804: 0x000a, 0x3805: 0x000a, + 0x3806: 0x000a, 0x3807: 0x000a, + 0x3810: 0x000a, 0x3811: 0x000a, + 0x3812: 0x000a, 0x3813: 0x000a, 0x3814: 0x000a, 0x3815: 0x000a, 0x3816: 0x000a, 0x3817: 0x000a, + 0x3818: 0x000a, 0x3819: 0x000a, + 0x3820: 0x000a, 0x3821: 0x000a, 0x3822: 0x000a, 0x3823: 0x000a, + 0x3824: 0x000a, 0x3825: 0x000a, 0x3826: 0x000a, 0x3827: 0x000a, 0x3828: 0x000a, 0x3829: 0x000a, + 0x382a: 0x000a, 0x382b: 0x000a, 0x382c: 0x000a, 0x382d: 0x000a, 0x382e: 0x000a, 0x382f: 0x000a, + 0x3830: 0x000a, 0x3831: 0x000a, 0x3832: 0x000a, 0x3833: 0x000a, 0x3834: 0x000a, 0x3835: 0x000a, + 0x3836: 0x000a, 0x3837: 0x000a, 0x3838: 0x000a, 0x3839: 0x000a, 0x383a: 0x000a, 0x383b: 0x000a, + 0x383c: 0x000a, 0x383d: 0x000a, 0x383e: 0x000a, 0x383f: 0x000a, + // Block 0xe1, offset 0x3840 + 0x3840: 0x000a, 0x3841: 0x000a, 0x3842: 0x000a, 0x3843: 0x000a, 0x3844: 0x000a, 0x3845: 0x000a, + 0x3846: 0x000a, 0x3847: 0x000a, + 0x3850: 0x000a, 0x3851: 0x000a, + 0x3852: 0x000a, 0x3853: 0x000a, 0x3854: 0x000a, 0x3855: 0x000a, 0x3856: 0x000a, 0x3857: 0x000a, + 0x3858: 0x000a, 0x3859: 0x000a, 0x385a: 0x000a, 0x385b: 0x000a, 0x385c: 0x000a, 0x385d: 0x000a, + 0x385e: 0x000a, 0x385f: 0x000a, 0x3860: 0x000a, 0x3861: 0x000a, 0x3862: 0x000a, 0x3863: 0x000a, + 0x3864: 0x000a, 0x3865: 0x000a, 0x3866: 0x000a, 0x3867: 0x000a, 0x3868: 0x000a, 0x3869: 0x000a, + 0x386a: 0x000a, 0x386b: 0x000a, 0x386c: 0x000a, 0x386d: 0x000a, + // Block 0xe2, offset 0x3880 + 0x3880: 0x000a, 0x3881: 0x000a, 0x3882: 0x000a, 0x3883: 0x000a, 0x3884: 0x000a, 0x3885: 0x000a, + 0x3886: 0x000a, 0x3887: 0x000a, 0x3888: 0x000a, 0x3889: 0x000a, 0x388a: 0x000a, 0x388b: 0x000a, + 0x3890: 0x000a, 0x3891: 0x000a, + 0x3892: 0x000a, 0x3893: 0x000a, 0x3894: 0x000a, 0x3895: 0x000a, 0x3896: 0x000a, 0x3897: 0x000a, + 0x3898: 0x000a, 0x3899: 0x000a, 0x389a: 0x000a, 0x389b: 0x000a, 0x389c: 0x000a, 0x389d: 0x000a, + 0x389e: 0x000a, 0x389f: 0x000a, 0x38a0: 0x000a, 0x38a1: 0x000a, 0x38a2: 0x000a, 0x38a3: 0x000a, + 0x38a4: 0x000a, 0x38a5: 0x000a, 0x38a6: 0x000a, 0x38a7: 0x000a, 0x38a8: 0x000a, 0x38a9: 0x000a, + 0x38aa: 0x000a, 0x38ab: 0x000a, 0x38ac: 0x000a, 0x38ad: 0x000a, 0x38ae: 0x000a, 0x38af: 0x000a, + 0x38b0: 0x000a, 0x38b1: 0x000a, 0x38b2: 0x000a, 0x38b3: 0x000a, 0x38b4: 0x000a, 0x38b5: 0x000a, + 0x38b6: 0x000a, 0x38b7: 0x000a, 0x38b8: 0x000a, 0x38b9: 0x000a, 0x38ba: 0x000a, 0x38bb: 0x000a, + 0x38bc: 0x000a, 0x38bd: 0x000a, 0x38be: 0x000a, + // Block 0xe3, offset 0x38c0 + 0x38c0: 0x000a, 0x38c1: 0x000a, 0x38c2: 0x000a, 0x38c3: 0x000a, 0x38c4: 0x000a, 0x38c5: 0x000a, + 0x38c6: 0x000a, 0x38c7: 0x000a, 0x38c8: 0x000a, 0x38c9: 0x000a, 0x38ca: 0x000a, 0x38cb: 0x000a, + 0x38cc: 0x000a, 0x38cd: 0x000a, 0x38ce: 0x000a, 0x38cf: 0x000a, 0x38d0: 0x000a, 0x38d1: 0x000a, + 0x38d2: 0x000a, 0x38d3: 0x000a, 0x38d4: 0x000a, 0x38d5: 0x000a, 0x38d6: 0x000a, 0x38d7: 0x000a, + 0x38d8: 0x000a, 0x38d9: 0x000a, 0x38da: 0x000a, 0x38db: 0x000a, 0x38dc: 0x000a, 0x38dd: 0x000a, + 0x38de: 0x000a, 0x38df: 0x000a, 0x38e0: 0x000a, 0x38e1: 0x000a, 0x38e2: 0x000a, 0x38e3: 0x000a, + 0x38e4: 0x000a, 0x38e5: 0x000a, 0x38e6: 0x000a, 0x38e7: 0x000a, 0x38e8: 0x000a, 0x38e9: 0x000a, + 0x38ea: 0x000a, 0x38eb: 0x000a, 0x38ec: 0x000a, 0x38ed: 0x000a, 0x38ee: 0x000a, 0x38ef: 0x000a, + 0x38f0: 0x000a, 0x38f3: 0x000a, 0x38f4: 0x000a, 0x38f5: 0x000a, + 0x38f6: 0x000a, 0x38fa: 0x000a, + 0x38fc: 0x000a, 0x38fd: 0x000a, 0x38fe: 0x000a, 0x38ff: 0x000a, + // Block 0xe4, offset 0x3900 + 0x3900: 0x000a, 0x3901: 0x000a, 0x3902: 0x000a, 0x3903: 0x000a, 0x3904: 0x000a, 0x3905: 0x000a, + 0x3906: 0x000a, 0x3907: 0x000a, 0x3908: 0x000a, 0x3909: 0x000a, 0x390a: 0x000a, 0x390b: 0x000a, + 0x390c: 0x000a, 0x390d: 0x000a, 0x390e: 0x000a, 0x390f: 0x000a, 0x3910: 0x000a, 0x3911: 0x000a, + 0x3912: 0x000a, 0x3913: 0x000a, 0x3914: 0x000a, 0x3915: 0x000a, 0x3916: 0x000a, 0x3917: 0x000a, + 0x3918: 0x000a, 0x3919: 0x000a, 0x391a: 0x000a, 0x391b: 0x000a, 0x391c: 0x000a, 0x391d: 0x000a, + 0x391e: 0x000a, 0x391f: 0x000a, 0x3920: 0x000a, 0x3921: 0x000a, 0x3922: 0x000a, + 0x3930: 0x000a, 0x3931: 0x000a, 0x3932: 0x000a, 0x3933: 0x000a, 0x3934: 0x000a, 0x3935: 0x000a, + 0x3936: 0x000a, 0x3937: 0x000a, 0x3938: 0x000a, 0x3939: 0x000a, + // Block 0xe5, offset 0x3940 + 0x3940: 0x000a, 0x3941: 0x000a, 0x3942: 0x000a, + 0x3950: 0x000a, 0x3951: 0x000a, + 0x3952: 0x000a, 0x3953: 0x000a, 0x3954: 0x000a, 0x3955: 0x000a, 0x3956: 0x000a, 0x3957: 0x000a, + 0x3958: 0x000a, 0x3959: 0x000a, 0x395a: 0x000a, 0x395b: 0x000a, 0x395c: 0x000a, 0x395d: 0x000a, + 0x395e: 0x000a, 0x395f: 0x000a, 0x3960: 0x000a, 0x3961: 0x000a, 0x3962: 0x000a, 0x3963: 0x000a, + 0x3964: 0x000a, 0x3965: 0x000a, 0x3966: 0x000a, 0x3967: 0x000a, 0x3968: 0x000a, 0x3969: 0x000a, + 0x396a: 0x000a, 0x396b: 0x000a, 0x396c: 0x000a, 0x396d: 0x000a, 0x396e: 0x000a, 0x396f: 0x000a, + 0x3970: 0x000a, 0x3971: 0x000a, 0x3972: 0x000a, 0x3973: 0x000a, 0x3974: 0x000a, 0x3975: 0x000a, + 0x3976: 0x000a, 0x3977: 0x000a, 0x3978: 0x000a, 0x3979: 0x000a, 0x397a: 0x000a, 0x397b: 0x000a, + 0x397c: 0x000a, 0x397d: 0x000a, 0x397e: 0x000a, 0x397f: 0x000a, + // Block 0xe6, offset 0x3980 + 0x39a0: 0x000a, 0x39a1: 0x000a, 0x39a2: 0x000a, 0x39a3: 0x000a, + 0x39a4: 0x000a, 0x39a5: 0x000a, 0x39a6: 0x000a, 0x39a7: 0x000a, 0x39a8: 0x000a, 0x39a9: 0x000a, + 0x39aa: 0x000a, 0x39ab: 0x000a, 0x39ac: 0x000a, 0x39ad: 0x000a, + // Block 0xe7, offset 0x39c0 + 0x39fe: 0x000b, 0x39ff: 0x000b, + // Block 0xe8, offset 0x3a00 + 0x3a00: 0x000b, 0x3a01: 0x000b, 0x3a02: 0x000b, 0x3a03: 0x000b, 0x3a04: 0x000b, 0x3a05: 0x000b, + 0x3a06: 0x000b, 0x3a07: 0x000b, 0x3a08: 0x000b, 0x3a09: 0x000b, 0x3a0a: 0x000b, 0x3a0b: 0x000b, + 0x3a0c: 0x000b, 0x3a0d: 0x000b, 0x3a0e: 0x000b, 0x3a0f: 0x000b, 0x3a10: 0x000b, 0x3a11: 0x000b, + 0x3a12: 0x000b, 0x3a13: 0x000b, 0x3a14: 0x000b, 0x3a15: 0x000b, 0x3a16: 0x000b, 0x3a17: 0x000b, + 0x3a18: 0x000b, 0x3a19: 0x000b, 0x3a1a: 0x000b, 0x3a1b: 0x000b, 0x3a1c: 0x000b, 0x3a1d: 0x000b, + 0x3a1e: 0x000b, 0x3a1f: 0x000b, 0x3a20: 0x000b, 0x3a21: 0x000b, 0x3a22: 0x000b, 0x3a23: 0x000b, + 0x3a24: 0x000b, 0x3a25: 0x000b, 0x3a26: 0x000b, 0x3a27: 0x000b, 0x3a28: 0x000b, 0x3a29: 0x000b, + 0x3a2a: 0x000b, 0x3a2b: 0x000b, 0x3a2c: 0x000b, 0x3a2d: 0x000b, 0x3a2e: 0x000b, 0x3a2f: 0x000b, + 0x3a30: 0x000b, 0x3a31: 0x000b, 0x3a32: 0x000b, 0x3a33: 0x000b, 0x3a34: 0x000b, 0x3a35: 0x000b, + 0x3a36: 0x000b, 0x3a37: 0x000b, 0x3a38: 0x000b, 0x3a39: 0x000b, 0x3a3a: 0x000b, 0x3a3b: 0x000b, + 0x3a3c: 0x000b, 0x3a3d: 0x000b, 0x3a3e: 0x000b, 0x3a3f: 0x000b, + // Block 0xe9, offset 0x3a40 + 0x3a40: 0x000c, 0x3a41: 0x000c, 0x3a42: 0x000c, 0x3a43: 0x000c, 0x3a44: 0x000c, 0x3a45: 0x000c, + 0x3a46: 0x000c, 0x3a47: 0x000c, 0x3a48: 0x000c, 0x3a49: 0x000c, 0x3a4a: 0x000c, 0x3a4b: 0x000c, + 0x3a4c: 0x000c, 0x3a4d: 0x000c, 0x3a4e: 0x000c, 0x3a4f: 0x000c, 0x3a50: 0x000c, 0x3a51: 0x000c, + 0x3a52: 0x000c, 0x3a53: 0x000c, 0x3a54: 0x000c, 0x3a55: 0x000c, 0x3a56: 0x000c, 0x3a57: 0x000c, + 0x3a58: 0x000c, 0x3a59: 0x000c, 0x3a5a: 0x000c, 0x3a5b: 0x000c, 0x3a5c: 0x000c, 0x3a5d: 0x000c, + 0x3a5e: 0x000c, 0x3a5f: 0x000c, 0x3a60: 0x000c, 0x3a61: 0x000c, 0x3a62: 0x000c, 0x3a63: 0x000c, + 0x3a64: 0x000c, 0x3a65: 0x000c, 0x3a66: 0x000c, 0x3a67: 0x000c, 0x3a68: 0x000c, 0x3a69: 0x000c, + 0x3a6a: 0x000c, 0x3a6b: 0x000c, 0x3a6c: 0x000c, 0x3a6d: 0x000c, 0x3a6e: 0x000c, 0x3a6f: 0x000c, + 0x3a70: 0x000b, 0x3a71: 0x000b, 0x3a72: 0x000b, 0x3a73: 0x000b, 0x3a74: 0x000b, 0x3a75: 0x000b, + 0x3a76: 0x000b, 0x3a77: 0x000b, 0x3a78: 0x000b, 0x3a79: 0x000b, 0x3a7a: 0x000b, 0x3a7b: 0x000b, + 0x3a7c: 0x000b, 0x3a7d: 0x000b, 0x3a7e: 0x000b, 0x3a7f: 0x000b, +} + +// bidiIndex: 24 blocks, 1536 entries, 1536 bytes +// Block 0 is the zero block. +var bidiIndex = [1536]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, + 0xca: 0x03, 0xcb: 0x04, 0xcc: 0x05, 0xcd: 0x06, 0xce: 0x07, 0xcf: 0x08, + 0xd2: 0x09, 0xd6: 0x0a, 0xd7: 0x0b, + 0xd8: 0x0c, 0xd9: 0x0d, 0xda: 0x0e, 0xdb: 0x0f, 0xdc: 0x10, 0xdd: 0x11, 0xde: 0x12, 0xdf: 0x13, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, + 0xea: 0x07, 0xef: 0x08, + 0xf0: 0x11, 0xf1: 0x12, 0xf2: 0x12, 0xf3: 0x14, 0xf4: 0x15, + // Block 0x4, offset 0x100 + 0x120: 0x14, 0x121: 0x15, 0x122: 0x16, 0x123: 0x17, 0x124: 0x18, 0x125: 0x19, 0x126: 0x1a, 0x127: 0x1b, + 0x128: 0x1c, 0x129: 0x1d, 0x12a: 0x1c, 0x12b: 0x1e, 0x12c: 0x1f, 0x12d: 0x20, 0x12e: 0x21, 0x12f: 0x22, + 0x130: 0x23, 0x131: 0x24, 0x132: 0x1a, 0x133: 0x25, 0x134: 0x26, 0x135: 0x27, 0x137: 0x28, + 0x138: 0x29, 0x139: 0x2a, 0x13a: 0x2b, 0x13b: 0x2c, 0x13c: 0x2d, 0x13d: 0x2e, 0x13e: 0x2f, 0x13f: 0x30, + // Block 0x5, offset 0x140 + 0x140: 0x31, 0x141: 0x32, 0x142: 0x33, + 0x14d: 0x34, 0x14e: 0x35, + 0x150: 0x36, + 0x15a: 0x37, 0x15c: 0x38, 0x15d: 0x39, 0x15e: 0x3a, 0x15f: 0x3b, + 0x160: 0x3c, 0x162: 0x3d, 0x164: 0x3e, 0x165: 0x3f, 0x167: 0x40, + 0x168: 0x41, 0x169: 0x42, 0x16a: 0x43, 0x16c: 0x44, 0x16d: 0x45, 0x16e: 0x46, 0x16f: 0x47, + 0x170: 0x48, 0x173: 0x49, 0x177: 0x4a, + 0x17e: 0x4b, 0x17f: 0x4c, + // Block 0x6, offset 0x180 + 0x180: 0x4d, 0x181: 0x4e, 0x182: 0x4f, 0x183: 0x50, 0x184: 0x51, 0x185: 0x52, 0x186: 0x53, 0x187: 0x54, + 0x188: 0x55, 0x189: 0x54, 0x18a: 0x54, 0x18b: 0x54, 0x18c: 0x56, 0x18d: 0x57, 0x18e: 0x58, 0x18f: 0x54, + 0x190: 0x59, 0x191: 0x5a, 0x192: 0x5b, 0x193: 0x5c, 0x194: 0x54, 0x195: 0x54, 0x196: 0x54, 0x197: 0x54, + 0x198: 0x54, 0x199: 0x54, 0x19a: 0x5d, 0x19b: 0x54, 0x19c: 0x54, 0x19d: 0x5e, 0x19e: 0x54, 0x19f: 0x5f, + 0x1a4: 0x54, 0x1a5: 0x54, 0x1a6: 0x60, 0x1a7: 0x61, + 0x1a8: 0x54, 0x1a9: 0x54, 0x1aa: 0x54, 0x1ab: 0x54, 0x1ac: 0x54, 0x1ad: 0x62, 0x1ae: 0x63, 0x1af: 0x64, + 0x1b3: 0x65, 0x1b5: 0x66, 0x1b7: 0x67, + 0x1b8: 0x68, 0x1b9: 0x69, 0x1ba: 0x6a, 0x1bb: 0x6b, 0x1bc: 0x54, 0x1bd: 0x54, 0x1be: 0x54, 0x1bf: 0x6c, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x6d, 0x1c2: 0x6e, 0x1c3: 0x6f, 0x1c7: 0x70, + 0x1c8: 0x71, 0x1c9: 0x72, 0x1ca: 0x73, 0x1cb: 0x74, 0x1cd: 0x75, 0x1cf: 0x76, + // Block 0x8, offset 0x200 + 0x237: 0x54, + // Block 0x9, offset 0x240 + 0x252: 0x77, 0x253: 0x78, + 0x258: 0x79, 0x259: 0x7a, 0x25a: 0x7b, 0x25b: 0x7c, 0x25c: 0x7d, 0x25e: 0x7e, + 0x260: 0x7f, 0x261: 0x80, 0x263: 0x81, 0x264: 0x82, 0x265: 0x83, 0x266: 0x84, 0x267: 0x85, + 0x268: 0x86, 0x269: 0x87, 0x26a: 0x88, 0x26b: 0x89, 0x26f: 0x8a, + // Block 0xa, offset 0x280 + 0x2ac: 0x8b, 0x2ad: 0x8c, 0x2ae: 0x0e, 0x2af: 0x0e, + 0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8d, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x8e, + 0x2b8: 0x8f, 0x2b9: 0x90, 0x2ba: 0x0e, 0x2bb: 0x91, 0x2bc: 0x92, 0x2bd: 0x93, 0x2bf: 0x94, + // Block 0xb, offset 0x2c0 + 0x2c4: 0x95, 0x2c5: 0x54, 0x2c6: 0x96, 0x2c7: 0x97, + 0x2cb: 0x98, 0x2cd: 0x99, + 0x2e0: 0x9a, 0x2e1: 0x9a, 0x2e2: 0x9a, 0x2e3: 0x9a, 0x2e4: 0x9b, 0x2e5: 0x9a, 0x2e6: 0x9a, 0x2e7: 0x9a, + 0x2e8: 0x9c, 0x2e9: 0x9a, 0x2ea: 0x9a, 0x2eb: 0x9d, 0x2ec: 0x9e, 0x2ed: 0x9a, 0x2ee: 0x9a, 0x2ef: 0x9a, + 0x2f0: 0x9a, 0x2f1: 0x9a, 0x2f2: 0x9a, 0x2f3: 0x9a, 0x2f4: 0x9f, 0x2f5: 0x9a, 0x2f6: 0x9a, 0x2f7: 0x9a, + 0x2f8: 0x9a, 0x2f9: 0xa0, 0x2fa: 0x9a, 0x2fb: 0x9a, 0x2fc: 0xa1, 0x2fd: 0xa2, 0x2fe: 0x9a, 0x2ff: 0x9a, + // Block 0xc, offset 0x300 + 0x300: 0xa3, 0x301: 0xa4, 0x302: 0xa5, 0x304: 0xa6, 0x305: 0xa7, 0x306: 0xa8, 0x307: 0xa9, + 0x308: 0xaa, 0x30b: 0xab, 0x30c: 0x26, 0x30d: 0xac, + 0x310: 0xad, 0x311: 0xae, 0x312: 0xaf, 0x313: 0xb0, 0x316: 0xb1, 0x317: 0xb2, + 0x318: 0xb3, 0x319: 0xb4, 0x31a: 0xb5, 0x31c: 0xb6, + 0x320: 0xb7, + 0x328: 0xb8, 0x329: 0xb9, 0x32a: 0xba, + 0x330: 0xbb, 0x332: 0xbc, 0x334: 0xbd, 0x335: 0xbe, 0x336: 0xbf, + 0x33b: 0xc0, + // Block 0xd, offset 0x340 + 0x36b: 0xc1, 0x36c: 0xc2, + 0x37e: 0xc3, + // Block 0xe, offset 0x380 + 0x3b2: 0xc4, + // Block 0xf, offset 0x3c0 + 0x3c5: 0xc5, 0x3c6: 0xc6, + 0x3c8: 0x54, 0x3c9: 0xc7, 0x3cc: 0x54, 0x3cd: 0xc8, + 0x3db: 0xc9, 0x3dc: 0xca, 0x3dd: 0xcb, 0x3de: 0xcc, 0x3df: 0xcd, + 0x3e8: 0xce, 0x3e9: 0xcf, 0x3ea: 0xd0, + // Block 0x10, offset 0x400 + 0x400: 0xd1, + 0x420: 0x9a, 0x421: 0x9a, 0x422: 0x9a, 0x423: 0xd2, 0x424: 0x9a, 0x425: 0xd3, 0x426: 0x9a, 0x427: 0x9a, + 0x428: 0x9a, 0x429: 0x9a, 0x42a: 0x9a, 0x42b: 0x9a, 0x42c: 0x9a, 0x42d: 0x9a, 0x42e: 0x9a, 0x42f: 0x9a, + 0x430: 0x9a, 0x431: 0xa1, 0x432: 0x0e, 0x433: 0x9a, 0x434: 0x9a, 0x435: 0x9a, 0x436: 0x9a, 0x437: 0x9a, + 0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xd4, 0x43c: 0x9a, 0x43d: 0x9a, 0x43e: 0x9a, 0x43f: 0x9a, + // Block 0x11, offset 0x440 + 0x440: 0xd5, 0x441: 0x54, 0x442: 0xd6, 0x443: 0xd7, 0x444: 0xd8, 0x445: 0xd9, + 0x449: 0xda, 0x44c: 0x54, 0x44d: 0x54, 0x44e: 0x54, 0x44f: 0x54, + 0x450: 0x54, 0x451: 0x54, 0x452: 0x54, 0x453: 0x54, 0x454: 0x54, 0x455: 0x54, 0x456: 0x54, 0x457: 0x54, + 0x458: 0x54, 0x459: 0x54, 0x45a: 0x54, 0x45b: 0xdb, 0x45c: 0x54, 0x45d: 0x6b, 0x45e: 0x54, 0x45f: 0xdc, + 0x460: 0xdd, 0x461: 0xde, 0x462: 0xdf, 0x464: 0xe0, 0x465: 0xe1, 0x466: 0xe2, 0x467: 0xe3, + 0x469: 0xe4, + 0x47f: 0xe5, + // Block 0x12, offset 0x480 + 0x4bf: 0xe5, + // Block 0x13, offset 0x4c0 + 0x4d0: 0x09, 0x4d1: 0x0a, 0x4d6: 0x0b, + 0x4db: 0x0c, 0x4dd: 0x0d, 0x4de: 0x0e, 0x4df: 0x0f, + 0x4ef: 0x10, + 0x4ff: 0x10, + // Block 0x14, offset 0x500 + 0x50f: 0x10, + 0x51f: 0x10, + 0x52f: 0x10, + 0x53f: 0x10, + // Block 0x15, offset 0x540 + 0x540: 0xe6, 0x541: 0xe6, 0x542: 0xe6, 0x543: 0xe6, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xe7, + 0x548: 0xe6, 0x549: 0xe6, 0x54a: 0xe6, 0x54b: 0xe6, 0x54c: 0xe6, 0x54d: 0xe6, 0x54e: 0xe6, 0x54f: 0xe6, + 0x550: 0xe6, 0x551: 0xe6, 0x552: 0xe6, 0x553: 0xe6, 0x554: 0xe6, 0x555: 0xe6, 0x556: 0xe6, 0x557: 0xe6, + 0x558: 0xe6, 0x559: 0xe6, 0x55a: 0xe6, 0x55b: 0xe6, 0x55c: 0xe6, 0x55d: 0xe6, 0x55e: 0xe6, 0x55f: 0xe6, + 0x560: 0xe6, 0x561: 0xe6, 0x562: 0xe6, 0x563: 0xe6, 0x564: 0xe6, 0x565: 0xe6, 0x566: 0xe6, 0x567: 0xe6, + 0x568: 0xe6, 0x569: 0xe6, 0x56a: 0xe6, 0x56b: 0xe6, 0x56c: 0xe6, 0x56d: 0xe6, 0x56e: 0xe6, 0x56f: 0xe6, + 0x570: 0xe6, 0x571: 0xe6, 0x572: 0xe6, 0x573: 0xe6, 0x574: 0xe6, 0x575: 0xe6, 0x576: 0xe6, 0x577: 0xe6, + 0x578: 0xe6, 0x579: 0xe6, 0x57a: 0xe6, 0x57b: 0xe6, 0x57c: 0xe6, 0x57d: 0xe6, 0x57e: 0xe6, 0x57f: 0xe6, + // Block 0x16, offset 0x580 + 0x58f: 0x10, + 0x59f: 0x10, + 0x5a0: 0x13, + 0x5af: 0x10, + 0x5bf: 0x10, + // Block 0x17, offset 0x5c0 + 0x5cf: 0x10, +} + +// Total table size 16568 bytes (16KiB); checksum: F50EF68C diff --git a/vendor/golang.org/x/text/unicode/norm/composition.go b/vendor/golang.org/x/text/unicode/norm/composition.go index bab4c5de02f5..e2087bce5277 100644 --- a/vendor/golang.org/x/text/unicode/norm/composition.go +++ b/vendor/golang.org/x/text/unicode/norm/composition.go @@ -407,7 +407,7 @@ func decomposeHangul(buf []byte, r rune) int { // decomposeHangul algorithmically decomposes a Hangul rune into // its Jamo components. -// See http://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul. +// See https://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul. func (rb *reorderBuffer) decomposeHangul(r rune) { r -= hangulBase x := r % jamoTCount @@ -420,7 +420,7 @@ func (rb *reorderBuffer) decomposeHangul(r rune) { } // combineHangul algorithmically combines Jamo character components into Hangul. -// See http://unicode.org/reports/tr15/#Hangul for details on combining Hangul. +// See https://unicode.org/reports/tr15/#Hangul for details on combining Hangul. func (rb *reorderBuffer) combineHangul(s, i, k int) { b := rb.rune[:] bn := rb.nrune @@ -461,6 +461,10 @@ func (rb *reorderBuffer) combineHangul(s, i, k int) { // It should only be used to recompose a single segment, as it will not // handle alternations between Hangul and non-Hangul characters correctly. func (rb *reorderBuffer) compose() { + // Lazily load the map used by the combine func below, but do + // it outside of the loop. + recompMapOnce.Do(buildRecompMap) + // UAX #15, section X5 , including Corrigendum #5 // "In any character sequence beginning with starter S, a character C is // blocked from S if and only if there is some character B between S diff --git a/vendor/golang.org/x/text/unicode/norm/forminfo.go b/vendor/golang.org/x/text/unicode/norm/forminfo.go index e67e7655c547..526c7033ac46 100644 --- a/vendor/golang.org/x/text/unicode/norm/forminfo.go +++ b/vendor/golang.org/x/text/unicode/norm/forminfo.go @@ -4,6 +4,8 @@ package norm +import "encoding/binary" + // This file contains Form-specific logic and wrappers for data in tables.go. // Rune info is stored in a separate trie per composing form. A composing form @@ -178,6 +180,17 @@ func (p Properties) TrailCCC() uint8 { return ccc[p.tccc] } +func buildRecompMap() { + recompMap = make(map[uint32]rune, len(recompMapPacked)/8) + var buf [8]byte + for i := 0; i < len(recompMapPacked); i += 8 { + copy(buf[:], recompMapPacked[i:i+8]) + key := binary.BigEndian.Uint32(buf[:4]) + val := binary.BigEndian.Uint32(buf[4:]) + recompMap[key] = rune(val) + } +} + // Recomposition // We use 32-bit keys instead of 64-bit for the two codepoint keys. // This clips off the bits of three entries, but we know this will not @@ -186,8 +199,14 @@ func (p Properties) TrailCCC() uint8 { // Note that the recomposition map for NFC and NFKC are identical. // combine returns the combined rune or 0 if it doesn't exist. +// +// The caller is responsible for calling +// recompMapOnce.Do(buildRecompMap) sometime before this is called. func combine(a, b rune) rune { key := uint32(uint16(a))<<16 + uint32(uint16(b)) + if recompMap == nil { + panic("caller error") // see func comment + } return recompMap[key] } diff --git a/vendor/golang.org/x/text/unicode/norm/iter.go b/vendor/golang.org/x/text/unicode/norm/iter.go index ce17f96c2e0c..417c6b26894d 100644 --- a/vendor/golang.org/x/text/unicode/norm/iter.go +++ b/vendor/golang.org/x/text/unicode/norm/iter.go @@ -128,8 +128,9 @@ func (i *Iter) Next() []byte { func nextASCIIBytes(i *Iter) []byte { p := i.p + 1 if p >= i.rb.nsrc { + p0 := i.p i.setDone() - return i.rb.src.bytes[i.p:p] + return i.rb.src.bytes[p0:p] } if i.rb.src.bytes[p] < utf8.RuneSelf { p0 := i.p diff --git a/vendor/golang.org/x/text/unicode/norm/maketables.go b/vendor/golang.org/x/text/unicode/norm/maketables.go index 338c395ee6f8..30a3aa93343d 100644 --- a/vendor/golang.org/x/text/unicode/norm/maketables.go +++ b/vendor/golang.org/x/text/unicode/norm/maketables.go @@ -12,6 +12,7 @@ package main import ( "bytes" + "encoding/binary" "flag" "fmt" "io" @@ -261,7 +262,7 @@ func compactCCC() { // CompositionExclusions.txt has form: // 0958 # ... -// See http://unicode.org/reports/tr44/ for full explanation +// See https://unicode.org/reports/tr44/ for full explanation func loadCompositionExclusions() { f := gen.OpenUCDFile("CompositionExclusions.txt") defer f.Close() @@ -735,6 +736,8 @@ func makeTables() { max = n } } + fmt.Fprintln(w, `import "sync"`) + fmt.Fprintln(w) fmt.Fprintln(w, "const (") fmt.Fprintln(w, "\t// Version is the Unicode edition from which the tables are derived.") @@ -782,16 +785,23 @@ func makeTables() { sz := nrentries * 8 size += sz fmt.Fprintf(w, "// recompMap: %d bytes (entries only)\n", sz) - fmt.Fprintln(w, "var recompMap = map[uint32]rune{") + fmt.Fprintln(w, "var recompMap map[uint32]rune") + fmt.Fprintln(w, "var recompMapOnce sync.Once\n") + fmt.Fprintln(w, `const recompMapPacked = "" +`) + var buf [8]byte for i, c := range chars { f := c.forms[FCanonical] d := f.decomp if !f.isOneWay && len(d) > 0 { key := uint32(uint16(d[0]))<<16 + uint32(uint16(d[1])) - fmt.Fprintf(w, "0x%.8X: 0x%.4X,\n", key, i) + binary.BigEndian.PutUint32(buf[:4], key) + binary.BigEndian.PutUint32(buf[4:], uint32(i)) + fmt.Fprintf(w, "\t\t%q + // 0x%.8X: 0x%.8X\n", string(buf[:]), key, uint32(i)) } } - fmt.Fprintf(w, "}\n\n") + // hack so we don't have to special case the trailing plus sign + fmt.Fprintf(w, ` ""`) + fmt.Fprintln(w) } fmt.Fprintf(w, "// Total size of tables: %dKB (%d bytes)\n", (size+512)/1024, size) @@ -857,7 +867,7 @@ func verifyComputed() { // DerivedNormalizationProps.txt has form: // 00C0..00C5 ; NFD_QC; N # ... // 0374 ; NFD_QC; N # ... -// See http://unicode.org/reports/tr44/ for full explanation +// See https://unicode.org/reports/tr44/ for full explanation func testDerived() { f := gen.OpenUCDFile("DerivedNormalizationProps.txt") defer f.Close() diff --git a/vendor/golang.org/x/text/unicode/norm/normalize.go b/vendor/golang.org/x/text/unicode/norm/normalize.go index e28ac641acaf..95efcf26e81d 100644 --- a/vendor/golang.org/x/text/unicode/norm/normalize.go +++ b/vendor/golang.org/x/text/unicode/norm/normalize.go @@ -29,8 +29,8 @@ import ( // proceed independently on both sides: // f(x) == append(f(x[0:n]), f(x[n:])...) // -// References: http://unicode.org/reports/tr15/ and -// http://unicode.org/notes/tn5/. +// References: https://unicode.org/reports/tr15/ and +// https://unicode.org/notes/tn5/. type Form int const ( diff --git a/vendor/golang.org/x/text/unicode/norm/readwriter.go b/vendor/golang.org/x/text/unicode/norm/readwriter.go index d926ee903e56..b38096f5ca92 100644 --- a/vendor/golang.org/x/text/unicode/norm/readwriter.go +++ b/vendor/golang.org/x/text/unicode/norm/readwriter.go @@ -60,8 +60,8 @@ func (w *normWriter) Close() error { } // Writer returns a new writer that implements Write(b) -// by writing f(b) to w. The returned writer may use an -// an internal buffer to maintain state across Write calls. +// by writing f(b) to w. The returned writer may use an +// internal buffer to maintain state across Write calls. // Calling its Close method writes any buffered data to w. func (f Form) Writer(w io.Writer) io.WriteCloser { wr := &normWriter{rb: reorderBuffer{}, w: w} diff --git a/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go index 44dd3978caa5..26fbd55a1243 100644 --- a/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go +++ b/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go @@ -1,9 +1,11 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. -// +build go1.10 +// +build go1.10,!go1.13 package norm +import "sync" + const ( // Version is the Unicode edition from which the tables are derived. Version = "10.0.0" @@ -6707,947 +6709,949 @@ var nfkcSparseValues = [869]valueRange{ } // recompMap: 7520 bytes (entries only) -var recompMap = map[uint32]rune{ - 0x00410300: 0x00C0, - 0x00410301: 0x00C1, - 0x00410302: 0x00C2, - 0x00410303: 0x00C3, - 0x00410308: 0x00C4, - 0x0041030A: 0x00C5, - 0x00430327: 0x00C7, - 0x00450300: 0x00C8, - 0x00450301: 0x00C9, - 0x00450302: 0x00CA, - 0x00450308: 0x00CB, - 0x00490300: 0x00CC, - 0x00490301: 0x00CD, - 0x00490302: 0x00CE, - 0x00490308: 0x00CF, - 0x004E0303: 0x00D1, - 0x004F0300: 0x00D2, - 0x004F0301: 0x00D3, - 0x004F0302: 0x00D4, - 0x004F0303: 0x00D5, - 0x004F0308: 0x00D6, - 0x00550300: 0x00D9, - 0x00550301: 0x00DA, - 0x00550302: 0x00DB, - 0x00550308: 0x00DC, - 0x00590301: 0x00DD, - 0x00610300: 0x00E0, - 0x00610301: 0x00E1, - 0x00610302: 0x00E2, - 0x00610303: 0x00E3, - 0x00610308: 0x00E4, - 0x0061030A: 0x00E5, - 0x00630327: 0x00E7, - 0x00650300: 0x00E8, - 0x00650301: 0x00E9, - 0x00650302: 0x00EA, - 0x00650308: 0x00EB, - 0x00690300: 0x00EC, - 0x00690301: 0x00ED, - 0x00690302: 0x00EE, - 0x00690308: 0x00EF, - 0x006E0303: 0x00F1, - 0x006F0300: 0x00F2, - 0x006F0301: 0x00F3, - 0x006F0302: 0x00F4, - 0x006F0303: 0x00F5, - 0x006F0308: 0x00F6, - 0x00750300: 0x00F9, - 0x00750301: 0x00FA, - 0x00750302: 0x00FB, - 0x00750308: 0x00FC, - 0x00790301: 0x00FD, - 0x00790308: 0x00FF, - 0x00410304: 0x0100, - 0x00610304: 0x0101, - 0x00410306: 0x0102, - 0x00610306: 0x0103, - 0x00410328: 0x0104, - 0x00610328: 0x0105, - 0x00430301: 0x0106, - 0x00630301: 0x0107, - 0x00430302: 0x0108, - 0x00630302: 0x0109, - 0x00430307: 0x010A, - 0x00630307: 0x010B, - 0x0043030C: 0x010C, - 0x0063030C: 0x010D, - 0x0044030C: 0x010E, - 0x0064030C: 0x010F, - 0x00450304: 0x0112, - 0x00650304: 0x0113, - 0x00450306: 0x0114, - 0x00650306: 0x0115, - 0x00450307: 0x0116, - 0x00650307: 0x0117, - 0x00450328: 0x0118, - 0x00650328: 0x0119, - 0x0045030C: 0x011A, - 0x0065030C: 0x011B, - 0x00470302: 0x011C, - 0x00670302: 0x011D, - 0x00470306: 0x011E, - 0x00670306: 0x011F, - 0x00470307: 0x0120, - 0x00670307: 0x0121, - 0x00470327: 0x0122, - 0x00670327: 0x0123, - 0x00480302: 0x0124, - 0x00680302: 0x0125, - 0x00490303: 0x0128, - 0x00690303: 0x0129, - 0x00490304: 0x012A, - 0x00690304: 0x012B, - 0x00490306: 0x012C, - 0x00690306: 0x012D, - 0x00490328: 0x012E, - 0x00690328: 0x012F, - 0x00490307: 0x0130, - 0x004A0302: 0x0134, - 0x006A0302: 0x0135, - 0x004B0327: 0x0136, - 0x006B0327: 0x0137, - 0x004C0301: 0x0139, - 0x006C0301: 0x013A, - 0x004C0327: 0x013B, - 0x006C0327: 0x013C, - 0x004C030C: 0x013D, - 0x006C030C: 0x013E, - 0x004E0301: 0x0143, - 0x006E0301: 0x0144, - 0x004E0327: 0x0145, - 0x006E0327: 0x0146, - 0x004E030C: 0x0147, - 0x006E030C: 0x0148, - 0x004F0304: 0x014C, - 0x006F0304: 0x014D, - 0x004F0306: 0x014E, - 0x006F0306: 0x014F, - 0x004F030B: 0x0150, - 0x006F030B: 0x0151, - 0x00520301: 0x0154, - 0x00720301: 0x0155, - 0x00520327: 0x0156, - 0x00720327: 0x0157, - 0x0052030C: 0x0158, - 0x0072030C: 0x0159, - 0x00530301: 0x015A, - 0x00730301: 0x015B, - 0x00530302: 0x015C, - 0x00730302: 0x015D, - 0x00530327: 0x015E, - 0x00730327: 0x015F, - 0x0053030C: 0x0160, - 0x0073030C: 0x0161, - 0x00540327: 0x0162, - 0x00740327: 0x0163, - 0x0054030C: 0x0164, - 0x0074030C: 0x0165, - 0x00550303: 0x0168, - 0x00750303: 0x0169, - 0x00550304: 0x016A, - 0x00750304: 0x016B, - 0x00550306: 0x016C, - 0x00750306: 0x016D, - 0x0055030A: 0x016E, - 0x0075030A: 0x016F, - 0x0055030B: 0x0170, - 0x0075030B: 0x0171, - 0x00550328: 0x0172, - 0x00750328: 0x0173, - 0x00570302: 0x0174, - 0x00770302: 0x0175, - 0x00590302: 0x0176, - 0x00790302: 0x0177, - 0x00590308: 0x0178, - 0x005A0301: 0x0179, - 0x007A0301: 0x017A, - 0x005A0307: 0x017B, - 0x007A0307: 0x017C, - 0x005A030C: 0x017D, - 0x007A030C: 0x017E, - 0x004F031B: 0x01A0, - 0x006F031B: 0x01A1, - 0x0055031B: 0x01AF, - 0x0075031B: 0x01B0, - 0x0041030C: 0x01CD, - 0x0061030C: 0x01CE, - 0x0049030C: 0x01CF, - 0x0069030C: 0x01D0, - 0x004F030C: 0x01D1, - 0x006F030C: 0x01D2, - 0x0055030C: 0x01D3, - 0x0075030C: 0x01D4, - 0x00DC0304: 0x01D5, - 0x00FC0304: 0x01D6, - 0x00DC0301: 0x01D7, - 0x00FC0301: 0x01D8, - 0x00DC030C: 0x01D9, - 0x00FC030C: 0x01DA, - 0x00DC0300: 0x01DB, - 0x00FC0300: 0x01DC, - 0x00C40304: 0x01DE, - 0x00E40304: 0x01DF, - 0x02260304: 0x01E0, - 0x02270304: 0x01E1, - 0x00C60304: 0x01E2, - 0x00E60304: 0x01E3, - 0x0047030C: 0x01E6, - 0x0067030C: 0x01E7, - 0x004B030C: 0x01E8, - 0x006B030C: 0x01E9, - 0x004F0328: 0x01EA, - 0x006F0328: 0x01EB, - 0x01EA0304: 0x01EC, - 0x01EB0304: 0x01ED, - 0x01B7030C: 0x01EE, - 0x0292030C: 0x01EF, - 0x006A030C: 0x01F0, - 0x00470301: 0x01F4, - 0x00670301: 0x01F5, - 0x004E0300: 0x01F8, - 0x006E0300: 0x01F9, - 0x00C50301: 0x01FA, - 0x00E50301: 0x01FB, - 0x00C60301: 0x01FC, - 0x00E60301: 0x01FD, - 0x00D80301: 0x01FE, - 0x00F80301: 0x01FF, - 0x0041030F: 0x0200, - 0x0061030F: 0x0201, - 0x00410311: 0x0202, - 0x00610311: 0x0203, - 0x0045030F: 0x0204, - 0x0065030F: 0x0205, - 0x00450311: 0x0206, - 0x00650311: 0x0207, - 0x0049030F: 0x0208, - 0x0069030F: 0x0209, - 0x00490311: 0x020A, - 0x00690311: 0x020B, - 0x004F030F: 0x020C, - 0x006F030F: 0x020D, - 0x004F0311: 0x020E, - 0x006F0311: 0x020F, - 0x0052030F: 0x0210, - 0x0072030F: 0x0211, - 0x00520311: 0x0212, - 0x00720311: 0x0213, - 0x0055030F: 0x0214, - 0x0075030F: 0x0215, - 0x00550311: 0x0216, - 0x00750311: 0x0217, - 0x00530326: 0x0218, - 0x00730326: 0x0219, - 0x00540326: 0x021A, - 0x00740326: 0x021B, - 0x0048030C: 0x021E, - 0x0068030C: 0x021F, - 0x00410307: 0x0226, - 0x00610307: 0x0227, - 0x00450327: 0x0228, - 0x00650327: 0x0229, - 0x00D60304: 0x022A, - 0x00F60304: 0x022B, - 0x00D50304: 0x022C, - 0x00F50304: 0x022D, - 0x004F0307: 0x022E, - 0x006F0307: 0x022F, - 0x022E0304: 0x0230, - 0x022F0304: 0x0231, - 0x00590304: 0x0232, - 0x00790304: 0x0233, - 0x00A80301: 0x0385, - 0x03910301: 0x0386, - 0x03950301: 0x0388, - 0x03970301: 0x0389, - 0x03990301: 0x038A, - 0x039F0301: 0x038C, - 0x03A50301: 0x038E, - 0x03A90301: 0x038F, - 0x03CA0301: 0x0390, - 0x03990308: 0x03AA, - 0x03A50308: 0x03AB, - 0x03B10301: 0x03AC, - 0x03B50301: 0x03AD, - 0x03B70301: 0x03AE, - 0x03B90301: 0x03AF, - 0x03CB0301: 0x03B0, - 0x03B90308: 0x03CA, - 0x03C50308: 0x03CB, - 0x03BF0301: 0x03CC, - 0x03C50301: 0x03CD, - 0x03C90301: 0x03CE, - 0x03D20301: 0x03D3, - 0x03D20308: 0x03D4, - 0x04150300: 0x0400, - 0x04150308: 0x0401, - 0x04130301: 0x0403, - 0x04060308: 0x0407, - 0x041A0301: 0x040C, - 0x04180300: 0x040D, - 0x04230306: 0x040E, - 0x04180306: 0x0419, - 0x04380306: 0x0439, - 0x04350300: 0x0450, - 0x04350308: 0x0451, - 0x04330301: 0x0453, - 0x04560308: 0x0457, - 0x043A0301: 0x045C, - 0x04380300: 0x045D, - 0x04430306: 0x045E, - 0x0474030F: 0x0476, - 0x0475030F: 0x0477, - 0x04160306: 0x04C1, - 0x04360306: 0x04C2, - 0x04100306: 0x04D0, - 0x04300306: 0x04D1, - 0x04100308: 0x04D2, - 0x04300308: 0x04D3, - 0x04150306: 0x04D6, - 0x04350306: 0x04D7, - 0x04D80308: 0x04DA, - 0x04D90308: 0x04DB, - 0x04160308: 0x04DC, - 0x04360308: 0x04DD, - 0x04170308: 0x04DE, - 0x04370308: 0x04DF, - 0x04180304: 0x04E2, - 0x04380304: 0x04E3, - 0x04180308: 0x04E4, - 0x04380308: 0x04E5, - 0x041E0308: 0x04E6, - 0x043E0308: 0x04E7, - 0x04E80308: 0x04EA, - 0x04E90308: 0x04EB, - 0x042D0308: 0x04EC, - 0x044D0308: 0x04ED, - 0x04230304: 0x04EE, - 0x04430304: 0x04EF, - 0x04230308: 0x04F0, - 0x04430308: 0x04F1, - 0x0423030B: 0x04F2, - 0x0443030B: 0x04F3, - 0x04270308: 0x04F4, - 0x04470308: 0x04F5, - 0x042B0308: 0x04F8, - 0x044B0308: 0x04F9, - 0x06270653: 0x0622, - 0x06270654: 0x0623, - 0x06480654: 0x0624, - 0x06270655: 0x0625, - 0x064A0654: 0x0626, - 0x06D50654: 0x06C0, - 0x06C10654: 0x06C2, - 0x06D20654: 0x06D3, - 0x0928093C: 0x0929, - 0x0930093C: 0x0931, - 0x0933093C: 0x0934, - 0x09C709BE: 0x09CB, - 0x09C709D7: 0x09CC, - 0x0B470B56: 0x0B48, - 0x0B470B3E: 0x0B4B, - 0x0B470B57: 0x0B4C, - 0x0B920BD7: 0x0B94, - 0x0BC60BBE: 0x0BCA, - 0x0BC70BBE: 0x0BCB, - 0x0BC60BD7: 0x0BCC, - 0x0C460C56: 0x0C48, - 0x0CBF0CD5: 0x0CC0, - 0x0CC60CD5: 0x0CC7, - 0x0CC60CD6: 0x0CC8, - 0x0CC60CC2: 0x0CCA, - 0x0CCA0CD5: 0x0CCB, - 0x0D460D3E: 0x0D4A, - 0x0D470D3E: 0x0D4B, - 0x0D460D57: 0x0D4C, - 0x0DD90DCA: 0x0DDA, - 0x0DD90DCF: 0x0DDC, - 0x0DDC0DCA: 0x0DDD, - 0x0DD90DDF: 0x0DDE, - 0x1025102E: 0x1026, - 0x1B051B35: 0x1B06, - 0x1B071B35: 0x1B08, - 0x1B091B35: 0x1B0A, - 0x1B0B1B35: 0x1B0C, - 0x1B0D1B35: 0x1B0E, - 0x1B111B35: 0x1B12, - 0x1B3A1B35: 0x1B3B, - 0x1B3C1B35: 0x1B3D, - 0x1B3E1B35: 0x1B40, - 0x1B3F1B35: 0x1B41, - 0x1B421B35: 0x1B43, - 0x00410325: 0x1E00, - 0x00610325: 0x1E01, - 0x00420307: 0x1E02, - 0x00620307: 0x1E03, - 0x00420323: 0x1E04, - 0x00620323: 0x1E05, - 0x00420331: 0x1E06, - 0x00620331: 0x1E07, - 0x00C70301: 0x1E08, - 0x00E70301: 0x1E09, - 0x00440307: 0x1E0A, - 0x00640307: 0x1E0B, - 0x00440323: 0x1E0C, - 0x00640323: 0x1E0D, - 0x00440331: 0x1E0E, - 0x00640331: 0x1E0F, - 0x00440327: 0x1E10, - 0x00640327: 0x1E11, - 0x0044032D: 0x1E12, - 0x0064032D: 0x1E13, - 0x01120300: 0x1E14, - 0x01130300: 0x1E15, - 0x01120301: 0x1E16, - 0x01130301: 0x1E17, - 0x0045032D: 0x1E18, - 0x0065032D: 0x1E19, - 0x00450330: 0x1E1A, - 0x00650330: 0x1E1B, - 0x02280306: 0x1E1C, - 0x02290306: 0x1E1D, - 0x00460307: 0x1E1E, - 0x00660307: 0x1E1F, - 0x00470304: 0x1E20, - 0x00670304: 0x1E21, - 0x00480307: 0x1E22, - 0x00680307: 0x1E23, - 0x00480323: 0x1E24, - 0x00680323: 0x1E25, - 0x00480308: 0x1E26, - 0x00680308: 0x1E27, - 0x00480327: 0x1E28, - 0x00680327: 0x1E29, - 0x0048032E: 0x1E2A, - 0x0068032E: 0x1E2B, - 0x00490330: 0x1E2C, - 0x00690330: 0x1E2D, - 0x00CF0301: 0x1E2E, - 0x00EF0301: 0x1E2F, - 0x004B0301: 0x1E30, - 0x006B0301: 0x1E31, - 0x004B0323: 0x1E32, - 0x006B0323: 0x1E33, - 0x004B0331: 0x1E34, - 0x006B0331: 0x1E35, - 0x004C0323: 0x1E36, - 0x006C0323: 0x1E37, - 0x1E360304: 0x1E38, - 0x1E370304: 0x1E39, - 0x004C0331: 0x1E3A, - 0x006C0331: 0x1E3B, - 0x004C032D: 0x1E3C, - 0x006C032D: 0x1E3D, - 0x004D0301: 0x1E3E, - 0x006D0301: 0x1E3F, - 0x004D0307: 0x1E40, - 0x006D0307: 0x1E41, - 0x004D0323: 0x1E42, - 0x006D0323: 0x1E43, - 0x004E0307: 0x1E44, - 0x006E0307: 0x1E45, - 0x004E0323: 0x1E46, - 0x006E0323: 0x1E47, - 0x004E0331: 0x1E48, - 0x006E0331: 0x1E49, - 0x004E032D: 0x1E4A, - 0x006E032D: 0x1E4B, - 0x00D50301: 0x1E4C, - 0x00F50301: 0x1E4D, - 0x00D50308: 0x1E4E, - 0x00F50308: 0x1E4F, - 0x014C0300: 0x1E50, - 0x014D0300: 0x1E51, - 0x014C0301: 0x1E52, - 0x014D0301: 0x1E53, - 0x00500301: 0x1E54, - 0x00700301: 0x1E55, - 0x00500307: 0x1E56, - 0x00700307: 0x1E57, - 0x00520307: 0x1E58, - 0x00720307: 0x1E59, - 0x00520323: 0x1E5A, - 0x00720323: 0x1E5B, - 0x1E5A0304: 0x1E5C, - 0x1E5B0304: 0x1E5D, - 0x00520331: 0x1E5E, - 0x00720331: 0x1E5F, - 0x00530307: 0x1E60, - 0x00730307: 0x1E61, - 0x00530323: 0x1E62, - 0x00730323: 0x1E63, - 0x015A0307: 0x1E64, - 0x015B0307: 0x1E65, - 0x01600307: 0x1E66, - 0x01610307: 0x1E67, - 0x1E620307: 0x1E68, - 0x1E630307: 0x1E69, - 0x00540307: 0x1E6A, - 0x00740307: 0x1E6B, - 0x00540323: 0x1E6C, - 0x00740323: 0x1E6D, - 0x00540331: 0x1E6E, - 0x00740331: 0x1E6F, - 0x0054032D: 0x1E70, - 0x0074032D: 0x1E71, - 0x00550324: 0x1E72, - 0x00750324: 0x1E73, - 0x00550330: 0x1E74, - 0x00750330: 0x1E75, - 0x0055032D: 0x1E76, - 0x0075032D: 0x1E77, - 0x01680301: 0x1E78, - 0x01690301: 0x1E79, - 0x016A0308: 0x1E7A, - 0x016B0308: 0x1E7B, - 0x00560303: 0x1E7C, - 0x00760303: 0x1E7D, - 0x00560323: 0x1E7E, - 0x00760323: 0x1E7F, - 0x00570300: 0x1E80, - 0x00770300: 0x1E81, - 0x00570301: 0x1E82, - 0x00770301: 0x1E83, - 0x00570308: 0x1E84, - 0x00770308: 0x1E85, - 0x00570307: 0x1E86, - 0x00770307: 0x1E87, - 0x00570323: 0x1E88, - 0x00770323: 0x1E89, - 0x00580307: 0x1E8A, - 0x00780307: 0x1E8B, - 0x00580308: 0x1E8C, - 0x00780308: 0x1E8D, - 0x00590307: 0x1E8E, - 0x00790307: 0x1E8F, - 0x005A0302: 0x1E90, - 0x007A0302: 0x1E91, - 0x005A0323: 0x1E92, - 0x007A0323: 0x1E93, - 0x005A0331: 0x1E94, - 0x007A0331: 0x1E95, - 0x00680331: 0x1E96, - 0x00740308: 0x1E97, - 0x0077030A: 0x1E98, - 0x0079030A: 0x1E99, - 0x017F0307: 0x1E9B, - 0x00410323: 0x1EA0, - 0x00610323: 0x1EA1, - 0x00410309: 0x1EA2, - 0x00610309: 0x1EA3, - 0x00C20301: 0x1EA4, - 0x00E20301: 0x1EA5, - 0x00C20300: 0x1EA6, - 0x00E20300: 0x1EA7, - 0x00C20309: 0x1EA8, - 0x00E20309: 0x1EA9, - 0x00C20303: 0x1EAA, - 0x00E20303: 0x1EAB, - 0x1EA00302: 0x1EAC, - 0x1EA10302: 0x1EAD, - 0x01020301: 0x1EAE, - 0x01030301: 0x1EAF, - 0x01020300: 0x1EB0, - 0x01030300: 0x1EB1, - 0x01020309: 0x1EB2, - 0x01030309: 0x1EB3, - 0x01020303: 0x1EB4, - 0x01030303: 0x1EB5, - 0x1EA00306: 0x1EB6, - 0x1EA10306: 0x1EB7, - 0x00450323: 0x1EB8, - 0x00650323: 0x1EB9, - 0x00450309: 0x1EBA, - 0x00650309: 0x1EBB, - 0x00450303: 0x1EBC, - 0x00650303: 0x1EBD, - 0x00CA0301: 0x1EBE, - 0x00EA0301: 0x1EBF, - 0x00CA0300: 0x1EC0, - 0x00EA0300: 0x1EC1, - 0x00CA0309: 0x1EC2, - 0x00EA0309: 0x1EC3, - 0x00CA0303: 0x1EC4, - 0x00EA0303: 0x1EC5, - 0x1EB80302: 0x1EC6, - 0x1EB90302: 0x1EC7, - 0x00490309: 0x1EC8, - 0x00690309: 0x1EC9, - 0x00490323: 0x1ECA, - 0x00690323: 0x1ECB, - 0x004F0323: 0x1ECC, - 0x006F0323: 0x1ECD, - 0x004F0309: 0x1ECE, - 0x006F0309: 0x1ECF, - 0x00D40301: 0x1ED0, - 0x00F40301: 0x1ED1, - 0x00D40300: 0x1ED2, - 0x00F40300: 0x1ED3, - 0x00D40309: 0x1ED4, - 0x00F40309: 0x1ED5, - 0x00D40303: 0x1ED6, - 0x00F40303: 0x1ED7, - 0x1ECC0302: 0x1ED8, - 0x1ECD0302: 0x1ED9, - 0x01A00301: 0x1EDA, - 0x01A10301: 0x1EDB, - 0x01A00300: 0x1EDC, - 0x01A10300: 0x1EDD, - 0x01A00309: 0x1EDE, - 0x01A10309: 0x1EDF, - 0x01A00303: 0x1EE0, - 0x01A10303: 0x1EE1, - 0x01A00323: 0x1EE2, - 0x01A10323: 0x1EE3, - 0x00550323: 0x1EE4, - 0x00750323: 0x1EE5, - 0x00550309: 0x1EE6, - 0x00750309: 0x1EE7, - 0x01AF0301: 0x1EE8, - 0x01B00301: 0x1EE9, - 0x01AF0300: 0x1EEA, - 0x01B00300: 0x1EEB, - 0x01AF0309: 0x1EEC, - 0x01B00309: 0x1EED, - 0x01AF0303: 0x1EEE, - 0x01B00303: 0x1EEF, - 0x01AF0323: 0x1EF0, - 0x01B00323: 0x1EF1, - 0x00590300: 0x1EF2, - 0x00790300: 0x1EF3, - 0x00590323: 0x1EF4, - 0x00790323: 0x1EF5, - 0x00590309: 0x1EF6, - 0x00790309: 0x1EF7, - 0x00590303: 0x1EF8, - 0x00790303: 0x1EF9, - 0x03B10313: 0x1F00, - 0x03B10314: 0x1F01, - 0x1F000300: 0x1F02, - 0x1F010300: 0x1F03, - 0x1F000301: 0x1F04, - 0x1F010301: 0x1F05, - 0x1F000342: 0x1F06, - 0x1F010342: 0x1F07, - 0x03910313: 0x1F08, - 0x03910314: 0x1F09, - 0x1F080300: 0x1F0A, - 0x1F090300: 0x1F0B, - 0x1F080301: 0x1F0C, - 0x1F090301: 0x1F0D, - 0x1F080342: 0x1F0E, - 0x1F090342: 0x1F0F, - 0x03B50313: 0x1F10, - 0x03B50314: 0x1F11, - 0x1F100300: 0x1F12, - 0x1F110300: 0x1F13, - 0x1F100301: 0x1F14, - 0x1F110301: 0x1F15, - 0x03950313: 0x1F18, - 0x03950314: 0x1F19, - 0x1F180300: 0x1F1A, - 0x1F190300: 0x1F1B, - 0x1F180301: 0x1F1C, - 0x1F190301: 0x1F1D, - 0x03B70313: 0x1F20, - 0x03B70314: 0x1F21, - 0x1F200300: 0x1F22, - 0x1F210300: 0x1F23, - 0x1F200301: 0x1F24, - 0x1F210301: 0x1F25, - 0x1F200342: 0x1F26, - 0x1F210342: 0x1F27, - 0x03970313: 0x1F28, - 0x03970314: 0x1F29, - 0x1F280300: 0x1F2A, - 0x1F290300: 0x1F2B, - 0x1F280301: 0x1F2C, - 0x1F290301: 0x1F2D, - 0x1F280342: 0x1F2E, - 0x1F290342: 0x1F2F, - 0x03B90313: 0x1F30, - 0x03B90314: 0x1F31, - 0x1F300300: 0x1F32, - 0x1F310300: 0x1F33, - 0x1F300301: 0x1F34, - 0x1F310301: 0x1F35, - 0x1F300342: 0x1F36, - 0x1F310342: 0x1F37, - 0x03990313: 0x1F38, - 0x03990314: 0x1F39, - 0x1F380300: 0x1F3A, - 0x1F390300: 0x1F3B, - 0x1F380301: 0x1F3C, - 0x1F390301: 0x1F3D, - 0x1F380342: 0x1F3E, - 0x1F390342: 0x1F3F, - 0x03BF0313: 0x1F40, - 0x03BF0314: 0x1F41, - 0x1F400300: 0x1F42, - 0x1F410300: 0x1F43, - 0x1F400301: 0x1F44, - 0x1F410301: 0x1F45, - 0x039F0313: 0x1F48, - 0x039F0314: 0x1F49, - 0x1F480300: 0x1F4A, - 0x1F490300: 0x1F4B, - 0x1F480301: 0x1F4C, - 0x1F490301: 0x1F4D, - 0x03C50313: 0x1F50, - 0x03C50314: 0x1F51, - 0x1F500300: 0x1F52, - 0x1F510300: 0x1F53, - 0x1F500301: 0x1F54, - 0x1F510301: 0x1F55, - 0x1F500342: 0x1F56, - 0x1F510342: 0x1F57, - 0x03A50314: 0x1F59, - 0x1F590300: 0x1F5B, - 0x1F590301: 0x1F5D, - 0x1F590342: 0x1F5F, - 0x03C90313: 0x1F60, - 0x03C90314: 0x1F61, - 0x1F600300: 0x1F62, - 0x1F610300: 0x1F63, - 0x1F600301: 0x1F64, - 0x1F610301: 0x1F65, - 0x1F600342: 0x1F66, - 0x1F610342: 0x1F67, - 0x03A90313: 0x1F68, - 0x03A90314: 0x1F69, - 0x1F680300: 0x1F6A, - 0x1F690300: 0x1F6B, - 0x1F680301: 0x1F6C, - 0x1F690301: 0x1F6D, - 0x1F680342: 0x1F6E, - 0x1F690342: 0x1F6F, - 0x03B10300: 0x1F70, - 0x03B50300: 0x1F72, - 0x03B70300: 0x1F74, - 0x03B90300: 0x1F76, - 0x03BF0300: 0x1F78, - 0x03C50300: 0x1F7A, - 0x03C90300: 0x1F7C, - 0x1F000345: 0x1F80, - 0x1F010345: 0x1F81, - 0x1F020345: 0x1F82, - 0x1F030345: 0x1F83, - 0x1F040345: 0x1F84, - 0x1F050345: 0x1F85, - 0x1F060345: 0x1F86, - 0x1F070345: 0x1F87, - 0x1F080345: 0x1F88, - 0x1F090345: 0x1F89, - 0x1F0A0345: 0x1F8A, - 0x1F0B0345: 0x1F8B, - 0x1F0C0345: 0x1F8C, - 0x1F0D0345: 0x1F8D, - 0x1F0E0345: 0x1F8E, - 0x1F0F0345: 0x1F8F, - 0x1F200345: 0x1F90, - 0x1F210345: 0x1F91, - 0x1F220345: 0x1F92, - 0x1F230345: 0x1F93, - 0x1F240345: 0x1F94, - 0x1F250345: 0x1F95, - 0x1F260345: 0x1F96, - 0x1F270345: 0x1F97, - 0x1F280345: 0x1F98, - 0x1F290345: 0x1F99, - 0x1F2A0345: 0x1F9A, - 0x1F2B0345: 0x1F9B, - 0x1F2C0345: 0x1F9C, - 0x1F2D0345: 0x1F9D, - 0x1F2E0345: 0x1F9E, - 0x1F2F0345: 0x1F9F, - 0x1F600345: 0x1FA0, - 0x1F610345: 0x1FA1, - 0x1F620345: 0x1FA2, - 0x1F630345: 0x1FA3, - 0x1F640345: 0x1FA4, - 0x1F650345: 0x1FA5, - 0x1F660345: 0x1FA6, - 0x1F670345: 0x1FA7, - 0x1F680345: 0x1FA8, - 0x1F690345: 0x1FA9, - 0x1F6A0345: 0x1FAA, - 0x1F6B0345: 0x1FAB, - 0x1F6C0345: 0x1FAC, - 0x1F6D0345: 0x1FAD, - 0x1F6E0345: 0x1FAE, - 0x1F6F0345: 0x1FAF, - 0x03B10306: 0x1FB0, - 0x03B10304: 0x1FB1, - 0x1F700345: 0x1FB2, - 0x03B10345: 0x1FB3, - 0x03AC0345: 0x1FB4, - 0x03B10342: 0x1FB6, - 0x1FB60345: 0x1FB7, - 0x03910306: 0x1FB8, - 0x03910304: 0x1FB9, - 0x03910300: 0x1FBA, - 0x03910345: 0x1FBC, - 0x00A80342: 0x1FC1, - 0x1F740345: 0x1FC2, - 0x03B70345: 0x1FC3, - 0x03AE0345: 0x1FC4, - 0x03B70342: 0x1FC6, - 0x1FC60345: 0x1FC7, - 0x03950300: 0x1FC8, - 0x03970300: 0x1FCA, - 0x03970345: 0x1FCC, - 0x1FBF0300: 0x1FCD, - 0x1FBF0301: 0x1FCE, - 0x1FBF0342: 0x1FCF, - 0x03B90306: 0x1FD0, - 0x03B90304: 0x1FD1, - 0x03CA0300: 0x1FD2, - 0x03B90342: 0x1FD6, - 0x03CA0342: 0x1FD7, - 0x03990306: 0x1FD8, - 0x03990304: 0x1FD9, - 0x03990300: 0x1FDA, - 0x1FFE0300: 0x1FDD, - 0x1FFE0301: 0x1FDE, - 0x1FFE0342: 0x1FDF, - 0x03C50306: 0x1FE0, - 0x03C50304: 0x1FE1, - 0x03CB0300: 0x1FE2, - 0x03C10313: 0x1FE4, - 0x03C10314: 0x1FE5, - 0x03C50342: 0x1FE6, - 0x03CB0342: 0x1FE7, - 0x03A50306: 0x1FE8, - 0x03A50304: 0x1FE9, - 0x03A50300: 0x1FEA, - 0x03A10314: 0x1FEC, - 0x00A80300: 0x1FED, - 0x1F7C0345: 0x1FF2, - 0x03C90345: 0x1FF3, - 0x03CE0345: 0x1FF4, - 0x03C90342: 0x1FF6, - 0x1FF60345: 0x1FF7, - 0x039F0300: 0x1FF8, - 0x03A90300: 0x1FFA, - 0x03A90345: 0x1FFC, - 0x21900338: 0x219A, - 0x21920338: 0x219B, - 0x21940338: 0x21AE, - 0x21D00338: 0x21CD, - 0x21D40338: 0x21CE, - 0x21D20338: 0x21CF, - 0x22030338: 0x2204, - 0x22080338: 0x2209, - 0x220B0338: 0x220C, - 0x22230338: 0x2224, - 0x22250338: 0x2226, - 0x223C0338: 0x2241, - 0x22430338: 0x2244, - 0x22450338: 0x2247, - 0x22480338: 0x2249, - 0x003D0338: 0x2260, - 0x22610338: 0x2262, - 0x224D0338: 0x226D, - 0x003C0338: 0x226E, - 0x003E0338: 0x226F, - 0x22640338: 0x2270, - 0x22650338: 0x2271, - 0x22720338: 0x2274, - 0x22730338: 0x2275, - 0x22760338: 0x2278, - 0x22770338: 0x2279, - 0x227A0338: 0x2280, - 0x227B0338: 0x2281, - 0x22820338: 0x2284, - 0x22830338: 0x2285, - 0x22860338: 0x2288, - 0x22870338: 0x2289, - 0x22A20338: 0x22AC, - 0x22A80338: 0x22AD, - 0x22A90338: 0x22AE, - 0x22AB0338: 0x22AF, - 0x227C0338: 0x22E0, - 0x227D0338: 0x22E1, - 0x22910338: 0x22E2, - 0x22920338: 0x22E3, - 0x22B20338: 0x22EA, - 0x22B30338: 0x22EB, - 0x22B40338: 0x22EC, - 0x22B50338: 0x22ED, - 0x304B3099: 0x304C, - 0x304D3099: 0x304E, - 0x304F3099: 0x3050, - 0x30513099: 0x3052, - 0x30533099: 0x3054, - 0x30553099: 0x3056, - 0x30573099: 0x3058, - 0x30593099: 0x305A, - 0x305B3099: 0x305C, - 0x305D3099: 0x305E, - 0x305F3099: 0x3060, - 0x30613099: 0x3062, - 0x30643099: 0x3065, - 0x30663099: 0x3067, - 0x30683099: 0x3069, - 0x306F3099: 0x3070, - 0x306F309A: 0x3071, - 0x30723099: 0x3073, - 0x3072309A: 0x3074, - 0x30753099: 0x3076, - 0x3075309A: 0x3077, - 0x30783099: 0x3079, - 0x3078309A: 0x307A, - 0x307B3099: 0x307C, - 0x307B309A: 0x307D, - 0x30463099: 0x3094, - 0x309D3099: 0x309E, - 0x30AB3099: 0x30AC, - 0x30AD3099: 0x30AE, - 0x30AF3099: 0x30B0, - 0x30B13099: 0x30B2, - 0x30B33099: 0x30B4, - 0x30B53099: 0x30B6, - 0x30B73099: 0x30B8, - 0x30B93099: 0x30BA, - 0x30BB3099: 0x30BC, - 0x30BD3099: 0x30BE, - 0x30BF3099: 0x30C0, - 0x30C13099: 0x30C2, - 0x30C43099: 0x30C5, - 0x30C63099: 0x30C7, - 0x30C83099: 0x30C9, - 0x30CF3099: 0x30D0, - 0x30CF309A: 0x30D1, - 0x30D23099: 0x30D3, - 0x30D2309A: 0x30D4, - 0x30D53099: 0x30D6, - 0x30D5309A: 0x30D7, - 0x30D83099: 0x30D9, - 0x30D8309A: 0x30DA, - 0x30DB3099: 0x30DC, - 0x30DB309A: 0x30DD, - 0x30A63099: 0x30F4, - 0x30EF3099: 0x30F7, - 0x30F03099: 0x30F8, - 0x30F13099: 0x30F9, - 0x30F23099: 0x30FA, - 0x30FD3099: 0x30FE, - 0x109910BA: 0x1109A, - 0x109B10BA: 0x1109C, - 0x10A510BA: 0x110AB, - 0x11311127: 0x1112E, - 0x11321127: 0x1112F, - 0x1347133E: 0x1134B, - 0x13471357: 0x1134C, - 0x14B914BA: 0x114BB, - 0x14B914B0: 0x114BC, - 0x14B914BD: 0x114BE, - 0x15B815AF: 0x115BA, - 0x15B915AF: 0x115BB, -} +var recompMap map[uint32]rune +var recompMapOnce sync.Once -// Total size of tables: 53KB (54226 bytes) +const recompMapPacked = "" + + "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0 + "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1 + "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2 + "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3 + "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4 + "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5 + "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7 + "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8 + "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9 + "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA + "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB + "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC + "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD + "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE + "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF + "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1 + "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2 + "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3 + "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4 + "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5 + "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6 + "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9 + "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA + "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB + "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC + "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD + "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0 + "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1 + "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2 + "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3 + "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4 + "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5 + "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7 + "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8 + "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9 + "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA + "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB + "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC + "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED + "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE + "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF + "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1 + "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2 + "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3 + "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4 + "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5 + "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6 + "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9 + "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA + "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB + "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC + "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD + "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF + "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100 + "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101 + "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102 + "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103 + "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104 + "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105 + "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106 + "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107 + "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108 + "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109 + "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A + "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B + "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C + "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D + "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E + "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F + "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112 + "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113 + "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114 + "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115 + "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116 + "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117 + "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118 + "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119 + "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A + "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B + "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C + "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D + "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E + "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F + "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120 + "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121 + "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122 + "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123 + "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124 + "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125 + "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128 + "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129 + "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A + "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B + "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C + "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D + "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E + "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F + "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130 + "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134 + "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135 + "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136 + "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137 + "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139 + "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A + "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B + "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C + "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D + "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E + "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143 + "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144 + "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145 + "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146 + "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147 + "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148 + "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C + "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D + "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E + "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F + "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150 + "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151 + "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154 + "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155 + "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156 + "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157 + "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158 + "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159 + "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A + "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B + "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C + "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D + "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E + "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F + "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160 + "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161 + "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162 + "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163 + "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164 + "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165 + "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168 + "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169 + "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A + "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B + "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C + "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D + "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E + "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F + "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170 + "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171 + "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172 + "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173 + "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174 + "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175 + "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176 + "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177 + "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178 + "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179 + "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A + "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B + "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C + "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D + "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E + "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0 + "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1 + "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF + "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0 + "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD + "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE + "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF + "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0 + "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1 + "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2 + "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3 + "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4 + "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5 + "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6 + "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7 + "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8 + "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9 + "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA + "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB + "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC + "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE + "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF + "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0 + "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1 + "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2 + "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3 + "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6 + "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7 + "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8 + "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9 + "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA + "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB + "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC + "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED + "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE + "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF + "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0 + "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4 + "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5 + "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8 + "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9 + "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA + "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB + "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC + "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD + "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE + "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF + "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200 + "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201 + "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202 + "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203 + "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204 + "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205 + "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206 + "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207 + "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208 + "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209 + "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A + "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B + "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C + "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D + "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E + "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F + "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210 + "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211 + "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212 + "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213 + "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214 + "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215 + "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216 + "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217 + "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218 + "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219 + "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A + "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B + "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E + "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F + "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226 + "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227 + "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228 + "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229 + "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A + "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B + "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C + "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D + "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E + "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F + "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230 + "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231 + "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232 + "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233 + "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385 + "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386 + "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388 + "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389 + "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A + "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C + "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E + "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F + "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390 + "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA + "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB + "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC + "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD + "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE + "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF + "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0 + "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA + "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB + "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC + "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD + "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE + "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3 + "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4 + "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400 + "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401 + "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403 + "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407 + "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C + "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D + "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E + "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419 + "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439 + "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450 + "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451 + "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453 + "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457 + "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C + "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D + "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E + "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476 + "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477 + "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1 + "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2 + "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0 + "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1 + "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2 + "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3 + "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6 + "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7 + "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA + "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB + "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC + "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD + "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE + "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF + "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2 + "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3 + "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4 + "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5 + "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6 + "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7 + "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA + "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB + "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC + "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED + "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE + "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF + "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0 + "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1 + "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2 + "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3 + "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4 + "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5 + "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8 + "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9 + "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622 + "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623 + "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624 + "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625 + "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626 + "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0 + "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2 + "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3 + "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929 + "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931 + "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934 + "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB + "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC + "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48 + "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B + "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C + "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94 + "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA + "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB + "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC + "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48 + "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0 + "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7 + "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8 + "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA + "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB + "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A + "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B + "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C + "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA + "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC + "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD + "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE + "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026 + "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06 + "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08 + "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A + "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C + "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E + "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12 + "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B + "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D + "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40 + "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41 + "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43 + "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00 + "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01 + "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02 + "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03 + "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04 + "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05 + "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06 + "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07 + "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08 + "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09 + "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A + "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B + "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C + "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D + "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E + "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F + "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10 + "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11 + "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12 + "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13 + "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14 + "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15 + "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16 + "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17 + "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18 + "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19 + "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A + "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B + "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C + "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D + "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E + "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F + "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20 + "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21 + "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22 + "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23 + "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24 + "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25 + "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26 + "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27 + "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28 + "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29 + "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A + "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B + "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C + "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D + "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E + "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F + "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30 + "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31 + "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32 + "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33 + "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34 + "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35 + "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36 + "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37 + "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38 + "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39 + "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A + "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B + "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C + "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D + "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E + "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F + "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40 + "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41 + "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42 + "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43 + "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44 + "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45 + "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46 + "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47 + "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48 + "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49 + "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A + "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B + "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C + "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D + "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E + "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F + "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50 + "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51 + "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52 + "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53 + "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54 + "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55 + "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56 + "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57 + "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58 + "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59 + "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A + "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B + "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C + "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D + "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E + "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F + "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60 + "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61 + "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62 + "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63 + "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64 + "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65 + "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66 + "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67 + "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68 + "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69 + "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A + "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B + "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C + "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D + "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E + "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F + "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70 + "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71 + "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72 + "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73 + "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74 + "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75 + "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76 + "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77 + "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78 + "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79 + "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A + "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B + "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C + "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D + "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E + "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F + "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 + "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 + "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 + "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83 + "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84 + "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85 + "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86 + "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87 + "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88 + "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89 + "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A + "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B + "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C + "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D + "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E + "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F + "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90 + "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91 + "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92 + "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93 + "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94 + "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95 + "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96 + "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 + "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 + "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 + "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B + "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 + "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 + "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 + "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3 + "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4 + "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5 + "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6 + "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7 + "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8 + "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9 + "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA + "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB + "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC + "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD + "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE + "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF + "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0 + "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1 + "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2 + "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3 + "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4 + "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5 + "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6 + "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7 + "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8 + "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9 + "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA + "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB + "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC + "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD + "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE + "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF + "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0 + "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1 + "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2 + "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3 + "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4 + "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5 + "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6 + "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7 + "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8 + "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9 + "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA + "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB + "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC + "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD + "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE + "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF + "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0 + "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1 + "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2 + "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3 + "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4 + "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5 + "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6 + "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7 + "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8 + "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9 + "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA + "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB + "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC + "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD + "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE + "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF + "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0 + "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1 + "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2 + "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3 + "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4 + "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5 + "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6 + "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7 + "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8 + "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9 + "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA + "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB + "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC + "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED + "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE + "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF + "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0 + "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1 + "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2 + "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3 + "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4 + "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5 + "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6 + "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7 + "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8 + "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9 + "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00 + "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01 + "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02 + "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03 + "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04 + "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05 + "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06 + "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07 + "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08 + "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09 + "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A + "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B + "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C + "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D + "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E + "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F + "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10 + "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11 + "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12 + "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13 + "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14 + "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15 + "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18 + "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19 + "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A + "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B + "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C + "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D + "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20 + "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21 + "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22 + "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23 + "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24 + "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25 + "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26 + "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27 + "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28 + "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29 + "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A + "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B + "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C + "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D + "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E + "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F + "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30 + "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31 + "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32 + "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33 + "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34 + "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35 + "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36 + "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37 + "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38 + "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39 + "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A + "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B + "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C + "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D + "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E + "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F + "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40 + "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41 + "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42 + "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43 + "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44 + "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45 + "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48 + "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49 + "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A + "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B + "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C + "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D + "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50 + "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51 + "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52 + "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53 + "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54 + "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55 + "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56 + "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57 + "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59 + "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B + "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D + "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F + "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60 + "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61 + "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62 + "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63 + "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64 + "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65 + "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66 + "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67 + "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68 + "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69 + "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A + "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B + "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C + "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D + "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E + "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F + "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70 + "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72 + "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74 + "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76 + "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78 + "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A + "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C + "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80 + "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81 + "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82 + "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83 + "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84 + "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85 + "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86 + "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87 + "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88 + "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89 + "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A + "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B + "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C + "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D + "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E + "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F + "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90 + "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91 + "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92 + "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93 + "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94 + "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95 + "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96 + "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97 + "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98 + "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99 + "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A + "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B + "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C + "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D + "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E + "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F + "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0 + "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1 + "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2 + "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3 + "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4 + "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5 + "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6 + "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7 + "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8 + "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9 + "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA + "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB + "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC + "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD + "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE + "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF + "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0 + "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1 + "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2 + "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3 + "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4 + "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6 + "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7 + "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8 + "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9 + "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA + "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC + "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1 + "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2 + "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3 + "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4 + "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6 + "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7 + "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8 + "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA + "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC + "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD + "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE + "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF + "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0 + "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1 + "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2 + "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6 + "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7 + "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8 + "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9 + "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA + "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD + "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE + "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF + "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0 + "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1 + "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2 + "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4 + "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5 + "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6 + "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7 + "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8 + "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9 + "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA + "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC + "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED + "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2 + "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3 + "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4 + "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6 + "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7 + "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8 + "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA + "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC + "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A + "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B + "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE + "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD + "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE + "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF + "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204 + "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209 + "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C + "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224 + "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226 + "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241 + "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244 + "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247 + "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249 + "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260 + "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262 + "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D + "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E + "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F + "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270 + "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271 + "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274 + "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275 + "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278 + "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279 + "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280 + "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281 + "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284 + "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285 + "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288 + "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289 + "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC + "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD + "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE + "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF + "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0 + "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1 + "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2 + "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3 + "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA + "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB + "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC + "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED + "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C + "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E + "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050 + "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052 + "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054 + "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056 + "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058 + "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A + "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C + "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E + "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060 + "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062 + "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065 + "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067 + "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069 + "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070 + "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071 + "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073 + "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074 + "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076 + "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077 + "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079 + "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A + "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C + "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D + "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094 + "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E + "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC + "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE + "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0 + "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2 + "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4 + "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6 + "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8 + "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA + "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC + "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE + "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0 + "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2 + "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5 + "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7 + "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9 + "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0 + "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1 + "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3 + "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4 + "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6 + "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7 + "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9 + "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA + "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC + "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD + "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4 + "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7 + "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8 + "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9 + "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA + "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE + "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A + "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C + "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB + "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E + "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F + "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B + "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C + "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB + "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC + "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE + "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA + "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB + "" + // Total size of tables: 53KB (54226 bytes) diff --git a/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go new file mode 100644 index 000000000000..7297cce32b79 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/tables11.0.0.go @@ -0,0 +1,7693 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.13 + +package norm + +import "sync" + +const ( + // Version is the Unicode edition from which the tables are derived. + Version = "11.0.0" + + // MaxTransformChunkSize indicates the maximum number of bytes that Transform + // may need to write atomically for any Form. Making a destination buffer at + // least this size ensures that Transform can always make progress and that + // the user does not need to grow the buffer on an ErrShortDst. + MaxTransformChunkSize = 35 + maxNonStarters*4 +) + +var ccc = [55]uint8{ + 0, 1, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, + 84, 91, 103, 107, 118, 122, 129, 130, + 132, 202, 214, 216, 218, 220, 222, 224, + 226, 228, 230, 232, 233, 234, 240, +} + +const ( + firstMulti = 0x186D + firstCCC = 0x2C9E + endMulti = 0x2F60 + firstLeadingCCC = 0x49AE + firstCCCZeroExcept = 0x4A78 + firstStarterWithNLead = 0x4A9F + lastDecomp = 0x4AA1 + maxDecomp = 0x8000 +) + +// decomps: 19105 bytes +var decomps = [...]byte{ + // Bytes 0 - 3f + 0x00, 0x41, 0x20, 0x41, 0x21, 0x41, 0x22, 0x41, + 0x23, 0x41, 0x24, 0x41, 0x25, 0x41, 0x26, 0x41, + 0x27, 0x41, 0x28, 0x41, 0x29, 0x41, 0x2A, 0x41, + 0x2B, 0x41, 0x2C, 0x41, 0x2D, 0x41, 0x2E, 0x41, + 0x2F, 0x41, 0x30, 0x41, 0x31, 0x41, 0x32, 0x41, + 0x33, 0x41, 0x34, 0x41, 0x35, 0x41, 0x36, 0x41, + 0x37, 0x41, 0x38, 0x41, 0x39, 0x41, 0x3A, 0x41, + 0x3B, 0x41, 0x3C, 0x41, 0x3D, 0x41, 0x3E, 0x41, + // Bytes 40 - 7f + 0x3F, 0x41, 0x40, 0x41, 0x41, 0x41, 0x42, 0x41, + 0x43, 0x41, 0x44, 0x41, 0x45, 0x41, 0x46, 0x41, + 0x47, 0x41, 0x48, 0x41, 0x49, 0x41, 0x4A, 0x41, + 0x4B, 0x41, 0x4C, 0x41, 0x4D, 0x41, 0x4E, 0x41, + 0x4F, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, + 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, + 0x57, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41, + 0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41, + // Bytes 80 - bf + 0x5F, 0x41, 0x60, 0x41, 0x61, 0x41, 0x62, 0x41, + 0x63, 0x41, 0x64, 0x41, 0x65, 0x41, 0x66, 0x41, + 0x67, 0x41, 0x68, 0x41, 0x69, 0x41, 0x6A, 0x41, + 0x6B, 0x41, 0x6C, 0x41, 0x6D, 0x41, 0x6E, 0x41, + 0x6F, 0x41, 0x70, 0x41, 0x71, 0x41, 0x72, 0x41, + 0x73, 0x41, 0x74, 0x41, 0x75, 0x41, 0x76, 0x41, + 0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7A, 0x41, + 0x7B, 0x41, 0x7C, 0x41, 0x7D, 0x41, 0x7E, 0x42, + // Bytes c0 - ff + 0xC2, 0xA2, 0x42, 0xC2, 0xA3, 0x42, 0xC2, 0xA5, + 0x42, 0xC2, 0xA6, 0x42, 0xC2, 0xAC, 0x42, 0xC2, + 0xB7, 0x42, 0xC3, 0x86, 0x42, 0xC3, 0xB0, 0x42, + 0xC4, 0xA6, 0x42, 0xC4, 0xA7, 0x42, 0xC4, 0xB1, + 0x42, 0xC5, 0x8B, 0x42, 0xC5, 0x93, 0x42, 0xC6, + 0x8E, 0x42, 0xC6, 0x90, 0x42, 0xC6, 0xAB, 0x42, + 0xC8, 0xA2, 0x42, 0xC8, 0xB7, 0x42, 0xC9, 0x90, + 0x42, 0xC9, 0x91, 0x42, 0xC9, 0x92, 0x42, 0xC9, + // Bytes 100 - 13f + 0x94, 0x42, 0xC9, 0x95, 0x42, 0xC9, 0x99, 0x42, + 0xC9, 0x9B, 0x42, 0xC9, 0x9C, 0x42, 0xC9, 0x9F, + 0x42, 0xC9, 0xA1, 0x42, 0xC9, 0xA3, 0x42, 0xC9, + 0xA5, 0x42, 0xC9, 0xA6, 0x42, 0xC9, 0xA8, 0x42, + 0xC9, 0xA9, 0x42, 0xC9, 0xAA, 0x42, 0xC9, 0xAB, + 0x42, 0xC9, 0xAD, 0x42, 0xC9, 0xAF, 0x42, 0xC9, + 0xB0, 0x42, 0xC9, 0xB1, 0x42, 0xC9, 0xB2, 0x42, + 0xC9, 0xB3, 0x42, 0xC9, 0xB4, 0x42, 0xC9, 0xB5, + // Bytes 140 - 17f + 0x42, 0xC9, 0xB8, 0x42, 0xC9, 0xB9, 0x42, 0xC9, + 0xBB, 0x42, 0xCA, 0x81, 0x42, 0xCA, 0x82, 0x42, + 0xCA, 0x83, 0x42, 0xCA, 0x89, 0x42, 0xCA, 0x8A, + 0x42, 0xCA, 0x8B, 0x42, 0xCA, 0x8C, 0x42, 0xCA, + 0x90, 0x42, 0xCA, 0x91, 0x42, 0xCA, 0x92, 0x42, + 0xCA, 0x95, 0x42, 0xCA, 0x9D, 0x42, 0xCA, 0x9F, + 0x42, 0xCA, 0xB9, 0x42, 0xCE, 0x91, 0x42, 0xCE, + 0x92, 0x42, 0xCE, 0x93, 0x42, 0xCE, 0x94, 0x42, + // Bytes 180 - 1bf + 0xCE, 0x95, 0x42, 0xCE, 0x96, 0x42, 0xCE, 0x97, + 0x42, 0xCE, 0x98, 0x42, 0xCE, 0x99, 0x42, 0xCE, + 0x9A, 0x42, 0xCE, 0x9B, 0x42, 0xCE, 0x9C, 0x42, + 0xCE, 0x9D, 0x42, 0xCE, 0x9E, 0x42, 0xCE, 0x9F, + 0x42, 0xCE, 0xA0, 0x42, 0xCE, 0xA1, 0x42, 0xCE, + 0xA3, 0x42, 0xCE, 0xA4, 0x42, 0xCE, 0xA5, 0x42, + 0xCE, 0xA6, 0x42, 0xCE, 0xA7, 0x42, 0xCE, 0xA8, + 0x42, 0xCE, 0xA9, 0x42, 0xCE, 0xB1, 0x42, 0xCE, + // Bytes 1c0 - 1ff + 0xB2, 0x42, 0xCE, 0xB3, 0x42, 0xCE, 0xB4, 0x42, + 0xCE, 0xB5, 0x42, 0xCE, 0xB6, 0x42, 0xCE, 0xB7, + 0x42, 0xCE, 0xB8, 0x42, 0xCE, 0xB9, 0x42, 0xCE, + 0xBA, 0x42, 0xCE, 0xBB, 0x42, 0xCE, 0xBC, 0x42, + 0xCE, 0xBD, 0x42, 0xCE, 0xBE, 0x42, 0xCE, 0xBF, + 0x42, 0xCF, 0x80, 0x42, 0xCF, 0x81, 0x42, 0xCF, + 0x82, 0x42, 0xCF, 0x83, 0x42, 0xCF, 0x84, 0x42, + 0xCF, 0x85, 0x42, 0xCF, 0x86, 0x42, 0xCF, 0x87, + // Bytes 200 - 23f + 0x42, 0xCF, 0x88, 0x42, 0xCF, 0x89, 0x42, 0xCF, + 0x9C, 0x42, 0xCF, 0x9D, 0x42, 0xD0, 0xBD, 0x42, + 0xD1, 0x8A, 0x42, 0xD1, 0x8C, 0x42, 0xD7, 0x90, + 0x42, 0xD7, 0x91, 0x42, 0xD7, 0x92, 0x42, 0xD7, + 0x93, 0x42, 0xD7, 0x94, 0x42, 0xD7, 0x9B, 0x42, + 0xD7, 0x9C, 0x42, 0xD7, 0x9D, 0x42, 0xD7, 0xA2, + 0x42, 0xD7, 0xA8, 0x42, 0xD7, 0xAA, 0x42, 0xD8, + 0xA1, 0x42, 0xD8, 0xA7, 0x42, 0xD8, 0xA8, 0x42, + // Bytes 240 - 27f + 0xD8, 0xA9, 0x42, 0xD8, 0xAA, 0x42, 0xD8, 0xAB, + 0x42, 0xD8, 0xAC, 0x42, 0xD8, 0xAD, 0x42, 0xD8, + 0xAE, 0x42, 0xD8, 0xAF, 0x42, 0xD8, 0xB0, 0x42, + 0xD8, 0xB1, 0x42, 0xD8, 0xB2, 0x42, 0xD8, 0xB3, + 0x42, 0xD8, 0xB4, 0x42, 0xD8, 0xB5, 0x42, 0xD8, + 0xB6, 0x42, 0xD8, 0xB7, 0x42, 0xD8, 0xB8, 0x42, + 0xD8, 0xB9, 0x42, 0xD8, 0xBA, 0x42, 0xD9, 0x81, + 0x42, 0xD9, 0x82, 0x42, 0xD9, 0x83, 0x42, 0xD9, + // Bytes 280 - 2bf + 0x84, 0x42, 0xD9, 0x85, 0x42, 0xD9, 0x86, 0x42, + 0xD9, 0x87, 0x42, 0xD9, 0x88, 0x42, 0xD9, 0x89, + 0x42, 0xD9, 0x8A, 0x42, 0xD9, 0xAE, 0x42, 0xD9, + 0xAF, 0x42, 0xD9, 0xB1, 0x42, 0xD9, 0xB9, 0x42, + 0xD9, 0xBA, 0x42, 0xD9, 0xBB, 0x42, 0xD9, 0xBE, + 0x42, 0xD9, 0xBF, 0x42, 0xDA, 0x80, 0x42, 0xDA, + 0x83, 0x42, 0xDA, 0x84, 0x42, 0xDA, 0x86, 0x42, + 0xDA, 0x87, 0x42, 0xDA, 0x88, 0x42, 0xDA, 0x8C, + // Bytes 2c0 - 2ff + 0x42, 0xDA, 0x8D, 0x42, 0xDA, 0x8E, 0x42, 0xDA, + 0x91, 0x42, 0xDA, 0x98, 0x42, 0xDA, 0xA1, 0x42, + 0xDA, 0xA4, 0x42, 0xDA, 0xA6, 0x42, 0xDA, 0xA9, + 0x42, 0xDA, 0xAD, 0x42, 0xDA, 0xAF, 0x42, 0xDA, + 0xB1, 0x42, 0xDA, 0xB3, 0x42, 0xDA, 0xBA, 0x42, + 0xDA, 0xBB, 0x42, 0xDA, 0xBE, 0x42, 0xDB, 0x81, + 0x42, 0xDB, 0x85, 0x42, 0xDB, 0x86, 0x42, 0xDB, + 0x87, 0x42, 0xDB, 0x88, 0x42, 0xDB, 0x89, 0x42, + // Bytes 300 - 33f + 0xDB, 0x8B, 0x42, 0xDB, 0x8C, 0x42, 0xDB, 0x90, + 0x42, 0xDB, 0x92, 0x43, 0xE0, 0xBC, 0x8B, 0x43, + 0xE1, 0x83, 0x9C, 0x43, 0xE1, 0x84, 0x80, 0x43, + 0xE1, 0x84, 0x81, 0x43, 0xE1, 0x84, 0x82, 0x43, + 0xE1, 0x84, 0x83, 0x43, 0xE1, 0x84, 0x84, 0x43, + 0xE1, 0x84, 0x85, 0x43, 0xE1, 0x84, 0x86, 0x43, + 0xE1, 0x84, 0x87, 0x43, 0xE1, 0x84, 0x88, 0x43, + 0xE1, 0x84, 0x89, 0x43, 0xE1, 0x84, 0x8A, 0x43, + // Bytes 340 - 37f + 0xE1, 0x84, 0x8B, 0x43, 0xE1, 0x84, 0x8C, 0x43, + 0xE1, 0x84, 0x8D, 0x43, 0xE1, 0x84, 0x8E, 0x43, + 0xE1, 0x84, 0x8F, 0x43, 0xE1, 0x84, 0x90, 0x43, + 0xE1, 0x84, 0x91, 0x43, 0xE1, 0x84, 0x92, 0x43, + 0xE1, 0x84, 0x94, 0x43, 0xE1, 0x84, 0x95, 0x43, + 0xE1, 0x84, 0x9A, 0x43, 0xE1, 0x84, 0x9C, 0x43, + 0xE1, 0x84, 0x9D, 0x43, 0xE1, 0x84, 0x9E, 0x43, + 0xE1, 0x84, 0xA0, 0x43, 0xE1, 0x84, 0xA1, 0x43, + // Bytes 380 - 3bf + 0xE1, 0x84, 0xA2, 0x43, 0xE1, 0x84, 0xA3, 0x43, + 0xE1, 0x84, 0xA7, 0x43, 0xE1, 0x84, 0xA9, 0x43, + 0xE1, 0x84, 0xAB, 0x43, 0xE1, 0x84, 0xAC, 0x43, + 0xE1, 0x84, 0xAD, 0x43, 0xE1, 0x84, 0xAE, 0x43, + 0xE1, 0x84, 0xAF, 0x43, 0xE1, 0x84, 0xB2, 0x43, + 0xE1, 0x84, 0xB6, 0x43, 0xE1, 0x85, 0x80, 0x43, + 0xE1, 0x85, 0x87, 0x43, 0xE1, 0x85, 0x8C, 0x43, + 0xE1, 0x85, 0x97, 0x43, 0xE1, 0x85, 0x98, 0x43, + // Bytes 3c0 - 3ff + 0xE1, 0x85, 0x99, 0x43, 0xE1, 0x85, 0xA0, 0x43, + 0xE1, 0x86, 0x84, 0x43, 0xE1, 0x86, 0x85, 0x43, + 0xE1, 0x86, 0x88, 0x43, 0xE1, 0x86, 0x91, 0x43, + 0xE1, 0x86, 0x92, 0x43, 0xE1, 0x86, 0x94, 0x43, + 0xE1, 0x86, 0x9E, 0x43, 0xE1, 0x86, 0xA1, 0x43, + 0xE1, 0x87, 0x87, 0x43, 0xE1, 0x87, 0x88, 0x43, + 0xE1, 0x87, 0x8C, 0x43, 0xE1, 0x87, 0x8E, 0x43, + 0xE1, 0x87, 0x93, 0x43, 0xE1, 0x87, 0x97, 0x43, + // Bytes 400 - 43f + 0xE1, 0x87, 0x99, 0x43, 0xE1, 0x87, 0x9D, 0x43, + 0xE1, 0x87, 0x9F, 0x43, 0xE1, 0x87, 0xB1, 0x43, + 0xE1, 0x87, 0xB2, 0x43, 0xE1, 0xB4, 0x82, 0x43, + 0xE1, 0xB4, 0x96, 0x43, 0xE1, 0xB4, 0x97, 0x43, + 0xE1, 0xB4, 0x9C, 0x43, 0xE1, 0xB4, 0x9D, 0x43, + 0xE1, 0xB4, 0xA5, 0x43, 0xE1, 0xB5, 0xBB, 0x43, + 0xE1, 0xB6, 0x85, 0x43, 0xE2, 0x80, 0x82, 0x43, + 0xE2, 0x80, 0x83, 0x43, 0xE2, 0x80, 0x90, 0x43, + // Bytes 440 - 47f + 0xE2, 0x80, 0x93, 0x43, 0xE2, 0x80, 0x94, 0x43, + 0xE2, 0x82, 0xA9, 0x43, 0xE2, 0x86, 0x90, 0x43, + 0xE2, 0x86, 0x91, 0x43, 0xE2, 0x86, 0x92, 0x43, + 0xE2, 0x86, 0x93, 0x43, 0xE2, 0x88, 0x82, 0x43, + 0xE2, 0x88, 0x87, 0x43, 0xE2, 0x88, 0x91, 0x43, + 0xE2, 0x88, 0x92, 0x43, 0xE2, 0x94, 0x82, 0x43, + 0xE2, 0x96, 0xA0, 0x43, 0xE2, 0x97, 0x8B, 0x43, + 0xE2, 0xA6, 0x85, 0x43, 0xE2, 0xA6, 0x86, 0x43, + // Bytes 480 - 4bf + 0xE2, 0xB5, 0xA1, 0x43, 0xE3, 0x80, 0x81, 0x43, + 0xE3, 0x80, 0x82, 0x43, 0xE3, 0x80, 0x88, 0x43, + 0xE3, 0x80, 0x89, 0x43, 0xE3, 0x80, 0x8A, 0x43, + 0xE3, 0x80, 0x8B, 0x43, 0xE3, 0x80, 0x8C, 0x43, + 0xE3, 0x80, 0x8D, 0x43, 0xE3, 0x80, 0x8E, 0x43, + 0xE3, 0x80, 0x8F, 0x43, 0xE3, 0x80, 0x90, 0x43, + 0xE3, 0x80, 0x91, 0x43, 0xE3, 0x80, 0x92, 0x43, + 0xE3, 0x80, 0x94, 0x43, 0xE3, 0x80, 0x95, 0x43, + // Bytes 4c0 - 4ff + 0xE3, 0x80, 0x96, 0x43, 0xE3, 0x80, 0x97, 0x43, + 0xE3, 0x82, 0xA1, 0x43, 0xE3, 0x82, 0xA2, 0x43, + 0xE3, 0x82, 0xA3, 0x43, 0xE3, 0x82, 0xA4, 0x43, + 0xE3, 0x82, 0xA5, 0x43, 0xE3, 0x82, 0xA6, 0x43, + 0xE3, 0x82, 0xA7, 0x43, 0xE3, 0x82, 0xA8, 0x43, + 0xE3, 0x82, 0xA9, 0x43, 0xE3, 0x82, 0xAA, 0x43, + 0xE3, 0x82, 0xAB, 0x43, 0xE3, 0x82, 0xAD, 0x43, + 0xE3, 0x82, 0xAF, 0x43, 0xE3, 0x82, 0xB1, 0x43, + // Bytes 500 - 53f + 0xE3, 0x82, 0xB3, 0x43, 0xE3, 0x82, 0xB5, 0x43, + 0xE3, 0x82, 0xB7, 0x43, 0xE3, 0x82, 0xB9, 0x43, + 0xE3, 0x82, 0xBB, 0x43, 0xE3, 0x82, 0xBD, 0x43, + 0xE3, 0x82, 0xBF, 0x43, 0xE3, 0x83, 0x81, 0x43, + 0xE3, 0x83, 0x83, 0x43, 0xE3, 0x83, 0x84, 0x43, + 0xE3, 0x83, 0x86, 0x43, 0xE3, 0x83, 0x88, 0x43, + 0xE3, 0x83, 0x8A, 0x43, 0xE3, 0x83, 0x8B, 0x43, + 0xE3, 0x83, 0x8C, 0x43, 0xE3, 0x83, 0x8D, 0x43, + // Bytes 540 - 57f + 0xE3, 0x83, 0x8E, 0x43, 0xE3, 0x83, 0x8F, 0x43, + 0xE3, 0x83, 0x92, 0x43, 0xE3, 0x83, 0x95, 0x43, + 0xE3, 0x83, 0x98, 0x43, 0xE3, 0x83, 0x9B, 0x43, + 0xE3, 0x83, 0x9E, 0x43, 0xE3, 0x83, 0x9F, 0x43, + 0xE3, 0x83, 0xA0, 0x43, 0xE3, 0x83, 0xA1, 0x43, + 0xE3, 0x83, 0xA2, 0x43, 0xE3, 0x83, 0xA3, 0x43, + 0xE3, 0x83, 0xA4, 0x43, 0xE3, 0x83, 0xA5, 0x43, + 0xE3, 0x83, 0xA6, 0x43, 0xE3, 0x83, 0xA7, 0x43, + // Bytes 580 - 5bf + 0xE3, 0x83, 0xA8, 0x43, 0xE3, 0x83, 0xA9, 0x43, + 0xE3, 0x83, 0xAA, 0x43, 0xE3, 0x83, 0xAB, 0x43, + 0xE3, 0x83, 0xAC, 0x43, 0xE3, 0x83, 0xAD, 0x43, + 0xE3, 0x83, 0xAF, 0x43, 0xE3, 0x83, 0xB0, 0x43, + 0xE3, 0x83, 0xB1, 0x43, 0xE3, 0x83, 0xB2, 0x43, + 0xE3, 0x83, 0xB3, 0x43, 0xE3, 0x83, 0xBB, 0x43, + 0xE3, 0x83, 0xBC, 0x43, 0xE3, 0x92, 0x9E, 0x43, + 0xE3, 0x92, 0xB9, 0x43, 0xE3, 0x92, 0xBB, 0x43, + // Bytes 5c0 - 5ff + 0xE3, 0x93, 0x9F, 0x43, 0xE3, 0x94, 0x95, 0x43, + 0xE3, 0x9B, 0xAE, 0x43, 0xE3, 0x9B, 0xBC, 0x43, + 0xE3, 0x9E, 0x81, 0x43, 0xE3, 0xA0, 0xAF, 0x43, + 0xE3, 0xA1, 0xA2, 0x43, 0xE3, 0xA1, 0xBC, 0x43, + 0xE3, 0xA3, 0x87, 0x43, 0xE3, 0xA3, 0xA3, 0x43, + 0xE3, 0xA4, 0x9C, 0x43, 0xE3, 0xA4, 0xBA, 0x43, + 0xE3, 0xA8, 0xAE, 0x43, 0xE3, 0xA9, 0xAC, 0x43, + 0xE3, 0xAB, 0xA4, 0x43, 0xE3, 0xAC, 0x88, 0x43, + // Bytes 600 - 63f + 0xE3, 0xAC, 0x99, 0x43, 0xE3, 0xAD, 0x89, 0x43, + 0xE3, 0xAE, 0x9D, 0x43, 0xE3, 0xB0, 0x98, 0x43, + 0xE3, 0xB1, 0x8E, 0x43, 0xE3, 0xB4, 0xB3, 0x43, + 0xE3, 0xB6, 0x96, 0x43, 0xE3, 0xBA, 0xAC, 0x43, + 0xE3, 0xBA, 0xB8, 0x43, 0xE3, 0xBC, 0x9B, 0x43, + 0xE3, 0xBF, 0xBC, 0x43, 0xE4, 0x80, 0x88, 0x43, + 0xE4, 0x80, 0x98, 0x43, 0xE4, 0x80, 0xB9, 0x43, + 0xE4, 0x81, 0x86, 0x43, 0xE4, 0x82, 0x96, 0x43, + // Bytes 640 - 67f + 0xE4, 0x83, 0xA3, 0x43, 0xE4, 0x84, 0xAF, 0x43, + 0xE4, 0x88, 0x82, 0x43, 0xE4, 0x88, 0xA7, 0x43, + 0xE4, 0x8A, 0xA0, 0x43, 0xE4, 0x8C, 0x81, 0x43, + 0xE4, 0x8C, 0xB4, 0x43, 0xE4, 0x8D, 0x99, 0x43, + 0xE4, 0x8F, 0x95, 0x43, 0xE4, 0x8F, 0x99, 0x43, + 0xE4, 0x90, 0x8B, 0x43, 0xE4, 0x91, 0xAB, 0x43, + 0xE4, 0x94, 0xAB, 0x43, 0xE4, 0x95, 0x9D, 0x43, + 0xE4, 0x95, 0xA1, 0x43, 0xE4, 0x95, 0xAB, 0x43, + // Bytes 680 - 6bf + 0xE4, 0x97, 0x97, 0x43, 0xE4, 0x97, 0xB9, 0x43, + 0xE4, 0x98, 0xB5, 0x43, 0xE4, 0x9A, 0xBE, 0x43, + 0xE4, 0x9B, 0x87, 0x43, 0xE4, 0xA6, 0x95, 0x43, + 0xE4, 0xA7, 0xA6, 0x43, 0xE4, 0xA9, 0xAE, 0x43, + 0xE4, 0xA9, 0xB6, 0x43, 0xE4, 0xAA, 0xB2, 0x43, + 0xE4, 0xAC, 0xB3, 0x43, 0xE4, 0xAF, 0x8E, 0x43, + 0xE4, 0xB3, 0x8E, 0x43, 0xE4, 0xB3, 0xAD, 0x43, + 0xE4, 0xB3, 0xB8, 0x43, 0xE4, 0xB5, 0x96, 0x43, + // Bytes 6c0 - 6ff + 0xE4, 0xB8, 0x80, 0x43, 0xE4, 0xB8, 0x81, 0x43, + 0xE4, 0xB8, 0x83, 0x43, 0xE4, 0xB8, 0x89, 0x43, + 0xE4, 0xB8, 0x8A, 0x43, 0xE4, 0xB8, 0x8B, 0x43, + 0xE4, 0xB8, 0x8D, 0x43, 0xE4, 0xB8, 0x99, 0x43, + 0xE4, 0xB8, 0xA6, 0x43, 0xE4, 0xB8, 0xA8, 0x43, + 0xE4, 0xB8, 0xAD, 0x43, 0xE4, 0xB8, 0xB2, 0x43, + 0xE4, 0xB8, 0xB6, 0x43, 0xE4, 0xB8, 0xB8, 0x43, + 0xE4, 0xB8, 0xB9, 0x43, 0xE4, 0xB8, 0xBD, 0x43, + // Bytes 700 - 73f + 0xE4, 0xB8, 0xBF, 0x43, 0xE4, 0xB9, 0x81, 0x43, + 0xE4, 0xB9, 0x99, 0x43, 0xE4, 0xB9, 0x9D, 0x43, + 0xE4, 0xBA, 0x82, 0x43, 0xE4, 0xBA, 0x85, 0x43, + 0xE4, 0xBA, 0x86, 0x43, 0xE4, 0xBA, 0x8C, 0x43, + 0xE4, 0xBA, 0x94, 0x43, 0xE4, 0xBA, 0xA0, 0x43, + 0xE4, 0xBA, 0xA4, 0x43, 0xE4, 0xBA, 0xAE, 0x43, + 0xE4, 0xBA, 0xBA, 0x43, 0xE4, 0xBB, 0x80, 0x43, + 0xE4, 0xBB, 0x8C, 0x43, 0xE4, 0xBB, 0xA4, 0x43, + // Bytes 740 - 77f + 0xE4, 0xBC, 0x81, 0x43, 0xE4, 0xBC, 0x91, 0x43, + 0xE4, 0xBD, 0xA0, 0x43, 0xE4, 0xBE, 0x80, 0x43, + 0xE4, 0xBE, 0x86, 0x43, 0xE4, 0xBE, 0x8B, 0x43, + 0xE4, 0xBE, 0xAE, 0x43, 0xE4, 0xBE, 0xBB, 0x43, + 0xE4, 0xBE, 0xBF, 0x43, 0xE5, 0x80, 0x82, 0x43, + 0xE5, 0x80, 0xAB, 0x43, 0xE5, 0x81, 0xBA, 0x43, + 0xE5, 0x82, 0x99, 0x43, 0xE5, 0x83, 0x8F, 0x43, + 0xE5, 0x83, 0x9A, 0x43, 0xE5, 0x83, 0xA7, 0x43, + // Bytes 780 - 7bf + 0xE5, 0x84, 0xAA, 0x43, 0xE5, 0x84, 0xBF, 0x43, + 0xE5, 0x85, 0x80, 0x43, 0xE5, 0x85, 0x85, 0x43, + 0xE5, 0x85, 0x8D, 0x43, 0xE5, 0x85, 0x94, 0x43, + 0xE5, 0x85, 0xA4, 0x43, 0xE5, 0x85, 0xA5, 0x43, + 0xE5, 0x85, 0xA7, 0x43, 0xE5, 0x85, 0xA8, 0x43, + 0xE5, 0x85, 0xA9, 0x43, 0xE5, 0x85, 0xAB, 0x43, + 0xE5, 0x85, 0xAD, 0x43, 0xE5, 0x85, 0xB7, 0x43, + 0xE5, 0x86, 0x80, 0x43, 0xE5, 0x86, 0x82, 0x43, + // Bytes 7c0 - 7ff + 0xE5, 0x86, 0x8D, 0x43, 0xE5, 0x86, 0x92, 0x43, + 0xE5, 0x86, 0x95, 0x43, 0xE5, 0x86, 0x96, 0x43, + 0xE5, 0x86, 0x97, 0x43, 0xE5, 0x86, 0x99, 0x43, + 0xE5, 0x86, 0xA4, 0x43, 0xE5, 0x86, 0xAB, 0x43, + 0xE5, 0x86, 0xAC, 0x43, 0xE5, 0x86, 0xB5, 0x43, + 0xE5, 0x86, 0xB7, 0x43, 0xE5, 0x87, 0x89, 0x43, + 0xE5, 0x87, 0x8C, 0x43, 0xE5, 0x87, 0x9C, 0x43, + 0xE5, 0x87, 0x9E, 0x43, 0xE5, 0x87, 0xA0, 0x43, + // Bytes 800 - 83f + 0xE5, 0x87, 0xB5, 0x43, 0xE5, 0x88, 0x80, 0x43, + 0xE5, 0x88, 0x83, 0x43, 0xE5, 0x88, 0x87, 0x43, + 0xE5, 0x88, 0x97, 0x43, 0xE5, 0x88, 0x9D, 0x43, + 0xE5, 0x88, 0xA9, 0x43, 0xE5, 0x88, 0xBA, 0x43, + 0xE5, 0x88, 0xBB, 0x43, 0xE5, 0x89, 0x86, 0x43, + 0xE5, 0x89, 0x8D, 0x43, 0xE5, 0x89, 0xB2, 0x43, + 0xE5, 0x89, 0xB7, 0x43, 0xE5, 0x8A, 0x89, 0x43, + 0xE5, 0x8A, 0x9B, 0x43, 0xE5, 0x8A, 0xA3, 0x43, + // Bytes 840 - 87f + 0xE5, 0x8A, 0xB3, 0x43, 0xE5, 0x8A, 0xB4, 0x43, + 0xE5, 0x8B, 0x87, 0x43, 0xE5, 0x8B, 0x89, 0x43, + 0xE5, 0x8B, 0x92, 0x43, 0xE5, 0x8B, 0x9E, 0x43, + 0xE5, 0x8B, 0xA4, 0x43, 0xE5, 0x8B, 0xB5, 0x43, + 0xE5, 0x8B, 0xB9, 0x43, 0xE5, 0x8B, 0xBA, 0x43, + 0xE5, 0x8C, 0x85, 0x43, 0xE5, 0x8C, 0x86, 0x43, + 0xE5, 0x8C, 0x95, 0x43, 0xE5, 0x8C, 0x97, 0x43, + 0xE5, 0x8C, 0x9A, 0x43, 0xE5, 0x8C, 0xB8, 0x43, + // Bytes 880 - 8bf + 0xE5, 0x8C, 0xBB, 0x43, 0xE5, 0x8C, 0xBF, 0x43, + 0xE5, 0x8D, 0x81, 0x43, 0xE5, 0x8D, 0x84, 0x43, + 0xE5, 0x8D, 0x85, 0x43, 0xE5, 0x8D, 0x89, 0x43, + 0xE5, 0x8D, 0x91, 0x43, 0xE5, 0x8D, 0x94, 0x43, + 0xE5, 0x8D, 0x9A, 0x43, 0xE5, 0x8D, 0x9C, 0x43, + 0xE5, 0x8D, 0xA9, 0x43, 0xE5, 0x8D, 0xB0, 0x43, + 0xE5, 0x8D, 0xB3, 0x43, 0xE5, 0x8D, 0xB5, 0x43, + 0xE5, 0x8D, 0xBD, 0x43, 0xE5, 0x8D, 0xBF, 0x43, + // Bytes 8c0 - 8ff + 0xE5, 0x8E, 0x82, 0x43, 0xE5, 0x8E, 0xB6, 0x43, + 0xE5, 0x8F, 0x83, 0x43, 0xE5, 0x8F, 0x88, 0x43, + 0xE5, 0x8F, 0x8A, 0x43, 0xE5, 0x8F, 0x8C, 0x43, + 0xE5, 0x8F, 0x9F, 0x43, 0xE5, 0x8F, 0xA3, 0x43, + 0xE5, 0x8F, 0xA5, 0x43, 0xE5, 0x8F, 0xAB, 0x43, + 0xE5, 0x8F, 0xAF, 0x43, 0xE5, 0x8F, 0xB1, 0x43, + 0xE5, 0x8F, 0xB3, 0x43, 0xE5, 0x90, 0x86, 0x43, + 0xE5, 0x90, 0x88, 0x43, 0xE5, 0x90, 0x8D, 0x43, + // Bytes 900 - 93f + 0xE5, 0x90, 0x8F, 0x43, 0xE5, 0x90, 0x9D, 0x43, + 0xE5, 0x90, 0xB8, 0x43, 0xE5, 0x90, 0xB9, 0x43, + 0xE5, 0x91, 0x82, 0x43, 0xE5, 0x91, 0x88, 0x43, + 0xE5, 0x91, 0xA8, 0x43, 0xE5, 0x92, 0x9E, 0x43, + 0xE5, 0x92, 0xA2, 0x43, 0xE5, 0x92, 0xBD, 0x43, + 0xE5, 0x93, 0xB6, 0x43, 0xE5, 0x94, 0x90, 0x43, + 0xE5, 0x95, 0x8F, 0x43, 0xE5, 0x95, 0x93, 0x43, + 0xE5, 0x95, 0x95, 0x43, 0xE5, 0x95, 0xA3, 0x43, + // Bytes 940 - 97f + 0xE5, 0x96, 0x84, 0x43, 0xE5, 0x96, 0x87, 0x43, + 0xE5, 0x96, 0x99, 0x43, 0xE5, 0x96, 0x9D, 0x43, + 0xE5, 0x96, 0xAB, 0x43, 0xE5, 0x96, 0xB3, 0x43, + 0xE5, 0x96, 0xB6, 0x43, 0xE5, 0x97, 0x80, 0x43, + 0xE5, 0x97, 0x82, 0x43, 0xE5, 0x97, 0xA2, 0x43, + 0xE5, 0x98, 0x86, 0x43, 0xE5, 0x99, 0x91, 0x43, + 0xE5, 0x99, 0xA8, 0x43, 0xE5, 0x99, 0xB4, 0x43, + 0xE5, 0x9B, 0x97, 0x43, 0xE5, 0x9B, 0x9B, 0x43, + // Bytes 980 - 9bf + 0xE5, 0x9B, 0xB9, 0x43, 0xE5, 0x9C, 0x96, 0x43, + 0xE5, 0x9C, 0x97, 0x43, 0xE5, 0x9C, 0x9F, 0x43, + 0xE5, 0x9C, 0xB0, 0x43, 0xE5, 0x9E, 0x8B, 0x43, + 0xE5, 0x9F, 0x8E, 0x43, 0xE5, 0x9F, 0xB4, 0x43, + 0xE5, 0xA0, 0x8D, 0x43, 0xE5, 0xA0, 0xB1, 0x43, + 0xE5, 0xA0, 0xB2, 0x43, 0xE5, 0xA1, 0x80, 0x43, + 0xE5, 0xA1, 0x9A, 0x43, 0xE5, 0xA1, 0x9E, 0x43, + 0xE5, 0xA2, 0xA8, 0x43, 0xE5, 0xA2, 0xAC, 0x43, + // Bytes 9c0 - 9ff + 0xE5, 0xA2, 0xB3, 0x43, 0xE5, 0xA3, 0x98, 0x43, + 0xE5, 0xA3, 0x9F, 0x43, 0xE5, 0xA3, 0xAB, 0x43, + 0xE5, 0xA3, 0xAE, 0x43, 0xE5, 0xA3, 0xB0, 0x43, + 0xE5, 0xA3, 0xB2, 0x43, 0xE5, 0xA3, 0xB7, 0x43, + 0xE5, 0xA4, 0x82, 0x43, 0xE5, 0xA4, 0x86, 0x43, + 0xE5, 0xA4, 0x8A, 0x43, 0xE5, 0xA4, 0x95, 0x43, + 0xE5, 0xA4, 0x9A, 0x43, 0xE5, 0xA4, 0x9C, 0x43, + 0xE5, 0xA4, 0xA2, 0x43, 0xE5, 0xA4, 0xA7, 0x43, + // Bytes a00 - a3f + 0xE5, 0xA4, 0xA9, 0x43, 0xE5, 0xA5, 0x84, 0x43, + 0xE5, 0xA5, 0x88, 0x43, 0xE5, 0xA5, 0x91, 0x43, + 0xE5, 0xA5, 0x94, 0x43, 0xE5, 0xA5, 0xA2, 0x43, + 0xE5, 0xA5, 0xB3, 0x43, 0xE5, 0xA7, 0x98, 0x43, + 0xE5, 0xA7, 0xAC, 0x43, 0xE5, 0xA8, 0x9B, 0x43, + 0xE5, 0xA8, 0xA7, 0x43, 0xE5, 0xA9, 0xA2, 0x43, + 0xE5, 0xA9, 0xA6, 0x43, 0xE5, 0xAA, 0xB5, 0x43, + 0xE5, 0xAC, 0x88, 0x43, 0xE5, 0xAC, 0xA8, 0x43, + // Bytes a40 - a7f + 0xE5, 0xAC, 0xBE, 0x43, 0xE5, 0xAD, 0x90, 0x43, + 0xE5, 0xAD, 0x97, 0x43, 0xE5, 0xAD, 0xA6, 0x43, + 0xE5, 0xAE, 0x80, 0x43, 0xE5, 0xAE, 0x85, 0x43, + 0xE5, 0xAE, 0x97, 0x43, 0xE5, 0xAF, 0x83, 0x43, + 0xE5, 0xAF, 0x98, 0x43, 0xE5, 0xAF, 0xA7, 0x43, + 0xE5, 0xAF, 0xAE, 0x43, 0xE5, 0xAF, 0xB3, 0x43, + 0xE5, 0xAF, 0xB8, 0x43, 0xE5, 0xAF, 0xBF, 0x43, + 0xE5, 0xB0, 0x86, 0x43, 0xE5, 0xB0, 0x8F, 0x43, + // Bytes a80 - abf + 0xE5, 0xB0, 0xA2, 0x43, 0xE5, 0xB0, 0xB8, 0x43, + 0xE5, 0xB0, 0xBF, 0x43, 0xE5, 0xB1, 0xA0, 0x43, + 0xE5, 0xB1, 0xA2, 0x43, 0xE5, 0xB1, 0xA4, 0x43, + 0xE5, 0xB1, 0xA5, 0x43, 0xE5, 0xB1, 0xAE, 0x43, + 0xE5, 0xB1, 0xB1, 0x43, 0xE5, 0xB2, 0x8D, 0x43, + 0xE5, 0xB3, 0x80, 0x43, 0xE5, 0xB4, 0x99, 0x43, + 0xE5, 0xB5, 0x83, 0x43, 0xE5, 0xB5, 0x90, 0x43, + 0xE5, 0xB5, 0xAB, 0x43, 0xE5, 0xB5, 0xAE, 0x43, + // Bytes ac0 - aff + 0xE5, 0xB5, 0xBC, 0x43, 0xE5, 0xB6, 0xB2, 0x43, + 0xE5, 0xB6, 0xBA, 0x43, 0xE5, 0xB7, 0x9B, 0x43, + 0xE5, 0xB7, 0xA1, 0x43, 0xE5, 0xB7, 0xA2, 0x43, + 0xE5, 0xB7, 0xA5, 0x43, 0xE5, 0xB7, 0xA6, 0x43, + 0xE5, 0xB7, 0xB1, 0x43, 0xE5, 0xB7, 0xBD, 0x43, + 0xE5, 0xB7, 0xBE, 0x43, 0xE5, 0xB8, 0xA8, 0x43, + 0xE5, 0xB8, 0xBD, 0x43, 0xE5, 0xB9, 0xA9, 0x43, + 0xE5, 0xB9, 0xB2, 0x43, 0xE5, 0xB9, 0xB4, 0x43, + // Bytes b00 - b3f + 0xE5, 0xB9, 0xBA, 0x43, 0xE5, 0xB9, 0xBC, 0x43, + 0xE5, 0xB9, 0xBF, 0x43, 0xE5, 0xBA, 0xA6, 0x43, + 0xE5, 0xBA, 0xB0, 0x43, 0xE5, 0xBA, 0xB3, 0x43, + 0xE5, 0xBA, 0xB6, 0x43, 0xE5, 0xBB, 0x89, 0x43, + 0xE5, 0xBB, 0x8A, 0x43, 0xE5, 0xBB, 0x92, 0x43, + 0xE5, 0xBB, 0x93, 0x43, 0xE5, 0xBB, 0x99, 0x43, + 0xE5, 0xBB, 0xAC, 0x43, 0xE5, 0xBB, 0xB4, 0x43, + 0xE5, 0xBB, 0xBE, 0x43, 0xE5, 0xBC, 0x84, 0x43, + // Bytes b40 - b7f + 0xE5, 0xBC, 0x8B, 0x43, 0xE5, 0xBC, 0x93, 0x43, + 0xE5, 0xBC, 0xA2, 0x43, 0xE5, 0xBD, 0x90, 0x43, + 0xE5, 0xBD, 0x93, 0x43, 0xE5, 0xBD, 0xA1, 0x43, + 0xE5, 0xBD, 0xA2, 0x43, 0xE5, 0xBD, 0xA9, 0x43, + 0xE5, 0xBD, 0xAB, 0x43, 0xE5, 0xBD, 0xB3, 0x43, + 0xE5, 0xBE, 0x8B, 0x43, 0xE5, 0xBE, 0x8C, 0x43, + 0xE5, 0xBE, 0x97, 0x43, 0xE5, 0xBE, 0x9A, 0x43, + 0xE5, 0xBE, 0xA9, 0x43, 0xE5, 0xBE, 0xAD, 0x43, + // Bytes b80 - bbf + 0xE5, 0xBF, 0x83, 0x43, 0xE5, 0xBF, 0x8D, 0x43, + 0xE5, 0xBF, 0x97, 0x43, 0xE5, 0xBF, 0xB5, 0x43, + 0xE5, 0xBF, 0xB9, 0x43, 0xE6, 0x80, 0x92, 0x43, + 0xE6, 0x80, 0x9C, 0x43, 0xE6, 0x81, 0xB5, 0x43, + 0xE6, 0x82, 0x81, 0x43, 0xE6, 0x82, 0x94, 0x43, + 0xE6, 0x83, 0x87, 0x43, 0xE6, 0x83, 0x98, 0x43, + 0xE6, 0x83, 0xA1, 0x43, 0xE6, 0x84, 0x88, 0x43, + 0xE6, 0x85, 0x84, 0x43, 0xE6, 0x85, 0x88, 0x43, + // Bytes bc0 - bff + 0xE6, 0x85, 0x8C, 0x43, 0xE6, 0x85, 0x8E, 0x43, + 0xE6, 0x85, 0xA0, 0x43, 0xE6, 0x85, 0xA8, 0x43, + 0xE6, 0x85, 0xBA, 0x43, 0xE6, 0x86, 0x8E, 0x43, + 0xE6, 0x86, 0x90, 0x43, 0xE6, 0x86, 0xA4, 0x43, + 0xE6, 0x86, 0xAF, 0x43, 0xE6, 0x86, 0xB2, 0x43, + 0xE6, 0x87, 0x9E, 0x43, 0xE6, 0x87, 0xB2, 0x43, + 0xE6, 0x87, 0xB6, 0x43, 0xE6, 0x88, 0x80, 0x43, + 0xE6, 0x88, 0x88, 0x43, 0xE6, 0x88, 0x90, 0x43, + // Bytes c00 - c3f + 0xE6, 0x88, 0x9B, 0x43, 0xE6, 0x88, 0xAE, 0x43, + 0xE6, 0x88, 0xB4, 0x43, 0xE6, 0x88, 0xB6, 0x43, + 0xE6, 0x89, 0x8B, 0x43, 0xE6, 0x89, 0x93, 0x43, + 0xE6, 0x89, 0x9D, 0x43, 0xE6, 0x8A, 0x95, 0x43, + 0xE6, 0x8A, 0xB1, 0x43, 0xE6, 0x8B, 0x89, 0x43, + 0xE6, 0x8B, 0x8F, 0x43, 0xE6, 0x8B, 0x93, 0x43, + 0xE6, 0x8B, 0x94, 0x43, 0xE6, 0x8B, 0xBC, 0x43, + 0xE6, 0x8B, 0xBE, 0x43, 0xE6, 0x8C, 0x87, 0x43, + // Bytes c40 - c7f + 0xE6, 0x8C, 0xBD, 0x43, 0xE6, 0x8D, 0x90, 0x43, + 0xE6, 0x8D, 0x95, 0x43, 0xE6, 0x8D, 0xA8, 0x43, + 0xE6, 0x8D, 0xBB, 0x43, 0xE6, 0x8E, 0x83, 0x43, + 0xE6, 0x8E, 0xA0, 0x43, 0xE6, 0x8E, 0xA9, 0x43, + 0xE6, 0x8F, 0x84, 0x43, 0xE6, 0x8F, 0x85, 0x43, + 0xE6, 0x8F, 0xA4, 0x43, 0xE6, 0x90, 0x9C, 0x43, + 0xE6, 0x90, 0xA2, 0x43, 0xE6, 0x91, 0x92, 0x43, + 0xE6, 0x91, 0xA9, 0x43, 0xE6, 0x91, 0xB7, 0x43, + // Bytes c80 - cbf + 0xE6, 0x91, 0xBE, 0x43, 0xE6, 0x92, 0x9A, 0x43, + 0xE6, 0x92, 0x9D, 0x43, 0xE6, 0x93, 0x84, 0x43, + 0xE6, 0x94, 0xAF, 0x43, 0xE6, 0x94, 0xB4, 0x43, + 0xE6, 0x95, 0x8F, 0x43, 0xE6, 0x95, 0x96, 0x43, + 0xE6, 0x95, 0xAC, 0x43, 0xE6, 0x95, 0xB8, 0x43, + 0xE6, 0x96, 0x87, 0x43, 0xE6, 0x96, 0x97, 0x43, + 0xE6, 0x96, 0x99, 0x43, 0xE6, 0x96, 0xA4, 0x43, + 0xE6, 0x96, 0xB0, 0x43, 0xE6, 0x96, 0xB9, 0x43, + // Bytes cc0 - cff + 0xE6, 0x97, 0x85, 0x43, 0xE6, 0x97, 0xA0, 0x43, + 0xE6, 0x97, 0xA2, 0x43, 0xE6, 0x97, 0xA3, 0x43, + 0xE6, 0x97, 0xA5, 0x43, 0xE6, 0x98, 0x93, 0x43, + 0xE6, 0x98, 0xA0, 0x43, 0xE6, 0x99, 0x89, 0x43, + 0xE6, 0x99, 0xB4, 0x43, 0xE6, 0x9A, 0x88, 0x43, + 0xE6, 0x9A, 0x91, 0x43, 0xE6, 0x9A, 0x9C, 0x43, + 0xE6, 0x9A, 0xB4, 0x43, 0xE6, 0x9B, 0x86, 0x43, + 0xE6, 0x9B, 0xB0, 0x43, 0xE6, 0x9B, 0xB4, 0x43, + // Bytes d00 - d3f + 0xE6, 0x9B, 0xB8, 0x43, 0xE6, 0x9C, 0x80, 0x43, + 0xE6, 0x9C, 0x88, 0x43, 0xE6, 0x9C, 0x89, 0x43, + 0xE6, 0x9C, 0x97, 0x43, 0xE6, 0x9C, 0x9B, 0x43, + 0xE6, 0x9C, 0xA1, 0x43, 0xE6, 0x9C, 0xA8, 0x43, + 0xE6, 0x9D, 0x8E, 0x43, 0xE6, 0x9D, 0x93, 0x43, + 0xE6, 0x9D, 0x96, 0x43, 0xE6, 0x9D, 0x9E, 0x43, + 0xE6, 0x9D, 0xBB, 0x43, 0xE6, 0x9E, 0x85, 0x43, + 0xE6, 0x9E, 0x97, 0x43, 0xE6, 0x9F, 0xB3, 0x43, + // Bytes d40 - d7f + 0xE6, 0x9F, 0xBA, 0x43, 0xE6, 0xA0, 0x97, 0x43, + 0xE6, 0xA0, 0x9F, 0x43, 0xE6, 0xA0, 0xAA, 0x43, + 0xE6, 0xA1, 0x92, 0x43, 0xE6, 0xA2, 0x81, 0x43, + 0xE6, 0xA2, 0x85, 0x43, 0xE6, 0xA2, 0x8E, 0x43, + 0xE6, 0xA2, 0xA8, 0x43, 0xE6, 0xA4, 0x94, 0x43, + 0xE6, 0xA5, 0x82, 0x43, 0xE6, 0xA6, 0xA3, 0x43, + 0xE6, 0xA7, 0xAA, 0x43, 0xE6, 0xA8, 0x82, 0x43, + 0xE6, 0xA8, 0x93, 0x43, 0xE6, 0xAA, 0xA8, 0x43, + // Bytes d80 - dbf + 0xE6, 0xAB, 0x93, 0x43, 0xE6, 0xAB, 0x9B, 0x43, + 0xE6, 0xAC, 0x84, 0x43, 0xE6, 0xAC, 0xA0, 0x43, + 0xE6, 0xAC, 0xA1, 0x43, 0xE6, 0xAD, 0x94, 0x43, + 0xE6, 0xAD, 0xA2, 0x43, 0xE6, 0xAD, 0xA3, 0x43, + 0xE6, 0xAD, 0xB2, 0x43, 0xE6, 0xAD, 0xB7, 0x43, + 0xE6, 0xAD, 0xB9, 0x43, 0xE6, 0xAE, 0x9F, 0x43, + 0xE6, 0xAE, 0xAE, 0x43, 0xE6, 0xAE, 0xB3, 0x43, + 0xE6, 0xAE, 0xBA, 0x43, 0xE6, 0xAE, 0xBB, 0x43, + // Bytes dc0 - dff + 0xE6, 0xAF, 0x8B, 0x43, 0xE6, 0xAF, 0x8D, 0x43, + 0xE6, 0xAF, 0x94, 0x43, 0xE6, 0xAF, 0x9B, 0x43, + 0xE6, 0xB0, 0x8F, 0x43, 0xE6, 0xB0, 0x94, 0x43, + 0xE6, 0xB0, 0xB4, 0x43, 0xE6, 0xB1, 0x8E, 0x43, + 0xE6, 0xB1, 0xA7, 0x43, 0xE6, 0xB2, 0x88, 0x43, + 0xE6, 0xB2, 0xBF, 0x43, 0xE6, 0xB3, 0x8C, 0x43, + 0xE6, 0xB3, 0x8D, 0x43, 0xE6, 0xB3, 0xA5, 0x43, + 0xE6, 0xB3, 0xA8, 0x43, 0xE6, 0xB4, 0x96, 0x43, + // Bytes e00 - e3f + 0xE6, 0xB4, 0x9B, 0x43, 0xE6, 0xB4, 0x9E, 0x43, + 0xE6, 0xB4, 0xB4, 0x43, 0xE6, 0xB4, 0xBE, 0x43, + 0xE6, 0xB5, 0x81, 0x43, 0xE6, 0xB5, 0xA9, 0x43, + 0xE6, 0xB5, 0xAA, 0x43, 0xE6, 0xB5, 0xB7, 0x43, + 0xE6, 0xB5, 0xB8, 0x43, 0xE6, 0xB6, 0x85, 0x43, + 0xE6, 0xB7, 0x8B, 0x43, 0xE6, 0xB7, 0x9A, 0x43, + 0xE6, 0xB7, 0xAA, 0x43, 0xE6, 0xB7, 0xB9, 0x43, + 0xE6, 0xB8, 0x9A, 0x43, 0xE6, 0xB8, 0xAF, 0x43, + // Bytes e40 - e7f + 0xE6, 0xB9, 0xAE, 0x43, 0xE6, 0xBA, 0x80, 0x43, + 0xE6, 0xBA, 0x9C, 0x43, 0xE6, 0xBA, 0xBA, 0x43, + 0xE6, 0xBB, 0x87, 0x43, 0xE6, 0xBB, 0x8B, 0x43, + 0xE6, 0xBB, 0x91, 0x43, 0xE6, 0xBB, 0x9B, 0x43, + 0xE6, 0xBC, 0x8F, 0x43, 0xE6, 0xBC, 0x94, 0x43, + 0xE6, 0xBC, 0xA2, 0x43, 0xE6, 0xBC, 0xA3, 0x43, + 0xE6, 0xBD, 0xAE, 0x43, 0xE6, 0xBF, 0x86, 0x43, + 0xE6, 0xBF, 0xAB, 0x43, 0xE6, 0xBF, 0xBE, 0x43, + // Bytes e80 - ebf + 0xE7, 0x80, 0x9B, 0x43, 0xE7, 0x80, 0x9E, 0x43, + 0xE7, 0x80, 0xB9, 0x43, 0xE7, 0x81, 0x8A, 0x43, + 0xE7, 0x81, 0xAB, 0x43, 0xE7, 0x81, 0xB0, 0x43, + 0xE7, 0x81, 0xB7, 0x43, 0xE7, 0x81, 0xBD, 0x43, + 0xE7, 0x82, 0x99, 0x43, 0xE7, 0x82, 0xAD, 0x43, + 0xE7, 0x83, 0x88, 0x43, 0xE7, 0x83, 0x99, 0x43, + 0xE7, 0x84, 0xA1, 0x43, 0xE7, 0x85, 0x85, 0x43, + 0xE7, 0x85, 0x89, 0x43, 0xE7, 0x85, 0xAE, 0x43, + // Bytes ec0 - eff + 0xE7, 0x86, 0x9C, 0x43, 0xE7, 0x87, 0x8E, 0x43, + 0xE7, 0x87, 0x90, 0x43, 0xE7, 0x88, 0x90, 0x43, + 0xE7, 0x88, 0x9B, 0x43, 0xE7, 0x88, 0xA8, 0x43, + 0xE7, 0x88, 0xAA, 0x43, 0xE7, 0x88, 0xAB, 0x43, + 0xE7, 0x88, 0xB5, 0x43, 0xE7, 0x88, 0xB6, 0x43, + 0xE7, 0x88, 0xBB, 0x43, 0xE7, 0x88, 0xBF, 0x43, + 0xE7, 0x89, 0x87, 0x43, 0xE7, 0x89, 0x90, 0x43, + 0xE7, 0x89, 0x99, 0x43, 0xE7, 0x89, 0x9B, 0x43, + // Bytes f00 - f3f + 0xE7, 0x89, 0xA2, 0x43, 0xE7, 0x89, 0xB9, 0x43, + 0xE7, 0x8A, 0x80, 0x43, 0xE7, 0x8A, 0x95, 0x43, + 0xE7, 0x8A, 0xAC, 0x43, 0xE7, 0x8A, 0xAF, 0x43, + 0xE7, 0x8B, 0x80, 0x43, 0xE7, 0x8B, 0xBC, 0x43, + 0xE7, 0x8C, 0xAA, 0x43, 0xE7, 0x8D, 0xB5, 0x43, + 0xE7, 0x8D, 0xBA, 0x43, 0xE7, 0x8E, 0x84, 0x43, + 0xE7, 0x8E, 0x87, 0x43, 0xE7, 0x8E, 0x89, 0x43, + 0xE7, 0x8E, 0x8B, 0x43, 0xE7, 0x8E, 0xA5, 0x43, + // Bytes f40 - f7f + 0xE7, 0x8E, 0xB2, 0x43, 0xE7, 0x8F, 0x9E, 0x43, + 0xE7, 0x90, 0x86, 0x43, 0xE7, 0x90, 0x89, 0x43, + 0xE7, 0x90, 0xA2, 0x43, 0xE7, 0x91, 0x87, 0x43, + 0xE7, 0x91, 0x9C, 0x43, 0xE7, 0x91, 0xA9, 0x43, + 0xE7, 0x91, 0xB1, 0x43, 0xE7, 0x92, 0x85, 0x43, + 0xE7, 0x92, 0x89, 0x43, 0xE7, 0x92, 0x98, 0x43, + 0xE7, 0x93, 0x8A, 0x43, 0xE7, 0x93, 0x9C, 0x43, + 0xE7, 0x93, 0xA6, 0x43, 0xE7, 0x94, 0x86, 0x43, + // Bytes f80 - fbf + 0xE7, 0x94, 0x98, 0x43, 0xE7, 0x94, 0x9F, 0x43, + 0xE7, 0x94, 0xA4, 0x43, 0xE7, 0x94, 0xA8, 0x43, + 0xE7, 0x94, 0xB0, 0x43, 0xE7, 0x94, 0xB2, 0x43, + 0xE7, 0x94, 0xB3, 0x43, 0xE7, 0x94, 0xB7, 0x43, + 0xE7, 0x94, 0xBB, 0x43, 0xE7, 0x94, 0xBE, 0x43, + 0xE7, 0x95, 0x99, 0x43, 0xE7, 0x95, 0xA5, 0x43, + 0xE7, 0x95, 0xB0, 0x43, 0xE7, 0x96, 0x8B, 0x43, + 0xE7, 0x96, 0x92, 0x43, 0xE7, 0x97, 0xA2, 0x43, + // Bytes fc0 - fff + 0xE7, 0x98, 0x90, 0x43, 0xE7, 0x98, 0x9D, 0x43, + 0xE7, 0x98, 0x9F, 0x43, 0xE7, 0x99, 0x82, 0x43, + 0xE7, 0x99, 0xA9, 0x43, 0xE7, 0x99, 0xB6, 0x43, + 0xE7, 0x99, 0xBD, 0x43, 0xE7, 0x9A, 0xAE, 0x43, + 0xE7, 0x9A, 0xBF, 0x43, 0xE7, 0x9B, 0x8A, 0x43, + 0xE7, 0x9B, 0x9B, 0x43, 0xE7, 0x9B, 0xA3, 0x43, + 0xE7, 0x9B, 0xA7, 0x43, 0xE7, 0x9B, 0xAE, 0x43, + 0xE7, 0x9B, 0xB4, 0x43, 0xE7, 0x9C, 0x81, 0x43, + // Bytes 1000 - 103f + 0xE7, 0x9C, 0x9E, 0x43, 0xE7, 0x9C, 0x9F, 0x43, + 0xE7, 0x9D, 0x80, 0x43, 0xE7, 0x9D, 0x8A, 0x43, + 0xE7, 0x9E, 0x8B, 0x43, 0xE7, 0x9E, 0xA7, 0x43, + 0xE7, 0x9F, 0x9B, 0x43, 0xE7, 0x9F, 0xA2, 0x43, + 0xE7, 0x9F, 0xB3, 0x43, 0xE7, 0xA1, 0x8E, 0x43, + 0xE7, 0xA1, 0xAB, 0x43, 0xE7, 0xA2, 0x8C, 0x43, + 0xE7, 0xA2, 0x91, 0x43, 0xE7, 0xA3, 0x8A, 0x43, + 0xE7, 0xA3, 0x8C, 0x43, 0xE7, 0xA3, 0xBB, 0x43, + // Bytes 1040 - 107f + 0xE7, 0xA4, 0xAA, 0x43, 0xE7, 0xA4, 0xBA, 0x43, + 0xE7, 0xA4, 0xBC, 0x43, 0xE7, 0xA4, 0xBE, 0x43, + 0xE7, 0xA5, 0x88, 0x43, 0xE7, 0xA5, 0x89, 0x43, + 0xE7, 0xA5, 0x90, 0x43, 0xE7, 0xA5, 0x96, 0x43, + 0xE7, 0xA5, 0x9D, 0x43, 0xE7, 0xA5, 0x9E, 0x43, + 0xE7, 0xA5, 0xA5, 0x43, 0xE7, 0xA5, 0xBF, 0x43, + 0xE7, 0xA6, 0x81, 0x43, 0xE7, 0xA6, 0x8D, 0x43, + 0xE7, 0xA6, 0x8E, 0x43, 0xE7, 0xA6, 0x8F, 0x43, + // Bytes 1080 - 10bf + 0xE7, 0xA6, 0xAE, 0x43, 0xE7, 0xA6, 0xB8, 0x43, + 0xE7, 0xA6, 0xBE, 0x43, 0xE7, 0xA7, 0x8A, 0x43, + 0xE7, 0xA7, 0x98, 0x43, 0xE7, 0xA7, 0xAB, 0x43, + 0xE7, 0xA8, 0x9C, 0x43, 0xE7, 0xA9, 0x80, 0x43, + 0xE7, 0xA9, 0x8A, 0x43, 0xE7, 0xA9, 0x8F, 0x43, + 0xE7, 0xA9, 0xB4, 0x43, 0xE7, 0xA9, 0xBA, 0x43, + 0xE7, 0xAA, 0x81, 0x43, 0xE7, 0xAA, 0xB1, 0x43, + 0xE7, 0xAB, 0x8B, 0x43, 0xE7, 0xAB, 0xAE, 0x43, + // Bytes 10c0 - 10ff + 0xE7, 0xAB, 0xB9, 0x43, 0xE7, 0xAC, 0xA0, 0x43, + 0xE7, 0xAE, 0x8F, 0x43, 0xE7, 0xAF, 0x80, 0x43, + 0xE7, 0xAF, 0x86, 0x43, 0xE7, 0xAF, 0x89, 0x43, + 0xE7, 0xB0, 0xBE, 0x43, 0xE7, 0xB1, 0xA0, 0x43, + 0xE7, 0xB1, 0xB3, 0x43, 0xE7, 0xB1, 0xBB, 0x43, + 0xE7, 0xB2, 0x92, 0x43, 0xE7, 0xB2, 0xBE, 0x43, + 0xE7, 0xB3, 0x92, 0x43, 0xE7, 0xB3, 0x96, 0x43, + 0xE7, 0xB3, 0xA3, 0x43, 0xE7, 0xB3, 0xA7, 0x43, + // Bytes 1100 - 113f + 0xE7, 0xB3, 0xA8, 0x43, 0xE7, 0xB3, 0xB8, 0x43, + 0xE7, 0xB4, 0x80, 0x43, 0xE7, 0xB4, 0x90, 0x43, + 0xE7, 0xB4, 0xA2, 0x43, 0xE7, 0xB4, 0xAF, 0x43, + 0xE7, 0xB5, 0x82, 0x43, 0xE7, 0xB5, 0x9B, 0x43, + 0xE7, 0xB5, 0xA3, 0x43, 0xE7, 0xB6, 0xA0, 0x43, + 0xE7, 0xB6, 0xBE, 0x43, 0xE7, 0xB7, 0x87, 0x43, + 0xE7, 0xB7, 0xB4, 0x43, 0xE7, 0xB8, 0x82, 0x43, + 0xE7, 0xB8, 0x89, 0x43, 0xE7, 0xB8, 0xB7, 0x43, + // Bytes 1140 - 117f + 0xE7, 0xB9, 0x81, 0x43, 0xE7, 0xB9, 0x85, 0x43, + 0xE7, 0xBC, 0xB6, 0x43, 0xE7, 0xBC, 0xBE, 0x43, + 0xE7, 0xBD, 0x91, 0x43, 0xE7, 0xBD, 0xB2, 0x43, + 0xE7, 0xBD, 0xB9, 0x43, 0xE7, 0xBD, 0xBA, 0x43, + 0xE7, 0xBE, 0x85, 0x43, 0xE7, 0xBE, 0x8A, 0x43, + 0xE7, 0xBE, 0x95, 0x43, 0xE7, 0xBE, 0x9A, 0x43, + 0xE7, 0xBE, 0xBD, 0x43, 0xE7, 0xBF, 0xBA, 0x43, + 0xE8, 0x80, 0x81, 0x43, 0xE8, 0x80, 0x85, 0x43, + // Bytes 1180 - 11bf + 0xE8, 0x80, 0x8C, 0x43, 0xE8, 0x80, 0x92, 0x43, + 0xE8, 0x80, 0xB3, 0x43, 0xE8, 0x81, 0x86, 0x43, + 0xE8, 0x81, 0xA0, 0x43, 0xE8, 0x81, 0xAF, 0x43, + 0xE8, 0x81, 0xB0, 0x43, 0xE8, 0x81, 0xBE, 0x43, + 0xE8, 0x81, 0xBF, 0x43, 0xE8, 0x82, 0x89, 0x43, + 0xE8, 0x82, 0x8B, 0x43, 0xE8, 0x82, 0xAD, 0x43, + 0xE8, 0x82, 0xB2, 0x43, 0xE8, 0x84, 0x83, 0x43, + 0xE8, 0x84, 0xBE, 0x43, 0xE8, 0x87, 0x98, 0x43, + // Bytes 11c0 - 11ff + 0xE8, 0x87, 0xA3, 0x43, 0xE8, 0x87, 0xA8, 0x43, + 0xE8, 0x87, 0xAA, 0x43, 0xE8, 0x87, 0xAD, 0x43, + 0xE8, 0x87, 0xB3, 0x43, 0xE8, 0x87, 0xBC, 0x43, + 0xE8, 0x88, 0x81, 0x43, 0xE8, 0x88, 0x84, 0x43, + 0xE8, 0x88, 0x8C, 0x43, 0xE8, 0x88, 0x98, 0x43, + 0xE8, 0x88, 0x9B, 0x43, 0xE8, 0x88, 0x9F, 0x43, + 0xE8, 0x89, 0xAE, 0x43, 0xE8, 0x89, 0xAF, 0x43, + 0xE8, 0x89, 0xB2, 0x43, 0xE8, 0x89, 0xB8, 0x43, + // Bytes 1200 - 123f + 0xE8, 0x89, 0xB9, 0x43, 0xE8, 0x8A, 0x8B, 0x43, + 0xE8, 0x8A, 0x91, 0x43, 0xE8, 0x8A, 0x9D, 0x43, + 0xE8, 0x8A, 0xB1, 0x43, 0xE8, 0x8A, 0xB3, 0x43, + 0xE8, 0x8A, 0xBD, 0x43, 0xE8, 0x8B, 0xA5, 0x43, + 0xE8, 0x8B, 0xA6, 0x43, 0xE8, 0x8C, 0x9D, 0x43, + 0xE8, 0x8C, 0xA3, 0x43, 0xE8, 0x8C, 0xB6, 0x43, + 0xE8, 0x8D, 0x92, 0x43, 0xE8, 0x8D, 0x93, 0x43, + 0xE8, 0x8D, 0xA3, 0x43, 0xE8, 0x8E, 0xAD, 0x43, + // Bytes 1240 - 127f + 0xE8, 0x8E, 0xBD, 0x43, 0xE8, 0x8F, 0x89, 0x43, + 0xE8, 0x8F, 0x8A, 0x43, 0xE8, 0x8F, 0x8C, 0x43, + 0xE8, 0x8F, 0x9C, 0x43, 0xE8, 0x8F, 0xA7, 0x43, + 0xE8, 0x8F, 0xAF, 0x43, 0xE8, 0x8F, 0xB1, 0x43, + 0xE8, 0x90, 0xBD, 0x43, 0xE8, 0x91, 0x89, 0x43, + 0xE8, 0x91, 0x97, 0x43, 0xE8, 0x93, 0xAE, 0x43, + 0xE8, 0x93, 0xB1, 0x43, 0xE8, 0x93, 0xB3, 0x43, + 0xE8, 0x93, 0xBC, 0x43, 0xE8, 0x94, 0x96, 0x43, + // Bytes 1280 - 12bf + 0xE8, 0x95, 0xA4, 0x43, 0xE8, 0x97, 0x8D, 0x43, + 0xE8, 0x97, 0xBA, 0x43, 0xE8, 0x98, 0x86, 0x43, + 0xE8, 0x98, 0x92, 0x43, 0xE8, 0x98, 0xAD, 0x43, + 0xE8, 0x98, 0xBF, 0x43, 0xE8, 0x99, 0x8D, 0x43, + 0xE8, 0x99, 0x90, 0x43, 0xE8, 0x99, 0x9C, 0x43, + 0xE8, 0x99, 0xA7, 0x43, 0xE8, 0x99, 0xA9, 0x43, + 0xE8, 0x99, 0xAB, 0x43, 0xE8, 0x9A, 0x88, 0x43, + 0xE8, 0x9A, 0xA9, 0x43, 0xE8, 0x9B, 0xA2, 0x43, + // Bytes 12c0 - 12ff + 0xE8, 0x9C, 0x8E, 0x43, 0xE8, 0x9C, 0xA8, 0x43, + 0xE8, 0x9D, 0xAB, 0x43, 0xE8, 0x9D, 0xB9, 0x43, + 0xE8, 0x9E, 0x86, 0x43, 0xE8, 0x9E, 0xBA, 0x43, + 0xE8, 0x9F, 0xA1, 0x43, 0xE8, 0xA0, 0x81, 0x43, + 0xE8, 0xA0, 0x9F, 0x43, 0xE8, 0xA1, 0x80, 0x43, + 0xE8, 0xA1, 0x8C, 0x43, 0xE8, 0xA1, 0xA0, 0x43, + 0xE8, 0xA1, 0xA3, 0x43, 0xE8, 0xA3, 0x82, 0x43, + 0xE8, 0xA3, 0x8F, 0x43, 0xE8, 0xA3, 0x97, 0x43, + // Bytes 1300 - 133f + 0xE8, 0xA3, 0x9E, 0x43, 0xE8, 0xA3, 0xA1, 0x43, + 0xE8, 0xA3, 0xB8, 0x43, 0xE8, 0xA3, 0xBA, 0x43, + 0xE8, 0xA4, 0x90, 0x43, 0xE8, 0xA5, 0x81, 0x43, + 0xE8, 0xA5, 0xA4, 0x43, 0xE8, 0xA5, 0xBE, 0x43, + 0xE8, 0xA6, 0x86, 0x43, 0xE8, 0xA6, 0x8B, 0x43, + 0xE8, 0xA6, 0x96, 0x43, 0xE8, 0xA7, 0x92, 0x43, + 0xE8, 0xA7, 0xA3, 0x43, 0xE8, 0xA8, 0x80, 0x43, + 0xE8, 0xAA, 0xA0, 0x43, 0xE8, 0xAA, 0xAA, 0x43, + // Bytes 1340 - 137f + 0xE8, 0xAA, 0xBF, 0x43, 0xE8, 0xAB, 0x8B, 0x43, + 0xE8, 0xAB, 0x92, 0x43, 0xE8, 0xAB, 0x96, 0x43, + 0xE8, 0xAB, 0xAD, 0x43, 0xE8, 0xAB, 0xB8, 0x43, + 0xE8, 0xAB, 0xBE, 0x43, 0xE8, 0xAC, 0x81, 0x43, + 0xE8, 0xAC, 0xB9, 0x43, 0xE8, 0xAD, 0x98, 0x43, + 0xE8, 0xAE, 0x80, 0x43, 0xE8, 0xAE, 0x8A, 0x43, + 0xE8, 0xB0, 0xB7, 0x43, 0xE8, 0xB1, 0x86, 0x43, + 0xE8, 0xB1, 0x88, 0x43, 0xE8, 0xB1, 0x95, 0x43, + // Bytes 1380 - 13bf + 0xE8, 0xB1, 0xB8, 0x43, 0xE8, 0xB2, 0x9D, 0x43, + 0xE8, 0xB2, 0xA1, 0x43, 0xE8, 0xB2, 0xA9, 0x43, + 0xE8, 0xB2, 0xAB, 0x43, 0xE8, 0xB3, 0x81, 0x43, + 0xE8, 0xB3, 0x82, 0x43, 0xE8, 0xB3, 0x87, 0x43, + 0xE8, 0xB3, 0x88, 0x43, 0xE8, 0xB3, 0x93, 0x43, + 0xE8, 0xB4, 0x88, 0x43, 0xE8, 0xB4, 0x9B, 0x43, + 0xE8, 0xB5, 0xA4, 0x43, 0xE8, 0xB5, 0xB0, 0x43, + 0xE8, 0xB5, 0xB7, 0x43, 0xE8, 0xB6, 0xB3, 0x43, + // Bytes 13c0 - 13ff + 0xE8, 0xB6, 0xBC, 0x43, 0xE8, 0xB7, 0x8B, 0x43, + 0xE8, 0xB7, 0xAF, 0x43, 0xE8, 0xB7, 0xB0, 0x43, + 0xE8, 0xBA, 0xAB, 0x43, 0xE8, 0xBB, 0x8A, 0x43, + 0xE8, 0xBB, 0x94, 0x43, 0xE8, 0xBC, 0xA6, 0x43, + 0xE8, 0xBC, 0xAA, 0x43, 0xE8, 0xBC, 0xB8, 0x43, + 0xE8, 0xBC, 0xBB, 0x43, 0xE8, 0xBD, 0xA2, 0x43, + 0xE8, 0xBE, 0x9B, 0x43, 0xE8, 0xBE, 0x9E, 0x43, + 0xE8, 0xBE, 0xB0, 0x43, 0xE8, 0xBE, 0xB5, 0x43, + // Bytes 1400 - 143f + 0xE8, 0xBE, 0xB6, 0x43, 0xE9, 0x80, 0xA3, 0x43, + 0xE9, 0x80, 0xB8, 0x43, 0xE9, 0x81, 0x8A, 0x43, + 0xE9, 0x81, 0xA9, 0x43, 0xE9, 0x81, 0xB2, 0x43, + 0xE9, 0x81, 0xBC, 0x43, 0xE9, 0x82, 0x8F, 0x43, + 0xE9, 0x82, 0x91, 0x43, 0xE9, 0x82, 0x94, 0x43, + 0xE9, 0x83, 0x8E, 0x43, 0xE9, 0x83, 0x9E, 0x43, + 0xE9, 0x83, 0xB1, 0x43, 0xE9, 0x83, 0xBD, 0x43, + 0xE9, 0x84, 0x91, 0x43, 0xE9, 0x84, 0x9B, 0x43, + // Bytes 1440 - 147f + 0xE9, 0x85, 0x89, 0x43, 0xE9, 0x85, 0x8D, 0x43, + 0xE9, 0x85, 0xAA, 0x43, 0xE9, 0x86, 0x99, 0x43, + 0xE9, 0x86, 0xB4, 0x43, 0xE9, 0x87, 0x86, 0x43, + 0xE9, 0x87, 0x8C, 0x43, 0xE9, 0x87, 0x8F, 0x43, + 0xE9, 0x87, 0x91, 0x43, 0xE9, 0x88, 0xB4, 0x43, + 0xE9, 0x88, 0xB8, 0x43, 0xE9, 0x89, 0xB6, 0x43, + 0xE9, 0x89, 0xBC, 0x43, 0xE9, 0x8B, 0x97, 0x43, + 0xE9, 0x8B, 0x98, 0x43, 0xE9, 0x8C, 0x84, 0x43, + // Bytes 1480 - 14bf + 0xE9, 0x8D, 0x8A, 0x43, 0xE9, 0x8F, 0xB9, 0x43, + 0xE9, 0x90, 0x95, 0x43, 0xE9, 0x95, 0xB7, 0x43, + 0xE9, 0x96, 0x80, 0x43, 0xE9, 0x96, 0x8B, 0x43, + 0xE9, 0x96, 0xAD, 0x43, 0xE9, 0x96, 0xB7, 0x43, + 0xE9, 0x98, 0x9C, 0x43, 0xE9, 0x98, 0xAE, 0x43, + 0xE9, 0x99, 0x8B, 0x43, 0xE9, 0x99, 0x8D, 0x43, + 0xE9, 0x99, 0xB5, 0x43, 0xE9, 0x99, 0xB8, 0x43, + 0xE9, 0x99, 0xBC, 0x43, 0xE9, 0x9A, 0x86, 0x43, + // Bytes 14c0 - 14ff + 0xE9, 0x9A, 0xA3, 0x43, 0xE9, 0x9A, 0xB6, 0x43, + 0xE9, 0x9A, 0xB7, 0x43, 0xE9, 0x9A, 0xB8, 0x43, + 0xE9, 0x9A, 0xB9, 0x43, 0xE9, 0x9B, 0x83, 0x43, + 0xE9, 0x9B, 0xA2, 0x43, 0xE9, 0x9B, 0xA3, 0x43, + 0xE9, 0x9B, 0xA8, 0x43, 0xE9, 0x9B, 0xB6, 0x43, + 0xE9, 0x9B, 0xB7, 0x43, 0xE9, 0x9C, 0xA3, 0x43, + 0xE9, 0x9C, 0xB2, 0x43, 0xE9, 0x9D, 0x88, 0x43, + 0xE9, 0x9D, 0x91, 0x43, 0xE9, 0x9D, 0x96, 0x43, + // Bytes 1500 - 153f + 0xE9, 0x9D, 0x9E, 0x43, 0xE9, 0x9D, 0xA2, 0x43, + 0xE9, 0x9D, 0xA9, 0x43, 0xE9, 0x9F, 0x8B, 0x43, + 0xE9, 0x9F, 0x9B, 0x43, 0xE9, 0x9F, 0xA0, 0x43, + 0xE9, 0x9F, 0xAD, 0x43, 0xE9, 0x9F, 0xB3, 0x43, + 0xE9, 0x9F, 0xBF, 0x43, 0xE9, 0xA0, 0x81, 0x43, + 0xE9, 0xA0, 0x85, 0x43, 0xE9, 0xA0, 0x8B, 0x43, + 0xE9, 0xA0, 0x98, 0x43, 0xE9, 0xA0, 0xA9, 0x43, + 0xE9, 0xA0, 0xBB, 0x43, 0xE9, 0xA1, 0x9E, 0x43, + // Bytes 1540 - 157f + 0xE9, 0xA2, 0xA8, 0x43, 0xE9, 0xA3, 0x9B, 0x43, + 0xE9, 0xA3, 0x9F, 0x43, 0xE9, 0xA3, 0xA2, 0x43, + 0xE9, 0xA3, 0xAF, 0x43, 0xE9, 0xA3, 0xBC, 0x43, + 0xE9, 0xA4, 0xA8, 0x43, 0xE9, 0xA4, 0xA9, 0x43, + 0xE9, 0xA6, 0x96, 0x43, 0xE9, 0xA6, 0x99, 0x43, + 0xE9, 0xA6, 0xA7, 0x43, 0xE9, 0xA6, 0xAC, 0x43, + 0xE9, 0xA7, 0x82, 0x43, 0xE9, 0xA7, 0xB1, 0x43, + 0xE9, 0xA7, 0xBE, 0x43, 0xE9, 0xA9, 0xAA, 0x43, + // Bytes 1580 - 15bf + 0xE9, 0xAA, 0xA8, 0x43, 0xE9, 0xAB, 0x98, 0x43, + 0xE9, 0xAB, 0x9F, 0x43, 0xE9, 0xAC, 0x92, 0x43, + 0xE9, 0xAC, 0xA5, 0x43, 0xE9, 0xAC, 0xAF, 0x43, + 0xE9, 0xAC, 0xB2, 0x43, 0xE9, 0xAC, 0xBC, 0x43, + 0xE9, 0xAD, 0x9A, 0x43, 0xE9, 0xAD, 0xAF, 0x43, + 0xE9, 0xB1, 0x80, 0x43, 0xE9, 0xB1, 0x97, 0x43, + 0xE9, 0xB3, 0xA5, 0x43, 0xE9, 0xB3, 0xBD, 0x43, + 0xE9, 0xB5, 0xA7, 0x43, 0xE9, 0xB6, 0xB4, 0x43, + // Bytes 15c0 - 15ff + 0xE9, 0xB7, 0xBA, 0x43, 0xE9, 0xB8, 0x9E, 0x43, + 0xE9, 0xB9, 0xB5, 0x43, 0xE9, 0xB9, 0xBF, 0x43, + 0xE9, 0xBA, 0x97, 0x43, 0xE9, 0xBA, 0x9F, 0x43, + 0xE9, 0xBA, 0xA5, 0x43, 0xE9, 0xBA, 0xBB, 0x43, + 0xE9, 0xBB, 0x83, 0x43, 0xE9, 0xBB, 0x8D, 0x43, + 0xE9, 0xBB, 0x8E, 0x43, 0xE9, 0xBB, 0x91, 0x43, + 0xE9, 0xBB, 0xB9, 0x43, 0xE9, 0xBB, 0xBD, 0x43, + 0xE9, 0xBB, 0xBE, 0x43, 0xE9, 0xBC, 0x85, 0x43, + // Bytes 1600 - 163f + 0xE9, 0xBC, 0x8E, 0x43, 0xE9, 0xBC, 0x8F, 0x43, + 0xE9, 0xBC, 0x93, 0x43, 0xE9, 0xBC, 0x96, 0x43, + 0xE9, 0xBC, 0xA0, 0x43, 0xE9, 0xBC, 0xBB, 0x43, + 0xE9, 0xBD, 0x83, 0x43, 0xE9, 0xBD, 0x8A, 0x43, + 0xE9, 0xBD, 0x92, 0x43, 0xE9, 0xBE, 0x8D, 0x43, + 0xE9, 0xBE, 0x8E, 0x43, 0xE9, 0xBE, 0x9C, 0x43, + 0xE9, 0xBE, 0x9F, 0x43, 0xE9, 0xBE, 0xA0, 0x43, + 0xEA, 0x9C, 0xA7, 0x43, 0xEA, 0x9D, 0xAF, 0x43, + // Bytes 1640 - 167f + 0xEA, 0xAC, 0xB7, 0x43, 0xEA, 0xAD, 0x92, 0x44, + 0xF0, 0xA0, 0x84, 0xA2, 0x44, 0xF0, 0xA0, 0x94, + 0x9C, 0x44, 0xF0, 0xA0, 0x94, 0xA5, 0x44, 0xF0, + 0xA0, 0x95, 0x8B, 0x44, 0xF0, 0xA0, 0x98, 0xBA, + 0x44, 0xF0, 0xA0, 0xA0, 0x84, 0x44, 0xF0, 0xA0, + 0xA3, 0x9E, 0x44, 0xF0, 0xA0, 0xA8, 0xAC, 0x44, + 0xF0, 0xA0, 0xAD, 0xA3, 0x44, 0xF0, 0xA1, 0x93, + 0xA4, 0x44, 0xF0, 0xA1, 0x9A, 0xA8, 0x44, 0xF0, + // Bytes 1680 - 16bf + 0xA1, 0x9B, 0xAA, 0x44, 0xF0, 0xA1, 0xA7, 0x88, + 0x44, 0xF0, 0xA1, 0xAC, 0x98, 0x44, 0xF0, 0xA1, + 0xB4, 0x8B, 0x44, 0xF0, 0xA1, 0xB7, 0xA4, 0x44, + 0xF0, 0xA1, 0xB7, 0xA6, 0x44, 0xF0, 0xA2, 0x86, + 0x83, 0x44, 0xF0, 0xA2, 0x86, 0x9F, 0x44, 0xF0, + 0xA2, 0x8C, 0xB1, 0x44, 0xF0, 0xA2, 0x9B, 0x94, + 0x44, 0xF0, 0xA2, 0xA1, 0x84, 0x44, 0xF0, 0xA2, + 0xA1, 0x8A, 0x44, 0xF0, 0xA2, 0xAC, 0x8C, 0x44, + // Bytes 16c0 - 16ff + 0xF0, 0xA2, 0xAF, 0xB1, 0x44, 0xF0, 0xA3, 0x80, + 0x8A, 0x44, 0xF0, 0xA3, 0x8A, 0xB8, 0x44, 0xF0, + 0xA3, 0x8D, 0x9F, 0x44, 0xF0, 0xA3, 0x8E, 0x93, + 0x44, 0xF0, 0xA3, 0x8E, 0x9C, 0x44, 0xF0, 0xA3, + 0x8F, 0x83, 0x44, 0xF0, 0xA3, 0x8F, 0x95, 0x44, + 0xF0, 0xA3, 0x91, 0xAD, 0x44, 0xF0, 0xA3, 0x9A, + 0xA3, 0x44, 0xF0, 0xA3, 0xA2, 0xA7, 0x44, 0xF0, + 0xA3, 0xAA, 0x8D, 0x44, 0xF0, 0xA3, 0xAB, 0xBA, + // Bytes 1700 - 173f + 0x44, 0xF0, 0xA3, 0xB2, 0xBC, 0x44, 0xF0, 0xA3, + 0xB4, 0x9E, 0x44, 0xF0, 0xA3, 0xBB, 0x91, 0x44, + 0xF0, 0xA3, 0xBD, 0x9E, 0x44, 0xF0, 0xA3, 0xBE, + 0x8E, 0x44, 0xF0, 0xA4, 0x89, 0xA3, 0x44, 0xF0, + 0xA4, 0x8B, 0xAE, 0x44, 0xF0, 0xA4, 0x8E, 0xAB, + 0x44, 0xF0, 0xA4, 0x98, 0x88, 0x44, 0xF0, 0xA4, + 0x9C, 0xB5, 0x44, 0xF0, 0xA4, 0xA0, 0x94, 0x44, + 0xF0, 0xA4, 0xB0, 0xB6, 0x44, 0xF0, 0xA4, 0xB2, + // Bytes 1740 - 177f + 0x92, 0x44, 0xF0, 0xA4, 0xBE, 0xA1, 0x44, 0xF0, + 0xA4, 0xBE, 0xB8, 0x44, 0xF0, 0xA5, 0x81, 0x84, + 0x44, 0xF0, 0xA5, 0x83, 0xB2, 0x44, 0xF0, 0xA5, + 0x83, 0xB3, 0x44, 0xF0, 0xA5, 0x84, 0x99, 0x44, + 0xF0, 0xA5, 0x84, 0xB3, 0x44, 0xF0, 0xA5, 0x89, + 0x89, 0x44, 0xF0, 0xA5, 0x90, 0x9D, 0x44, 0xF0, + 0xA5, 0x98, 0xA6, 0x44, 0xF0, 0xA5, 0x9A, 0x9A, + 0x44, 0xF0, 0xA5, 0x9B, 0x85, 0x44, 0xF0, 0xA5, + // Bytes 1780 - 17bf + 0xA5, 0xBC, 0x44, 0xF0, 0xA5, 0xAA, 0xA7, 0x44, + 0xF0, 0xA5, 0xAE, 0xAB, 0x44, 0xF0, 0xA5, 0xB2, + 0x80, 0x44, 0xF0, 0xA5, 0xB3, 0x90, 0x44, 0xF0, + 0xA5, 0xBE, 0x86, 0x44, 0xF0, 0xA6, 0x87, 0x9A, + 0x44, 0xF0, 0xA6, 0x88, 0xA8, 0x44, 0xF0, 0xA6, + 0x89, 0x87, 0x44, 0xF0, 0xA6, 0x8B, 0x99, 0x44, + 0xF0, 0xA6, 0x8C, 0xBE, 0x44, 0xF0, 0xA6, 0x93, + 0x9A, 0x44, 0xF0, 0xA6, 0x94, 0xA3, 0x44, 0xF0, + // Bytes 17c0 - 17ff + 0xA6, 0x96, 0xA8, 0x44, 0xF0, 0xA6, 0x9E, 0xA7, + 0x44, 0xF0, 0xA6, 0x9E, 0xB5, 0x44, 0xF0, 0xA6, + 0xAC, 0xBC, 0x44, 0xF0, 0xA6, 0xB0, 0xB6, 0x44, + 0xF0, 0xA6, 0xB3, 0x95, 0x44, 0xF0, 0xA6, 0xB5, + 0xAB, 0x44, 0xF0, 0xA6, 0xBC, 0xAC, 0x44, 0xF0, + 0xA6, 0xBE, 0xB1, 0x44, 0xF0, 0xA7, 0x83, 0x92, + 0x44, 0xF0, 0xA7, 0x8F, 0x8A, 0x44, 0xF0, 0xA7, + 0x99, 0xA7, 0x44, 0xF0, 0xA7, 0xA2, 0xAE, 0x44, + // Bytes 1800 - 183f + 0xF0, 0xA7, 0xA5, 0xA6, 0x44, 0xF0, 0xA7, 0xB2, + 0xA8, 0x44, 0xF0, 0xA7, 0xBB, 0x93, 0x44, 0xF0, + 0xA7, 0xBC, 0xAF, 0x44, 0xF0, 0xA8, 0x97, 0x92, + 0x44, 0xF0, 0xA8, 0x97, 0xAD, 0x44, 0xF0, 0xA8, + 0x9C, 0xAE, 0x44, 0xF0, 0xA8, 0xAF, 0xBA, 0x44, + 0xF0, 0xA8, 0xB5, 0xB7, 0x44, 0xF0, 0xA9, 0x85, + 0x85, 0x44, 0xF0, 0xA9, 0x87, 0x9F, 0x44, 0xF0, + 0xA9, 0x88, 0x9A, 0x44, 0xF0, 0xA9, 0x90, 0x8A, + // Bytes 1840 - 187f + 0x44, 0xF0, 0xA9, 0x92, 0x96, 0x44, 0xF0, 0xA9, + 0x96, 0xB6, 0x44, 0xF0, 0xA9, 0xAC, 0xB0, 0x44, + 0xF0, 0xAA, 0x83, 0x8E, 0x44, 0xF0, 0xAA, 0x84, + 0x85, 0x44, 0xF0, 0xAA, 0x88, 0x8E, 0x44, 0xF0, + 0xAA, 0x8A, 0x91, 0x44, 0xF0, 0xAA, 0x8E, 0x92, + 0x44, 0xF0, 0xAA, 0x98, 0x80, 0x42, 0x21, 0x21, + 0x42, 0x21, 0x3F, 0x42, 0x2E, 0x2E, 0x42, 0x30, + 0x2C, 0x42, 0x30, 0x2E, 0x42, 0x31, 0x2C, 0x42, + // Bytes 1880 - 18bf + 0x31, 0x2E, 0x42, 0x31, 0x30, 0x42, 0x31, 0x31, + 0x42, 0x31, 0x32, 0x42, 0x31, 0x33, 0x42, 0x31, + 0x34, 0x42, 0x31, 0x35, 0x42, 0x31, 0x36, 0x42, + 0x31, 0x37, 0x42, 0x31, 0x38, 0x42, 0x31, 0x39, + 0x42, 0x32, 0x2C, 0x42, 0x32, 0x2E, 0x42, 0x32, + 0x30, 0x42, 0x32, 0x31, 0x42, 0x32, 0x32, 0x42, + 0x32, 0x33, 0x42, 0x32, 0x34, 0x42, 0x32, 0x35, + 0x42, 0x32, 0x36, 0x42, 0x32, 0x37, 0x42, 0x32, + // Bytes 18c0 - 18ff + 0x38, 0x42, 0x32, 0x39, 0x42, 0x33, 0x2C, 0x42, + 0x33, 0x2E, 0x42, 0x33, 0x30, 0x42, 0x33, 0x31, + 0x42, 0x33, 0x32, 0x42, 0x33, 0x33, 0x42, 0x33, + 0x34, 0x42, 0x33, 0x35, 0x42, 0x33, 0x36, 0x42, + 0x33, 0x37, 0x42, 0x33, 0x38, 0x42, 0x33, 0x39, + 0x42, 0x34, 0x2C, 0x42, 0x34, 0x2E, 0x42, 0x34, + 0x30, 0x42, 0x34, 0x31, 0x42, 0x34, 0x32, 0x42, + 0x34, 0x33, 0x42, 0x34, 0x34, 0x42, 0x34, 0x35, + // Bytes 1900 - 193f + 0x42, 0x34, 0x36, 0x42, 0x34, 0x37, 0x42, 0x34, + 0x38, 0x42, 0x34, 0x39, 0x42, 0x35, 0x2C, 0x42, + 0x35, 0x2E, 0x42, 0x35, 0x30, 0x42, 0x36, 0x2C, + 0x42, 0x36, 0x2E, 0x42, 0x37, 0x2C, 0x42, 0x37, + 0x2E, 0x42, 0x38, 0x2C, 0x42, 0x38, 0x2E, 0x42, + 0x39, 0x2C, 0x42, 0x39, 0x2E, 0x42, 0x3D, 0x3D, + 0x42, 0x3F, 0x21, 0x42, 0x3F, 0x3F, 0x42, 0x41, + 0x55, 0x42, 0x42, 0x71, 0x42, 0x43, 0x44, 0x42, + // Bytes 1940 - 197f + 0x44, 0x4A, 0x42, 0x44, 0x5A, 0x42, 0x44, 0x7A, + 0x42, 0x47, 0x42, 0x42, 0x47, 0x79, 0x42, 0x48, + 0x50, 0x42, 0x48, 0x56, 0x42, 0x48, 0x67, 0x42, + 0x48, 0x7A, 0x42, 0x49, 0x49, 0x42, 0x49, 0x4A, + 0x42, 0x49, 0x55, 0x42, 0x49, 0x56, 0x42, 0x49, + 0x58, 0x42, 0x4B, 0x42, 0x42, 0x4B, 0x4B, 0x42, + 0x4B, 0x4D, 0x42, 0x4C, 0x4A, 0x42, 0x4C, 0x6A, + 0x42, 0x4D, 0x42, 0x42, 0x4D, 0x43, 0x42, 0x4D, + // Bytes 1980 - 19bf + 0x44, 0x42, 0x4D, 0x56, 0x42, 0x4D, 0x57, 0x42, + 0x4E, 0x4A, 0x42, 0x4E, 0x6A, 0x42, 0x4E, 0x6F, + 0x42, 0x50, 0x48, 0x42, 0x50, 0x52, 0x42, 0x50, + 0x61, 0x42, 0x52, 0x73, 0x42, 0x53, 0x44, 0x42, + 0x53, 0x4D, 0x42, 0x53, 0x53, 0x42, 0x53, 0x76, + 0x42, 0x54, 0x4D, 0x42, 0x56, 0x49, 0x42, 0x57, + 0x43, 0x42, 0x57, 0x5A, 0x42, 0x57, 0x62, 0x42, + 0x58, 0x49, 0x42, 0x63, 0x63, 0x42, 0x63, 0x64, + // Bytes 19c0 - 19ff + 0x42, 0x63, 0x6D, 0x42, 0x64, 0x42, 0x42, 0x64, + 0x61, 0x42, 0x64, 0x6C, 0x42, 0x64, 0x6D, 0x42, + 0x64, 0x7A, 0x42, 0x65, 0x56, 0x42, 0x66, 0x66, + 0x42, 0x66, 0x69, 0x42, 0x66, 0x6C, 0x42, 0x66, + 0x6D, 0x42, 0x68, 0x61, 0x42, 0x69, 0x69, 0x42, + 0x69, 0x6A, 0x42, 0x69, 0x6E, 0x42, 0x69, 0x76, + 0x42, 0x69, 0x78, 0x42, 0x6B, 0x41, 0x42, 0x6B, + 0x56, 0x42, 0x6B, 0x57, 0x42, 0x6B, 0x67, 0x42, + // Bytes 1a00 - 1a3f + 0x6B, 0x6C, 0x42, 0x6B, 0x6D, 0x42, 0x6B, 0x74, + 0x42, 0x6C, 0x6A, 0x42, 0x6C, 0x6D, 0x42, 0x6C, + 0x6E, 0x42, 0x6C, 0x78, 0x42, 0x6D, 0x32, 0x42, + 0x6D, 0x33, 0x42, 0x6D, 0x41, 0x42, 0x6D, 0x56, + 0x42, 0x6D, 0x57, 0x42, 0x6D, 0x62, 0x42, 0x6D, + 0x67, 0x42, 0x6D, 0x6C, 0x42, 0x6D, 0x6D, 0x42, + 0x6D, 0x73, 0x42, 0x6E, 0x41, 0x42, 0x6E, 0x46, + 0x42, 0x6E, 0x56, 0x42, 0x6E, 0x57, 0x42, 0x6E, + // Bytes 1a40 - 1a7f + 0x6A, 0x42, 0x6E, 0x6D, 0x42, 0x6E, 0x73, 0x42, + 0x6F, 0x56, 0x42, 0x70, 0x41, 0x42, 0x70, 0x46, + 0x42, 0x70, 0x56, 0x42, 0x70, 0x57, 0x42, 0x70, + 0x63, 0x42, 0x70, 0x73, 0x42, 0x73, 0x72, 0x42, + 0x73, 0x74, 0x42, 0x76, 0x69, 0x42, 0x78, 0x69, + 0x43, 0x28, 0x31, 0x29, 0x43, 0x28, 0x32, 0x29, + 0x43, 0x28, 0x33, 0x29, 0x43, 0x28, 0x34, 0x29, + 0x43, 0x28, 0x35, 0x29, 0x43, 0x28, 0x36, 0x29, + // Bytes 1a80 - 1abf + 0x43, 0x28, 0x37, 0x29, 0x43, 0x28, 0x38, 0x29, + 0x43, 0x28, 0x39, 0x29, 0x43, 0x28, 0x41, 0x29, + 0x43, 0x28, 0x42, 0x29, 0x43, 0x28, 0x43, 0x29, + 0x43, 0x28, 0x44, 0x29, 0x43, 0x28, 0x45, 0x29, + 0x43, 0x28, 0x46, 0x29, 0x43, 0x28, 0x47, 0x29, + 0x43, 0x28, 0x48, 0x29, 0x43, 0x28, 0x49, 0x29, + 0x43, 0x28, 0x4A, 0x29, 0x43, 0x28, 0x4B, 0x29, + 0x43, 0x28, 0x4C, 0x29, 0x43, 0x28, 0x4D, 0x29, + // Bytes 1ac0 - 1aff + 0x43, 0x28, 0x4E, 0x29, 0x43, 0x28, 0x4F, 0x29, + 0x43, 0x28, 0x50, 0x29, 0x43, 0x28, 0x51, 0x29, + 0x43, 0x28, 0x52, 0x29, 0x43, 0x28, 0x53, 0x29, + 0x43, 0x28, 0x54, 0x29, 0x43, 0x28, 0x55, 0x29, + 0x43, 0x28, 0x56, 0x29, 0x43, 0x28, 0x57, 0x29, + 0x43, 0x28, 0x58, 0x29, 0x43, 0x28, 0x59, 0x29, + 0x43, 0x28, 0x5A, 0x29, 0x43, 0x28, 0x61, 0x29, + 0x43, 0x28, 0x62, 0x29, 0x43, 0x28, 0x63, 0x29, + // Bytes 1b00 - 1b3f + 0x43, 0x28, 0x64, 0x29, 0x43, 0x28, 0x65, 0x29, + 0x43, 0x28, 0x66, 0x29, 0x43, 0x28, 0x67, 0x29, + 0x43, 0x28, 0x68, 0x29, 0x43, 0x28, 0x69, 0x29, + 0x43, 0x28, 0x6A, 0x29, 0x43, 0x28, 0x6B, 0x29, + 0x43, 0x28, 0x6C, 0x29, 0x43, 0x28, 0x6D, 0x29, + 0x43, 0x28, 0x6E, 0x29, 0x43, 0x28, 0x6F, 0x29, + 0x43, 0x28, 0x70, 0x29, 0x43, 0x28, 0x71, 0x29, + 0x43, 0x28, 0x72, 0x29, 0x43, 0x28, 0x73, 0x29, + // Bytes 1b40 - 1b7f + 0x43, 0x28, 0x74, 0x29, 0x43, 0x28, 0x75, 0x29, + 0x43, 0x28, 0x76, 0x29, 0x43, 0x28, 0x77, 0x29, + 0x43, 0x28, 0x78, 0x29, 0x43, 0x28, 0x79, 0x29, + 0x43, 0x28, 0x7A, 0x29, 0x43, 0x2E, 0x2E, 0x2E, + 0x43, 0x31, 0x30, 0x2E, 0x43, 0x31, 0x31, 0x2E, + 0x43, 0x31, 0x32, 0x2E, 0x43, 0x31, 0x33, 0x2E, + 0x43, 0x31, 0x34, 0x2E, 0x43, 0x31, 0x35, 0x2E, + 0x43, 0x31, 0x36, 0x2E, 0x43, 0x31, 0x37, 0x2E, + // Bytes 1b80 - 1bbf + 0x43, 0x31, 0x38, 0x2E, 0x43, 0x31, 0x39, 0x2E, + 0x43, 0x32, 0x30, 0x2E, 0x43, 0x3A, 0x3A, 0x3D, + 0x43, 0x3D, 0x3D, 0x3D, 0x43, 0x43, 0x6F, 0x2E, + 0x43, 0x46, 0x41, 0x58, 0x43, 0x47, 0x48, 0x7A, + 0x43, 0x47, 0x50, 0x61, 0x43, 0x49, 0x49, 0x49, + 0x43, 0x4C, 0x54, 0x44, 0x43, 0x4C, 0xC2, 0xB7, + 0x43, 0x4D, 0x48, 0x7A, 0x43, 0x4D, 0x50, 0x61, + 0x43, 0x4D, 0xCE, 0xA9, 0x43, 0x50, 0x50, 0x4D, + // Bytes 1bc0 - 1bff + 0x43, 0x50, 0x50, 0x56, 0x43, 0x50, 0x54, 0x45, + 0x43, 0x54, 0x45, 0x4C, 0x43, 0x54, 0x48, 0x7A, + 0x43, 0x56, 0x49, 0x49, 0x43, 0x58, 0x49, 0x49, + 0x43, 0x61, 0x2F, 0x63, 0x43, 0x61, 0x2F, 0x73, + 0x43, 0x61, 0xCA, 0xBE, 0x43, 0x62, 0x61, 0x72, + 0x43, 0x63, 0x2F, 0x6F, 0x43, 0x63, 0x2F, 0x75, + 0x43, 0x63, 0x61, 0x6C, 0x43, 0x63, 0x6D, 0x32, + 0x43, 0x63, 0x6D, 0x33, 0x43, 0x64, 0x6D, 0x32, + // Bytes 1c00 - 1c3f + 0x43, 0x64, 0x6D, 0x33, 0x43, 0x65, 0x72, 0x67, + 0x43, 0x66, 0x66, 0x69, 0x43, 0x66, 0x66, 0x6C, + 0x43, 0x67, 0x61, 0x6C, 0x43, 0x68, 0x50, 0x61, + 0x43, 0x69, 0x69, 0x69, 0x43, 0x6B, 0x48, 0x7A, + 0x43, 0x6B, 0x50, 0x61, 0x43, 0x6B, 0x6D, 0x32, + 0x43, 0x6B, 0x6D, 0x33, 0x43, 0x6B, 0xCE, 0xA9, + 0x43, 0x6C, 0x6F, 0x67, 0x43, 0x6C, 0xC2, 0xB7, + 0x43, 0x6D, 0x69, 0x6C, 0x43, 0x6D, 0x6D, 0x32, + // Bytes 1c40 - 1c7f + 0x43, 0x6D, 0x6D, 0x33, 0x43, 0x6D, 0x6F, 0x6C, + 0x43, 0x72, 0x61, 0x64, 0x43, 0x76, 0x69, 0x69, + 0x43, 0x78, 0x69, 0x69, 0x43, 0xC2, 0xB0, 0x43, + 0x43, 0xC2, 0xB0, 0x46, 0x43, 0xCA, 0xBC, 0x6E, + 0x43, 0xCE, 0xBC, 0x41, 0x43, 0xCE, 0xBC, 0x46, + 0x43, 0xCE, 0xBC, 0x56, 0x43, 0xCE, 0xBC, 0x57, + 0x43, 0xCE, 0xBC, 0x67, 0x43, 0xCE, 0xBC, 0x6C, + 0x43, 0xCE, 0xBC, 0x6D, 0x43, 0xCE, 0xBC, 0x73, + // Bytes 1c80 - 1cbf + 0x44, 0x28, 0x31, 0x30, 0x29, 0x44, 0x28, 0x31, + 0x31, 0x29, 0x44, 0x28, 0x31, 0x32, 0x29, 0x44, + 0x28, 0x31, 0x33, 0x29, 0x44, 0x28, 0x31, 0x34, + 0x29, 0x44, 0x28, 0x31, 0x35, 0x29, 0x44, 0x28, + 0x31, 0x36, 0x29, 0x44, 0x28, 0x31, 0x37, 0x29, + 0x44, 0x28, 0x31, 0x38, 0x29, 0x44, 0x28, 0x31, + 0x39, 0x29, 0x44, 0x28, 0x32, 0x30, 0x29, 0x44, + 0x30, 0xE7, 0x82, 0xB9, 0x44, 0x31, 0xE2, 0x81, + // Bytes 1cc0 - 1cff + 0x84, 0x44, 0x31, 0xE6, 0x97, 0xA5, 0x44, 0x31, + 0xE6, 0x9C, 0x88, 0x44, 0x31, 0xE7, 0x82, 0xB9, + 0x44, 0x32, 0xE6, 0x97, 0xA5, 0x44, 0x32, 0xE6, + 0x9C, 0x88, 0x44, 0x32, 0xE7, 0x82, 0xB9, 0x44, + 0x33, 0xE6, 0x97, 0xA5, 0x44, 0x33, 0xE6, 0x9C, + 0x88, 0x44, 0x33, 0xE7, 0x82, 0xB9, 0x44, 0x34, + 0xE6, 0x97, 0xA5, 0x44, 0x34, 0xE6, 0x9C, 0x88, + 0x44, 0x34, 0xE7, 0x82, 0xB9, 0x44, 0x35, 0xE6, + // Bytes 1d00 - 1d3f + 0x97, 0xA5, 0x44, 0x35, 0xE6, 0x9C, 0x88, 0x44, + 0x35, 0xE7, 0x82, 0xB9, 0x44, 0x36, 0xE6, 0x97, + 0xA5, 0x44, 0x36, 0xE6, 0x9C, 0x88, 0x44, 0x36, + 0xE7, 0x82, 0xB9, 0x44, 0x37, 0xE6, 0x97, 0xA5, + 0x44, 0x37, 0xE6, 0x9C, 0x88, 0x44, 0x37, 0xE7, + 0x82, 0xB9, 0x44, 0x38, 0xE6, 0x97, 0xA5, 0x44, + 0x38, 0xE6, 0x9C, 0x88, 0x44, 0x38, 0xE7, 0x82, + 0xB9, 0x44, 0x39, 0xE6, 0x97, 0xA5, 0x44, 0x39, + // Bytes 1d40 - 1d7f + 0xE6, 0x9C, 0x88, 0x44, 0x39, 0xE7, 0x82, 0xB9, + 0x44, 0x56, 0x49, 0x49, 0x49, 0x44, 0x61, 0x2E, + 0x6D, 0x2E, 0x44, 0x6B, 0x63, 0x61, 0x6C, 0x44, + 0x70, 0x2E, 0x6D, 0x2E, 0x44, 0x76, 0x69, 0x69, + 0x69, 0x44, 0xD5, 0xA5, 0xD6, 0x82, 0x44, 0xD5, + 0xB4, 0xD5, 0xA5, 0x44, 0xD5, 0xB4, 0xD5, 0xAB, + 0x44, 0xD5, 0xB4, 0xD5, 0xAD, 0x44, 0xD5, 0xB4, + 0xD5, 0xB6, 0x44, 0xD5, 0xBE, 0xD5, 0xB6, 0x44, + // Bytes 1d80 - 1dbf + 0xD7, 0x90, 0xD7, 0x9C, 0x44, 0xD8, 0xA7, 0xD9, + 0xB4, 0x44, 0xD8, 0xA8, 0xD8, 0xAC, 0x44, 0xD8, + 0xA8, 0xD8, 0xAD, 0x44, 0xD8, 0xA8, 0xD8, 0xAE, + 0x44, 0xD8, 0xA8, 0xD8, 0xB1, 0x44, 0xD8, 0xA8, + 0xD8, 0xB2, 0x44, 0xD8, 0xA8, 0xD9, 0x85, 0x44, + 0xD8, 0xA8, 0xD9, 0x86, 0x44, 0xD8, 0xA8, 0xD9, + 0x87, 0x44, 0xD8, 0xA8, 0xD9, 0x89, 0x44, 0xD8, + 0xA8, 0xD9, 0x8A, 0x44, 0xD8, 0xAA, 0xD8, 0xAC, + // Bytes 1dc0 - 1dff + 0x44, 0xD8, 0xAA, 0xD8, 0xAD, 0x44, 0xD8, 0xAA, + 0xD8, 0xAE, 0x44, 0xD8, 0xAA, 0xD8, 0xB1, 0x44, + 0xD8, 0xAA, 0xD8, 0xB2, 0x44, 0xD8, 0xAA, 0xD9, + 0x85, 0x44, 0xD8, 0xAA, 0xD9, 0x86, 0x44, 0xD8, + 0xAA, 0xD9, 0x87, 0x44, 0xD8, 0xAA, 0xD9, 0x89, + 0x44, 0xD8, 0xAA, 0xD9, 0x8A, 0x44, 0xD8, 0xAB, + 0xD8, 0xAC, 0x44, 0xD8, 0xAB, 0xD8, 0xB1, 0x44, + 0xD8, 0xAB, 0xD8, 0xB2, 0x44, 0xD8, 0xAB, 0xD9, + // Bytes 1e00 - 1e3f + 0x85, 0x44, 0xD8, 0xAB, 0xD9, 0x86, 0x44, 0xD8, + 0xAB, 0xD9, 0x87, 0x44, 0xD8, 0xAB, 0xD9, 0x89, + 0x44, 0xD8, 0xAB, 0xD9, 0x8A, 0x44, 0xD8, 0xAC, + 0xD8, 0xAD, 0x44, 0xD8, 0xAC, 0xD9, 0x85, 0x44, + 0xD8, 0xAC, 0xD9, 0x89, 0x44, 0xD8, 0xAC, 0xD9, + 0x8A, 0x44, 0xD8, 0xAD, 0xD8, 0xAC, 0x44, 0xD8, + 0xAD, 0xD9, 0x85, 0x44, 0xD8, 0xAD, 0xD9, 0x89, + 0x44, 0xD8, 0xAD, 0xD9, 0x8A, 0x44, 0xD8, 0xAE, + // Bytes 1e40 - 1e7f + 0xD8, 0xAC, 0x44, 0xD8, 0xAE, 0xD8, 0xAD, 0x44, + 0xD8, 0xAE, 0xD9, 0x85, 0x44, 0xD8, 0xAE, 0xD9, + 0x89, 0x44, 0xD8, 0xAE, 0xD9, 0x8A, 0x44, 0xD8, + 0xB3, 0xD8, 0xAC, 0x44, 0xD8, 0xB3, 0xD8, 0xAD, + 0x44, 0xD8, 0xB3, 0xD8, 0xAE, 0x44, 0xD8, 0xB3, + 0xD8, 0xB1, 0x44, 0xD8, 0xB3, 0xD9, 0x85, 0x44, + 0xD8, 0xB3, 0xD9, 0x87, 0x44, 0xD8, 0xB3, 0xD9, + 0x89, 0x44, 0xD8, 0xB3, 0xD9, 0x8A, 0x44, 0xD8, + // Bytes 1e80 - 1ebf + 0xB4, 0xD8, 0xAC, 0x44, 0xD8, 0xB4, 0xD8, 0xAD, + 0x44, 0xD8, 0xB4, 0xD8, 0xAE, 0x44, 0xD8, 0xB4, + 0xD8, 0xB1, 0x44, 0xD8, 0xB4, 0xD9, 0x85, 0x44, + 0xD8, 0xB4, 0xD9, 0x87, 0x44, 0xD8, 0xB4, 0xD9, + 0x89, 0x44, 0xD8, 0xB4, 0xD9, 0x8A, 0x44, 0xD8, + 0xB5, 0xD8, 0xAD, 0x44, 0xD8, 0xB5, 0xD8, 0xAE, + 0x44, 0xD8, 0xB5, 0xD8, 0xB1, 0x44, 0xD8, 0xB5, + 0xD9, 0x85, 0x44, 0xD8, 0xB5, 0xD9, 0x89, 0x44, + // Bytes 1ec0 - 1eff + 0xD8, 0xB5, 0xD9, 0x8A, 0x44, 0xD8, 0xB6, 0xD8, + 0xAC, 0x44, 0xD8, 0xB6, 0xD8, 0xAD, 0x44, 0xD8, + 0xB6, 0xD8, 0xAE, 0x44, 0xD8, 0xB6, 0xD8, 0xB1, + 0x44, 0xD8, 0xB6, 0xD9, 0x85, 0x44, 0xD8, 0xB6, + 0xD9, 0x89, 0x44, 0xD8, 0xB6, 0xD9, 0x8A, 0x44, + 0xD8, 0xB7, 0xD8, 0xAD, 0x44, 0xD8, 0xB7, 0xD9, + 0x85, 0x44, 0xD8, 0xB7, 0xD9, 0x89, 0x44, 0xD8, + 0xB7, 0xD9, 0x8A, 0x44, 0xD8, 0xB8, 0xD9, 0x85, + // Bytes 1f00 - 1f3f + 0x44, 0xD8, 0xB9, 0xD8, 0xAC, 0x44, 0xD8, 0xB9, + 0xD9, 0x85, 0x44, 0xD8, 0xB9, 0xD9, 0x89, 0x44, + 0xD8, 0xB9, 0xD9, 0x8A, 0x44, 0xD8, 0xBA, 0xD8, + 0xAC, 0x44, 0xD8, 0xBA, 0xD9, 0x85, 0x44, 0xD8, + 0xBA, 0xD9, 0x89, 0x44, 0xD8, 0xBA, 0xD9, 0x8A, + 0x44, 0xD9, 0x81, 0xD8, 0xAC, 0x44, 0xD9, 0x81, + 0xD8, 0xAD, 0x44, 0xD9, 0x81, 0xD8, 0xAE, 0x44, + 0xD9, 0x81, 0xD9, 0x85, 0x44, 0xD9, 0x81, 0xD9, + // Bytes 1f40 - 1f7f + 0x89, 0x44, 0xD9, 0x81, 0xD9, 0x8A, 0x44, 0xD9, + 0x82, 0xD8, 0xAD, 0x44, 0xD9, 0x82, 0xD9, 0x85, + 0x44, 0xD9, 0x82, 0xD9, 0x89, 0x44, 0xD9, 0x82, + 0xD9, 0x8A, 0x44, 0xD9, 0x83, 0xD8, 0xA7, 0x44, + 0xD9, 0x83, 0xD8, 0xAC, 0x44, 0xD9, 0x83, 0xD8, + 0xAD, 0x44, 0xD9, 0x83, 0xD8, 0xAE, 0x44, 0xD9, + 0x83, 0xD9, 0x84, 0x44, 0xD9, 0x83, 0xD9, 0x85, + 0x44, 0xD9, 0x83, 0xD9, 0x89, 0x44, 0xD9, 0x83, + // Bytes 1f80 - 1fbf + 0xD9, 0x8A, 0x44, 0xD9, 0x84, 0xD8, 0xA7, 0x44, + 0xD9, 0x84, 0xD8, 0xAC, 0x44, 0xD9, 0x84, 0xD8, + 0xAD, 0x44, 0xD9, 0x84, 0xD8, 0xAE, 0x44, 0xD9, + 0x84, 0xD9, 0x85, 0x44, 0xD9, 0x84, 0xD9, 0x87, + 0x44, 0xD9, 0x84, 0xD9, 0x89, 0x44, 0xD9, 0x84, + 0xD9, 0x8A, 0x44, 0xD9, 0x85, 0xD8, 0xA7, 0x44, + 0xD9, 0x85, 0xD8, 0xAC, 0x44, 0xD9, 0x85, 0xD8, + 0xAD, 0x44, 0xD9, 0x85, 0xD8, 0xAE, 0x44, 0xD9, + // Bytes 1fc0 - 1fff + 0x85, 0xD9, 0x85, 0x44, 0xD9, 0x85, 0xD9, 0x89, + 0x44, 0xD9, 0x85, 0xD9, 0x8A, 0x44, 0xD9, 0x86, + 0xD8, 0xAC, 0x44, 0xD9, 0x86, 0xD8, 0xAD, 0x44, + 0xD9, 0x86, 0xD8, 0xAE, 0x44, 0xD9, 0x86, 0xD8, + 0xB1, 0x44, 0xD9, 0x86, 0xD8, 0xB2, 0x44, 0xD9, + 0x86, 0xD9, 0x85, 0x44, 0xD9, 0x86, 0xD9, 0x86, + 0x44, 0xD9, 0x86, 0xD9, 0x87, 0x44, 0xD9, 0x86, + 0xD9, 0x89, 0x44, 0xD9, 0x86, 0xD9, 0x8A, 0x44, + // Bytes 2000 - 203f + 0xD9, 0x87, 0xD8, 0xAC, 0x44, 0xD9, 0x87, 0xD9, + 0x85, 0x44, 0xD9, 0x87, 0xD9, 0x89, 0x44, 0xD9, + 0x87, 0xD9, 0x8A, 0x44, 0xD9, 0x88, 0xD9, 0xB4, + 0x44, 0xD9, 0x8A, 0xD8, 0xAC, 0x44, 0xD9, 0x8A, + 0xD8, 0xAD, 0x44, 0xD9, 0x8A, 0xD8, 0xAE, 0x44, + 0xD9, 0x8A, 0xD8, 0xB1, 0x44, 0xD9, 0x8A, 0xD8, + 0xB2, 0x44, 0xD9, 0x8A, 0xD9, 0x85, 0x44, 0xD9, + 0x8A, 0xD9, 0x86, 0x44, 0xD9, 0x8A, 0xD9, 0x87, + // Bytes 2040 - 207f + 0x44, 0xD9, 0x8A, 0xD9, 0x89, 0x44, 0xD9, 0x8A, + 0xD9, 0x8A, 0x44, 0xD9, 0x8A, 0xD9, 0xB4, 0x44, + 0xDB, 0x87, 0xD9, 0xB4, 0x45, 0x28, 0xE1, 0x84, + 0x80, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x82, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x83, 0x29, 0x45, 0x28, + 0xE1, 0x84, 0x85, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x86, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x87, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x89, 0x29, 0x45, 0x28, + // Bytes 2080 - 20bf + 0xE1, 0x84, 0x8B, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x8C, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8E, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x8F, 0x29, 0x45, 0x28, + 0xE1, 0x84, 0x90, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x91, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x92, 0x29, + 0x45, 0x28, 0xE4, 0xB8, 0x80, 0x29, 0x45, 0x28, + 0xE4, 0xB8, 0x83, 0x29, 0x45, 0x28, 0xE4, 0xB8, + 0x89, 0x29, 0x45, 0x28, 0xE4, 0xB9, 0x9D, 0x29, + // Bytes 20c0 - 20ff + 0x45, 0x28, 0xE4, 0xBA, 0x8C, 0x29, 0x45, 0x28, + 0xE4, 0xBA, 0x94, 0x29, 0x45, 0x28, 0xE4, 0xBB, + 0xA3, 0x29, 0x45, 0x28, 0xE4, 0xBC, 0x81, 0x29, + 0x45, 0x28, 0xE4, 0xBC, 0x91, 0x29, 0x45, 0x28, + 0xE5, 0x85, 0xAB, 0x29, 0x45, 0x28, 0xE5, 0x85, + 0xAD, 0x29, 0x45, 0x28, 0xE5, 0x8A, 0xB4, 0x29, + 0x45, 0x28, 0xE5, 0x8D, 0x81, 0x29, 0x45, 0x28, + 0xE5, 0x8D, 0x94, 0x29, 0x45, 0x28, 0xE5, 0x90, + // Bytes 2100 - 213f + 0x8D, 0x29, 0x45, 0x28, 0xE5, 0x91, 0xBC, 0x29, + 0x45, 0x28, 0xE5, 0x9B, 0x9B, 0x29, 0x45, 0x28, + 0xE5, 0x9C, 0x9F, 0x29, 0x45, 0x28, 0xE5, 0xAD, + 0xA6, 0x29, 0x45, 0x28, 0xE6, 0x97, 0xA5, 0x29, + 0x45, 0x28, 0xE6, 0x9C, 0x88, 0x29, 0x45, 0x28, + 0xE6, 0x9C, 0x89, 0x29, 0x45, 0x28, 0xE6, 0x9C, + 0xA8, 0x29, 0x45, 0x28, 0xE6, 0xA0, 0xAA, 0x29, + 0x45, 0x28, 0xE6, 0xB0, 0xB4, 0x29, 0x45, 0x28, + // Bytes 2140 - 217f + 0xE7, 0x81, 0xAB, 0x29, 0x45, 0x28, 0xE7, 0x89, + 0xB9, 0x29, 0x45, 0x28, 0xE7, 0x9B, 0xA3, 0x29, + 0x45, 0x28, 0xE7, 0xA4, 0xBE, 0x29, 0x45, 0x28, + 0xE7, 0xA5, 0x9D, 0x29, 0x45, 0x28, 0xE7, 0xA5, + 0xAD, 0x29, 0x45, 0x28, 0xE8, 0x87, 0xAA, 0x29, + 0x45, 0x28, 0xE8, 0x87, 0xB3, 0x29, 0x45, 0x28, + 0xE8, 0xB2, 0xA1, 0x29, 0x45, 0x28, 0xE8, 0xB3, + 0x87, 0x29, 0x45, 0x28, 0xE9, 0x87, 0x91, 0x29, + // Bytes 2180 - 21bf + 0x45, 0x30, 0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, + 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x30, 0xE6, + 0x9C, 0x88, 0x45, 0x31, 0x30, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x31, 0xE6, 0x9C, 0x88, 0x45, 0x31, 0x31, 0xE7, + 0x82, 0xB9, 0x45, 0x31, 0x32, 0xE6, 0x97, 0xA5, + 0x45, 0x31, 0x32, 0xE6, 0x9C, 0x88, 0x45, 0x31, + 0x32, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x33, 0xE6, + // Bytes 21c0 - 21ff + 0x97, 0xA5, 0x45, 0x31, 0x33, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x34, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x35, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x35, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x36, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x36, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x37, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x37, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x38, 0xE6, 0x97, 0xA5, 0x45, 0x31, + // Bytes 2200 - 223f + 0x38, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x39, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x39, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0xE2, 0x81, 0x84, 0x32, 0x45, 0x31, + 0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, 0xE2, 0x81, + 0x84, 0x34, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x35, + 0x45, 0x31, 0xE2, 0x81, 0x84, 0x36, 0x45, 0x31, + 0xE2, 0x81, 0x84, 0x37, 0x45, 0x31, 0xE2, 0x81, + 0x84, 0x38, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x39, + // Bytes 2240 - 227f + 0x45, 0x32, 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x30, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x31, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0x31, 0xE7, 0x82, 0xB9, + 0x45, 0x32, 0x32, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x32, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x33, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0x33, 0xE7, 0x82, 0xB9, + 0x45, 0x32, 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x34, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x35, 0xE6, + // Bytes 2280 - 22bf + 0x97, 0xA5, 0x45, 0x32, 0x36, 0xE6, 0x97, 0xA5, + 0x45, 0x32, 0x37, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x38, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x39, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0xE2, 0x81, 0x84, 0x33, + 0x45, 0x32, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, + 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x33, 0x31, 0xE6, + 0x97, 0xA5, 0x45, 0x33, 0xE2, 0x81, 0x84, 0x34, + 0x45, 0x33, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, + // Bytes 22c0 - 22ff + 0xE2, 0x81, 0x84, 0x38, 0x45, 0x34, 0xE2, 0x81, + 0x84, 0x35, 0x45, 0x35, 0xE2, 0x81, 0x84, 0x36, + 0x45, 0x35, 0xE2, 0x81, 0x84, 0x38, 0x45, 0x37, + 0xE2, 0x81, 0x84, 0x38, 0x45, 0x41, 0xE2, 0x88, + 0x95, 0x6D, 0x45, 0x56, 0xE2, 0x88, 0x95, 0x6D, + 0x45, 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x46, 0x31, + 0xE2, 0x81, 0x84, 0x31, 0x30, 0x46, 0x43, 0xE2, + 0x88, 0x95, 0x6B, 0x67, 0x46, 0x6D, 0xE2, 0x88, + // Bytes 2300 - 233f + 0x95, 0x73, 0x32, 0x46, 0xD8, 0xA8, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD8, 0xA8, 0xD8, 0xAE, 0xD9, + 0x8A, 0x46, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x85, + 0x46, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0x46, + 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, + 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, 0xD8, 0xAA, + 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, + 0xAE, 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, + // Bytes 2340 - 237f + 0xD9, 0x89, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, + 0x8A, 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC, + 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0x46, + 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8, + 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAA, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD8, + 0xAD, 0xD9, 0x89, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, + // Bytes 2380 - 23bf + 0xAD, 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89, + 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, + 0xAD, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAD, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xB3, 0xD8, + 0xAC, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, + 0xD9, 0x89, 0x46, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, + 0xAC, 0x46, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, + // Bytes 23c0 - 23ff + 0x46, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x8A, 0x46, + 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8, + 0xB3, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, + 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, + 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, + 0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, + 0x8A, 0x46, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, + 0x46, 0xD8, 0xB4, 0xD9, 0x85, 0xD9, 0x85, 0x46, + // Bytes 2400 - 243f + 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, 0xAD, 0x46, 0xD8, + 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB5, + 0xD9, 0x84, 0xD9, 0x89, 0x46, 0xD8, 0xB5, 0xD9, + 0x84, 0xDB, 0x92, 0x46, 0xD8, 0xB5, 0xD9, 0x85, + 0xD9, 0x85, 0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, + 0x89, 0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, + 0x46, 0xD8, 0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0x46, + 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, + // Bytes 2440 - 247f + 0xB7, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB7, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xB9, 0xD8, + 0xAC, 0xD9, 0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, + 0xD9, 0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, + 0x89, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x8A, + 0x46, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x85, 0x46, + 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, + 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x81, + // Bytes 2480 - 24bf + 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x81, 0xD9, + 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x82, 0xD9, 0x84, + 0xDB, 0x92, 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD8, + 0xAD, 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x85, + 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, + 0x83, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x84, + 0xD8, 0xAC, 0xD8, 0xAC, 0x46, 0xD9, 0x84, 0xD8, + // Bytes 24c0 - 24ff + 0xAC, 0xD9, 0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAC, + 0xD9, 0x8A, 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, + 0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, + 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, + 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, + 0x84, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD9, 0x84, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, + 0xAC, 0xD8, 0xAD, 0x46, 0xD9, 0x85, 0xD8, 0xAC, + // Bytes 2500 - 253f + 0xD8, 0xAE, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, + 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, + 0x46, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, + 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, + 0x85, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x85, + 0xD8, 0xAE, 0xD8, 0xAC, 0x46, 0xD9, 0x85, 0xD8, + 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAE, + 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD9, 0x85, 0xD9, + // Bytes 2540 - 257f + 0x8A, 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, + 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0x46, + 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD9, + 0x86, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x86, + 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, 0x86, 0xD8, + 0xAD, 0xD9, 0x89, 0x46, 0xD9, 0x86, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, + 0x89, 0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, + // Bytes 2580 - 25bf + 0x46, 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0x46, + 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, + 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, + 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, + 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x85, + 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, + 0xA7, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAC, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAD, 0x46, + // Bytes 25c0 - 25ff + 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, 0x46, 0xD9, + 0x8A, 0xD9, 0x94, 0xD8, 0xB1, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xD8, 0xB2, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xD9, 0x86, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, + 0x87, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0x46, + 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x8A, 0x46, 0xD9, + // Bytes 2600 - 263f + 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xDB, 0x87, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xDB, 0x88, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xDB, 0x90, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, + 0x95, 0x46, 0xE0, 0xB9, 0x8D, 0xE0, 0xB8, 0xB2, + 0x46, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0x99, 0x46, + 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0xA1, 0x46, 0xE0, + 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, 0x46, 0xE0, 0xBD, + // Bytes 2640 - 267f + 0x80, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, 0xBD, 0x82, + 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x8C, 0xE0, + 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, + 0xB7, 0x46, 0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, + 0x46, 0xE0, 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x46, + 0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, + 0xBE, 0x92, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, + 0x9C, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA1, + // Bytes 2680 - 26bf + 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA6, 0xE0, + 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, + 0xB7, 0x46, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0x46, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x46, + 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x46, 0xE2, + 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0x46, 0xE3, 0x81, + 0xBB, 0xE3, 0x81, 0x8B, 0x46, 0xE3, 0x82, 0x88, + 0xE3, 0x82, 0x8A, 0x46, 0xE3, 0x82, 0xAD, 0xE3, + // Bytes 26c0 - 26ff + 0x83, 0xAD, 0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x82, + 0xB3, 0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, + 0x46, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x46, + 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8E, 0x46, 0xE3, + 0x83, 0x9B, 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83, + 0x9F, 0xE3, 0x83, 0xAA, 0x46, 0xE3, 0x83, 0xAA, + 0xE3, 0x83, 0xA9, 0x46, 0xE3, 0x83, 0xAC, 0xE3, + 0x83, 0xA0, 0x46, 0xE5, 0xA4, 0xA7, 0xE6, 0xAD, + // Bytes 2700 - 273f + 0xA3, 0x46, 0xE5, 0xB9, 0xB3, 0xE6, 0x88, 0x90, + 0x46, 0xE6, 0x98, 0x8E, 0xE6, 0xB2, 0xBB, 0x46, + 0xE6, 0x98, 0xAD, 0xE5, 0x92, 0x8C, 0x47, 0x72, + 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x47, 0xE3, + 0x80, 0x94, 0x53, 0xE3, 0x80, 0x95, 0x48, 0x28, + 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x29, + 0x48, 0x28, 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, + // Bytes 2740 - 277f + 0x29, 0x48, 0x28, 0xE1, 0x84, 0x85, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x86, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x87, + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x89, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, + 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, + 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xAE, 0x29, + // Bytes 2780 - 27bf + 0x48, 0x28, 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, + 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8F, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x90, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x91, + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x92, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x72, 0x61, + 0x64, 0xE2, 0x88, 0x95, 0x73, 0x32, 0x48, 0xD8, + 0xA7, 0xD9, 0x83, 0xD8, 0xA8, 0xD8, 0xB1, 0x48, + // Bytes 27c0 - 27ff + 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x87, + 0x48, 0xD8, 0xB1, 0xD8, 0xB3, 0xD9, 0x88, 0xD9, + 0x84, 0x48, 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, + 0xD9, 0x84, 0x48, 0xD8, 0xB5, 0xD9, 0x84, 0xD8, + 0xB9, 0xD9, 0x85, 0x48, 0xD8, 0xB9, 0xD9, 0x84, + 0xD9, 0x8A, 0xD9, 0x87, 0x48, 0xD9, 0x85, 0xD8, + 0xAD, 0xD9, 0x85, 0xD8, 0xAF, 0x48, 0xD9, 0x88, + 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x49, 0xE2, + // Bytes 2800 - 283f + 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0x49, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, + 0x80, 0xB5, 0x49, 0xE2, 0x88, 0xAB, 0xE2, 0x88, + 0xAB, 0xE2, 0x88, 0xAB, 0x49, 0xE2, 0x88, 0xAE, + 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0x49, 0xE3, + 0x80, 0x94, 0xE4, 0xB8, 0x89, 0xE3, 0x80, 0x95, + 0x49, 0xE3, 0x80, 0x94, 0xE4, 0xBA, 0x8C, 0xE3, + 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE5, 0x8B, + // Bytes 2840 - 287f + 0x9D, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, + 0xE5, 0xAE, 0x89, 0xE3, 0x80, 0x95, 0x49, 0xE3, + 0x80, 0x94, 0xE6, 0x89, 0x93, 0xE3, 0x80, 0x95, + 0x49, 0xE3, 0x80, 0x94, 0xE6, 0x95, 0x97, 0xE3, + 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6, 0x9C, + 0xAC, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, + 0xE7, 0x82, 0xB9, 0xE3, 0x80, 0x95, 0x49, 0xE3, + 0x80, 0x94, 0xE7, 0x9B, 0x97, 0xE3, 0x80, 0x95, + // Bytes 2880 - 28bf + 0x49, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xAB, 0x49, 0xE3, 0x82, 0xA4, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x81, 0x49, 0xE3, 0x82, 0xA6, + 0xE3, 0x82, 0xA9, 0xE3, 0x83, 0xB3, 0x49, 0xE3, + 0x82, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, + 0x49, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xA0, 0x49, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xAA, 0x49, 0xE3, 0x82, 0xB1, + // Bytes 28c0 - 28ff + 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, 0x49, 0xE3, + 0x82, 0xB3, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x8A, + 0x49, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, + 0x83, 0x81, 0x49, 0xE3, 0x82, 0xBB, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0x49, 0xE3, 0x83, 0x86, + 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xB7, 0x49, 0xE3, + 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, + 0x49, 0xE3, 0x83, 0x8E, 0xE3, 0x83, 0x83, 0xE3, + // Bytes 2900 - 293f + 0x83, 0x88, 0x49, 0xE3, 0x83, 0x8F, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0x84, 0x49, 0xE3, 0x83, 0x92, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x49, 0xE3, + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB3, + 0x49, 0xE3, 0x83, 0x95, 0xE3, 0x83, 0xA9, 0xE3, + 0x83, 0xB3, 0x49, 0xE3, 0x83, 0x98, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xBD, 0x49, 0xE3, 0x83, 0x98, + 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x84, 0x49, 0xE3, + // Bytes 2940 - 297f + 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, + 0x49, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xB3, 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x9E, + 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x8F, 0x49, 0xE3, + 0x83, 0x9E, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xAF, + 0x49, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xAB, 0x49, 0xE3, 0x83, 0xA6, 0xE3, 0x82, + // Bytes 2980 - 29bf + 0xA2, 0xE3, 0x83, 0xB3, 0x49, 0xE3, 0x83, 0xAF, + 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x4C, 0xE2, + 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0xE2, 0x80, 0xB2, 0x4C, 0xE2, 0x88, 0xAB, 0xE2, + 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, + 0x4C, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xAB, 0xE3, + 0x83, 0x95, 0xE3, 0x82, 0xA1, 0x4C, 0xE3, 0x82, + 0xA8, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, + // Bytes 29c0 - 29ff + 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x4C, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x9E, 0x4C, 0xE3, 0x82, 0xAB, + 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x88, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xAD, + 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, + 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x8B, + // Bytes 2a00 - 2a3f + 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, + 0x83, 0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, + 0x4C, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x4C, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0x8D, 0x4C, 0xE3, 0x82, 0xB5, 0xE3, 0x82, + 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x4C, + 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + // Bytes 2a40 - 2a7f + 0xBC, 0xE3, 0x82, 0xB9, 0x4C, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0x84, 0x4C, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, + 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, + 0x83, 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, 0xBC, + 0xE3, 0x83, 0x88, 0x4C, 0xE3, 0x83, 0x98, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBF, + 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, + // Bytes 2a80 - 2abf + 0x83, 0x8B, 0xE3, 0x83, 0x92, 0x4C, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, 0xE3, + 0x82, 0xB9, 0x4C, 0xE3, 0x83, 0x9B, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x88, 0x4C, + 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xAD, 0x4C, 0xE3, 0x83, 0x9F, + 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, + 0xB3, 0x4C, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC, + // Bytes 2ac0 - 2aff + 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, + 0x83, 0xAA, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, + 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0xAB, 0xE3, + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, + 0x4C, 0xE6, 0xA0, 0xAA, 0xE5, 0xBC, 0x8F, 0xE4, + 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x4E, 0x28, 0xE1, + 0x84, 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x92, + 0xE1, 0x85, 0xAE, 0x29, 0x4F, 0xD8, 0xAC, 0xD9, + // Bytes 2b00 - 2b3f + 0x84, 0x20, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xA7, + 0xD9, 0x84, 0xD9, 0x87, 0x4F, 0xE3, 0x82, 0xA2, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x82, 0xA2, + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xA2, 0x4F, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAF, 0xE3, 0x83, + 0x83, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x82, 0xB5, + // Bytes 2b40 - 2b7f + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xA0, 0x4F, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0xAC, 0xE3, 0x83, 0xAB, 0x4F, 0xE3, 0x83, 0x98, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xBF, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xAB, 0x4F, 0xE3, 0x83, 0x9B, + 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA4, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x83, 0x9E, + // Bytes 2b80 - 2bbf + 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7, 0xE3, 0x83, + 0xA7, 0xE3, 0x83, 0xB3, 0x4F, 0xE3, 0x83, 0xA1, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0x88, 0xE3, 0x83, 0xB3, 0x4F, 0xE3, 0x83, 0xAB, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x95, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0x51, 0x28, 0xE1, 0x84, + 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xA5, 0xE1, 0x86, 0xAB, 0x29, 0x52, 0xE3, + // Bytes 2bc0 - 2bff + 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, + 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xBC, 0x52, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xA9, 0xE3, 0x83, 0xA0, 0x52, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x52, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + // Bytes 2c00 - 2c3f + 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0x88, 0xE3, + 0x83, 0xB3, 0x52, 0xE3, 0x82, 0xAF, 0xE3, 0x83, + 0xAB, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0xE3, + 0x82, 0xA4, 0xE3, 0x83, 0xAD, 0x52, 0xE3, 0x83, + 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, + 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, + 0x52, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, + 0x82, 0xA2, 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x88, + // Bytes 2c40 - 2c7f + 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x83, 0x95, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0x83, 0xE3, 0x82, 0xB7, + 0xE3, 0x82, 0xA7, 0xE3, 0x83, 0xAB, 0x52, 0xE3, + 0x83, 0x9F, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0xAB, 0x52, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xB3, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xB1, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xB3, 0x61, 0xD8, 0xB5, 0xD9, + // Bytes 2c80 - 2cbf + 0x84, 0xD9, 0x89, 0x20, 0xD8, 0xA7, 0xD9, 0x84, + 0xD9, 0x84, 0xD9, 0x87, 0x20, 0xD8, 0xB9, 0xD9, + 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x20, 0xD9, 0x88, + 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x06, 0xE0, + 0xA7, 0x87, 0xE0, 0xA6, 0xBE, 0x01, 0x06, 0xE0, + 0xA7, 0x87, 0xE0, 0xA7, 0x97, 0x01, 0x06, 0xE0, + 0xAD, 0x87, 0xE0, 0xAC, 0xBE, 0x01, 0x06, 0xE0, + 0xAD, 0x87, 0xE0, 0xAD, 0x96, 0x01, 0x06, 0xE0, + // Bytes 2cc0 - 2cff + 0xAD, 0x87, 0xE0, 0xAD, 0x97, 0x01, 0x06, 0xE0, + 0xAE, 0x92, 0xE0, 0xAF, 0x97, 0x01, 0x06, 0xE0, + 0xAF, 0x86, 0xE0, 0xAE, 0xBE, 0x01, 0x06, 0xE0, + 0xAF, 0x86, 0xE0, 0xAF, 0x97, 0x01, 0x06, 0xE0, + 0xAF, 0x87, 0xE0, 0xAE, 0xBE, 0x01, 0x06, 0xE0, + 0xB2, 0xBF, 0xE0, 0xB3, 0x95, 0x01, 0x06, 0xE0, + 0xB3, 0x86, 0xE0, 0xB3, 0x95, 0x01, 0x06, 0xE0, + 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0x01, 0x06, 0xE0, + // Bytes 2d00 - 2d3f + 0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0x01, 0x06, 0xE0, + 0xB5, 0x86, 0xE0, 0xB5, 0x97, 0x01, 0x06, 0xE0, + 0xB5, 0x87, 0xE0, 0xB4, 0xBE, 0x01, 0x06, 0xE0, + 0xB7, 0x99, 0xE0, 0xB7, 0x9F, 0x01, 0x06, 0xE1, + 0x80, 0xA5, 0xE1, 0x80, 0xAE, 0x01, 0x06, 0xE1, + 0xAC, 0x85, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x87, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x89, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + // Bytes 2d40 - 2d7f + 0xAC, 0x8B, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x8D, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x91, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBA, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBC, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBE, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBF, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAD, 0x82, 0xE1, 0xAC, 0xB5, 0x01, 0x08, 0xF0, + // Bytes 2d80 - 2dbf + 0x91, 0x84, 0xB1, 0xF0, 0x91, 0x84, 0xA7, 0x01, + 0x08, 0xF0, 0x91, 0x84, 0xB2, 0xF0, 0x91, 0x84, + 0xA7, 0x01, 0x08, 0xF0, 0x91, 0x8D, 0x87, 0xF0, + 0x91, 0x8C, 0xBE, 0x01, 0x08, 0xF0, 0x91, 0x8D, + 0x87, 0xF0, 0x91, 0x8D, 0x97, 0x01, 0x08, 0xF0, + 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xB0, 0x01, + 0x08, 0xF0, 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, + 0xBA, 0x01, 0x08, 0xF0, 0x91, 0x92, 0xB9, 0xF0, + // Bytes 2dc0 - 2dff + 0x91, 0x92, 0xBD, 0x01, 0x08, 0xF0, 0x91, 0x96, + 0xB8, 0xF0, 0x91, 0x96, 0xAF, 0x01, 0x08, 0xF0, + 0x91, 0x96, 0xB9, 0xF0, 0x91, 0x96, 0xAF, 0x01, + 0x09, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, + 0xB3, 0x95, 0x02, 0x09, 0xE0, 0xB7, 0x99, 0xE0, + 0xB7, 0x8F, 0xE0, 0xB7, 0x8A, 0x12, 0x44, 0x44, + 0x5A, 0xCC, 0x8C, 0xC9, 0x44, 0x44, 0x7A, 0xCC, + 0x8C, 0xC9, 0x44, 0x64, 0x7A, 0xCC, 0x8C, 0xC9, + // Bytes 2e00 - 2e3f + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xC9, + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xC9, + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xB5, + 0x46, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x01, + // Bytes 2e40 - 2e7f + 0x46, 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x89, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0x01, + 0x46, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x01, + // Bytes 2e80 - 2ebf + 0x46, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0x01, + 0x49, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, + 0x82, 0x99, 0x0D, 0x4C, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, + 0x01, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0D, 0x4C, + 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + // Bytes 2ec0 - 2eff + 0x9B, 0xE3, 0x82, 0x9A, 0x0D, 0x4C, 0xE3, 0x83, + 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, + 0x82, 0x99, 0x0D, 0x4F, 0xE1, 0x84, 0x8E, 0xE1, + 0x85, 0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, + 0xE1, 0x85, 0xA9, 0x01, 0x4F, 0xE3, 0x82, 0xA4, + 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, + 0xAF, 0xE3, 0x82, 0x99, 0x0D, 0x4F, 0xE3, 0x82, + 0xB7, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, + // Bytes 2f00 - 2f3f + 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x0D, 0x4F, 0xE3, + 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, + 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x0D, 0x4F, + 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x52, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, + 0x82, 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, + 0xE3, 0x82, 0x99, 0x0D, 0x52, 0xE3, 0x83, 0x95, + // Bytes 2f40 - 2f7f + 0xE3, 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, + 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x86, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x01, + 0x86, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8F, 0x01, + 0x03, 0x3C, 0xCC, 0xB8, 0x05, 0x03, 0x3D, 0xCC, + 0xB8, 0x05, 0x03, 0x3E, 0xCC, 0xB8, 0x05, 0x03, + 0x41, 0xCC, 0x80, 0xC9, 0x03, 0x41, 0xCC, 0x81, + 0xC9, 0x03, 0x41, 0xCC, 0x83, 0xC9, 0x03, 0x41, + // Bytes 2f80 - 2fbf + 0xCC, 0x84, 0xC9, 0x03, 0x41, 0xCC, 0x89, 0xC9, + 0x03, 0x41, 0xCC, 0x8C, 0xC9, 0x03, 0x41, 0xCC, + 0x8F, 0xC9, 0x03, 0x41, 0xCC, 0x91, 0xC9, 0x03, + 0x41, 0xCC, 0xA5, 0xB5, 0x03, 0x41, 0xCC, 0xA8, + 0xA5, 0x03, 0x42, 0xCC, 0x87, 0xC9, 0x03, 0x42, + 0xCC, 0xA3, 0xB5, 0x03, 0x42, 0xCC, 0xB1, 0xB5, + 0x03, 0x43, 0xCC, 0x81, 0xC9, 0x03, 0x43, 0xCC, + 0x82, 0xC9, 0x03, 0x43, 0xCC, 0x87, 0xC9, 0x03, + // Bytes 2fc0 - 2fff + 0x43, 0xCC, 0x8C, 0xC9, 0x03, 0x44, 0xCC, 0x87, + 0xC9, 0x03, 0x44, 0xCC, 0x8C, 0xC9, 0x03, 0x44, + 0xCC, 0xA3, 0xB5, 0x03, 0x44, 0xCC, 0xA7, 0xA5, + 0x03, 0x44, 0xCC, 0xAD, 0xB5, 0x03, 0x44, 0xCC, + 0xB1, 0xB5, 0x03, 0x45, 0xCC, 0x80, 0xC9, 0x03, + 0x45, 0xCC, 0x81, 0xC9, 0x03, 0x45, 0xCC, 0x83, + 0xC9, 0x03, 0x45, 0xCC, 0x86, 0xC9, 0x03, 0x45, + 0xCC, 0x87, 0xC9, 0x03, 0x45, 0xCC, 0x88, 0xC9, + // Bytes 3000 - 303f + 0x03, 0x45, 0xCC, 0x89, 0xC9, 0x03, 0x45, 0xCC, + 0x8C, 0xC9, 0x03, 0x45, 0xCC, 0x8F, 0xC9, 0x03, + 0x45, 0xCC, 0x91, 0xC9, 0x03, 0x45, 0xCC, 0xA8, + 0xA5, 0x03, 0x45, 0xCC, 0xAD, 0xB5, 0x03, 0x45, + 0xCC, 0xB0, 0xB5, 0x03, 0x46, 0xCC, 0x87, 0xC9, + 0x03, 0x47, 0xCC, 0x81, 0xC9, 0x03, 0x47, 0xCC, + 0x82, 0xC9, 0x03, 0x47, 0xCC, 0x84, 0xC9, 0x03, + 0x47, 0xCC, 0x86, 0xC9, 0x03, 0x47, 0xCC, 0x87, + // Bytes 3040 - 307f + 0xC9, 0x03, 0x47, 0xCC, 0x8C, 0xC9, 0x03, 0x47, + 0xCC, 0xA7, 0xA5, 0x03, 0x48, 0xCC, 0x82, 0xC9, + 0x03, 0x48, 0xCC, 0x87, 0xC9, 0x03, 0x48, 0xCC, + 0x88, 0xC9, 0x03, 0x48, 0xCC, 0x8C, 0xC9, 0x03, + 0x48, 0xCC, 0xA3, 0xB5, 0x03, 0x48, 0xCC, 0xA7, + 0xA5, 0x03, 0x48, 0xCC, 0xAE, 0xB5, 0x03, 0x49, + 0xCC, 0x80, 0xC9, 0x03, 0x49, 0xCC, 0x81, 0xC9, + 0x03, 0x49, 0xCC, 0x82, 0xC9, 0x03, 0x49, 0xCC, + // Bytes 3080 - 30bf + 0x83, 0xC9, 0x03, 0x49, 0xCC, 0x84, 0xC9, 0x03, + 0x49, 0xCC, 0x86, 0xC9, 0x03, 0x49, 0xCC, 0x87, + 0xC9, 0x03, 0x49, 0xCC, 0x89, 0xC9, 0x03, 0x49, + 0xCC, 0x8C, 0xC9, 0x03, 0x49, 0xCC, 0x8F, 0xC9, + 0x03, 0x49, 0xCC, 0x91, 0xC9, 0x03, 0x49, 0xCC, + 0xA3, 0xB5, 0x03, 0x49, 0xCC, 0xA8, 0xA5, 0x03, + 0x49, 0xCC, 0xB0, 0xB5, 0x03, 0x4A, 0xCC, 0x82, + 0xC9, 0x03, 0x4B, 0xCC, 0x81, 0xC9, 0x03, 0x4B, + // Bytes 30c0 - 30ff + 0xCC, 0x8C, 0xC9, 0x03, 0x4B, 0xCC, 0xA3, 0xB5, + 0x03, 0x4B, 0xCC, 0xA7, 0xA5, 0x03, 0x4B, 0xCC, + 0xB1, 0xB5, 0x03, 0x4C, 0xCC, 0x81, 0xC9, 0x03, + 0x4C, 0xCC, 0x8C, 0xC9, 0x03, 0x4C, 0xCC, 0xA7, + 0xA5, 0x03, 0x4C, 0xCC, 0xAD, 0xB5, 0x03, 0x4C, + 0xCC, 0xB1, 0xB5, 0x03, 0x4D, 0xCC, 0x81, 0xC9, + 0x03, 0x4D, 0xCC, 0x87, 0xC9, 0x03, 0x4D, 0xCC, + 0xA3, 0xB5, 0x03, 0x4E, 0xCC, 0x80, 0xC9, 0x03, + // Bytes 3100 - 313f + 0x4E, 0xCC, 0x81, 0xC9, 0x03, 0x4E, 0xCC, 0x83, + 0xC9, 0x03, 0x4E, 0xCC, 0x87, 0xC9, 0x03, 0x4E, + 0xCC, 0x8C, 0xC9, 0x03, 0x4E, 0xCC, 0xA3, 0xB5, + 0x03, 0x4E, 0xCC, 0xA7, 0xA5, 0x03, 0x4E, 0xCC, + 0xAD, 0xB5, 0x03, 0x4E, 0xCC, 0xB1, 0xB5, 0x03, + 0x4F, 0xCC, 0x80, 0xC9, 0x03, 0x4F, 0xCC, 0x81, + 0xC9, 0x03, 0x4F, 0xCC, 0x86, 0xC9, 0x03, 0x4F, + 0xCC, 0x89, 0xC9, 0x03, 0x4F, 0xCC, 0x8B, 0xC9, + // Bytes 3140 - 317f + 0x03, 0x4F, 0xCC, 0x8C, 0xC9, 0x03, 0x4F, 0xCC, + 0x8F, 0xC9, 0x03, 0x4F, 0xCC, 0x91, 0xC9, 0x03, + 0x50, 0xCC, 0x81, 0xC9, 0x03, 0x50, 0xCC, 0x87, + 0xC9, 0x03, 0x52, 0xCC, 0x81, 0xC9, 0x03, 0x52, + 0xCC, 0x87, 0xC9, 0x03, 0x52, 0xCC, 0x8C, 0xC9, + 0x03, 0x52, 0xCC, 0x8F, 0xC9, 0x03, 0x52, 0xCC, + 0x91, 0xC9, 0x03, 0x52, 0xCC, 0xA7, 0xA5, 0x03, + 0x52, 0xCC, 0xB1, 0xB5, 0x03, 0x53, 0xCC, 0x82, + // Bytes 3180 - 31bf + 0xC9, 0x03, 0x53, 0xCC, 0x87, 0xC9, 0x03, 0x53, + 0xCC, 0xA6, 0xB5, 0x03, 0x53, 0xCC, 0xA7, 0xA5, + 0x03, 0x54, 0xCC, 0x87, 0xC9, 0x03, 0x54, 0xCC, + 0x8C, 0xC9, 0x03, 0x54, 0xCC, 0xA3, 0xB5, 0x03, + 0x54, 0xCC, 0xA6, 0xB5, 0x03, 0x54, 0xCC, 0xA7, + 0xA5, 0x03, 0x54, 0xCC, 0xAD, 0xB5, 0x03, 0x54, + 0xCC, 0xB1, 0xB5, 0x03, 0x55, 0xCC, 0x80, 0xC9, + 0x03, 0x55, 0xCC, 0x81, 0xC9, 0x03, 0x55, 0xCC, + // Bytes 31c0 - 31ff + 0x82, 0xC9, 0x03, 0x55, 0xCC, 0x86, 0xC9, 0x03, + 0x55, 0xCC, 0x89, 0xC9, 0x03, 0x55, 0xCC, 0x8A, + 0xC9, 0x03, 0x55, 0xCC, 0x8B, 0xC9, 0x03, 0x55, + 0xCC, 0x8C, 0xC9, 0x03, 0x55, 0xCC, 0x8F, 0xC9, + 0x03, 0x55, 0xCC, 0x91, 0xC9, 0x03, 0x55, 0xCC, + 0xA3, 0xB5, 0x03, 0x55, 0xCC, 0xA4, 0xB5, 0x03, + 0x55, 0xCC, 0xA8, 0xA5, 0x03, 0x55, 0xCC, 0xAD, + 0xB5, 0x03, 0x55, 0xCC, 0xB0, 0xB5, 0x03, 0x56, + // Bytes 3200 - 323f + 0xCC, 0x83, 0xC9, 0x03, 0x56, 0xCC, 0xA3, 0xB5, + 0x03, 0x57, 0xCC, 0x80, 0xC9, 0x03, 0x57, 0xCC, + 0x81, 0xC9, 0x03, 0x57, 0xCC, 0x82, 0xC9, 0x03, + 0x57, 0xCC, 0x87, 0xC9, 0x03, 0x57, 0xCC, 0x88, + 0xC9, 0x03, 0x57, 0xCC, 0xA3, 0xB5, 0x03, 0x58, + 0xCC, 0x87, 0xC9, 0x03, 0x58, 0xCC, 0x88, 0xC9, + 0x03, 0x59, 0xCC, 0x80, 0xC9, 0x03, 0x59, 0xCC, + 0x81, 0xC9, 0x03, 0x59, 0xCC, 0x82, 0xC9, 0x03, + // Bytes 3240 - 327f + 0x59, 0xCC, 0x83, 0xC9, 0x03, 0x59, 0xCC, 0x84, + 0xC9, 0x03, 0x59, 0xCC, 0x87, 0xC9, 0x03, 0x59, + 0xCC, 0x88, 0xC9, 0x03, 0x59, 0xCC, 0x89, 0xC9, + 0x03, 0x59, 0xCC, 0xA3, 0xB5, 0x03, 0x5A, 0xCC, + 0x81, 0xC9, 0x03, 0x5A, 0xCC, 0x82, 0xC9, 0x03, + 0x5A, 0xCC, 0x87, 0xC9, 0x03, 0x5A, 0xCC, 0x8C, + 0xC9, 0x03, 0x5A, 0xCC, 0xA3, 0xB5, 0x03, 0x5A, + 0xCC, 0xB1, 0xB5, 0x03, 0x61, 0xCC, 0x80, 0xC9, + // Bytes 3280 - 32bf + 0x03, 0x61, 0xCC, 0x81, 0xC9, 0x03, 0x61, 0xCC, + 0x83, 0xC9, 0x03, 0x61, 0xCC, 0x84, 0xC9, 0x03, + 0x61, 0xCC, 0x89, 0xC9, 0x03, 0x61, 0xCC, 0x8C, + 0xC9, 0x03, 0x61, 0xCC, 0x8F, 0xC9, 0x03, 0x61, + 0xCC, 0x91, 0xC9, 0x03, 0x61, 0xCC, 0xA5, 0xB5, + 0x03, 0x61, 0xCC, 0xA8, 0xA5, 0x03, 0x62, 0xCC, + 0x87, 0xC9, 0x03, 0x62, 0xCC, 0xA3, 0xB5, 0x03, + 0x62, 0xCC, 0xB1, 0xB5, 0x03, 0x63, 0xCC, 0x81, + // Bytes 32c0 - 32ff + 0xC9, 0x03, 0x63, 0xCC, 0x82, 0xC9, 0x03, 0x63, + 0xCC, 0x87, 0xC9, 0x03, 0x63, 0xCC, 0x8C, 0xC9, + 0x03, 0x64, 0xCC, 0x87, 0xC9, 0x03, 0x64, 0xCC, + 0x8C, 0xC9, 0x03, 0x64, 0xCC, 0xA3, 0xB5, 0x03, + 0x64, 0xCC, 0xA7, 0xA5, 0x03, 0x64, 0xCC, 0xAD, + 0xB5, 0x03, 0x64, 0xCC, 0xB1, 0xB5, 0x03, 0x65, + 0xCC, 0x80, 0xC9, 0x03, 0x65, 0xCC, 0x81, 0xC9, + 0x03, 0x65, 0xCC, 0x83, 0xC9, 0x03, 0x65, 0xCC, + // Bytes 3300 - 333f + 0x86, 0xC9, 0x03, 0x65, 0xCC, 0x87, 0xC9, 0x03, + 0x65, 0xCC, 0x88, 0xC9, 0x03, 0x65, 0xCC, 0x89, + 0xC9, 0x03, 0x65, 0xCC, 0x8C, 0xC9, 0x03, 0x65, + 0xCC, 0x8F, 0xC9, 0x03, 0x65, 0xCC, 0x91, 0xC9, + 0x03, 0x65, 0xCC, 0xA8, 0xA5, 0x03, 0x65, 0xCC, + 0xAD, 0xB5, 0x03, 0x65, 0xCC, 0xB0, 0xB5, 0x03, + 0x66, 0xCC, 0x87, 0xC9, 0x03, 0x67, 0xCC, 0x81, + 0xC9, 0x03, 0x67, 0xCC, 0x82, 0xC9, 0x03, 0x67, + // Bytes 3340 - 337f + 0xCC, 0x84, 0xC9, 0x03, 0x67, 0xCC, 0x86, 0xC9, + 0x03, 0x67, 0xCC, 0x87, 0xC9, 0x03, 0x67, 0xCC, + 0x8C, 0xC9, 0x03, 0x67, 0xCC, 0xA7, 0xA5, 0x03, + 0x68, 0xCC, 0x82, 0xC9, 0x03, 0x68, 0xCC, 0x87, + 0xC9, 0x03, 0x68, 0xCC, 0x88, 0xC9, 0x03, 0x68, + 0xCC, 0x8C, 0xC9, 0x03, 0x68, 0xCC, 0xA3, 0xB5, + 0x03, 0x68, 0xCC, 0xA7, 0xA5, 0x03, 0x68, 0xCC, + 0xAE, 0xB5, 0x03, 0x68, 0xCC, 0xB1, 0xB5, 0x03, + // Bytes 3380 - 33bf + 0x69, 0xCC, 0x80, 0xC9, 0x03, 0x69, 0xCC, 0x81, + 0xC9, 0x03, 0x69, 0xCC, 0x82, 0xC9, 0x03, 0x69, + 0xCC, 0x83, 0xC9, 0x03, 0x69, 0xCC, 0x84, 0xC9, + 0x03, 0x69, 0xCC, 0x86, 0xC9, 0x03, 0x69, 0xCC, + 0x89, 0xC9, 0x03, 0x69, 0xCC, 0x8C, 0xC9, 0x03, + 0x69, 0xCC, 0x8F, 0xC9, 0x03, 0x69, 0xCC, 0x91, + 0xC9, 0x03, 0x69, 0xCC, 0xA3, 0xB5, 0x03, 0x69, + 0xCC, 0xA8, 0xA5, 0x03, 0x69, 0xCC, 0xB0, 0xB5, + // Bytes 33c0 - 33ff + 0x03, 0x6A, 0xCC, 0x82, 0xC9, 0x03, 0x6A, 0xCC, + 0x8C, 0xC9, 0x03, 0x6B, 0xCC, 0x81, 0xC9, 0x03, + 0x6B, 0xCC, 0x8C, 0xC9, 0x03, 0x6B, 0xCC, 0xA3, + 0xB5, 0x03, 0x6B, 0xCC, 0xA7, 0xA5, 0x03, 0x6B, + 0xCC, 0xB1, 0xB5, 0x03, 0x6C, 0xCC, 0x81, 0xC9, + 0x03, 0x6C, 0xCC, 0x8C, 0xC9, 0x03, 0x6C, 0xCC, + 0xA7, 0xA5, 0x03, 0x6C, 0xCC, 0xAD, 0xB5, 0x03, + 0x6C, 0xCC, 0xB1, 0xB5, 0x03, 0x6D, 0xCC, 0x81, + // Bytes 3400 - 343f + 0xC9, 0x03, 0x6D, 0xCC, 0x87, 0xC9, 0x03, 0x6D, + 0xCC, 0xA3, 0xB5, 0x03, 0x6E, 0xCC, 0x80, 0xC9, + 0x03, 0x6E, 0xCC, 0x81, 0xC9, 0x03, 0x6E, 0xCC, + 0x83, 0xC9, 0x03, 0x6E, 0xCC, 0x87, 0xC9, 0x03, + 0x6E, 0xCC, 0x8C, 0xC9, 0x03, 0x6E, 0xCC, 0xA3, + 0xB5, 0x03, 0x6E, 0xCC, 0xA7, 0xA5, 0x03, 0x6E, + 0xCC, 0xAD, 0xB5, 0x03, 0x6E, 0xCC, 0xB1, 0xB5, + 0x03, 0x6F, 0xCC, 0x80, 0xC9, 0x03, 0x6F, 0xCC, + // Bytes 3440 - 347f + 0x81, 0xC9, 0x03, 0x6F, 0xCC, 0x86, 0xC9, 0x03, + 0x6F, 0xCC, 0x89, 0xC9, 0x03, 0x6F, 0xCC, 0x8B, + 0xC9, 0x03, 0x6F, 0xCC, 0x8C, 0xC9, 0x03, 0x6F, + 0xCC, 0x8F, 0xC9, 0x03, 0x6F, 0xCC, 0x91, 0xC9, + 0x03, 0x70, 0xCC, 0x81, 0xC9, 0x03, 0x70, 0xCC, + 0x87, 0xC9, 0x03, 0x72, 0xCC, 0x81, 0xC9, 0x03, + 0x72, 0xCC, 0x87, 0xC9, 0x03, 0x72, 0xCC, 0x8C, + 0xC9, 0x03, 0x72, 0xCC, 0x8F, 0xC9, 0x03, 0x72, + // Bytes 3480 - 34bf + 0xCC, 0x91, 0xC9, 0x03, 0x72, 0xCC, 0xA7, 0xA5, + 0x03, 0x72, 0xCC, 0xB1, 0xB5, 0x03, 0x73, 0xCC, + 0x82, 0xC9, 0x03, 0x73, 0xCC, 0x87, 0xC9, 0x03, + 0x73, 0xCC, 0xA6, 0xB5, 0x03, 0x73, 0xCC, 0xA7, + 0xA5, 0x03, 0x74, 0xCC, 0x87, 0xC9, 0x03, 0x74, + 0xCC, 0x88, 0xC9, 0x03, 0x74, 0xCC, 0x8C, 0xC9, + 0x03, 0x74, 0xCC, 0xA3, 0xB5, 0x03, 0x74, 0xCC, + 0xA6, 0xB5, 0x03, 0x74, 0xCC, 0xA7, 0xA5, 0x03, + // Bytes 34c0 - 34ff + 0x74, 0xCC, 0xAD, 0xB5, 0x03, 0x74, 0xCC, 0xB1, + 0xB5, 0x03, 0x75, 0xCC, 0x80, 0xC9, 0x03, 0x75, + 0xCC, 0x81, 0xC9, 0x03, 0x75, 0xCC, 0x82, 0xC9, + 0x03, 0x75, 0xCC, 0x86, 0xC9, 0x03, 0x75, 0xCC, + 0x89, 0xC9, 0x03, 0x75, 0xCC, 0x8A, 0xC9, 0x03, + 0x75, 0xCC, 0x8B, 0xC9, 0x03, 0x75, 0xCC, 0x8C, + 0xC9, 0x03, 0x75, 0xCC, 0x8F, 0xC9, 0x03, 0x75, + 0xCC, 0x91, 0xC9, 0x03, 0x75, 0xCC, 0xA3, 0xB5, + // Bytes 3500 - 353f + 0x03, 0x75, 0xCC, 0xA4, 0xB5, 0x03, 0x75, 0xCC, + 0xA8, 0xA5, 0x03, 0x75, 0xCC, 0xAD, 0xB5, 0x03, + 0x75, 0xCC, 0xB0, 0xB5, 0x03, 0x76, 0xCC, 0x83, + 0xC9, 0x03, 0x76, 0xCC, 0xA3, 0xB5, 0x03, 0x77, + 0xCC, 0x80, 0xC9, 0x03, 0x77, 0xCC, 0x81, 0xC9, + 0x03, 0x77, 0xCC, 0x82, 0xC9, 0x03, 0x77, 0xCC, + 0x87, 0xC9, 0x03, 0x77, 0xCC, 0x88, 0xC9, 0x03, + 0x77, 0xCC, 0x8A, 0xC9, 0x03, 0x77, 0xCC, 0xA3, + // Bytes 3540 - 357f + 0xB5, 0x03, 0x78, 0xCC, 0x87, 0xC9, 0x03, 0x78, + 0xCC, 0x88, 0xC9, 0x03, 0x79, 0xCC, 0x80, 0xC9, + 0x03, 0x79, 0xCC, 0x81, 0xC9, 0x03, 0x79, 0xCC, + 0x82, 0xC9, 0x03, 0x79, 0xCC, 0x83, 0xC9, 0x03, + 0x79, 0xCC, 0x84, 0xC9, 0x03, 0x79, 0xCC, 0x87, + 0xC9, 0x03, 0x79, 0xCC, 0x88, 0xC9, 0x03, 0x79, + 0xCC, 0x89, 0xC9, 0x03, 0x79, 0xCC, 0x8A, 0xC9, + 0x03, 0x79, 0xCC, 0xA3, 0xB5, 0x03, 0x7A, 0xCC, + // Bytes 3580 - 35bf + 0x81, 0xC9, 0x03, 0x7A, 0xCC, 0x82, 0xC9, 0x03, + 0x7A, 0xCC, 0x87, 0xC9, 0x03, 0x7A, 0xCC, 0x8C, + 0xC9, 0x03, 0x7A, 0xCC, 0xA3, 0xB5, 0x03, 0x7A, + 0xCC, 0xB1, 0xB5, 0x04, 0xC2, 0xA8, 0xCC, 0x80, + 0xCA, 0x04, 0xC2, 0xA8, 0xCC, 0x81, 0xCA, 0x04, + 0xC2, 0xA8, 0xCD, 0x82, 0xCA, 0x04, 0xC3, 0x86, + 0xCC, 0x81, 0xC9, 0x04, 0xC3, 0x86, 0xCC, 0x84, + 0xC9, 0x04, 0xC3, 0x98, 0xCC, 0x81, 0xC9, 0x04, + // Bytes 35c0 - 35ff + 0xC3, 0xA6, 0xCC, 0x81, 0xC9, 0x04, 0xC3, 0xA6, + 0xCC, 0x84, 0xC9, 0x04, 0xC3, 0xB8, 0xCC, 0x81, + 0xC9, 0x04, 0xC5, 0xBF, 0xCC, 0x87, 0xC9, 0x04, + 0xC6, 0xB7, 0xCC, 0x8C, 0xC9, 0x04, 0xCA, 0x92, + 0xCC, 0x8C, 0xC9, 0x04, 0xCE, 0x91, 0xCC, 0x80, + 0xC9, 0x04, 0xCE, 0x91, 0xCC, 0x81, 0xC9, 0x04, + 0xCE, 0x91, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0x91, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0x91, 0xCD, 0x85, + // Bytes 3600 - 363f + 0xD9, 0x04, 0xCE, 0x95, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0x95, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0x97, + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x97, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0x97, 0xCD, 0x85, 0xD9, 0x04, + 0xCE, 0x99, 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x99, + 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0x99, 0xCC, 0x84, + 0xC9, 0x04, 0xCE, 0x99, 0xCC, 0x86, 0xC9, 0x04, + 0xCE, 0x99, 0xCC, 0x88, 0xC9, 0x04, 0xCE, 0x9F, + // Bytes 3640 - 367f + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x9F, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0xA1, 0xCC, 0x94, 0xC9, 0x04, + 0xCE, 0xA5, 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0xA5, + 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0xA5, 0xCC, 0x84, + 0xC9, 0x04, 0xCE, 0xA5, 0xCC, 0x86, 0xC9, 0x04, + 0xCE, 0xA5, 0xCC, 0x88, 0xC9, 0x04, 0xCE, 0xA9, + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0xA9, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0xA9, 0xCD, 0x85, 0xD9, 0x04, + // Bytes 3680 - 36bf + 0xCE, 0xB1, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0xB1, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0xB1, 0xCD, 0x85, + 0xD9, 0x04, 0xCE, 0xB5, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0xB5, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0xB7, + 0xCD, 0x85, 0xD9, 0x04, 0xCE, 0xB9, 0xCC, 0x80, + 0xC9, 0x04, 0xCE, 0xB9, 0xCC, 0x81, 0xC9, 0x04, + 0xCE, 0xB9, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0xB9, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0xB9, 0xCD, 0x82, + // Bytes 36c0 - 36ff + 0xC9, 0x04, 0xCE, 0xBF, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0xBF, 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x81, + 0xCC, 0x93, 0xC9, 0x04, 0xCF, 0x81, 0xCC, 0x94, + 0xC9, 0x04, 0xCF, 0x85, 0xCC, 0x80, 0xC9, 0x04, + 0xCF, 0x85, 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x85, + 0xCC, 0x84, 0xC9, 0x04, 0xCF, 0x85, 0xCC, 0x86, + 0xC9, 0x04, 0xCF, 0x85, 0xCD, 0x82, 0xC9, 0x04, + 0xCF, 0x89, 0xCD, 0x85, 0xD9, 0x04, 0xCF, 0x92, + // Bytes 3700 - 373f + 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x92, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0x86, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0x90, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0x90, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x93, 0xCC, 0x81, + 0xC9, 0x04, 0xD0, 0x95, 0xCC, 0x80, 0xC9, 0x04, + 0xD0, 0x95, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0x95, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x96, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0x96, 0xCC, 0x88, 0xC9, 0x04, + // Bytes 3740 - 377f + 0xD0, 0x97, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x98, + 0xCC, 0x80, 0xC9, 0x04, 0xD0, 0x98, 0xCC, 0x84, + 0xC9, 0x04, 0xD0, 0x98, 0xCC, 0x86, 0xC9, 0x04, + 0xD0, 0x98, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x9A, + 0xCC, 0x81, 0xC9, 0x04, 0xD0, 0x9E, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xA3, 0xCC, 0x84, 0xC9, 0x04, + 0xD0, 0xA3, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xA3, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, + // Bytes 3780 - 37bf + 0xC9, 0x04, 0xD0, 0xA7, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xAB, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xAD, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xB0, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0xB0, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xB3, 0xCC, 0x81, 0xC9, 0x04, 0xD0, 0xB5, + 0xCC, 0x80, 0xC9, 0x04, 0xD0, 0xB5, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0xB5, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xB6, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xB6, + // Bytes 37c0 - 37ff + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xB7, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xB8, 0xCC, 0x80, 0xC9, 0x04, + 0xD0, 0xB8, 0xCC, 0x84, 0xC9, 0x04, 0xD0, 0xB8, + 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xB8, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xBA, 0xCC, 0x81, 0xC9, 0x04, + 0xD0, 0xBE, 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0x83, + 0xCC, 0x84, 0xC9, 0x04, 0xD1, 0x83, 0xCC, 0x86, + 0xC9, 0x04, 0xD1, 0x83, 0xCC, 0x88, 0xC9, 0x04, + // Bytes 3800 - 383f + 0xD1, 0x83, 0xCC, 0x8B, 0xC9, 0x04, 0xD1, 0x87, + 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0x8B, 0xCC, 0x88, + 0xC9, 0x04, 0xD1, 0x8D, 0xCC, 0x88, 0xC9, 0x04, + 0xD1, 0x96, 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0xB4, + 0xCC, 0x8F, 0xC9, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, + 0xC9, 0x04, 0xD3, 0x98, 0xCC, 0x88, 0xC9, 0x04, + 0xD3, 0x99, 0xCC, 0x88, 0xC9, 0x04, 0xD3, 0xA8, + 0xCC, 0x88, 0xC9, 0x04, 0xD3, 0xA9, 0xCC, 0x88, + // Bytes 3840 - 387f + 0xC9, 0x04, 0xD8, 0xA7, 0xD9, 0x93, 0xC9, 0x04, + 0xD8, 0xA7, 0xD9, 0x94, 0xC9, 0x04, 0xD8, 0xA7, + 0xD9, 0x95, 0xB5, 0x04, 0xD9, 0x88, 0xD9, 0x94, + 0xC9, 0x04, 0xD9, 0x8A, 0xD9, 0x94, 0xC9, 0x04, + 0xDB, 0x81, 0xD9, 0x94, 0xC9, 0x04, 0xDB, 0x92, + 0xD9, 0x94, 0xC9, 0x04, 0xDB, 0x95, 0xD9, 0x94, + 0xC9, 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x80, 0xCA, + 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, + // Bytes 3880 - 38bf + 0x41, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x41, + 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x41, 0xCC, + 0x86, 0xCC, 0x80, 0xCA, 0x05, 0x41, 0xCC, 0x86, + 0xCC, 0x81, 0xCA, 0x05, 0x41, 0xCC, 0x86, 0xCC, + 0x83, 0xCA, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x89, + 0xCA, 0x05, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xCA, + 0x05, 0x41, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, + 0x41, 0xCC, 0x8A, 0xCC, 0x81, 0xCA, 0x05, 0x41, + // Bytes 38c0 - 38ff + 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x41, 0xCC, + 0xA3, 0xCC, 0x86, 0xCA, 0x05, 0x43, 0xCC, 0xA7, + 0xCC, 0x81, 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, + 0x80, 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x81, + 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x83, 0xCA, + 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, + 0x45, 0xCC, 0x84, 0xCC, 0x80, 0xCA, 0x05, 0x45, + 0xCC, 0x84, 0xCC, 0x81, 0xCA, 0x05, 0x45, 0xCC, + // Bytes 3900 - 393f + 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x45, 0xCC, 0xA7, + 0xCC, 0x86, 0xCA, 0x05, 0x49, 0xCC, 0x88, 0xCC, + 0x81, 0xCA, 0x05, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, + 0xCA, 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xCA, + 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, + 0x4F, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x4F, + 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x4F, 0xCC, + 0x83, 0xCC, 0x81, 0xCA, 0x05, 0x4F, 0xCC, 0x83, + // Bytes 3940 - 397f + 0xCC, 0x84, 0xCA, 0x05, 0x4F, 0xCC, 0x83, 0xCC, + 0x88, 0xCA, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, + 0xCA, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xCA, + 0x05, 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, + 0x4F, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x4F, + 0xCC, 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x4F, 0xCC, + 0x9B, 0xCC, 0x81, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, + 0xCC, 0x83, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, + // Bytes 3980 - 39bf + 0x89, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, + 0xB6, 0x05, 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, + 0x05, 0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xCA, 0x05, + 0x52, 0xCC, 0xA3, 0xCC, 0x84, 0xCA, 0x05, 0x53, + 0xCC, 0x81, 0xCC, 0x87, 0xCA, 0x05, 0x53, 0xCC, + 0x8C, 0xCC, 0x87, 0xCA, 0x05, 0x53, 0xCC, 0xA3, + 0xCC, 0x87, 0xCA, 0x05, 0x55, 0xCC, 0x83, 0xCC, + 0x81, 0xCA, 0x05, 0x55, 0xCC, 0x84, 0xCC, 0x88, + // Bytes 39c0 - 39ff + 0xCA, 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x05, + 0x55, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x55, + 0xCC, 0x88, 0xCC, 0x8C, 0xCA, 0x05, 0x55, 0xCC, + 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x55, 0xCC, 0x9B, + 0xCC, 0x81, 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, + 0x83, 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x89, + 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, + // Bytes 3a00 - 3a3f + 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x80, 0xCA, 0x05, + 0x61, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, 0x61, + 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x61, 0xCC, + 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x61, 0xCC, 0x86, + 0xCC, 0x80, 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, + 0x81, 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, + 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x89, 0xCA, + 0x05, 0x61, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, + // Bytes 3a40 - 3a7f + 0x61, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x61, + 0xCC, 0x8A, 0xCC, 0x81, 0xCA, 0x05, 0x61, 0xCC, + 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x61, 0xCC, 0xA3, + 0xCC, 0x86, 0xCA, 0x05, 0x63, 0xCC, 0xA7, 0xCC, + 0x81, 0xCA, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x80, + 0xCA, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xCA, + 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, + 0x65, 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x65, + // Bytes 3a80 - 3abf + 0xCC, 0x84, 0xCC, 0x80, 0xCA, 0x05, 0x65, 0xCC, + 0x84, 0xCC, 0x81, 0xCA, 0x05, 0x65, 0xCC, 0xA3, + 0xCC, 0x82, 0xCA, 0x05, 0x65, 0xCC, 0xA7, 0xCC, + 0x86, 0xCA, 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, + 0xCA, 0x05, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xCA, + 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xCA, 0x05, + 0x6F, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, 0x6F, + 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x6F, 0xCC, + // Bytes 3ac0 - 3aff + 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x6F, 0xCC, 0x83, + 0xCC, 0x81, 0xCA, 0x05, 0x6F, 0xCC, 0x83, 0xCC, + 0x84, 0xCA, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x88, + 0xCA, 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0xCA, + 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xCA, 0x05, + 0x6F, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, 0x6F, + 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x6F, 0xCC, + 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, + // Bytes 3b00 - 3b3f + 0xCC, 0x81, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, + 0x83, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, + 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, + 0x05, 0x6F, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, + 0x6F, 0xCC, 0xA8, 0xCC, 0x84, 0xCA, 0x05, 0x72, + 0xCC, 0xA3, 0xCC, 0x84, 0xCA, 0x05, 0x73, 0xCC, + 0x81, 0xCC, 0x87, 0xCA, 0x05, 0x73, 0xCC, 0x8C, + 0xCC, 0x87, 0xCA, 0x05, 0x73, 0xCC, 0xA3, 0xCC, + // Bytes 3b40 - 3b7f + 0x87, 0xCA, 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, + 0xCA, 0x05, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xCA, + 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x80, 0xCA, 0x05, + 0x75, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x05, 0x75, + 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x75, 0xCC, + 0x88, 0xCC, 0x8C, 0xCA, 0x05, 0x75, 0xCC, 0x9B, + 0xCC, 0x80, 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, + 0x81, 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, + // Bytes 3b80 - 3bbf + 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x89, 0xCA, + 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, 0x05, + 0xE1, 0xBE, 0xBF, 0xCC, 0x80, 0xCA, 0x05, 0xE1, + 0xBE, 0xBF, 0xCC, 0x81, 0xCA, 0x05, 0xE1, 0xBE, + 0xBF, 0xCD, 0x82, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, + 0xCC, 0x80, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, + 0x81, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, 0xCD, 0x82, + 0xCA, 0x05, 0xE2, 0x86, 0x90, 0xCC, 0xB8, 0x05, + // Bytes 3bc0 - 3bff + 0x05, 0xE2, 0x86, 0x92, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x86, 0x94, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x87, 0x90, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, + 0x92, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x94, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x83, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x88, 0xA3, 0xCC, 0xB8, 0x05, 0x05, + // Bytes 3c00 - 3c3f + 0xE2, 0x88, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x88, 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, + 0x83, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x85, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x88, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x8D, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x89, 0xA4, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + // Bytes 3c40 - 3c7f + 0x89, 0xB2, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, + 0xB3, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB6, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB7, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xBA, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x89, 0xBB, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x89, 0xBC, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0xBD, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x8A, 0x82, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + // Bytes 3c80 - 3cbf + 0x83, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x86, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x87, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x91, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x8A, 0x92, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x8A, 0xA2, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x8A, 0xA8, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x8A, 0xA9, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + 0xAB, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB2, + // Bytes 3cc0 - 3cff + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB3, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x8A, 0xB5, 0xCC, 0xB8, 0x05, + 0x06, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + // Bytes 3d00 - 3d3f + 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + // Bytes 3d40 - 3d7f + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + // Bytes 3d80 - 3dbf + 0x06, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + // Bytes 3dc0 - 3dff + 0x06, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + // Bytes 3e00 - 3e3f + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + // Bytes 3e40 - 3e7f + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, 0xCA, + // Bytes 3e80 - 3ebf + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + // Bytes 3ec0 - 3eff + 0x06, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + 0x06, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96, 0x85, + 0x06, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8A, 0x11, + // Bytes 3f00 - 3f3f + 0x06, 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x97, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 3f40 - 3f7f + 0x06, 0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA6, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA8, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 3f80 - 3fbf + 0x06, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x9A, 0x0D, + // Bytes 3fc0 - 3fff + 0x06, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4000 - 403f + 0x06, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4040 - 407f + 0x06, 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4080 - 40bf + 0x06, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 40c0 - 40ff + 0x06, 0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xBD, 0xE3, 0x82, 0x99, 0x0D, + 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + // Bytes 4100 - 413f + 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCD, + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0x97, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + // Bytes 4140 - 417f + 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, + // Bytes 4180 - 41bf + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + // Bytes 41c0 - 41ff + 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, + // Bytes 4200 - 423f + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCF, + 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCF, + 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + 0x08, 0xF0, 0x91, 0x82, 0x99, 0xF0, 0x91, 0x82, + // Bytes 4240 - 427f + 0xBA, 0x09, 0x08, 0xF0, 0x91, 0x82, 0x9B, 0xF0, + 0x91, 0x82, 0xBA, 0x09, 0x08, 0xF0, 0x91, 0x82, + 0xA5, 0xF0, 0x91, 0x82, 0xBA, 0x09, 0x42, 0xC2, + 0xB4, 0x01, 0x43, 0x20, 0xCC, 0x81, 0xC9, 0x43, + 0x20, 0xCC, 0x83, 0xC9, 0x43, 0x20, 0xCC, 0x84, + 0xC9, 0x43, 0x20, 0xCC, 0x85, 0xC9, 0x43, 0x20, + 0xCC, 0x86, 0xC9, 0x43, 0x20, 0xCC, 0x87, 0xC9, + 0x43, 0x20, 0xCC, 0x88, 0xC9, 0x43, 0x20, 0xCC, + // Bytes 4280 - 42bf + 0x8A, 0xC9, 0x43, 0x20, 0xCC, 0x8B, 0xC9, 0x43, + 0x20, 0xCC, 0x93, 0xC9, 0x43, 0x20, 0xCC, 0x94, + 0xC9, 0x43, 0x20, 0xCC, 0xA7, 0xA5, 0x43, 0x20, + 0xCC, 0xA8, 0xA5, 0x43, 0x20, 0xCC, 0xB3, 0xB5, + 0x43, 0x20, 0xCD, 0x82, 0xC9, 0x43, 0x20, 0xCD, + 0x85, 0xD9, 0x43, 0x20, 0xD9, 0x8B, 0x59, 0x43, + 0x20, 0xD9, 0x8C, 0x5D, 0x43, 0x20, 0xD9, 0x8D, + 0x61, 0x43, 0x20, 0xD9, 0x8E, 0x65, 0x43, 0x20, + // Bytes 42c0 - 42ff + 0xD9, 0x8F, 0x69, 0x43, 0x20, 0xD9, 0x90, 0x6D, + 0x43, 0x20, 0xD9, 0x91, 0x71, 0x43, 0x20, 0xD9, + 0x92, 0x75, 0x43, 0x41, 0xCC, 0x8A, 0xC9, 0x43, + 0x73, 0xCC, 0x87, 0xC9, 0x44, 0x20, 0xE3, 0x82, + 0x99, 0x0D, 0x44, 0x20, 0xE3, 0x82, 0x9A, 0x0D, + 0x44, 0xC2, 0xA8, 0xCC, 0x81, 0xCA, 0x44, 0xCE, + 0x91, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0x95, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0x97, 0xCC, 0x81, 0xC9, + // Bytes 4300 - 433f + 0x44, 0xCE, 0x99, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0x9F, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xA5, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0xA5, 0xCC, 0x88, 0xC9, + 0x44, 0xCE, 0xA9, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0xB1, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xB5, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0xB7, 0xCC, 0x81, 0xC9, + 0x44, 0xCE, 0xB9, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0xBF, 0xCC, 0x81, 0xC9, 0x44, 0xCF, 0x85, 0xCC, + // Bytes 4340 - 437f + 0x81, 0xC9, 0x44, 0xCF, 0x89, 0xCC, 0x81, 0xC9, + 0x44, 0xD7, 0x90, 0xD6, 0xB7, 0x31, 0x44, 0xD7, + 0x90, 0xD6, 0xB8, 0x35, 0x44, 0xD7, 0x90, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x91, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x91, 0xD6, 0xBF, 0x49, 0x44, 0xD7, + 0x92, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x93, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x94, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x95, 0xD6, 0xB9, 0x39, 0x44, 0xD7, + // Bytes 4380 - 43bf + 0x95, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x96, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x98, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x99, 0xD6, 0xB4, 0x25, 0x44, 0xD7, + 0x99, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x9A, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x9B, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x9B, 0xD6, 0xBF, 0x49, 0x44, 0xD7, + 0x9C, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x9E, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA0, 0xD6, 0xBC, 0x41, + // Bytes 43c0 - 43ff + 0x44, 0xD7, 0xA1, 0xD6, 0xBC, 0x41, 0x44, 0xD7, + 0xA3, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA4, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA4, 0xD6, 0xBF, 0x49, + 0x44, 0xD7, 0xA6, 0xD6, 0xBC, 0x41, 0x44, 0xD7, + 0xA7, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA8, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA9, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0xA9, 0xD7, 0x81, 0x4D, 0x44, 0xD7, + 0xA9, 0xD7, 0x82, 0x51, 0x44, 0xD7, 0xAA, 0xD6, + // Bytes 4400 - 443f + 0xBC, 0x41, 0x44, 0xD7, 0xB2, 0xD6, 0xB7, 0x31, + 0x44, 0xD8, 0xA7, 0xD9, 0x8B, 0x59, 0x44, 0xD8, + 0xA7, 0xD9, 0x93, 0xC9, 0x44, 0xD8, 0xA7, 0xD9, + 0x94, 0xC9, 0x44, 0xD8, 0xA7, 0xD9, 0x95, 0xB5, + 0x44, 0xD8, 0xB0, 0xD9, 0xB0, 0x79, 0x44, 0xD8, + 0xB1, 0xD9, 0xB0, 0x79, 0x44, 0xD9, 0x80, 0xD9, + 0x8B, 0x59, 0x44, 0xD9, 0x80, 0xD9, 0x8E, 0x65, + 0x44, 0xD9, 0x80, 0xD9, 0x8F, 0x69, 0x44, 0xD9, + // Bytes 4440 - 447f + 0x80, 0xD9, 0x90, 0x6D, 0x44, 0xD9, 0x80, 0xD9, + 0x91, 0x71, 0x44, 0xD9, 0x80, 0xD9, 0x92, 0x75, + 0x44, 0xD9, 0x87, 0xD9, 0xB0, 0x79, 0x44, 0xD9, + 0x88, 0xD9, 0x94, 0xC9, 0x44, 0xD9, 0x89, 0xD9, + 0xB0, 0x79, 0x44, 0xD9, 0x8A, 0xD9, 0x94, 0xC9, + 0x44, 0xDB, 0x92, 0xD9, 0x94, 0xC9, 0x44, 0xDB, + 0x95, 0xD9, 0x94, 0xC9, 0x45, 0x20, 0xCC, 0x88, + 0xCC, 0x80, 0xCA, 0x45, 0x20, 0xCC, 0x88, 0xCC, + // Bytes 4480 - 44bf + 0x81, 0xCA, 0x45, 0x20, 0xCC, 0x88, 0xCD, 0x82, + 0xCA, 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x45, + 0x20, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x45, 0x20, + 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x45, 0x20, 0xCC, + 0x94, 0xCC, 0x81, 0xCA, 0x45, 0x20, 0xCC, 0x94, + 0xCD, 0x82, 0xCA, 0x45, 0x20, 0xD9, 0x8C, 0xD9, + 0x91, 0x72, 0x45, 0x20, 0xD9, 0x8D, 0xD9, 0x91, + // Bytes 44c0 - 44ff + 0x72, 0x45, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x72, + 0x45, 0x20, 0xD9, 0x8F, 0xD9, 0x91, 0x72, 0x45, + 0x20, 0xD9, 0x90, 0xD9, 0x91, 0x72, 0x45, 0x20, + 0xD9, 0x91, 0xD9, 0xB0, 0x7A, 0x45, 0xE2, 0xAB, + 0x9D, 0xCC, 0xB8, 0x05, 0x46, 0xCE, 0xB9, 0xCC, + 0x88, 0xCC, 0x81, 0xCA, 0x46, 0xCF, 0x85, 0xCC, + 0x88, 0xCC, 0x81, 0xCA, 0x46, 0xD7, 0xA9, 0xD6, + 0xBC, 0xD7, 0x81, 0x4E, 0x46, 0xD7, 0xA9, 0xD6, + // Bytes 4500 - 453f + 0xBC, 0xD7, 0x82, 0x52, 0x46, 0xD9, 0x80, 0xD9, + 0x8E, 0xD9, 0x91, 0x72, 0x46, 0xD9, 0x80, 0xD9, + 0x8F, 0xD9, 0x91, 0x72, 0x46, 0xD9, 0x80, 0xD9, + 0x90, 0xD9, 0x91, 0x72, 0x46, 0xE0, 0xA4, 0x95, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x96, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x97, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x9C, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xA1, + // Bytes 4540 - 457f + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xA2, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xAB, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xAF, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xA1, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xA2, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xAF, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x96, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x97, + // Bytes 4580 - 45bf + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x9C, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xAB, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xB2, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xB8, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xAC, 0xA1, + 0xE0, 0xAC, 0xBC, 0x09, 0x46, 0xE0, 0xAC, 0xA2, + 0xE0, 0xAC, 0xBC, 0x09, 0x46, 0xE0, 0xBE, 0xB2, + 0xE0, 0xBE, 0x80, 0x9D, 0x46, 0xE0, 0xBE, 0xB3, + // Bytes 45c0 - 45ff + 0xE0, 0xBE, 0x80, 0x9D, 0x46, 0xE3, 0x83, 0x86, + 0xE3, 0x82, 0x99, 0x0D, 0x48, 0xF0, 0x9D, 0x85, + 0x97, 0xF0, 0x9D, 0x85, 0xA5, 0xAD, 0x48, 0xF0, + 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xAD, + 0x48, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, + 0xA5, 0xAD, 0x48, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, + 0x9D, 0x85, 0xA5, 0xAD, 0x49, 0xE0, 0xBE, 0xB2, + 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x9E, 0x49, + // Bytes 4600 - 463f + 0xE0, 0xBE, 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, + 0x80, 0x9E, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xAE, + 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, + 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xAE, 0x4C, 0xF0, + 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, + 0x9D, 0x85, 0xB0, 0xAE, 0x4C, 0xF0, 0x9D, 0x85, + 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, + // Bytes 4640 - 467f + 0xB1, 0xAE, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xAE, + 0x4C, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, + 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xAE, 0x4C, 0xF0, + 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, + 0x9D, 0x85, 0xAF, 0xAE, 0x4C, 0xF0, 0x9D, 0x86, + 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, + 0xAE, 0xAE, 0x4C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, + // Bytes 4680 - 46bf + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xAE, + 0x83, 0x41, 0xCC, 0x82, 0xC9, 0x83, 0x41, 0xCC, + 0x86, 0xC9, 0x83, 0x41, 0xCC, 0x87, 0xC9, 0x83, + 0x41, 0xCC, 0x88, 0xC9, 0x83, 0x41, 0xCC, 0x8A, + 0xC9, 0x83, 0x41, 0xCC, 0xA3, 0xB5, 0x83, 0x43, + 0xCC, 0xA7, 0xA5, 0x83, 0x45, 0xCC, 0x82, 0xC9, + 0x83, 0x45, 0xCC, 0x84, 0xC9, 0x83, 0x45, 0xCC, + 0xA3, 0xB5, 0x83, 0x45, 0xCC, 0xA7, 0xA5, 0x83, + // Bytes 46c0 - 46ff + 0x49, 0xCC, 0x88, 0xC9, 0x83, 0x4C, 0xCC, 0xA3, + 0xB5, 0x83, 0x4F, 0xCC, 0x82, 0xC9, 0x83, 0x4F, + 0xCC, 0x83, 0xC9, 0x83, 0x4F, 0xCC, 0x84, 0xC9, + 0x83, 0x4F, 0xCC, 0x87, 0xC9, 0x83, 0x4F, 0xCC, + 0x88, 0xC9, 0x83, 0x4F, 0xCC, 0x9B, 0xAD, 0x83, + 0x4F, 0xCC, 0xA3, 0xB5, 0x83, 0x4F, 0xCC, 0xA8, + 0xA5, 0x83, 0x52, 0xCC, 0xA3, 0xB5, 0x83, 0x53, + 0xCC, 0x81, 0xC9, 0x83, 0x53, 0xCC, 0x8C, 0xC9, + // Bytes 4700 - 473f + 0x83, 0x53, 0xCC, 0xA3, 0xB5, 0x83, 0x55, 0xCC, + 0x83, 0xC9, 0x83, 0x55, 0xCC, 0x84, 0xC9, 0x83, + 0x55, 0xCC, 0x88, 0xC9, 0x83, 0x55, 0xCC, 0x9B, + 0xAD, 0x83, 0x61, 0xCC, 0x82, 0xC9, 0x83, 0x61, + 0xCC, 0x86, 0xC9, 0x83, 0x61, 0xCC, 0x87, 0xC9, + 0x83, 0x61, 0xCC, 0x88, 0xC9, 0x83, 0x61, 0xCC, + 0x8A, 0xC9, 0x83, 0x61, 0xCC, 0xA3, 0xB5, 0x83, + 0x63, 0xCC, 0xA7, 0xA5, 0x83, 0x65, 0xCC, 0x82, + // Bytes 4740 - 477f + 0xC9, 0x83, 0x65, 0xCC, 0x84, 0xC9, 0x83, 0x65, + 0xCC, 0xA3, 0xB5, 0x83, 0x65, 0xCC, 0xA7, 0xA5, + 0x83, 0x69, 0xCC, 0x88, 0xC9, 0x83, 0x6C, 0xCC, + 0xA3, 0xB5, 0x83, 0x6F, 0xCC, 0x82, 0xC9, 0x83, + 0x6F, 0xCC, 0x83, 0xC9, 0x83, 0x6F, 0xCC, 0x84, + 0xC9, 0x83, 0x6F, 0xCC, 0x87, 0xC9, 0x83, 0x6F, + 0xCC, 0x88, 0xC9, 0x83, 0x6F, 0xCC, 0x9B, 0xAD, + 0x83, 0x6F, 0xCC, 0xA3, 0xB5, 0x83, 0x6F, 0xCC, + // Bytes 4780 - 47bf + 0xA8, 0xA5, 0x83, 0x72, 0xCC, 0xA3, 0xB5, 0x83, + 0x73, 0xCC, 0x81, 0xC9, 0x83, 0x73, 0xCC, 0x8C, + 0xC9, 0x83, 0x73, 0xCC, 0xA3, 0xB5, 0x83, 0x75, + 0xCC, 0x83, 0xC9, 0x83, 0x75, 0xCC, 0x84, 0xC9, + 0x83, 0x75, 0xCC, 0x88, 0xC9, 0x83, 0x75, 0xCC, + 0x9B, 0xAD, 0x84, 0xCE, 0x91, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x91, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0x95, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x95, 0xCC, + // Bytes 47c0 - 47ff + 0x94, 0xC9, 0x84, 0xCE, 0x97, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x97, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0x99, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x99, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0x9F, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x9F, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0xA5, 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0xA9, 0xCC, + 0x93, 0xC9, 0x84, 0xCE, 0xA9, 0xCC, 0x94, 0xC9, + 0x84, 0xCE, 0xB1, 0xCC, 0x80, 0xC9, 0x84, 0xCE, + // Bytes 4800 - 483f + 0xB1, 0xCC, 0x81, 0xC9, 0x84, 0xCE, 0xB1, 0xCC, + 0x93, 0xC9, 0x84, 0xCE, 0xB1, 0xCC, 0x94, 0xC9, + 0x84, 0xCE, 0xB1, 0xCD, 0x82, 0xC9, 0x84, 0xCE, + 0xB5, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB5, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xB7, 0xCC, 0x80, 0xC9, + 0x84, 0xCE, 0xB7, 0xCC, 0x81, 0xC9, 0x84, 0xCE, + 0xB7, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB7, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xB7, 0xCD, 0x82, 0xC9, + // Bytes 4840 - 487f + 0x84, 0xCE, 0xB9, 0xCC, 0x88, 0xC9, 0x84, 0xCE, + 0xB9, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB9, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xBF, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0xBF, 0xCC, 0x94, 0xC9, 0x84, 0xCF, + 0x85, 0xCC, 0x88, 0xC9, 0x84, 0xCF, 0x85, 0xCC, + 0x93, 0xC9, 0x84, 0xCF, 0x85, 0xCC, 0x94, 0xC9, + 0x84, 0xCF, 0x89, 0xCC, 0x80, 0xC9, 0x84, 0xCF, + 0x89, 0xCC, 0x81, 0xC9, 0x84, 0xCF, 0x89, 0xCC, + // Bytes 4880 - 48bf + 0x93, 0xC9, 0x84, 0xCF, 0x89, 0xCC, 0x94, 0xC9, + 0x84, 0xCF, 0x89, 0xCD, 0x82, 0xC9, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + // Bytes 48c0 - 48ff + 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + // Bytes 4900 - 493f + 0xA9, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + // Bytes 4940 - 497f + 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCF, + // Bytes 4980 - 49bf + 0x89, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x42, 0xCC, + 0x80, 0xC9, 0x32, 0x42, 0xCC, 0x81, 0xC9, 0x32, + 0x42, 0xCC, 0x93, 0xC9, 0x32, 0x43, 0xE1, 0x85, + // Bytes 49c0 - 49ff + 0xA1, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA2, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xA3, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xA4, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xA5, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA6, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xA7, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xA8, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xA9, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAA, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xAB, 0x01, 0x00, 0x43, + // Bytes 4a00 - 4a3f + 0xE1, 0x85, 0xAC, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAE, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xAF, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xB1, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB2, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xB3, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xB5, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xAA, 0x01, + // Bytes 4a40 - 4a7f + 0x00, 0x43, 0xE1, 0x86, 0xAC, 0x01, 0x00, 0x43, + 0xE1, 0x86, 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x86, + 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB1, 0x01, + 0x00, 0x43, 0xE1, 0x86, 0xB2, 0x01, 0x00, 0x43, + 0xE1, 0x86, 0xB3, 0x01, 0x00, 0x43, 0xE1, 0x86, + 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB5, 0x01, + 0x00, 0x44, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x32, + 0x43, 0xE3, 0x82, 0x99, 0x0D, 0x03, 0x43, 0xE3, + // Bytes 4a80 - 4abf + 0x82, 0x9A, 0x0D, 0x03, 0x46, 0xE0, 0xBD, 0xB1, + 0xE0, 0xBD, 0xB2, 0x9E, 0x26, 0x46, 0xE0, 0xBD, + 0xB1, 0xE0, 0xBD, 0xB4, 0xA2, 0x26, 0x46, 0xE0, + 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x9E, 0x26, 0x00, + 0x01, +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfcTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfcTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfcValues[c0] + } + i := nfcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfcTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfcTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfcValues[c0] + } + i := nfcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// nfcTrie. Total size: 10586 bytes (10.34 KiB). Checksum: dd926e82067bee11. +type nfcTrie struct{} + +func newNfcTrie(i int) *nfcTrie { + return &nfcTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *nfcTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 46: + return uint16(nfcValues[n<<6+uint32(b)]) + default: + n -= 46 + return uint16(nfcSparse.lookup(n, b)) + } +} + +// nfcValues: 48 blocks, 3072 entries, 6144 bytes +// The third block is the zero block. +var nfcValues = [3072]uint16{ + // Block 0x0, offset 0x0 + 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000, + // Block 0x1, offset 0x40 + 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000, + 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000, + 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000, + 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000, + 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000, + 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000, + 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000, + 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000, + 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000, + 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x2f6f, 0xc1: 0x2f74, 0xc2: 0x4688, 0xc3: 0x2f79, 0xc4: 0x4697, 0xc5: 0x469c, + 0xc6: 0xa000, 0xc7: 0x46a6, 0xc8: 0x2fe2, 0xc9: 0x2fe7, 0xca: 0x46ab, 0xcb: 0x2ffb, + 0xcc: 0x306e, 0xcd: 0x3073, 0xce: 0x3078, 0xcf: 0x46bf, 0xd1: 0x3104, + 0xd2: 0x3127, 0xd3: 0x312c, 0xd4: 0x46c9, 0xd5: 0x46ce, 0xd6: 0x46dd, + 0xd8: 0xa000, 0xd9: 0x31b3, 0xda: 0x31b8, 0xdb: 0x31bd, 0xdc: 0x470f, 0xdd: 0x3235, + 0xe0: 0x327b, 0xe1: 0x3280, 0xe2: 0x4719, 0xe3: 0x3285, + 0xe4: 0x4728, 0xe5: 0x472d, 0xe6: 0xa000, 0xe7: 0x4737, 0xe8: 0x32ee, 0xe9: 0x32f3, + 0xea: 0x473c, 0xeb: 0x3307, 0xec: 0x337f, 0xed: 0x3384, 0xee: 0x3389, 0xef: 0x4750, + 0xf1: 0x3415, 0xf2: 0x3438, 0xf3: 0x343d, 0xf4: 0x475a, 0xf5: 0x475f, + 0xf6: 0x476e, 0xf8: 0xa000, 0xf9: 0x34c9, 0xfa: 0x34ce, 0xfb: 0x34d3, + 0xfc: 0x47a0, 0xfd: 0x3550, 0xff: 0x3569, + // Block 0x4, offset 0x100 + 0x100: 0x2f7e, 0x101: 0x328a, 0x102: 0x468d, 0x103: 0x471e, 0x104: 0x2f9c, 0x105: 0x32a8, + 0x106: 0x2fb0, 0x107: 0x32bc, 0x108: 0x2fb5, 0x109: 0x32c1, 0x10a: 0x2fba, 0x10b: 0x32c6, + 0x10c: 0x2fbf, 0x10d: 0x32cb, 0x10e: 0x2fc9, 0x10f: 0x32d5, + 0x112: 0x46b0, 0x113: 0x4741, 0x114: 0x2ff1, 0x115: 0x32fd, 0x116: 0x2ff6, 0x117: 0x3302, + 0x118: 0x3014, 0x119: 0x3320, 0x11a: 0x3005, 0x11b: 0x3311, 0x11c: 0x302d, 0x11d: 0x3339, + 0x11e: 0x3037, 0x11f: 0x3343, 0x120: 0x303c, 0x121: 0x3348, 0x122: 0x3046, 0x123: 0x3352, + 0x124: 0x304b, 0x125: 0x3357, 0x128: 0x307d, 0x129: 0x338e, + 0x12a: 0x3082, 0x12b: 0x3393, 0x12c: 0x3087, 0x12d: 0x3398, 0x12e: 0x30aa, 0x12f: 0x33b6, + 0x130: 0x308c, 0x134: 0x30b4, 0x135: 0x33c0, + 0x136: 0x30c8, 0x137: 0x33d9, 0x139: 0x30d2, 0x13a: 0x33e3, 0x13b: 0x30dc, + 0x13c: 0x33ed, 0x13d: 0x30d7, 0x13e: 0x33e8, + // Block 0x5, offset 0x140 + 0x143: 0x30ff, 0x144: 0x3410, 0x145: 0x3118, + 0x146: 0x3429, 0x147: 0x310e, 0x148: 0x341f, + 0x14c: 0x46d3, 0x14d: 0x4764, 0x14e: 0x3131, 0x14f: 0x3442, 0x150: 0x313b, 0x151: 0x344c, + 0x154: 0x3159, 0x155: 0x346a, 0x156: 0x3172, 0x157: 0x3483, + 0x158: 0x3163, 0x159: 0x3474, 0x15a: 0x46f6, 0x15b: 0x4787, 0x15c: 0x317c, 0x15d: 0x348d, + 0x15e: 0x318b, 0x15f: 0x349c, 0x160: 0x46fb, 0x161: 0x478c, 0x162: 0x31a4, 0x163: 0x34ba, + 0x164: 0x3195, 0x165: 0x34ab, 0x168: 0x4705, 0x169: 0x4796, + 0x16a: 0x470a, 0x16b: 0x479b, 0x16c: 0x31c2, 0x16d: 0x34d8, 0x16e: 0x31cc, 0x16f: 0x34e2, + 0x170: 0x31d1, 0x171: 0x34e7, 0x172: 0x31ef, 0x173: 0x3505, 0x174: 0x3212, 0x175: 0x3528, + 0x176: 0x323a, 0x177: 0x3555, 0x178: 0x324e, 0x179: 0x325d, 0x17a: 0x357d, 0x17b: 0x3267, + 0x17c: 0x3587, 0x17d: 0x326c, 0x17e: 0x358c, 0x17f: 0xa000, + // Block 0x6, offset 0x180 + 0x184: 0x8100, 0x185: 0x8100, + 0x186: 0x8100, + 0x18d: 0x2f88, 0x18e: 0x3294, 0x18f: 0x3096, 0x190: 0x33a2, 0x191: 0x3140, + 0x192: 0x3451, 0x193: 0x31d6, 0x194: 0x34ec, 0x195: 0x39cf, 0x196: 0x3b5e, 0x197: 0x39c8, + 0x198: 0x3b57, 0x199: 0x39d6, 0x19a: 0x3b65, 0x19b: 0x39c1, 0x19c: 0x3b50, + 0x19e: 0x38b0, 0x19f: 0x3a3f, 0x1a0: 0x38a9, 0x1a1: 0x3a38, 0x1a2: 0x35b3, 0x1a3: 0x35c5, + 0x1a6: 0x3041, 0x1a7: 0x334d, 0x1a8: 0x30be, 0x1a9: 0x33cf, + 0x1aa: 0x46ec, 0x1ab: 0x477d, 0x1ac: 0x3990, 0x1ad: 0x3b1f, 0x1ae: 0x35d7, 0x1af: 0x35dd, + 0x1b0: 0x33c5, 0x1b4: 0x3028, 0x1b5: 0x3334, + 0x1b8: 0x30fa, 0x1b9: 0x340b, 0x1ba: 0x38b7, 0x1bb: 0x3a46, + 0x1bc: 0x35ad, 0x1bd: 0x35bf, 0x1be: 0x35b9, 0x1bf: 0x35cb, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2f8d, 0x1c1: 0x3299, 0x1c2: 0x2f92, 0x1c3: 0x329e, 0x1c4: 0x300a, 0x1c5: 0x3316, + 0x1c6: 0x300f, 0x1c7: 0x331b, 0x1c8: 0x309b, 0x1c9: 0x33a7, 0x1ca: 0x30a0, 0x1cb: 0x33ac, + 0x1cc: 0x3145, 0x1cd: 0x3456, 0x1ce: 0x314a, 0x1cf: 0x345b, 0x1d0: 0x3168, 0x1d1: 0x3479, + 0x1d2: 0x316d, 0x1d3: 0x347e, 0x1d4: 0x31db, 0x1d5: 0x34f1, 0x1d6: 0x31e0, 0x1d7: 0x34f6, + 0x1d8: 0x3186, 0x1d9: 0x3497, 0x1da: 0x319f, 0x1db: 0x34b5, + 0x1de: 0x305a, 0x1df: 0x3366, + 0x1e6: 0x4692, 0x1e7: 0x4723, 0x1e8: 0x46ba, 0x1e9: 0x474b, + 0x1ea: 0x395f, 0x1eb: 0x3aee, 0x1ec: 0x393c, 0x1ed: 0x3acb, 0x1ee: 0x46d8, 0x1ef: 0x4769, + 0x1f0: 0x3958, 0x1f1: 0x3ae7, 0x1f2: 0x3244, 0x1f3: 0x355f, + // Block 0x8, offset 0x200 + 0x200: 0x9932, 0x201: 0x9932, 0x202: 0x9932, 0x203: 0x9932, 0x204: 0x9932, 0x205: 0x8132, + 0x206: 0x9932, 0x207: 0x9932, 0x208: 0x9932, 0x209: 0x9932, 0x20a: 0x9932, 0x20b: 0x9932, + 0x20c: 0x9932, 0x20d: 0x8132, 0x20e: 0x8132, 0x20f: 0x9932, 0x210: 0x8132, 0x211: 0x9932, + 0x212: 0x8132, 0x213: 0x9932, 0x214: 0x9932, 0x215: 0x8133, 0x216: 0x812d, 0x217: 0x812d, + 0x218: 0x812d, 0x219: 0x812d, 0x21a: 0x8133, 0x21b: 0x992b, 0x21c: 0x812d, 0x21d: 0x812d, + 0x21e: 0x812d, 0x21f: 0x812d, 0x220: 0x812d, 0x221: 0x8129, 0x222: 0x8129, 0x223: 0x992d, + 0x224: 0x992d, 0x225: 0x992d, 0x226: 0x992d, 0x227: 0x9929, 0x228: 0x9929, 0x229: 0x812d, + 0x22a: 0x812d, 0x22b: 0x812d, 0x22c: 0x812d, 0x22d: 0x992d, 0x22e: 0x992d, 0x22f: 0x812d, + 0x230: 0x992d, 0x231: 0x992d, 0x232: 0x812d, 0x233: 0x812d, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812d, 0x23a: 0x812d, 0x23b: 0x812d, + 0x23c: 0x812d, 0x23d: 0x8132, 0x23e: 0x8132, 0x23f: 0x8132, + // Block 0x9, offset 0x240 + 0x240: 0x49ae, 0x241: 0x49b3, 0x242: 0x9932, 0x243: 0x49b8, 0x244: 0x4a71, 0x245: 0x9936, + 0x246: 0x8132, 0x247: 0x812d, 0x248: 0x812d, 0x249: 0x812d, 0x24a: 0x8132, 0x24b: 0x8132, + 0x24c: 0x8132, 0x24d: 0x812d, 0x24e: 0x812d, 0x250: 0x8132, 0x251: 0x8132, + 0x252: 0x8132, 0x253: 0x812d, 0x254: 0x812d, 0x255: 0x812d, 0x256: 0x812d, 0x257: 0x8132, + 0x258: 0x8133, 0x259: 0x812d, 0x25a: 0x812d, 0x25b: 0x8132, 0x25c: 0x8134, 0x25d: 0x8135, + 0x25e: 0x8135, 0x25f: 0x8134, 0x260: 0x8135, 0x261: 0x8135, 0x262: 0x8134, 0x263: 0x8132, + 0x264: 0x8132, 0x265: 0x8132, 0x266: 0x8132, 0x267: 0x8132, 0x268: 0x8132, 0x269: 0x8132, + 0x26a: 0x8132, 0x26b: 0x8132, 0x26c: 0x8132, 0x26d: 0x8132, 0x26e: 0x8132, 0x26f: 0x8132, + 0x274: 0x0170, + 0x27a: 0x8100, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x8100, 0x285: 0x35a1, + 0x286: 0x35e9, 0x287: 0x00ce, 0x288: 0x3607, 0x289: 0x3613, 0x28a: 0x3625, + 0x28c: 0x3643, 0x28e: 0x3655, 0x28f: 0x3673, 0x290: 0x3e08, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x3637, 0x2ab: 0x3667, 0x2ac: 0x47fe, 0x2ad: 0x3697, 0x2ae: 0x4828, 0x2af: 0x36a9, + 0x2b0: 0x3e70, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x3721, 0x2c1: 0x372d, 0x2c3: 0x371b, + 0x2c6: 0xa000, 0x2c7: 0x3709, + 0x2cc: 0x375d, 0x2cd: 0x3745, 0x2ce: 0x376f, 0x2d0: 0xa000, + 0x2d3: 0xa000, 0x2d5: 0xa000, 0x2d6: 0xa000, 0x2d7: 0xa000, + 0x2d8: 0xa000, 0x2d9: 0x3751, 0x2da: 0xa000, + 0x2de: 0xa000, 0x2e3: 0xa000, + 0x2e7: 0xa000, + 0x2eb: 0xa000, 0x2ed: 0xa000, + 0x2f0: 0xa000, 0x2f3: 0xa000, 0x2f5: 0xa000, + 0x2f6: 0xa000, 0x2f7: 0xa000, 0x2f8: 0xa000, 0x2f9: 0x37d5, 0x2fa: 0xa000, + 0x2fe: 0xa000, + // Block 0xc, offset 0x300 + 0x301: 0x3733, 0x302: 0x37b7, + 0x310: 0x370f, 0x311: 0x3793, + 0x312: 0x3715, 0x313: 0x3799, 0x316: 0x3727, 0x317: 0x37ab, + 0x318: 0xa000, 0x319: 0xa000, 0x31a: 0x3829, 0x31b: 0x382f, 0x31c: 0x3739, 0x31d: 0x37bd, + 0x31e: 0x373f, 0x31f: 0x37c3, 0x322: 0x374b, 0x323: 0x37cf, + 0x324: 0x3757, 0x325: 0x37db, 0x326: 0x3763, 0x327: 0x37e7, 0x328: 0xa000, 0x329: 0xa000, + 0x32a: 0x3835, 0x32b: 0x383b, 0x32c: 0x378d, 0x32d: 0x3811, 0x32e: 0x3769, 0x32f: 0x37ed, + 0x330: 0x3775, 0x331: 0x37f9, 0x332: 0x377b, 0x333: 0x37ff, 0x334: 0x3781, 0x335: 0x3805, + 0x338: 0x3787, 0x339: 0x380b, + // Block 0xd, offset 0x340 + 0x351: 0x812d, + 0x352: 0x8132, 0x353: 0x8132, 0x354: 0x8132, 0x355: 0x8132, 0x356: 0x812d, 0x357: 0x8132, + 0x358: 0x8132, 0x359: 0x8132, 0x35a: 0x812e, 0x35b: 0x812d, 0x35c: 0x8132, 0x35d: 0x8132, + 0x35e: 0x8132, 0x35f: 0x8132, 0x360: 0x8132, 0x361: 0x8132, 0x362: 0x812d, 0x363: 0x812d, + 0x364: 0x812d, 0x365: 0x812d, 0x366: 0x812d, 0x367: 0x812d, 0x368: 0x8132, 0x369: 0x8132, + 0x36a: 0x812d, 0x36b: 0x8132, 0x36c: 0x8132, 0x36d: 0x812e, 0x36e: 0x8131, 0x36f: 0x8132, + 0x370: 0x8105, 0x371: 0x8106, 0x372: 0x8107, 0x373: 0x8108, 0x374: 0x8109, 0x375: 0x810a, + 0x376: 0x810b, 0x377: 0x810c, 0x378: 0x810d, 0x379: 0x810e, 0x37a: 0x810e, 0x37b: 0x810f, + 0x37c: 0x8110, 0x37d: 0x8111, 0x37f: 0x8112, + // Block 0xe, offset 0x380 + 0x388: 0xa000, 0x38a: 0xa000, 0x38b: 0x8116, + 0x38c: 0x8117, 0x38d: 0x8118, 0x38e: 0x8119, 0x38f: 0x811a, 0x390: 0x811b, 0x391: 0x811c, + 0x392: 0x811d, 0x393: 0x9932, 0x394: 0x9932, 0x395: 0x992d, 0x396: 0x812d, 0x397: 0x8132, + 0x398: 0x8132, 0x399: 0x8132, 0x39a: 0x8132, 0x39b: 0x8132, 0x39c: 0x812d, 0x39d: 0x8132, + 0x39e: 0x8132, 0x39f: 0x812d, + 0x3b0: 0x811e, + // Block 0xf, offset 0x3c0 + 0x3d3: 0x812d, 0x3d4: 0x8132, 0x3d5: 0x8132, 0x3d6: 0x8132, 0x3d7: 0x8132, + 0x3d8: 0x8132, 0x3d9: 0x8132, 0x3da: 0x8132, 0x3db: 0x8132, 0x3dc: 0x8132, 0x3dd: 0x8132, + 0x3de: 0x8132, 0x3df: 0x8132, 0x3e0: 0x8132, 0x3e1: 0x8132, 0x3e3: 0x812d, + 0x3e4: 0x8132, 0x3e5: 0x8132, 0x3e6: 0x812d, 0x3e7: 0x8132, 0x3e8: 0x8132, 0x3e9: 0x812d, + 0x3ea: 0x8132, 0x3eb: 0x8132, 0x3ec: 0x8132, 0x3ed: 0x812d, 0x3ee: 0x812d, 0x3ef: 0x812d, + 0x3f0: 0x8116, 0x3f1: 0x8117, 0x3f2: 0x8118, 0x3f3: 0x8132, 0x3f4: 0x8132, 0x3f5: 0x8132, + 0x3f6: 0x812d, 0x3f7: 0x8132, 0x3f8: 0x8132, 0x3f9: 0x812d, 0x3fa: 0x812d, 0x3fb: 0x8132, + 0x3fc: 0x8132, 0x3fd: 0x8132, 0x3fe: 0x8132, 0x3ff: 0x8132, + // Block 0x10, offset 0x400 + 0x405: 0xa000, + 0x406: 0x2d26, 0x407: 0xa000, 0x408: 0x2d2e, 0x409: 0xa000, 0x40a: 0x2d36, 0x40b: 0xa000, + 0x40c: 0x2d3e, 0x40d: 0xa000, 0x40e: 0x2d46, 0x411: 0xa000, + 0x412: 0x2d4e, + 0x434: 0x8102, 0x435: 0x9900, + 0x43a: 0xa000, 0x43b: 0x2d56, + 0x43c: 0xa000, 0x43d: 0x2d5e, 0x43e: 0xa000, 0x43f: 0xa000, + // Block 0x11, offset 0x440 + 0x440: 0x8132, 0x441: 0x8132, 0x442: 0x812d, 0x443: 0x8132, 0x444: 0x8132, 0x445: 0x8132, + 0x446: 0x8132, 0x447: 0x8132, 0x448: 0x8132, 0x449: 0x8132, 0x44a: 0x812d, 0x44b: 0x8132, + 0x44c: 0x8132, 0x44d: 0x8135, 0x44e: 0x812a, 0x44f: 0x812d, 0x450: 0x8129, 0x451: 0x8132, + 0x452: 0x8132, 0x453: 0x8132, 0x454: 0x8132, 0x455: 0x8132, 0x456: 0x8132, 0x457: 0x8132, + 0x458: 0x8132, 0x459: 0x8132, 0x45a: 0x8132, 0x45b: 0x8132, 0x45c: 0x8132, 0x45d: 0x8132, + 0x45e: 0x8132, 0x45f: 0x8132, 0x460: 0x8132, 0x461: 0x8132, 0x462: 0x8132, 0x463: 0x8132, + 0x464: 0x8132, 0x465: 0x8132, 0x466: 0x8132, 0x467: 0x8132, 0x468: 0x8132, 0x469: 0x8132, + 0x46a: 0x8132, 0x46b: 0x8132, 0x46c: 0x8132, 0x46d: 0x8132, 0x46e: 0x8132, 0x46f: 0x8132, + 0x470: 0x8132, 0x471: 0x8132, 0x472: 0x8132, 0x473: 0x8132, 0x474: 0x8132, 0x475: 0x8132, + 0x476: 0x8133, 0x477: 0x8131, 0x478: 0x8131, 0x479: 0x812d, 0x47b: 0x8132, + 0x47c: 0x8134, 0x47d: 0x812d, 0x47e: 0x8132, 0x47f: 0x812d, + // Block 0x12, offset 0x480 + 0x480: 0x2f97, 0x481: 0x32a3, 0x482: 0x2fa1, 0x483: 0x32ad, 0x484: 0x2fa6, 0x485: 0x32b2, + 0x486: 0x2fab, 0x487: 0x32b7, 0x488: 0x38cc, 0x489: 0x3a5b, 0x48a: 0x2fc4, 0x48b: 0x32d0, + 0x48c: 0x2fce, 0x48d: 0x32da, 0x48e: 0x2fdd, 0x48f: 0x32e9, 0x490: 0x2fd3, 0x491: 0x32df, + 0x492: 0x2fd8, 0x493: 0x32e4, 0x494: 0x38ef, 0x495: 0x3a7e, 0x496: 0x38f6, 0x497: 0x3a85, + 0x498: 0x3019, 0x499: 0x3325, 0x49a: 0x301e, 0x49b: 0x332a, 0x49c: 0x3904, 0x49d: 0x3a93, + 0x49e: 0x3023, 0x49f: 0x332f, 0x4a0: 0x3032, 0x4a1: 0x333e, 0x4a2: 0x3050, 0x4a3: 0x335c, + 0x4a4: 0x305f, 0x4a5: 0x336b, 0x4a6: 0x3055, 0x4a7: 0x3361, 0x4a8: 0x3064, 0x4a9: 0x3370, + 0x4aa: 0x3069, 0x4ab: 0x3375, 0x4ac: 0x30af, 0x4ad: 0x33bb, 0x4ae: 0x390b, 0x4af: 0x3a9a, + 0x4b0: 0x30b9, 0x4b1: 0x33ca, 0x4b2: 0x30c3, 0x4b3: 0x33d4, 0x4b4: 0x30cd, 0x4b5: 0x33de, + 0x4b6: 0x46c4, 0x4b7: 0x4755, 0x4b8: 0x3912, 0x4b9: 0x3aa1, 0x4ba: 0x30e6, 0x4bb: 0x33f7, + 0x4bc: 0x30e1, 0x4bd: 0x33f2, 0x4be: 0x30eb, 0x4bf: 0x33fc, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x30f0, 0x4c1: 0x3401, 0x4c2: 0x30f5, 0x4c3: 0x3406, 0x4c4: 0x3109, 0x4c5: 0x341a, + 0x4c6: 0x3113, 0x4c7: 0x3424, 0x4c8: 0x3122, 0x4c9: 0x3433, 0x4ca: 0x311d, 0x4cb: 0x342e, + 0x4cc: 0x3935, 0x4cd: 0x3ac4, 0x4ce: 0x3943, 0x4cf: 0x3ad2, 0x4d0: 0x394a, 0x4d1: 0x3ad9, + 0x4d2: 0x3951, 0x4d3: 0x3ae0, 0x4d4: 0x314f, 0x4d5: 0x3460, 0x4d6: 0x3154, 0x4d7: 0x3465, + 0x4d8: 0x315e, 0x4d9: 0x346f, 0x4da: 0x46f1, 0x4db: 0x4782, 0x4dc: 0x3997, 0x4dd: 0x3b26, + 0x4de: 0x3177, 0x4df: 0x3488, 0x4e0: 0x3181, 0x4e1: 0x3492, 0x4e2: 0x4700, 0x4e3: 0x4791, + 0x4e4: 0x399e, 0x4e5: 0x3b2d, 0x4e6: 0x39a5, 0x4e7: 0x3b34, 0x4e8: 0x39ac, 0x4e9: 0x3b3b, + 0x4ea: 0x3190, 0x4eb: 0x34a1, 0x4ec: 0x319a, 0x4ed: 0x34b0, 0x4ee: 0x31ae, 0x4ef: 0x34c4, + 0x4f0: 0x31a9, 0x4f1: 0x34bf, 0x4f2: 0x31ea, 0x4f3: 0x3500, 0x4f4: 0x31f9, 0x4f5: 0x350f, + 0x4f6: 0x31f4, 0x4f7: 0x350a, 0x4f8: 0x39b3, 0x4f9: 0x3b42, 0x4fa: 0x39ba, 0x4fb: 0x3b49, + 0x4fc: 0x31fe, 0x4fd: 0x3514, 0x4fe: 0x3203, 0x4ff: 0x3519, + // Block 0x14, offset 0x500 + 0x500: 0x3208, 0x501: 0x351e, 0x502: 0x320d, 0x503: 0x3523, 0x504: 0x321c, 0x505: 0x3532, + 0x506: 0x3217, 0x507: 0x352d, 0x508: 0x3221, 0x509: 0x353c, 0x50a: 0x3226, 0x50b: 0x3541, + 0x50c: 0x322b, 0x50d: 0x3546, 0x50e: 0x3249, 0x50f: 0x3564, 0x510: 0x3262, 0x511: 0x3582, + 0x512: 0x3271, 0x513: 0x3591, 0x514: 0x3276, 0x515: 0x3596, 0x516: 0x337a, 0x517: 0x34a6, + 0x518: 0x3537, 0x519: 0x3573, 0x51b: 0x35d1, + 0x520: 0x46a1, 0x521: 0x4732, 0x522: 0x2f83, 0x523: 0x328f, + 0x524: 0x3878, 0x525: 0x3a07, 0x526: 0x3871, 0x527: 0x3a00, 0x528: 0x3886, 0x529: 0x3a15, + 0x52a: 0x387f, 0x52b: 0x3a0e, 0x52c: 0x38be, 0x52d: 0x3a4d, 0x52e: 0x3894, 0x52f: 0x3a23, + 0x530: 0x388d, 0x531: 0x3a1c, 0x532: 0x38a2, 0x533: 0x3a31, 0x534: 0x389b, 0x535: 0x3a2a, + 0x536: 0x38c5, 0x537: 0x3a54, 0x538: 0x46b5, 0x539: 0x4746, 0x53a: 0x3000, 0x53b: 0x330c, + 0x53c: 0x2fec, 0x53d: 0x32f8, 0x53e: 0x38da, 0x53f: 0x3a69, + // Block 0x15, offset 0x540 + 0x540: 0x38d3, 0x541: 0x3a62, 0x542: 0x38e8, 0x543: 0x3a77, 0x544: 0x38e1, 0x545: 0x3a70, + 0x546: 0x38fd, 0x547: 0x3a8c, 0x548: 0x3091, 0x549: 0x339d, 0x54a: 0x30a5, 0x54b: 0x33b1, + 0x54c: 0x46e7, 0x54d: 0x4778, 0x54e: 0x3136, 0x54f: 0x3447, 0x550: 0x3920, 0x551: 0x3aaf, + 0x552: 0x3919, 0x553: 0x3aa8, 0x554: 0x392e, 0x555: 0x3abd, 0x556: 0x3927, 0x557: 0x3ab6, + 0x558: 0x3989, 0x559: 0x3b18, 0x55a: 0x396d, 0x55b: 0x3afc, 0x55c: 0x3966, 0x55d: 0x3af5, + 0x55e: 0x397b, 0x55f: 0x3b0a, 0x560: 0x3974, 0x561: 0x3b03, 0x562: 0x3982, 0x563: 0x3b11, + 0x564: 0x31e5, 0x565: 0x34fb, 0x566: 0x31c7, 0x567: 0x34dd, 0x568: 0x39e4, 0x569: 0x3b73, + 0x56a: 0x39dd, 0x56b: 0x3b6c, 0x56c: 0x39f2, 0x56d: 0x3b81, 0x56e: 0x39eb, 0x56f: 0x3b7a, + 0x570: 0x39f9, 0x571: 0x3b88, 0x572: 0x3230, 0x573: 0x354b, 0x574: 0x3258, 0x575: 0x3578, + 0x576: 0x3253, 0x577: 0x356e, 0x578: 0x323f, 0x579: 0x355a, + // Block 0x16, offset 0x580 + 0x580: 0x4804, 0x581: 0x480a, 0x582: 0x491e, 0x583: 0x4936, 0x584: 0x4926, 0x585: 0x493e, + 0x586: 0x492e, 0x587: 0x4946, 0x588: 0x47aa, 0x589: 0x47b0, 0x58a: 0x488e, 0x58b: 0x48a6, + 0x58c: 0x4896, 0x58d: 0x48ae, 0x58e: 0x489e, 0x58f: 0x48b6, 0x590: 0x4816, 0x591: 0x481c, + 0x592: 0x3db8, 0x593: 0x3dc8, 0x594: 0x3dc0, 0x595: 0x3dd0, + 0x598: 0x47b6, 0x599: 0x47bc, 0x59a: 0x3ce8, 0x59b: 0x3cf8, 0x59c: 0x3cf0, 0x59d: 0x3d00, + 0x5a0: 0x482e, 0x5a1: 0x4834, 0x5a2: 0x494e, 0x5a3: 0x4966, + 0x5a4: 0x4956, 0x5a5: 0x496e, 0x5a6: 0x495e, 0x5a7: 0x4976, 0x5a8: 0x47c2, 0x5a9: 0x47c8, + 0x5aa: 0x48be, 0x5ab: 0x48d6, 0x5ac: 0x48c6, 0x5ad: 0x48de, 0x5ae: 0x48ce, 0x5af: 0x48e6, + 0x5b0: 0x4846, 0x5b1: 0x484c, 0x5b2: 0x3e18, 0x5b3: 0x3e30, 0x5b4: 0x3e20, 0x5b5: 0x3e38, + 0x5b6: 0x3e28, 0x5b7: 0x3e40, 0x5b8: 0x47ce, 0x5b9: 0x47d4, 0x5ba: 0x3d18, 0x5bb: 0x3d30, + 0x5bc: 0x3d20, 0x5bd: 0x3d38, 0x5be: 0x3d28, 0x5bf: 0x3d40, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x4852, 0x5c1: 0x4858, 0x5c2: 0x3e48, 0x5c3: 0x3e58, 0x5c4: 0x3e50, 0x5c5: 0x3e60, + 0x5c8: 0x47da, 0x5c9: 0x47e0, 0x5ca: 0x3d48, 0x5cb: 0x3d58, + 0x5cc: 0x3d50, 0x5cd: 0x3d60, 0x5d0: 0x4864, 0x5d1: 0x486a, + 0x5d2: 0x3e80, 0x5d3: 0x3e98, 0x5d4: 0x3e88, 0x5d5: 0x3ea0, 0x5d6: 0x3e90, 0x5d7: 0x3ea8, + 0x5d9: 0x47e6, 0x5db: 0x3d68, 0x5dd: 0x3d70, + 0x5df: 0x3d78, 0x5e0: 0x487c, 0x5e1: 0x4882, 0x5e2: 0x497e, 0x5e3: 0x4996, + 0x5e4: 0x4986, 0x5e5: 0x499e, 0x5e6: 0x498e, 0x5e7: 0x49a6, 0x5e8: 0x47ec, 0x5e9: 0x47f2, + 0x5ea: 0x48ee, 0x5eb: 0x4906, 0x5ec: 0x48f6, 0x5ed: 0x490e, 0x5ee: 0x48fe, 0x5ef: 0x4916, + 0x5f0: 0x47f8, 0x5f1: 0x431e, 0x5f2: 0x3691, 0x5f3: 0x4324, 0x5f4: 0x4822, 0x5f5: 0x432a, + 0x5f6: 0x36a3, 0x5f7: 0x4330, 0x5f8: 0x36c1, 0x5f9: 0x4336, 0x5fa: 0x36d9, 0x5fb: 0x433c, + 0x5fc: 0x4870, 0x5fd: 0x4342, + // Block 0x18, offset 0x600 + 0x600: 0x3da0, 0x601: 0x3da8, 0x602: 0x4184, 0x603: 0x41a2, 0x604: 0x418e, 0x605: 0x41ac, + 0x606: 0x4198, 0x607: 0x41b6, 0x608: 0x3cd8, 0x609: 0x3ce0, 0x60a: 0x40d0, 0x60b: 0x40ee, + 0x60c: 0x40da, 0x60d: 0x40f8, 0x60e: 0x40e4, 0x60f: 0x4102, 0x610: 0x3de8, 0x611: 0x3df0, + 0x612: 0x41c0, 0x613: 0x41de, 0x614: 0x41ca, 0x615: 0x41e8, 0x616: 0x41d4, 0x617: 0x41f2, + 0x618: 0x3d08, 0x619: 0x3d10, 0x61a: 0x410c, 0x61b: 0x412a, 0x61c: 0x4116, 0x61d: 0x4134, + 0x61e: 0x4120, 0x61f: 0x413e, 0x620: 0x3ec0, 0x621: 0x3ec8, 0x622: 0x41fc, 0x623: 0x421a, + 0x624: 0x4206, 0x625: 0x4224, 0x626: 0x4210, 0x627: 0x422e, 0x628: 0x3d80, 0x629: 0x3d88, + 0x62a: 0x4148, 0x62b: 0x4166, 0x62c: 0x4152, 0x62d: 0x4170, 0x62e: 0x415c, 0x62f: 0x417a, + 0x630: 0x3685, 0x631: 0x367f, 0x632: 0x3d90, 0x633: 0x368b, 0x634: 0x3d98, + 0x636: 0x4810, 0x637: 0x3db0, 0x638: 0x35f5, 0x639: 0x35ef, 0x63a: 0x35e3, 0x63b: 0x42ee, + 0x63c: 0x35fb, 0x63d: 0x8100, 0x63e: 0x01d3, 0x63f: 0xa100, + // Block 0x19, offset 0x640 + 0x640: 0x8100, 0x641: 0x35a7, 0x642: 0x3dd8, 0x643: 0x369d, 0x644: 0x3de0, + 0x646: 0x483a, 0x647: 0x3df8, 0x648: 0x3601, 0x649: 0x42f4, 0x64a: 0x360d, 0x64b: 0x42fa, + 0x64c: 0x3619, 0x64d: 0x3b8f, 0x64e: 0x3b96, 0x64f: 0x3b9d, 0x650: 0x36b5, 0x651: 0x36af, + 0x652: 0x3e00, 0x653: 0x44e4, 0x656: 0x36bb, 0x657: 0x3e10, + 0x658: 0x3631, 0x659: 0x362b, 0x65a: 0x361f, 0x65b: 0x4300, 0x65d: 0x3ba4, + 0x65e: 0x3bab, 0x65f: 0x3bb2, 0x660: 0x36eb, 0x661: 0x36e5, 0x662: 0x3e68, 0x663: 0x44ec, + 0x664: 0x36cd, 0x665: 0x36d3, 0x666: 0x36f1, 0x667: 0x3e78, 0x668: 0x3661, 0x669: 0x365b, + 0x66a: 0x364f, 0x66b: 0x430c, 0x66c: 0x3649, 0x66d: 0x359b, 0x66e: 0x42e8, 0x66f: 0x0081, + 0x672: 0x3eb0, 0x673: 0x36f7, 0x674: 0x3eb8, + 0x676: 0x4888, 0x677: 0x3ed0, 0x678: 0x363d, 0x679: 0x4306, 0x67a: 0x366d, 0x67b: 0x4318, + 0x67c: 0x3679, 0x67d: 0x4256, 0x67e: 0xa100, + // Block 0x1a, offset 0x680 + 0x681: 0x3c06, 0x683: 0xa000, 0x684: 0x3c0d, 0x685: 0xa000, + 0x687: 0x3c14, 0x688: 0xa000, 0x689: 0x3c1b, + 0x68d: 0xa000, + 0x6a0: 0x2f65, 0x6a1: 0xa000, 0x6a2: 0x3c29, + 0x6a4: 0xa000, 0x6a5: 0xa000, + 0x6ad: 0x3c22, 0x6ae: 0x2f60, 0x6af: 0x2f6a, + 0x6b0: 0x3c30, 0x6b1: 0x3c37, 0x6b2: 0xa000, 0x6b3: 0xa000, 0x6b4: 0x3c3e, 0x6b5: 0x3c45, + 0x6b6: 0xa000, 0x6b7: 0xa000, 0x6b8: 0x3c4c, 0x6b9: 0x3c53, 0x6ba: 0xa000, 0x6bb: 0xa000, + 0x6bc: 0xa000, 0x6bd: 0xa000, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x3c5a, 0x6c1: 0x3c61, 0x6c2: 0xa000, 0x6c3: 0xa000, 0x6c4: 0x3c76, 0x6c5: 0x3c7d, + 0x6c6: 0xa000, 0x6c7: 0xa000, 0x6c8: 0x3c84, 0x6c9: 0x3c8b, + 0x6d1: 0xa000, + 0x6d2: 0xa000, + 0x6e2: 0xa000, + 0x6e8: 0xa000, 0x6e9: 0xa000, + 0x6eb: 0xa000, 0x6ec: 0x3ca0, 0x6ed: 0x3ca7, 0x6ee: 0x3cae, 0x6ef: 0x3cb5, + 0x6f2: 0xa000, 0x6f3: 0xa000, 0x6f4: 0xa000, 0x6f5: 0xa000, + // Block 0x1c, offset 0x700 + 0x706: 0xa000, 0x70b: 0xa000, + 0x70c: 0x3f08, 0x70d: 0xa000, 0x70e: 0x3f10, 0x70f: 0xa000, 0x710: 0x3f18, 0x711: 0xa000, + 0x712: 0x3f20, 0x713: 0xa000, 0x714: 0x3f28, 0x715: 0xa000, 0x716: 0x3f30, 0x717: 0xa000, + 0x718: 0x3f38, 0x719: 0xa000, 0x71a: 0x3f40, 0x71b: 0xa000, 0x71c: 0x3f48, 0x71d: 0xa000, + 0x71e: 0x3f50, 0x71f: 0xa000, 0x720: 0x3f58, 0x721: 0xa000, 0x722: 0x3f60, + 0x724: 0xa000, 0x725: 0x3f68, 0x726: 0xa000, 0x727: 0x3f70, 0x728: 0xa000, 0x729: 0x3f78, + 0x72f: 0xa000, + 0x730: 0x3f80, 0x731: 0x3f88, 0x732: 0xa000, 0x733: 0x3f90, 0x734: 0x3f98, 0x735: 0xa000, + 0x736: 0x3fa0, 0x737: 0x3fa8, 0x738: 0xa000, 0x739: 0x3fb0, 0x73a: 0x3fb8, 0x73b: 0xa000, + 0x73c: 0x3fc0, 0x73d: 0x3fc8, + // Block 0x1d, offset 0x740 + 0x754: 0x3f00, + 0x759: 0x9903, 0x75a: 0x9903, 0x75b: 0x8100, 0x75c: 0x8100, 0x75d: 0xa000, + 0x75e: 0x3fd0, + 0x766: 0xa000, + 0x76b: 0xa000, 0x76c: 0x3fe0, 0x76d: 0xa000, 0x76e: 0x3fe8, 0x76f: 0xa000, + 0x770: 0x3ff0, 0x771: 0xa000, 0x772: 0x3ff8, 0x773: 0xa000, 0x774: 0x4000, 0x775: 0xa000, + 0x776: 0x4008, 0x777: 0xa000, 0x778: 0x4010, 0x779: 0xa000, 0x77a: 0x4018, 0x77b: 0xa000, + 0x77c: 0x4020, 0x77d: 0xa000, 0x77e: 0x4028, 0x77f: 0xa000, + // Block 0x1e, offset 0x780 + 0x780: 0x4030, 0x781: 0xa000, 0x782: 0x4038, 0x784: 0xa000, 0x785: 0x4040, + 0x786: 0xa000, 0x787: 0x4048, 0x788: 0xa000, 0x789: 0x4050, + 0x78f: 0xa000, 0x790: 0x4058, 0x791: 0x4060, + 0x792: 0xa000, 0x793: 0x4068, 0x794: 0x4070, 0x795: 0xa000, 0x796: 0x4078, 0x797: 0x4080, + 0x798: 0xa000, 0x799: 0x4088, 0x79a: 0x4090, 0x79b: 0xa000, 0x79c: 0x4098, 0x79d: 0x40a0, + 0x7af: 0xa000, + 0x7b0: 0xa000, 0x7b1: 0xa000, 0x7b2: 0xa000, 0x7b4: 0x3fd8, + 0x7b7: 0x40a8, 0x7b8: 0x40b0, 0x7b9: 0x40b8, 0x7ba: 0x40c0, + 0x7bd: 0xa000, 0x7be: 0x40c8, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x1377, 0x7c1: 0x0cfb, 0x7c2: 0x13d3, 0x7c3: 0x139f, 0x7c4: 0x0e57, 0x7c5: 0x06eb, + 0x7c6: 0x08df, 0x7c7: 0x162b, 0x7c8: 0x162b, 0x7c9: 0x0a0b, 0x7ca: 0x145f, 0x7cb: 0x0943, + 0x7cc: 0x0a07, 0x7cd: 0x0bef, 0x7ce: 0x0fcf, 0x7cf: 0x115f, 0x7d0: 0x1297, 0x7d1: 0x12d3, + 0x7d2: 0x1307, 0x7d3: 0x141b, 0x7d4: 0x0d73, 0x7d5: 0x0dff, 0x7d6: 0x0eab, 0x7d7: 0x0f43, + 0x7d8: 0x125f, 0x7d9: 0x1447, 0x7da: 0x1573, 0x7db: 0x070f, 0x7dc: 0x08b3, 0x7dd: 0x0d87, + 0x7de: 0x0ecf, 0x7df: 0x1293, 0x7e0: 0x15c3, 0x7e1: 0x0ab3, 0x7e2: 0x0e77, 0x7e3: 0x1283, + 0x7e4: 0x1317, 0x7e5: 0x0c23, 0x7e6: 0x11bb, 0x7e7: 0x12df, 0x7e8: 0x0b1f, 0x7e9: 0x0d0f, + 0x7ea: 0x0e17, 0x7eb: 0x0f1b, 0x7ec: 0x1427, 0x7ed: 0x074f, 0x7ee: 0x07e7, 0x7ef: 0x0853, + 0x7f0: 0x0c8b, 0x7f1: 0x0d7f, 0x7f2: 0x0ecb, 0x7f3: 0x0fef, 0x7f4: 0x1177, 0x7f5: 0x128b, + 0x7f6: 0x12a3, 0x7f7: 0x13c7, 0x7f8: 0x14ef, 0x7f9: 0x15a3, 0x7fa: 0x15bf, 0x7fb: 0x102b, + 0x7fc: 0x106b, 0x7fd: 0x1123, 0x7fe: 0x1243, 0x7ff: 0x147b, + // Block 0x20, offset 0x800 + 0x800: 0x15cb, 0x801: 0x134b, 0x802: 0x09c7, 0x803: 0x0b3b, 0x804: 0x10db, 0x805: 0x119b, + 0x806: 0x0eff, 0x807: 0x1033, 0x808: 0x1397, 0x809: 0x14e7, 0x80a: 0x09c3, 0x80b: 0x0a8f, + 0x80c: 0x0d77, 0x80d: 0x0e2b, 0x80e: 0x0e5f, 0x80f: 0x1113, 0x810: 0x113b, 0x811: 0x14a7, + 0x812: 0x084f, 0x813: 0x11a7, 0x814: 0x07f3, 0x815: 0x07ef, 0x816: 0x1097, 0x817: 0x1127, + 0x818: 0x125b, 0x819: 0x14af, 0x81a: 0x1367, 0x81b: 0x0c27, 0x81c: 0x0d73, 0x81d: 0x1357, + 0x81e: 0x06f7, 0x81f: 0x0a63, 0x820: 0x0b93, 0x821: 0x0f2f, 0x822: 0x0faf, 0x823: 0x0873, + 0x824: 0x103b, 0x825: 0x075f, 0x826: 0x0b77, 0x827: 0x06d7, 0x828: 0x0deb, 0x829: 0x0ca3, + 0x82a: 0x110f, 0x82b: 0x08c7, 0x82c: 0x09b3, 0x82d: 0x0ffb, 0x82e: 0x1263, 0x82f: 0x133b, + 0x830: 0x0db7, 0x831: 0x13f7, 0x832: 0x0de3, 0x833: 0x0c37, 0x834: 0x121b, 0x835: 0x0c57, + 0x836: 0x0fab, 0x837: 0x072b, 0x838: 0x07a7, 0x839: 0x07eb, 0x83a: 0x0d53, 0x83b: 0x10fb, + 0x83c: 0x11f3, 0x83d: 0x1347, 0x83e: 0x145b, 0x83f: 0x085b, + // Block 0x21, offset 0x840 + 0x840: 0x090f, 0x841: 0x0a17, 0x842: 0x0b2f, 0x843: 0x0cbf, 0x844: 0x0e7b, 0x845: 0x103f, + 0x846: 0x1497, 0x847: 0x157b, 0x848: 0x15cf, 0x849: 0x15e7, 0x84a: 0x0837, 0x84b: 0x0cf3, + 0x84c: 0x0da3, 0x84d: 0x13eb, 0x84e: 0x0afb, 0x84f: 0x0bd7, 0x850: 0x0bf3, 0x851: 0x0c83, + 0x852: 0x0e6b, 0x853: 0x0eb7, 0x854: 0x0f67, 0x855: 0x108b, 0x856: 0x112f, 0x857: 0x1193, + 0x858: 0x13db, 0x859: 0x126b, 0x85a: 0x1403, 0x85b: 0x147f, 0x85c: 0x080f, 0x85d: 0x083b, + 0x85e: 0x0923, 0x85f: 0x0ea7, 0x860: 0x12f3, 0x861: 0x133b, 0x862: 0x0b1b, 0x863: 0x0b8b, + 0x864: 0x0c4f, 0x865: 0x0daf, 0x866: 0x10d7, 0x867: 0x0f23, 0x868: 0x073b, 0x869: 0x097f, + 0x86a: 0x0a63, 0x86b: 0x0ac7, 0x86c: 0x0b97, 0x86d: 0x0f3f, 0x86e: 0x0f5b, 0x86f: 0x116b, + 0x870: 0x118b, 0x871: 0x1463, 0x872: 0x14e3, 0x873: 0x14f3, 0x874: 0x152f, 0x875: 0x0753, + 0x876: 0x107f, 0x877: 0x144f, 0x878: 0x14cb, 0x879: 0x0baf, 0x87a: 0x0717, 0x87b: 0x0777, + 0x87c: 0x0a67, 0x87d: 0x0a87, 0x87e: 0x0caf, 0x87f: 0x0d73, + // Block 0x22, offset 0x880 + 0x880: 0x0ec3, 0x881: 0x0fcb, 0x882: 0x1277, 0x883: 0x1417, 0x884: 0x1623, 0x885: 0x0ce3, + 0x886: 0x14a3, 0x887: 0x0833, 0x888: 0x0d2f, 0x889: 0x0d3b, 0x88a: 0x0e0f, 0x88b: 0x0e47, + 0x88c: 0x0f4b, 0x88d: 0x0fa7, 0x88e: 0x1027, 0x88f: 0x110b, 0x890: 0x153b, 0x891: 0x07af, + 0x892: 0x0c03, 0x893: 0x14b3, 0x894: 0x0767, 0x895: 0x0aab, 0x896: 0x0e2f, 0x897: 0x13df, + 0x898: 0x0b67, 0x899: 0x0bb7, 0x89a: 0x0d43, 0x89b: 0x0f2f, 0x89c: 0x14bb, 0x89d: 0x0817, + 0x89e: 0x08ff, 0x89f: 0x0a97, 0x8a0: 0x0cd3, 0x8a1: 0x0d1f, 0x8a2: 0x0d5f, 0x8a3: 0x0df3, + 0x8a4: 0x0f47, 0x8a5: 0x0fbb, 0x8a6: 0x1157, 0x8a7: 0x12f7, 0x8a8: 0x1303, 0x8a9: 0x1457, + 0x8aa: 0x14d7, 0x8ab: 0x0883, 0x8ac: 0x0e4b, 0x8ad: 0x0903, 0x8ae: 0x0ec7, 0x8af: 0x0f6b, + 0x8b0: 0x1287, 0x8b1: 0x14bf, 0x8b2: 0x15ab, 0x8b3: 0x15d3, 0x8b4: 0x0d37, 0x8b5: 0x0e27, + 0x8b6: 0x11c3, 0x8b7: 0x10b7, 0x8b8: 0x10c3, 0x8b9: 0x10e7, 0x8ba: 0x0f17, 0x8bb: 0x0e9f, + 0x8bc: 0x1363, 0x8bd: 0x0733, 0x8be: 0x122b, 0x8bf: 0x081b, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x080b, 0x8c1: 0x0b0b, 0x8c2: 0x0c2b, 0x8c3: 0x10f3, 0x8c4: 0x0a53, 0x8c5: 0x0e03, + 0x8c6: 0x0cef, 0x8c7: 0x13e7, 0x8c8: 0x12e7, 0x8c9: 0x14ab, 0x8ca: 0x1323, 0x8cb: 0x0b27, + 0x8cc: 0x0787, 0x8cd: 0x095b, 0x8d0: 0x09af, + 0x8d2: 0x0cdf, 0x8d5: 0x07f7, 0x8d6: 0x0f1f, 0x8d7: 0x0fe3, + 0x8d8: 0x1047, 0x8d9: 0x1063, 0x8da: 0x1067, 0x8db: 0x107b, 0x8dc: 0x14fb, 0x8dd: 0x10eb, + 0x8de: 0x116f, 0x8e0: 0x128f, 0x8e2: 0x1353, + 0x8e5: 0x1407, 0x8e6: 0x1433, + 0x8ea: 0x154f, 0x8eb: 0x1553, 0x8ec: 0x1557, 0x8ed: 0x15bb, 0x8ee: 0x142b, 0x8ef: 0x14c7, + 0x8f0: 0x0757, 0x8f1: 0x077b, 0x8f2: 0x078f, 0x8f3: 0x084b, 0x8f4: 0x0857, 0x8f5: 0x0897, + 0x8f6: 0x094b, 0x8f7: 0x0967, 0x8f8: 0x096f, 0x8f9: 0x09ab, 0x8fa: 0x09b7, 0x8fb: 0x0a93, + 0x8fc: 0x0a9b, 0x8fd: 0x0ba3, 0x8fe: 0x0bcb, 0x8ff: 0x0bd3, + // Block 0x24, offset 0x900 + 0x900: 0x0beb, 0x901: 0x0c97, 0x902: 0x0cc7, 0x903: 0x0ce7, 0x904: 0x0d57, 0x905: 0x0e1b, + 0x906: 0x0e37, 0x907: 0x0e67, 0x908: 0x0ebb, 0x909: 0x0edb, 0x90a: 0x0f4f, 0x90b: 0x102f, + 0x90c: 0x104b, 0x90d: 0x1053, 0x90e: 0x104f, 0x90f: 0x1057, 0x910: 0x105b, 0x911: 0x105f, + 0x912: 0x1073, 0x913: 0x1077, 0x914: 0x109b, 0x915: 0x10af, 0x916: 0x10cb, 0x917: 0x112f, + 0x918: 0x1137, 0x919: 0x113f, 0x91a: 0x1153, 0x91b: 0x117b, 0x91c: 0x11cb, 0x91d: 0x11ff, + 0x91e: 0x11ff, 0x91f: 0x1267, 0x920: 0x130f, 0x921: 0x1327, 0x922: 0x135b, 0x923: 0x135f, + 0x924: 0x13a3, 0x925: 0x13a7, 0x926: 0x13ff, 0x927: 0x1407, 0x928: 0x14db, 0x929: 0x151f, + 0x92a: 0x1537, 0x92b: 0x0b9b, 0x92c: 0x171e, 0x92d: 0x11e3, + 0x930: 0x06df, 0x931: 0x07e3, 0x932: 0x07a3, 0x933: 0x074b, 0x934: 0x078b, 0x935: 0x07b7, + 0x936: 0x0847, 0x937: 0x0863, 0x938: 0x094b, 0x939: 0x0937, 0x93a: 0x0947, 0x93b: 0x0963, + 0x93c: 0x09af, 0x93d: 0x09bf, 0x93e: 0x0a03, 0x93f: 0x0a0f, + // Block 0x25, offset 0x940 + 0x940: 0x0a2b, 0x941: 0x0a3b, 0x942: 0x0b23, 0x943: 0x0b2b, 0x944: 0x0b5b, 0x945: 0x0b7b, + 0x946: 0x0bab, 0x947: 0x0bc3, 0x948: 0x0bb3, 0x949: 0x0bd3, 0x94a: 0x0bc7, 0x94b: 0x0beb, + 0x94c: 0x0c07, 0x94d: 0x0c5f, 0x94e: 0x0c6b, 0x94f: 0x0c73, 0x950: 0x0c9b, 0x951: 0x0cdf, + 0x952: 0x0d0f, 0x953: 0x0d13, 0x954: 0x0d27, 0x955: 0x0da7, 0x956: 0x0db7, 0x957: 0x0e0f, + 0x958: 0x0e5b, 0x959: 0x0e53, 0x95a: 0x0e67, 0x95b: 0x0e83, 0x95c: 0x0ebb, 0x95d: 0x1013, + 0x95e: 0x0edf, 0x95f: 0x0f13, 0x960: 0x0f1f, 0x961: 0x0f5f, 0x962: 0x0f7b, 0x963: 0x0f9f, + 0x964: 0x0fc3, 0x965: 0x0fc7, 0x966: 0x0fe3, 0x967: 0x0fe7, 0x968: 0x0ff7, 0x969: 0x100b, + 0x96a: 0x1007, 0x96b: 0x1037, 0x96c: 0x10b3, 0x96d: 0x10cb, 0x96e: 0x10e3, 0x96f: 0x111b, + 0x970: 0x112f, 0x971: 0x114b, 0x972: 0x117b, 0x973: 0x122f, 0x974: 0x1257, 0x975: 0x12cb, + 0x976: 0x1313, 0x977: 0x131f, 0x978: 0x1327, 0x979: 0x133f, 0x97a: 0x1353, 0x97b: 0x1343, + 0x97c: 0x135b, 0x97d: 0x1357, 0x97e: 0x134f, 0x97f: 0x135f, + // Block 0x26, offset 0x980 + 0x980: 0x136b, 0x981: 0x13a7, 0x982: 0x13e3, 0x983: 0x1413, 0x984: 0x144b, 0x985: 0x146b, + 0x986: 0x14b7, 0x987: 0x14db, 0x988: 0x14fb, 0x989: 0x150f, 0x98a: 0x151f, 0x98b: 0x152b, + 0x98c: 0x1537, 0x98d: 0x158b, 0x98e: 0x162b, 0x98f: 0x16b5, 0x990: 0x16b0, 0x991: 0x16e2, + 0x992: 0x0607, 0x993: 0x062f, 0x994: 0x0633, 0x995: 0x1764, 0x996: 0x1791, 0x997: 0x1809, + 0x998: 0x1617, 0x999: 0x1627, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x06fb, 0x9c1: 0x06f3, 0x9c2: 0x0703, 0x9c3: 0x1647, 0x9c4: 0x0747, 0x9c5: 0x0757, + 0x9c6: 0x075b, 0x9c7: 0x0763, 0x9c8: 0x076b, 0x9c9: 0x076f, 0x9ca: 0x077b, 0x9cb: 0x0773, + 0x9cc: 0x05b3, 0x9cd: 0x165b, 0x9ce: 0x078f, 0x9cf: 0x0793, 0x9d0: 0x0797, 0x9d1: 0x07b3, + 0x9d2: 0x164c, 0x9d3: 0x05b7, 0x9d4: 0x079f, 0x9d5: 0x07bf, 0x9d6: 0x1656, 0x9d7: 0x07cf, + 0x9d8: 0x07d7, 0x9d9: 0x0737, 0x9da: 0x07df, 0x9db: 0x07e3, 0x9dc: 0x1831, 0x9dd: 0x07ff, + 0x9de: 0x0807, 0x9df: 0x05bf, 0x9e0: 0x081f, 0x9e1: 0x0823, 0x9e2: 0x082b, 0x9e3: 0x082f, + 0x9e4: 0x05c3, 0x9e5: 0x0847, 0x9e6: 0x084b, 0x9e7: 0x0857, 0x9e8: 0x0863, 0x9e9: 0x0867, + 0x9ea: 0x086b, 0x9eb: 0x0873, 0x9ec: 0x0893, 0x9ed: 0x0897, 0x9ee: 0x089f, 0x9ef: 0x08af, + 0x9f0: 0x08b7, 0x9f1: 0x08bb, 0x9f2: 0x08bb, 0x9f3: 0x08bb, 0x9f4: 0x166a, 0x9f5: 0x0e93, + 0x9f6: 0x08cf, 0x9f7: 0x08d7, 0x9f8: 0x166f, 0x9f9: 0x08e3, 0x9fa: 0x08eb, 0x9fb: 0x08f3, + 0x9fc: 0x091b, 0x9fd: 0x0907, 0x9fe: 0x0913, 0x9ff: 0x0917, + // Block 0x28, offset 0xa00 + 0xa00: 0x091f, 0xa01: 0x0927, 0xa02: 0x092b, 0xa03: 0x0933, 0xa04: 0x093b, 0xa05: 0x093f, + 0xa06: 0x093f, 0xa07: 0x0947, 0xa08: 0x094f, 0xa09: 0x0953, 0xa0a: 0x095f, 0xa0b: 0x0983, + 0xa0c: 0x0967, 0xa0d: 0x0987, 0xa0e: 0x096b, 0xa0f: 0x0973, 0xa10: 0x080b, 0xa11: 0x09cf, + 0xa12: 0x0997, 0xa13: 0x099b, 0xa14: 0x099f, 0xa15: 0x0993, 0xa16: 0x09a7, 0xa17: 0x09a3, + 0xa18: 0x09bb, 0xa19: 0x1674, 0xa1a: 0x09d7, 0xa1b: 0x09db, 0xa1c: 0x09e3, 0xa1d: 0x09ef, + 0xa1e: 0x09f7, 0xa1f: 0x0a13, 0xa20: 0x1679, 0xa21: 0x167e, 0xa22: 0x0a1f, 0xa23: 0x0a23, + 0xa24: 0x0a27, 0xa25: 0x0a1b, 0xa26: 0x0a2f, 0xa27: 0x05c7, 0xa28: 0x05cb, 0xa29: 0x0a37, + 0xa2a: 0x0a3f, 0xa2b: 0x0a3f, 0xa2c: 0x1683, 0xa2d: 0x0a5b, 0xa2e: 0x0a5f, 0xa2f: 0x0a63, + 0xa30: 0x0a6b, 0xa31: 0x1688, 0xa32: 0x0a73, 0xa33: 0x0a77, 0xa34: 0x0b4f, 0xa35: 0x0a7f, + 0xa36: 0x05cf, 0xa37: 0x0a8b, 0xa38: 0x0a9b, 0xa39: 0x0aa7, 0xa3a: 0x0aa3, 0xa3b: 0x1692, + 0xa3c: 0x0aaf, 0xa3d: 0x1697, 0xa3e: 0x0abb, 0xa3f: 0x0ab7, + // Block 0x29, offset 0xa40 + 0xa40: 0x0abf, 0xa41: 0x0acf, 0xa42: 0x0ad3, 0xa43: 0x05d3, 0xa44: 0x0ae3, 0xa45: 0x0aeb, + 0xa46: 0x0aef, 0xa47: 0x0af3, 0xa48: 0x05d7, 0xa49: 0x169c, 0xa4a: 0x05db, 0xa4b: 0x0b0f, + 0xa4c: 0x0b13, 0xa4d: 0x0b17, 0xa4e: 0x0b1f, 0xa4f: 0x1863, 0xa50: 0x0b37, 0xa51: 0x16a6, + 0xa52: 0x16a6, 0xa53: 0x11d7, 0xa54: 0x0b47, 0xa55: 0x0b47, 0xa56: 0x05df, 0xa57: 0x16c9, + 0xa58: 0x179b, 0xa59: 0x0b57, 0xa5a: 0x0b5f, 0xa5b: 0x05e3, 0xa5c: 0x0b73, 0xa5d: 0x0b83, + 0xa5e: 0x0b87, 0xa5f: 0x0b8f, 0xa60: 0x0b9f, 0xa61: 0x05eb, 0xa62: 0x05e7, 0xa63: 0x0ba3, + 0xa64: 0x16ab, 0xa65: 0x0ba7, 0xa66: 0x0bbb, 0xa67: 0x0bbf, 0xa68: 0x0bc3, 0xa69: 0x0bbf, + 0xa6a: 0x0bcf, 0xa6b: 0x0bd3, 0xa6c: 0x0be3, 0xa6d: 0x0bdb, 0xa6e: 0x0bdf, 0xa6f: 0x0be7, + 0xa70: 0x0beb, 0xa71: 0x0bef, 0xa72: 0x0bfb, 0xa73: 0x0bff, 0xa74: 0x0c17, 0xa75: 0x0c1f, + 0xa76: 0x0c2f, 0xa77: 0x0c43, 0xa78: 0x16ba, 0xa79: 0x0c3f, 0xa7a: 0x0c33, 0xa7b: 0x0c4b, + 0xa7c: 0x0c53, 0xa7d: 0x0c67, 0xa7e: 0x16bf, 0xa7f: 0x0c6f, + // Block 0x2a, offset 0xa80 + 0xa80: 0x0c63, 0xa81: 0x0c5b, 0xa82: 0x05ef, 0xa83: 0x0c77, 0xa84: 0x0c7f, 0xa85: 0x0c87, + 0xa86: 0x0c7b, 0xa87: 0x05f3, 0xa88: 0x0c97, 0xa89: 0x0c9f, 0xa8a: 0x16c4, 0xa8b: 0x0ccb, + 0xa8c: 0x0cff, 0xa8d: 0x0cdb, 0xa8e: 0x05ff, 0xa8f: 0x0ce7, 0xa90: 0x05fb, 0xa91: 0x05f7, + 0xa92: 0x07c3, 0xa93: 0x07c7, 0xa94: 0x0d03, 0xa95: 0x0ceb, 0xa96: 0x11ab, 0xa97: 0x0663, + 0xa98: 0x0d0f, 0xa99: 0x0d13, 0xa9a: 0x0d17, 0xa9b: 0x0d2b, 0xa9c: 0x0d23, 0xa9d: 0x16dd, + 0xa9e: 0x0603, 0xa9f: 0x0d3f, 0xaa0: 0x0d33, 0xaa1: 0x0d4f, 0xaa2: 0x0d57, 0xaa3: 0x16e7, + 0xaa4: 0x0d5b, 0xaa5: 0x0d47, 0xaa6: 0x0d63, 0xaa7: 0x0607, 0xaa8: 0x0d67, 0xaa9: 0x0d6b, + 0xaaa: 0x0d6f, 0xaab: 0x0d7b, 0xaac: 0x16ec, 0xaad: 0x0d83, 0xaae: 0x060b, 0xaaf: 0x0d8f, + 0xab0: 0x16f1, 0xab1: 0x0d93, 0xab2: 0x060f, 0xab3: 0x0d9f, 0xab4: 0x0dab, 0xab5: 0x0db7, + 0xab6: 0x0dbb, 0xab7: 0x16f6, 0xab8: 0x168d, 0xab9: 0x16fb, 0xaba: 0x0ddb, 0xabb: 0x1700, + 0xabc: 0x0de7, 0xabd: 0x0def, 0xabe: 0x0ddf, 0xabf: 0x0dfb, + // Block 0x2b, offset 0xac0 + 0xac0: 0x0e0b, 0xac1: 0x0e1b, 0xac2: 0x0e0f, 0xac3: 0x0e13, 0xac4: 0x0e1f, 0xac5: 0x0e23, + 0xac6: 0x1705, 0xac7: 0x0e07, 0xac8: 0x0e3b, 0xac9: 0x0e3f, 0xaca: 0x0613, 0xacb: 0x0e53, + 0xacc: 0x0e4f, 0xacd: 0x170a, 0xace: 0x0e33, 0xacf: 0x0e6f, 0xad0: 0x170f, 0xad1: 0x1714, + 0xad2: 0x0e73, 0xad3: 0x0e87, 0xad4: 0x0e83, 0xad5: 0x0e7f, 0xad6: 0x0617, 0xad7: 0x0e8b, + 0xad8: 0x0e9b, 0xad9: 0x0e97, 0xada: 0x0ea3, 0xadb: 0x1651, 0xadc: 0x0eb3, 0xadd: 0x1719, + 0xade: 0x0ebf, 0xadf: 0x1723, 0xae0: 0x0ed3, 0xae1: 0x0edf, 0xae2: 0x0ef3, 0xae3: 0x1728, + 0xae4: 0x0f07, 0xae5: 0x0f0b, 0xae6: 0x172d, 0xae7: 0x1732, 0xae8: 0x0f27, 0xae9: 0x0f37, + 0xaea: 0x061b, 0xaeb: 0x0f3b, 0xaec: 0x061f, 0xaed: 0x061f, 0xaee: 0x0f53, 0xaef: 0x0f57, + 0xaf0: 0x0f5f, 0xaf1: 0x0f63, 0xaf2: 0x0f6f, 0xaf3: 0x0623, 0xaf4: 0x0f87, 0xaf5: 0x1737, + 0xaf6: 0x0fa3, 0xaf7: 0x173c, 0xaf8: 0x0faf, 0xaf9: 0x16a1, 0xafa: 0x0fbf, 0xafb: 0x1741, + 0xafc: 0x1746, 0xafd: 0x174b, 0xafe: 0x0627, 0xaff: 0x062b, + // Block 0x2c, offset 0xb00 + 0xb00: 0x0ff7, 0xb01: 0x1755, 0xb02: 0x1750, 0xb03: 0x175a, 0xb04: 0x175f, 0xb05: 0x0fff, + 0xb06: 0x1003, 0xb07: 0x1003, 0xb08: 0x100b, 0xb09: 0x0633, 0xb0a: 0x100f, 0xb0b: 0x0637, + 0xb0c: 0x063b, 0xb0d: 0x1769, 0xb0e: 0x1023, 0xb0f: 0x102b, 0xb10: 0x1037, 0xb11: 0x063f, + 0xb12: 0x176e, 0xb13: 0x105b, 0xb14: 0x1773, 0xb15: 0x1778, 0xb16: 0x107b, 0xb17: 0x1093, + 0xb18: 0x0643, 0xb19: 0x109b, 0xb1a: 0x109f, 0xb1b: 0x10a3, 0xb1c: 0x177d, 0xb1d: 0x1782, + 0xb1e: 0x1782, 0xb1f: 0x10bb, 0xb20: 0x0647, 0xb21: 0x1787, 0xb22: 0x10cf, 0xb23: 0x10d3, + 0xb24: 0x064b, 0xb25: 0x178c, 0xb26: 0x10ef, 0xb27: 0x064f, 0xb28: 0x10ff, 0xb29: 0x10f7, + 0xb2a: 0x1107, 0xb2b: 0x1796, 0xb2c: 0x111f, 0xb2d: 0x0653, 0xb2e: 0x112b, 0xb2f: 0x1133, + 0xb30: 0x1143, 0xb31: 0x0657, 0xb32: 0x17a0, 0xb33: 0x17a5, 0xb34: 0x065b, 0xb35: 0x17aa, + 0xb36: 0x115b, 0xb37: 0x17af, 0xb38: 0x1167, 0xb39: 0x1173, 0xb3a: 0x117b, 0xb3b: 0x17b4, + 0xb3c: 0x17b9, 0xb3d: 0x118f, 0xb3e: 0x17be, 0xb3f: 0x1197, + // Block 0x2d, offset 0xb40 + 0xb40: 0x16ce, 0xb41: 0x065f, 0xb42: 0x11af, 0xb43: 0x11b3, 0xb44: 0x0667, 0xb45: 0x11b7, + 0xb46: 0x0a33, 0xb47: 0x17c3, 0xb48: 0x17c8, 0xb49: 0x16d3, 0xb4a: 0x16d8, 0xb4b: 0x11d7, + 0xb4c: 0x11db, 0xb4d: 0x13f3, 0xb4e: 0x066b, 0xb4f: 0x1207, 0xb50: 0x1203, 0xb51: 0x120b, + 0xb52: 0x083f, 0xb53: 0x120f, 0xb54: 0x1213, 0xb55: 0x1217, 0xb56: 0x121f, 0xb57: 0x17cd, + 0xb58: 0x121b, 0xb59: 0x1223, 0xb5a: 0x1237, 0xb5b: 0x123b, 0xb5c: 0x1227, 0xb5d: 0x123f, + 0xb5e: 0x1253, 0xb5f: 0x1267, 0xb60: 0x1233, 0xb61: 0x1247, 0xb62: 0x124b, 0xb63: 0x124f, + 0xb64: 0x17d2, 0xb65: 0x17dc, 0xb66: 0x17d7, 0xb67: 0x066f, 0xb68: 0x126f, 0xb69: 0x1273, + 0xb6a: 0x127b, 0xb6b: 0x17f0, 0xb6c: 0x127f, 0xb6d: 0x17e1, 0xb6e: 0x0673, 0xb6f: 0x0677, + 0xb70: 0x17e6, 0xb71: 0x17eb, 0xb72: 0x067b, 0xb73: 0x129f, 0xb74: 0x12a3, 0xb75: 0x12a7, + 0xb76: 0x12ab, 0xb77: 0x12b7, 0xb78: 0x12b3, 0xb79: 0x12bf, 0xb7a: 0x12bb, 0xb7b: 0x12cb, + 0xb7c: 0x12c3, 0xb7d: 0x12c7, 0xb7e: 0x12cf, 0xb7f: 0x067f, + // Block 0x2e, offset 0xb80 + 0xb80: 0x12d7, 0xb81: 0x12db, 0xb82: 0x0683, 0xb83: 0x12eb, 0xb84: 0x12ef, 0xb85: 0x17f5, + 0xb86: 0x12fb, 0xb87: 0x12ff, 0xb88: 0x0687, 0xb89: 0x130b, 0xb8a: 0x05bb, 0xb8b: 0x17fa, + 0xb8c: 0x17ff, 0xb8d: 0x068b, 0xb8e: 0x068f, 0xb8f: 0x1337, 0xb90: 0x134f, 0xb91: 0x136b, + 0xb92: 0x137b, 0xb93: 0x1804, 0xb94: 0x138f, 0xb95: 0x1393, 0xb96: 0x13ab, 0xb97: 0x13b7, + 0xb98: 0x180e, 0xb99: 0x1660, 0xb9a: 0x13c3, 0xb9b: 0x13bf, 0xb9c: 0x13cb, 0xb9d: 0x1665, + 0xb9e: 0x13d7, 0xb9f: 0x13e3, 0xba0: 0x1813, 0xba1: 0x1818, 0xba2: 0x1423, 0xba3: 0x142f, + 0xba4: 0x1437, 0xba5: 0x181d, 0xba6: 0x143b, 0xba7: 0x1467, 0xba8: 0x1473, 0xba9: 0x1477, + 0xbaa: 0x146f, 0xbab: 0x1483, 0xbac: 0x1487, 0xbad: 0x1822, 0xbae: 0x1493, 0xbaf: 0x0693, + 0xbb0: 0x149b, 0xbb1: 0x1827, 0xbb2: 0x0697, 0xbb3: 0x14d3, 0xbb4: 0x0ac3, 0xbb5: 0x14eb, + 0xbb6: 0x182c, 0xbb7: 0x1836, 0xbb8: 0x069b, 0xbb9: 0x069f, 0xbba: 0x1513, 0xbbb: 0x183b, + 0xbbc: 0x06a3, 0xbbd: 0x1840, 0xbbe: 0x152b, 0xbbf: 0x152b, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x1533, 0xbc1: 0x1845, 0xbc2: 0x154b, 0xbc3: 0x06a7, 0xbc4: 0x155b, 0xbc5: 0x1567, + 0xbc6: 0x156f, 0xbc7: 0x1577, 0xbc8: 0x06ab, 0xbc9: 0x184a, 0xbca: 0x158b, 0xbcb: 0x15a7, + 0xbcc: 0x15b3, 0xbcd: 0x06af, 0xbce: 0x06b3, 0xbcf: 0x15b7, 0xbd0: 0x184f, 0xbd1: 0x06b7, + 0xbd2: 0x1854, 0xbd3: 0x1859, 0xbd4: 0x185e, 0xbd5: 0x15db, 0xbd6: 0x06bb, 0xbd7: 0x15ef, + 0xbd8: 0x15f7, 0xbd9: 0x15fb, 0xbda: 0x1603, 0xbdb: 0x160b, 0xbdc: 0x1613, 0xbdd: 0x1868, +} + +// nfcIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var nfcIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x2e, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2f, 0xc7: 0x04, + 0xc8: 0x05, 0xca: 0x30, 0xcb: 0x31, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x32, + 0xd0: 0x09, 0xd1: 0x33, 0xd2: 0x34, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x35, + 0xd8: 0x36, 0xd9: 0x0c, 0xdb: 0x37, 0xdc: 0x38, 0xdd: 0x39, 0xdf: 0x3a, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, + 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a, + 0xf0: 0x13, + // Block 0x4, offset 0x100 + 0x120: 0x3b, 0x121: 0x3c, 0x123: 0x0d, 0x124: 0x3d, 0x125: 0x3e, 0x126: 0x3f, 0x127: 0x40, + 0x128: 0x41, 0x129: 0x42, 0x12a: 0x43, 0x12b: 0x44, 0x12c: 0x3f, 0x12d: 0x45, 0x12e: 0x46, 0x12f: 0x47, + 0x131: 0x48, 0x132: 0x49, 0x133: 0x4a, 0x134: 0x4b, 0x135: 0x4c, 0x137: 0x4d, + 0x138: 0x4e, 0x139: 0x4f, 0x13a: 0x50, 0x13b: 0x51, 0x13c: 0x52, 0x13d: 0x53, 0x13e: 0x54, 0x13f: 0x55, + // Block 0x5, offset 0x140 + 0x140: 0x56, 0x142: 0x57, 0x144: 0x58, 0x145: 0x59, 0x146: 0x5a, 0x147: 0x5b, + 0x14d: 0x5c, + 0x15c: 0x5d, 0x15f: 0x5e, + 0x162: 0x5f, 0x164: 0x60, + 0x168: 0x61, 0x169: 0x62, 0x16a: 0x63, 0x16c: 0x0e, 0x16d: 0x64, 0x16e: 0x65, 0x16f: 0x66, + 0x170: 0x67, 0x173: 0x68, 0x177: 0x0f, + 0x178: 0x10, 0x179: 0x11, 0x17a: 0x12, 0x17b: 0x13, 0x17c: 0x14, 0x17d: 0x15, 0x17e: 0x16, 0x17f: 0x17, + // Block 0x6, offset 0x180 + 0x180: 0x69, 0x183: 0x6a, 0x184: 0x6b, 0x186: 0x6c, 0x187: 0x6d, + 0x188: 0x6e, 0x189: 0x18, 0x18a: 0x19, 0x18b: 0x6f, 0x18c: 0x70, + 0x1ab: 0x71, + 0x1b3: 0x72, 0x1b5: 0x73, 0x1b7: 0x74, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x75, 0x1c1: 0x1a, 0x1c2: 0x1b, 0x1c3: 0x1c, 0x1c4: 0x76, 0x1c5: 0x77, + 0x1c9: 0x78, 0x1cc: 0x79, 0x1cd: 0x7a, + // Block 0x8, offset 0x200 + 0x219: 0x7b, 0x21a: 0x7c, 0x21b: 0x7d, + 0x220: 0x7e, 0x223: 0x7f, 0x224: 0x80, 0x225: 0x81, 0x226: 0x82, 0x227: 0x83, + 0x22a: 0x84, 0x22b: 0x85, 0x22f: 0x86, + 0x230: 0x87, 0x231: 0x88, 0x232: 0x89, 0x233: 0x8a, 0x234: 0x8b, 0x235: 0x8c, 0x236: 0x8d, 0x237: 0x87, + 0x238: 0x88, 0x239: 0x89, 0x23a: 0x8a, 0x23b: 0x8b, 0x23c: 0x8c, 0x23d: 0x8d, 0x23e: 0x87, 0x23f: 0x88, + // Block 0x9, offset 0x240 + 0x240: 0x89, 0x241: 0x8a, 0x242: 0x8b, 0x243: 0x8c, 0x244: 0x8d, 0x245: 0x87, 0x246: 0x88, 0x247: 0x89, + 0x248: 0x8a, 0x249: 0x8b, 0x24a: 0x8c, 0x24b: 0x8d, 0x24c: 0x87, 0x24d: 0x88, 0x24e: 0x89, 0x24f: 0x8a, + 0x250: 0x8b, 0x251: 0x8c, 0x252: 0x8d, 0x253: 0x87, 0x254: 0x88, 0x255: 0x89, 0x256: 0x8a, 0x257: 0x8b, + 0x258: 0x8c, 0x259: 0x8d, 0x25a: 0x87, 0x25b: 0x88, 0x25c: 0x89, 0x25d: 0x8a, 0x25e: 0x8b, 0x25f: 0x8c, + 0x260: 0x8d, 0x261: 0x87, 0x262: 0x88, 0x263: 0x89, 0x264: 0x8a, 0x265: 0x8b, 0x266: 0x8c, 0x267: 0x8d, + 0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26c: 0x8b, 0x26d: 0x8c, 0x26e: 0x8d, 0x26f: 0x87, + 0x270: 0x88, 0x271: 0x89, 0x272: 0x8a, 0x273: 0x8b, 0x274: 0x8c, 0x275: 0x8d, 0x276: 0x87, 0x277: 0x88, + 0x278: 0x89, 0x279: 0x8a, 0x27a: 0x8b, 0x27b: 0x8c, 0x27c: 0x8d, 0x27d: 0x87, 0x27e: 0x88, 0x27f: 0x89, + // Block 0xa, offset 0x280 + 0x280: 0x8a, 0x281: 0x8b, 0x282: 0x8c, 0x283: 0x8d, 0x284: 0x87, 0x285: 0x88, 0x286: 0x89, 0x287: 0x8a, + 0x288: 0x8b, 0x289: 0x8c, 0x28a: 0x8d, 0x28b: 0x87, 0x28c: 0x88, 0x28d: 0x89, 0x28e: 0x8a, 0x28f: 0x8b, + 0x290: 0x8c, 0x291: 0x8d, 0x292: 0x87, 0x293: 0x88, 0x294: 0x89, 0x295: 0x8a, 0x296: 0x8b, 0x297: 0x8c, + 0x298: 0x8d, 0x299: 0x87, 0x29a: 0x88, 0x29b: 0x89, 0x29c: 0x8a, 0x29d: 0x8b, 0x29e: 0x8c, 0x29f: 0x8d, + 0x2a0: 0x87, 0x2a1: 0x88, 0x2a2: 0x89, 0x2a3: 0x8a, 0x2a4: 0x8b, 0x2a5: 0x8c, 0x2a6: 0x8d, 0x2a7: 0x87, + 0x2a8: 0x88, 0x2a9: 0x89, 0x2aa: 0x8a, 0x2ab: 0x8b, 0x2ac: 0x8c, 0x2ad: 0x8d, 0x2ae: 0x87, 0x2af: 0x88, + 0x2b0: 0x89, 0x2b1: 0x8a, 0x2b2: 0x8b, 0x2b3: 0x8c, 0x2b4: 0x8d, 0x2b5: 0x87, 0x2b6: 0x88, 0x2b7: 0x89, + 0x2b8: 0x8a, 0x2b9: 0x8b, 0x2ba: 0x8c, 0x2bb: 0x8d, 0x2bc: 0x87, 0x2bd: 0x88, 0x2be: 0x89, 0x2bf: 0x8a, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x8b, 0x2c1: 0x8c, 0x2c2: 0x8d, 0x2c3: 0x87, 0x2c4: 0x88, 0x2c5: 0x89, 0x2c6: 0x8a, 0x2c7: 0x8b, + 0x2c8: 0x8c, 0x2c9: 0x8d, 0x2ca: 0x87, 0x2cb: 0x88, 0x2cc: 0x89, 0x2cd: 0x8a, 0x2ce: 0x8b, 0x2cf: 0x8c, + 0x2d0: 0x8d, 0x2d1: 0x87, 0x2d2: 0x88, 0x2d3: 0x89, 0x2d4: 0x8a, 0x2d5: 0x8b, 0x2d6: 0x8c, 0x2d7: 0x8d, + 0x2d8: 0x87, 0x2d9: 0x88, 0x2da: 0x89, 0x2db: 0x8a, 0x2dc: 0x8b, 0x2dd: 0x8c, 0x2de: 0x8e, + // Block 0xc, offset 0x300 + 0x324: 0x1d, 0x325: 0x1e, 0x326: 0x1f, 0x327: 0x20, + 0x328: 0x21, 0x329: 0x22, 0x32a: 0x23, 0x32b: 0x24, 0x32c: 0x8f, 0x32d: 0x90, 0x32e: 0x91, + 0x331: 0x92, 0x332: 0x93, 0x333: 0x94, 0x334: 0x95, + 0x338: 0x96, 0x339: 0x97, 0x33a: 0x98, 0x33b: 0x99, 0x33e: 0x9a, 0x33f: 0x9b, + // Block 0xd, offset 0x340 + 0x347: 0x9c, + 0x34b: 0x9d, 0x34d: 0x9e, + 0x368: 0x9f, 0x36b: 0xa0, + 0x374: 0xa1, + 0x37d: 0xa2, + // Block 0xe, offset 0x380 + 0x381: 0xa3, 0x382: 0xa4, 0x384: 0xa5, 0x385: 0x82, 0x387: 0xa6, + 0x388: 0xa7, 0x38b: 0xa8, 0x38c: 0xa9, 0x38d: 0xaa, + 0x391: 0xab, 0x392: 0xac, 0x393: 0xad, 0x396: 0xae, 0x397: 0xaf, + 0x398: 0x73, 0x39a: 0xb0, 0x39c: 0xb1, + 0x3a0: 0xb2, + 0x3a8: 0xb3, 0x3a9: 0xb4, 0x3aa: 0xb5, + 0x3b0: 0x73, 0x3b5: 0xb6, 0x3b6: 0xb7, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xb8, 0x3ec: 0xb9, + // Block 0x10, offset 0x400 + 0x432: 0xba, + // Block 0x11, offset 0x440 + 0x445: 0xbb, 0x446: 0xbc, 0x447: 0xbd, + 0x449: 0xbe, + // Block 0x12, offset 0x480 + 0x480: 0xbf, + 0x4a3: 0xc0, 0x4a5: 0xc1, + // Block 0x13, offset 0x4c0 + 0x4c8: 0xc2, + // Block 0x14, offset 0x500 + 0x520: 0x25, 0x521: 0x26, 0x522: 0x27, 0x523: 0x28, 0x524: 0x29, 0x525: 0x2a, 0x526: 0x2b, 0x527: 0x2c, + 0x528: 0x2d, + // Block 0x15, offset 0x540 + 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d, + 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11, + 0x56f: 0x12, +} + +// nfcSparseOffset: 149 entries, 298 bytes +var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x63, 0x68, 0x6a, 0x72, 0x79, 0x7c, 0x84, 0x88, 0x8c, 0x8e, 0x90, 0x99, 0x9d, 0xa4, 0xa9, 0xac, 0xb6, 0xb9, 0xc0, 0xc8, 0xcb, 0xcd, 0xcf, 0xd1, 0xd6, 0xe7, 0xf3, 0xf5, 0xfb, 0xfd, 0xff, 0x101, 0x103, 0x105, 0x107, 0x10a, 0x10d, 0x10f, 0x112, 0x115, 0x119, 0x11e, 0x127, 0x129, 0x12c, 0x12e, 0x139, 0x13d, 0x14b, 0x14e, 0x154, 0x15a, 0x165, 0x169, 0x16b, 0x16d, 0x16f, 0x171, 0x173, 0x179, 0x17d, 0x17f, 0x181, 0x189, 0x18d, 0x190, 0x192, 0x194, 0x196, 0x199, 0x19b, 0x19d, 0x19f, 0x1a1, 0x1a7, 0x1aa, 0x1ac, 0x1b3, 0x1b9, 0x1bf, 0x1c7, 0x1cd, 0x1d3, 0x1d9, 0x1dd, 0x1eb, 0x1f4, 0x1f7, 0x1fa, 0x1fc, 0x1ff, 0x201, 0x205, 0x20a, 0x20c, 0x20e, 0x213, 0x219, 0x21b, 0x21d, 0x21f, 0x225, 0x228, 0x22a, 0x230, 0x233, 0x23b, 0x242, 0x245, 0x248, 0x24a, 0x24d, 0x255, 0x259, 0x260, 0x263, 0x269, 0x26b, 0x26e, 0x270, 0x273, 0x275, 0x277, 0x279, 0x27c, 0x27e, 0x280, 0x282, 0x284, 0x291, 0x29b, 0x29d, 0x29f, 0x2a5, 0x2a7, 0x2aa} + +// nfcSparseValues: 684 entries, 2736 bytes +var nfcSparseValues = [684]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x04}, + {value: 0xa100, lo: 0xa8, hi: 0xa8}, + {value: 0x8100, lo: 0xaf, hi: 0xaf}, + {value: 0x8100, lo: 0xb4, hi: 0xb4}, + {value: 0x8100, lo: 0xb8, hi: 0xb8}, + // Block 0x1, offset 0x5 + {value: 0x0091, lo: 0x03}, + {value: 0x46e2, lo: 0xa0, hi: 0xa1}, + {value: 0x4714, lo: 0xaf, hi: 0xb0}, + {value: 0xa000, lo: 0xb7, hi: 0xb7}, + // Block 0x2, offset 0x9 + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + // Block 0x3, offset 0xb + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x98, hi: 0x9d}, + // Block 0x4, offset 0xd + {value: 0x0006, lo: 0x0a}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x85, hi: 0x85}, + {value: 0xa000, lo: 0x89, hi: 0x89}, + {value: 0x4840, lo: 0x8a, hi: 0x8a}, + {value: 0x485e, lo: 0x8b, hi: 0x8b}, + {value: 0x36c7, lo: 0x8c, hi: 0x8c}, + {value: 0x36df, lo: 0x8d, hi: 0x8d}, + {value: 0x4876, lo: 0x8e, hi: 0x8e}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x36fd, lo: 0x93, hi: 0x94}, + // Block 0x5, offset 0x18 + {value: 0x0000, lo: 0x0f}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0xa000, lo: 0x8d, hi: 0x8d}, + {value: 0x37a5, lo: 0x90, hi: 0x90}, + {value: 0x37b1, lo: 0x91, hi: 0x91}, + {value: 0x379f, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x3817, lo: 0x97, hi: 0x97}, + {value: 0x37e1, lo: 0x9c, hi: 0x9c}, + {value: 0x37c9, lo: 0x9d, hi: 0x9d}, + {value: 0x37f3, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x381d, lo: 0xb6, hi: 0xb6}, + {value: 0x3823, lo: 0xb7, hi: 0xb7}, + // Block 0x6, offset 0x28 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x83, hi: 0x87}, + // Block 0x7, offset 0x2a + {value: 0x0001, lo: 0x04}, + {value: 0x8113, lo: 0x81, hi: 0x82}, + {value: 0x8132, lo: 0x84, hi: 0x84}, + {value: 0x812d, lo: 0x85, hi: 0x85}, + {value: 0x810d, lo: 0x87, hi: 0x87}, + // Block 0x8, offset 0x2f + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x97}, + {value: 0x8119, lo: 0x98, hi: 0x98}, + {value: 0x811a, lo: 0x99, hi: 0x99}, + {value: 0x811b, lo: 0x9a, hi: 0x9a}, + {value: 0x3841, lo: 0xa2, hi: 0xa2}, + {value: 0x3847, lo: 0xa3, hi: 0xa3}, + {value: 0x3853, lo: 0xa4, hi: 0xa4}, + {value: 0x384d, lo: 0xa5, hi: 0xa5}, + {value: 0x3859, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x9, offset 0x3a + {value: 0x0000, lo: 0x0e}, + {value: 0x386b, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x385f, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3865, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8132, lo: 0x96, hi: 0x9c}, + {value: 0x8132, lo: 0x9f, hi: 0xa2}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa4}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + // Block 0xa, offset 0x49 + {value: 0x0000, lo: 0x0c}, + {value: 0x811f, lo: 0x91, hi: 0x91}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x812d, lo: 0xb1, hi: 0xb1}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb5, hi: 0xb6}, + {value: 0x812d, lo: 0xb7, hi: 0xb9}, + {value: 0x8132, lo: 0xba, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbc}, + {value: 0x8132, lo: 0xbd, hi: 0xbd}, + {value: 0x812d, lo: 0xbe, hi: 0xbe}, + {value: 0x8132, lo: 0xbf, hi: 0xbf}, + // Block 0xb, offset 0x56 + {value: 0x0005, lo: 0x07}, + {value: 0x8132, lo: 0x80, hi: 0x80}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x83}, + {value: 0x812d, lo: 0x84, hi: 0x85}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x812d, lo: 0x88, hi: 0x89}, + {value: 0x8132, lo: 0x8a, hi: 0x8a}, + // Block 0xc, offset 0x5e + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xab, hi: 0xb1}, + {value: 0x812d, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb3}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0xd, offset 0x63 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0x96, hi: 0x99}, + {value: 0x8132, lo: 0x9b, hi: 0xa3}, + {value: 0x8132, lo: 0xa5, hi: 0xa7}, + {value: 0x8132, lo: 0xa9, hi: 0xad}, + // Block 0xe, offset 0x68 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x99, hi: 0x9b}, + // Block 0xf, offset 0x6a + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3ed8, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ee0, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3ee8, lo: 0xb4, hi: 0xb4}, + {value: 0x9902, lo: 0xbc, hi: 0xbc}, + // Block 0x10, offset 0x72 + {value: 0x0008, lo: 0x06}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x91, hi: 0x91}, + {value: 0x812d, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x93, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x94}, + {value: 0x451c, lo: 0x98, hi: 0x9f}, + // Block 0x11, offset 0x79 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x12, offset 0x7c + {value: 0x0008, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2c9e, lo: 0x8b, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x455c, lo: 0x9c, hi: 0x9d}, + {value: 0x456c, lo: 0x9f, hi: 0x9f}, + {value: 0x8132, lo: 0xbe, hi: 0xbe}, + // Block 0x13, offset 0x84 + {value: 0x0000, lo: 0x03}, + {value: 0x4594, lo: 0xb3, hi: 0xb3}, + {value: 0x459c, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x14, offset 0x88 + {value: 0x0008, lo: 0x03}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x4574, lo: 0x99, hi: 0x9b}, + {value: 0x458c, lo: 0x9e, hi: 0x9e}, + // Block 0x15, offset 0x8c + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x16, offset 0x8e + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + // Block 0x17, offset 0x90 + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cb6, lo: 0x88, hi: 0x88}, + {value: 0x2cae, lo: 0x8b, hi: 0x8b}, + {value: 0x2cbe, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45a4, lo: 0x9c, hi: 0x9c}, + {value: 0x45ac, lo: 0x9d, hi: 0x9d}, + // Block 0x18, offset 0x99 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cc6, lo: 0x94, hi: 0x94}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x19, offset 0x9d + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cce, lo: 0x8a, hi: 0x8a}, + {value: 0x2cde, lo: 0x8b, hi: 0x8b}, + {value: 0x2cd6, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1a, offset 0xa4 + {value: 0x1801, lo: 0x04}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x3ef0, lo: 0x88, hi: 0x88}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8120, lo: 0x95, hi: 0x96}, + // Block 0x1b, offset 0xa9 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1c, offset 0xac + {value: 0x0000, lo: 0x09}, + {value: 0x2ce6, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cee, lo: 0x87, hi: 0x87}, + {value: 0x2cf6, lo: 0x88, hi: 0x88}, + {value: 0x2f50, lo: 0x8a, hi: 0x8a}, + {value: 0x2dd8, lo: 0x8b, hi: 0x8b}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1d, offset 0xb6 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1e, offset 0xb9 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cfe, lo: 0x8a, hi: 0x8a}, + {value: 0x2d0e, lo: 0x8b, hi: 0x8b}, + {value: 0x2d06, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1f, offset 0xc0 + {value: 0x6bea, lo: 0x07}, + {value: 0x9904, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3ef8, lo: 0x9a, hi: 0x9a}, + {value: 0x2f58, lo: 0x9c, hi: 0x9c}, + {value: 0x2de3, lo: 0x9d, hi: 0x9d}, + {value: 0x2d16, lo: 0x9e, hi: 0x9f}, + // Block 0x20, offset 0xc8 + {value: 0x0000, lo: 0x02}, + {value: 0x8122, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x21, offset 0xcb + {value: 0x0000, lo: 0x01}, + {value: 0x8123, lo: 0x88, hi: 0x8b}, + // Block 0x22, offset 0xcd + {value: 0x0000, lo: 0x01}, + {value: 0x8124, lo: 0xb8, hi: 0xb9}, + // Block 0x23, offset 0xcf + {value: 0x0000, lo: 0x01}, + {value: 0x8125, lo: 0x88, hi: 0x8b}, + // Block 0x24, offset 0xd1 + {value: 0x0000, lo: 0x04}, + {value: 0x812d, lo: 0x98, hi: 0x99}, + {value: 0x812d, lo: 0xb5, hi: 0xb5}, + {value: 0x812d, lo: 0xb7, hi: 0xb7}, + {value: 0x812b, lo: 0xb9, hi: 0xb9}, + // Block 0x25, offset 0xd6 + {value: 0x0000, lo: 0x10}, + {value: 0x2644, lo: 0x83, hi: 0x83}, + {value: 0x264b, lo: 0x8d, hi: 0x8d}, + {value: 0x2652, lo: 0x92, hi: 0x92}, + {value: 0x2659, lo: 0x97, hi: 0x97}, + {value: 0x2660, lo: 0x9c, hi: 0x9c}, + {value: 0x263d, lo: 0xa9, hi: 0xa9}, + {value: 0x8126, lo: 0xb1, hi: 0xb1}, + {value: 0x8127, lo: 0xb2, hi: 0xb2}, + {value: 0x4a84, lo: 0xb3, hi: 0xb3}, + {value: 0x8128, lo: 0xb4, hi: 0xb4}, + {value: 0x4a8d, lo: 0xb5, hi: 0xb5}, + {value: 0x45b4, lo: 0xb6, hi: 0xb6}, + {value: 0x8200, lo: 0xb7, hi: 0xb7}, + {value: 0x45bc, lo: 0xb8, hi: 0xb8}, + {value: 0x8200, lo: 0xb9, hi: 0xb9}, + {value: 0x8127, lo: 0xba, hi: 0xbd}, + // Block 0x26, offset 0xe7 + {value: 0x0000, lo: 0x0b}, + {value: 0x8127, lo: 0x80, hi: 0x80}, + {value: 0x4a96, lo: 0x81, hi: 0x81}, + {value: 0x8132, lo: 0x82, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0x86, hi: 0x87}, + {value: 0x266e, lo: 0x93, hi: 0x93}, + {value: 0x2675, lo: 0x9d, hi: 0x9d}, + {value: 0x267c, lo: 0xa2, hi: 0xa2}, + {value: 0x2683, lo: 0xa7, hi: 0xa7}, + {value: 0x268a, lo: 0xac, hi: 0xac}, + {value: 0x2667, lo: 0xb9, hi: 0xb9}, + // Block 0x27, offset 0xf3 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x86, hi: 0x86}, + // Block 0x28, offset 0xf5 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d1e, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x29, offset 0xfb + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + // Block 0x2a, offset 0xfd + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x80, hi: 0x92}, + // Block 0x2b, offset 0xff + {value: 0x0000, lo: 0x01}, + {value: 0xb900, lo: 0xa1, hi: 0xb5}, + // Block 0x2c, offset 0x101 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xa8, hi: 0xbf}, + // Block 0x2d, offset 0x103 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0x80, hi: 0x82}, + // Block 0x2e, offset 0x105 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9d, hi: 0x9f}, + // Block 0x2f, offset 0x107 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x94, hi: 0x94}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x30, offset 0x10a + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x9d, hi: 0x9d}, + // Block 0x31, offset 0x10d + {value: 0x0000, lo: 0x01}, + {value: 0x8131, lo: 0xa9, hi: 0xa9}, + // Block 0x32, offset 0x10f + {value: 0x0004, lo: 0x02}, + {value: 0x812e, lo: 0xb9, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbb}, + // Block 0x33, offset 0x112 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x97, hi: 0x97}, + {value: 0x812d, lo: 0x98, hi: 0x98}, + // Block 0x34, offset 0x115 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + {value: 0x8132, lo: 0xb5, hi: 0xbc}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x35, offset 0x119 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + {value: 0x812d, lo: 0xb5, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x36, offset 0x11e + {value: 0x0000, lo: 0x08}, + {value: 0x2d66, lo: 0x80, hi: 0x80}, + {value: 0x2d6e, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d76, lo: 0x83, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xac}, + {value: 0x8132, lo: 0xad, hi: 0xb3}, + // Block 0x37, offset 0x127 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xaa, hi: 0xab}, + // Block 0x38, offset 0x129 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xa6, hi: 0xa6}, + {value: 0x8104, lo: 0xb2, hi: 0xb3}, + // Block 0x39, offset 0x12c + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x3a, offset 0x12e + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812d, lo: 0x95, hi: 0x99}, + {value: 0x8132, lo: 0x9a, hi: 0x9b}, + {value: 0x812d, lo: 0x9c, hi: 0x9f}, + {value: 0x8132, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + {value: 0x8132, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb8, hi: 0xb9}, + // Block 0x3b, offset 0x139 + {value: 0x0004, lo: 0x03}, + {value: 0x0433, lo: 0x80, hi: 0x81}, + {value: 0x8100, lo: 0x97, hi: 0x97}, + {value: 0x8100, lo: 0xbe, hi: 0xbe}, + // Block 0x3c, offset 0x13d + {value: 0x0000, lo: 0x0d}, + {value: 0x8132, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8132, lo: 0x9b, hi: 0x9c}, + {value: 0x8132, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa7}, + {value: 0x812d, lo: 0xa8, hi: 0xa8}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xaf}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + // Block 0x3d, offset 0x14b + {value: 0x427b, lo: 0x02}, + {value: 0x01b8, lo: 0xa6, hi: 0xa6}, + {value: 0x0057, lo: 0xaa, hi: 0xab}, + // Block 0x3e, offset 0x14e + {value: 0x0007, lo: 0x05}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bb9, lo: 0x9a, hi: 0x9b}, + {value: 0x3bc7, lo: 0xae, hi: 0xae}, + // Block 0x3f, offset 0x154 + {value: 0x000e, lo: 0x05}, + {value: 0x3bce, lo: 0x8d, hi: 0x8e}, + {value: 0x3bd5, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x40, offset 0x15a + {value: 0x6408, lo: 0x0a}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3be3, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3bea, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3bf1, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3bf8, lo: 0xa4, hi: 0xa5}, + {value: 0x3bff, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x41, offset 0x165 + {value: 0x0007, lo: 0x03}, + {value: 0x3c68, lo: 0xa0, hi: 0xa1}, + {value: 0x3c92, lo: 0xa2, hi: 0xa3}, + {value: 0x3cbc, lo: 0xaa, hi: 0xad}, + // Block 0x42, offset 0x169 + {value: 0x0004, lo: 0x01}, + {value: 0x048b, lo: 0xa9, hi: 0xaa}, + // Block 0x43, offset 0x16b + {value: 0x0000, lo: 0x01}, + {value: 0x44dd, lo: 0x9c, hi: 0x9c}, + // Block 0x44, offset 0x16d + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xaf, hi: 0xb1}, + // Block 0x45, offset 0x16f + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x46, offset 0x171 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa0, hi: 0xbf}, + // Block 0x47, offset 0x173 + {value: 0x0000, lo: 0x05}, + {value: 0x812c, lo: 0xaa, hi: 0xaa}, + {value: 0x8131, lo: 0xab, hi: 0xab}, + {value: 0x8133, lo: 0xac, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x812f, lo: 0xae, hi: 0xaf}, + // Block 0x48, offset 0x179 + {value: 0x0000, lo: 0x03}, + {value: 0x4a9f, lo: 0xb3, hi: 0xb3}, + {value: 0x4a9f, lo: 0xb5, hi: 0xb6}, + {value: 0x4a9f, lo: 0xba, hi: 0xbf}, + // Block 0x49, offset 0x17d + {value: 0x0000, lo: 0x01}, + {value: 0x4a9f, lo: 0x8f, hi: 0xa3}, + // Block 0x4a, offset 0x17f + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xae, hi: 0xbe}, + // Block 0x4b, offset 0x181 + {value: 0x0000, lo: 0x07}, + {value: 0x8100, lo: 0x84, hi: 0x84}, + {value: 0x8100, lo: 0x87, hi: 0x87}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + {value: 0x8100, lo: 0x9e, hi: 0x9e}, + {value: 0x8100, lo: 0xa1, hi: 0xa1}, + {value: 0x8100, lo: 0xb2, hi: 0xb2}, + {value: 0x8100, lo: 0xbb, hi: 0xbb}, + // Block 0x4c, offset 0x189 + {value: 0x0000, lo: 0x03}, + {value: 0x8100, lo: 0x80, hi: 0x80}, + {value: 0x8100, lo: 0x8b, hi: 0x8b}, + {value: 0x8100, lo: 0x8e, hi: 0x8e}, + // Block 0x4d, offset 0x18d + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xaf, hi: 0xaf}, + {value: 0x8132, lo: 0xb4, hi: 0xbd}, + // Block 0x4e, offset 0x190 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9e, hi: 0x9f}, + // Block 0x4f, offset 0x192 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb1}, + // Block 0x50, offset 0x194 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + // Block 0x51, offset 0x196 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xa0, hi: 0xb1}, + // Block 0x52, offset 0x199 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xab, hi: 0xad}, + // Block 0x53, offset 0x19b + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x93, hi: 0x93}, + // Block 0x54, offset 0x19d + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb3, hi: 0xb3}, + // Block 0x55, offset 0x19f + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + // Block 0x56, offset 0x1a1 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x8132, lo: 0xbe, hi: 0xbf}, + // Block 0x57, offset 0x1a7 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + // Block 0x58, offset 0x1aa + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xad, hi: 0xad}, + // Block 0x59, offset 0x1ac + {value: 0x0000, lo: 0x06}, + {value: 0xe500, lo: 0x80, hi: 0x80}, + {value: 0xc600, lo: 0x81, hi: 0x9b}, + {value: 0xe500, lo: 0x9c, hi: 0x9c}, + {value: 0xc600, lo: 0x9d, hi: 0xb7}, + {value: 0xe500, lo: 0xb8, hi: 0xb8}, + {value: 0xc600, lo: 0xb9, hi: 0xbf}, + // Block 0x5a, offset 0x1b3 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x93}, + {value: 0xe500, lo: 0x94, hi: 0x94}, + {value: 0xc600, lo: 0x95, hi: 0xaf}, + {value: 0xe500, lo: 0xb0, hi: 0xb0}, + {value: 0xc600, lo: 0xb1, hi: 0xbf}, + // Block 0x5b, offset 0x1b9 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8b}, + {value: 0xe500, lo: 0x8c, hi: 0x8c}, + {value: 0xc600, lo: 0x8d, hi: 0xa7}, + {value: 0xe500, lo: 0xa8, hi: 0xa8}, + {value: 0xc600, lo: 0xa9, hi: 0xbf}, + // Block 0x5c, offset 0x1bf + {value: 0x0000, lo: 0x07}, + {value: 0xc600, lo: 0x80, hi: 0x83}, + {value: 0xe500, lo: 0x84, hi: 0x84}, + {value: 0xc600, lo: 0x85, hi: 0x9f}, + {value: 0xe500, lo: 0xa0, hi: 0xa0}, + {value: 0xc600, lo: 0xa1, hi: 0xbb}, + {value: 0xe500, lo: 0xbc, hi: 0xbc}, + {value: 0xc600, lo: 0xbd, hi: 0xbf}, + // Block 0x5d, offset 0x1c7 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x97}, + {value: 0xe500, lo: 0x98, hi: 0x98}, + {value: 0xc600, lo: 0x99, hi: 0xb3}, + {value: 0xe500, lo: 0xb4, hi: 0xb4}, + {value: 0xc600, lo: 0xb5, hi: 0xbf}, + // Block 0x5e, offset 0x1cd + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8f}, + {value: 0xe500, lo: 0x90, hi: 0x90}, + {value: 0xc600, lo: 0x91, hi: 0xab}, + {value: 0xe500, lo: 0xac, hi: 0xac}, + {value: 0xc600, lo: 0xad, hi: 0xbf}, + // Block 0x5f, offset 0x1d3 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + {value: 0xe500, lo: 0xa4, hi: 0xa4}, + {value: 0xc600, lo: 0xa5, hi: 0xbf}, + // Block 0x60, offset 0x1d9 + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x61, offset 0x1dd + {value: 0x0006, lo: 0x0d}, + {value: 0x4390, lo: 0x9d, hi: 0x9d}, + {value: 0x8115, lo: 0x9e, hi: 0x9e}, + {value: 0x4402, lo: 0x9f, hi: 0x9f}, + {value: 0x43f0, lo: 0xaa, hi: 0xab}, + {value: 0x44f4, lo: 0xac, hi: 0xac}, + {value: 0x44fc, lo: 0xad, hi: 0xad}, + {value: 0x4348, lo: 0xae, hi: 0xb1}, + {value: 0x4366, lo: 0xb2, hi: 0xb4}, + {value: 0x437e, lo: 0xb5, hi: 0xb6}, + {value: 0x438a, lo: 0xb8, hi: 0xb8}, + {value: 0x4396, lo: 0xb9, hi: 0xbb}, + {value: 0x43ae, lo: 0xbc, hi: 0xbc}, + {value: 0x43b4, lo: 0xbe, hi: 0xbe}, + // Block 0x62, offset 0x1eb + {value: 0x0006, lo: 0x08}, + {value: 0x43ba, lo: 0x80, hi: 0x81}, + {value: 0x43c6, lo: 0x83, hi: 0x84}, + {value: 0x43d8, lo: 0x86, hi: 0x89}, + {value: 0x43fc, lo: 0x8a, hi: 0x8a}, + {value: 0x4378, lo: 0x8b, hi: 0x8b}, + {value: 0x4360, lo: 0x8c, hi: 0x8c}, + {value: 0x43a8, lo: 0x8d, hi: 0x8d}, + {value: 0x43d2, lo: 0x8e, hi: 0x8e}, + // Block 0x63, offset 0x1f4 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0xa4, hi: 0xa5}, + {value: 0x8100, lo: 0xb0, hi: 0xb1}, + // Block 0x64, offset 0x1f7 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x9b, hi: 0x9d}, + {value: 0x8200, lo: 0x9e, hi: 0xa3}, + // Block 0x65, offset 0x1fa + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + // Block 0x66, offset 0x1fc + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x99, hi: 0x99}, + {value: 0x8200, lo: 0xb2, hi: 0xb4}, + // Block 0x67, offset 0x1ff + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xbc, hi: 0xbd}, + // Block 0x68, offset 0x201 + {value: 0x0000, lo: 0x03}, + {value: 0x8132, lo: 0xa0, hi: 0xa6}, + {value: 0x812d, lo: 0xa7, hi: 0xad}, + {value: 0x8132, lo: 0xae, hi: 0xaf}, + // Block 0x69, offset 0x205 + {value: 0x0000, lo: 0x04}, + {value: 0x8100, lo: 0x89, hi: 0x8c}, + {value: 0x8100, lo: 0xb0, hi: 0xb2}, + {value: 0x8100, lo: 0xb4, hi: 0xb4}, + {value: 0x8100, lo: 0xb6, hi: 0xbf}, + // Block 0x6a, offset 0x20a + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x81, hi: 0x8c}, + // Block 0x6b, offset 0x20c + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xb5, hi: 0xba}, + // Block 0x6c, offset 0x20e + {value: 0x0000, lo: 0x04}, + {value: 0x4a9f, lo: 0x9e, hi: 0x9f}, + {value: 0x4a9f, lo: 0xa3, hi: 0xa3}, + {value: 0x4a9f, lo: 0xa5, hi: 0xa6}, + {value: 0x4a9f, lo: 0xaa, hi: 0xaf}, + // Block 0x6d, offset 0x213 + {value: 0x0000, lo: 0x05}, + {value: 0x4a9f, lo: 0x82, hi: 0x87}, + {value: 0x4a9f, lo: 0x8a, hi: 0x8f}, + {value: 0x4a9f, lo: 0x92, hi: 0x97}, + {value: 0x4a9f, lo: 0x9a, hi: 0x9c}, + {value: 0x8100, lo: 0xa3, hi: 0xa3}, + // Block 0x6e, offset 0x219 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x6f, offset 0x21b + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xa0, hi: 0xa0}, + // Block 0x70, offset 0x21d + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb6, hi: 0xba}, + // Block 0x71, offset 0x21f + {value: 0x002c, lo: 0x05}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x8f, hi: 0x8f}, + {value: 0x8132, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x72, offset 0x225 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xa5, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + // Block 0x73, offset 0x228 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa4, hi: 0xa7}, + // Block 0x74, offset 0x22a + {value: 0x0000, lo: 0x05}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x8132, lo: 0x88, hi: 0x8a}, + {value: 0x812d, lo: 0x8b, hi: 0x8b}, + {value: 0x8132, lo: 0x8c, hi: 0x8c}, + {value: 0x812d, lo: 0x8d, hi: 0x90}, + // Block 0x75, offset 0x230 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x76, offset 0x233 + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x4238, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4242, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x424c, lo: 0xab, hi: 0xab}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x77, offset 0x23b + {value: 0x0000, lo: 0x06}, + {value: 0x8132, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d7e, lo: 0xae, hi: 0xae}, + {value: 0x2d88, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8104, lo: 0xb3, hi: 0xb4}, + // Block 0x78, offset 0x242 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x79, offset 0x245 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb5, hi: 0xb5}, + {value: 0x8102, lo: 0xb6, hi: 0xb6}, + // Block 0x7a, offset 0x248 + {value: 0x0002, lo: 0x01}, + {value: 0x8102, lo: 0xa9, hi: 0xaa}, + // Block 0x7b, offset 0x24a + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x7c, offset 0x24d + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d92, lo: 0x8b, hi: 0x8b}, + {value: 0x2d9c, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8132, lo: 0xa6, hi: 0xac}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + // Block 0x7d, offset 0x255 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x86, hi: 0x86}, + {value: 0x8132, lo: 0x9e, hi: 0x9e}, + // Block 0x7e, offset 0x259 + {value: 0x6b5a, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2db0, lo: 0xbb, hi: 0xbb}, + {value: 0x2da6, lo: 0xbc, hi: 0xbd}, + {value: 0x2dba, lo: 0xbe, hi: 0xbe}, + // Block 0x7f, offset 0x260 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x83, hi: 0x83}, + // Block 0x80, offset 0x263 + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dc4, lo: 0xba, hi: 0xba}, + {value: 0x2dce, lo: 0xbb, hi: 0xbb}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x81, offset 0x269 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0x80, hi: 0x80}, + // Block 0x82, offset 0x26b + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x83, offset 0x26e + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xab, hi: 0xab}, + // Block 0x84, offset 0x270 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb9, hi: 0xb9}, + {value: 0x8102, lo: 0xba, hi: 0xba}, + // Block 0x85, offset 0x273 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x86, offset 0x275 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x87, hi: 0x87}, + // Block 0x87, offset 0x277 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x99, hi: 0x99}, + // Block 0x88, offset 0x279 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0x82, hi: 0x82}, + {value: 0x8104, lo: 0x84, hi: 0x85}, + // Block 0x89, offset 0x27c + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x97, hi: 0x97}, + // Block 0x8a, offset 0x27e + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x8b, offset 0x280 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb6}, + // Block 0x8c, offset 0x282 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x8d, offset 0x284 + {value: 0x0000, lo: 0x0c}, + {value: 0x45cc, lo: 0x9e, hi: 0x9e}, + {value: 0x45d6, lo: 0x9f, hi: 0x9f}, + {value: 0x460a, lo: 0xa0, hi: 0xa0}, + {value: 0x4618, lo: 0xa1, hi: 0xa1}, + {value: 0x4626, lo: 0xa2, hi: 0xa2}, + {value: 0x4634, lo: 0xa3, hi: 0xa3}, + {value: 0x4642, lo: 0xa4, hi: 0xa4}, + {value: 0x812b, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8130, lo: 0xad, hi: 0xad}, + {value: 0x812b, lo: 0xae, hi: 0xb2}, + {value: 0x812d, lo: 0xbb, hi: 0xbf}, + // Block 0x8e, offset 0x291 + {value: 0x0000, lo: 0x09}, + {value: 0x812d, lo: 0x80, hi: 0x82}, + {value: 0x8132, lo: 0x85, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8b}, + {value: 0x8132, lo: 0xaa, hi: 0xad}, + {value: 0x45e0, lo: 0xbb, hi: 0xbb}, + {value: 0x45ea, lo: 0xbc, hi: 0xbc}, + {value: 0x4650, lo: 0xbd, hi: 0xbd}, + {value: 0x466c, lo: 0xbe, hi: 0xbe}, + {value: 0x465e, lo: 0xbf, hi: 0xbf}, + // Block 0x8f, offset 0x29b + {value: 0x0000, lo: 0x01}, + {value: 0x467a, lo: 0x80, hi: 0x80}, + // Block 0x90, offset 0x29d + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x82, hi: 0x84}, + // Block 0x91, offset 0x29f + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0x80, hi: 0x86}, + {value: 0x8132, lo: 0x88, hi: 0x98}, + {value: 0x8132, lo: 0x9b, hi: 0xa1}, + {value: 0x8132, lo: 0xa3, hi: 0xa4}, + {value: 0x8132, lo: 0xa6, hi: 0xaa}, + // Block 0x92, offset 0x2a5 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x90, hi: 0x96}, + // Block 0x93, offset 0x2a7 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x84, hi: 0x89}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x94, offset 0x2aa + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x93, hi: 0x93}, +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfkcTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfkcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfkcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfkcTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfkcValues[c0] + } + i := nfkcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfkcTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfkcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfkcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfkcTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfkcValues[c0] + } + i := nfkcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// nfkcTrie. Total size: 17248 bytes (16.84 KiB). Checksum: 4fb368372b6b1b27. +type nfkcTrie struct{} + +func newNfkcTrie(i int) *nfkcTrie { + return &nfkcTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *nfkcTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 92: + return uint16(nfkcValues[n<<6+uint32(b)]) + default: + n -= 92 + return uint16(nfkcSparse.lookup(n, b)) + } +} + +// nfkcValues: 94 blocks, 6016 entries, 12032 bytes +// The third block is the zero block. +var nfkcValues = [6016]uint16{ + // Block 0x0, offset 0x0 + 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000, + // Block 0x1, offset 0x40 + 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000, + 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000, + 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000, + 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000, + 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000, + 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000, + 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000, + 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000, + 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000, + 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x2f6f, 0xc1: 0x2f74, 0xc2: 0x4688, 0xc3: 0x2f79, 0xc4: 0x4697, 0xc5: 0x469c, + 0xc6: 0xa000, 0xc7: 0x46a6, 0xc8: 0x2fe2, 0xc9: 0x2fe7, 0xca: 0x46ab, 0xcb: 0x2ffb, + 0xcc: 0x306e, 0xcd: 0x3073, 0xce: 0x3078, 0xcf: 0x46bf, 0xd1: 0x3104, + 0xd2: 0x3127, 0xd3: 0x312c, 0xd4: 0x46c9, 0xd5: 0x46ce, 0xd6: 0x46dd, + 0xd8: 0xa000, 0xd9: 0x31b3, 0xda: 0x31b8, 0xdb: 0x31bd, 0xdc: 0x470f, 0xdd: 0x3235, + 0xe0: 0x327b, 0xe1: 0x3280, 0xe2: 0x4719, 0xe3: 0x3285, + 0xe4: 0x4728, 0xe5: 0x472d, 0xe6: 0xa000, 0xe7: 0x4737, 0xe8: 0x32ee, 0xe9: 0x32f3, + 0xea: 0x473c, 0xeb: 0x3307, 0xec: 0x337f, 0xed: 0x3384, 0xee: 0x3389, 0xef: 0x4750, + 0xf1: 0x3415, 0xf2: 0x3438, 0xf3: 0x343d, 0xf4: 0x475a, 0xf5: 0x475f, + 0xf6: 0x476e, 0xf8: 0xa000, 0xf9: 0x34c9, 0xfa: 0x34ce, 0xfb: 0x34d3, + 0xfc: 0x47a0, 0xfd: 0x3550, 0xff: 0x3569, + // Block 0x4, offset 0x100 + 0x100: 0x2f7e, 0x101: 0x328a, 0x102: 0x468d, 0x103: 0x471e, 0x104: 0x2f9c, 0x105: 0x32a8, + 0x106: 0x2fb0, 0x107: 0x32bc, 0x108: 0x2fb5, 0x109: 0x32c1, 0x10a: 0x2fba, 0x10b: 0x32c6, + 0x10c: 0x2fbf, 0x10d: 0x32cb, 0x10e: 0x2fc9, 0x10f: 0x32d5, + 0x112: 0x46b0, 0x113: 0x4741, 0x114: 0x2ff1, 0x115: 0x32fd, 0x116: 0x2ff6, 0x117: 0x3302, + 0x118: 0x3014, 0x119: 0x3320, 0x11a: 0x3005, 0x11b: 0x3311, 0x11c: 0x302d, 0x11d: 0x3339, + 0x11e: 0x3037, 0x11f: 0x3343, 0x120: 0x303c, 0x121: 0x3348, 0x122: 0x3046, 0x123: 0x3352, + 0x124: 0x304b, 0x125: 0x3357, 0x128: 0x307d, 0x129: 0x338e, + 0x12a: 0x3082, 0x12b: 0x3393, 0x12c: 0x3087, 0x12d: 0x3398, 0x12e: 0x30aa, 0x12f: 0x33b6, + 0x130: 0x308c, 0x132: 0x195d, 0x133: 0x19e7, 0x134: 0x30b4, 0x135: 0x33c0, + 0x136: 0x30c8, 0x137: 0x33d9, 0x139: 0x30d2, 0x13a: 0x33e3, 0x13b: 0x30dc, + 0x13c: 0x33ed, 0x13d: 0x30d7, 0x13e: 0x33e8, 0x13f: 0x1bac, + // Block 0x5, offset 0x140 + 0x140: 0x1c34, 0x143: 0x30ff, 0x144: 0x3410, 0x145: 0x3118, + 0x146: 0x3429, 0x147: 0x310e, 0x148: 0x341f, 0x149: 0x1c5c, + 0x14c: 0x46d3, 0x14d: 0x4764, 0x14e: 0x3131, 0x14f: 0x3442, 0x150: 0x313b, 0x151: 0x344c, + 0x154: 0x3159, 0x155: 0x346a, 0x156: 0x3172, 0x157: 0x3483, + 0x158: 0x3163, 0x159: 0x3474, 0x15a: 0x46f6, 0x15b: 0x4787, 0x15c: 0x317c, 0x15d: 0x348d, + 0x15e: 0x318b, 0x15f: 0x349c, 0x160: 0x46fb, 0x161: 0x478c, 0x162: 0x31a4, 0x163: 0x34ba, + 0x164: 0x3195, 0x165: 0x34ab, 0x168: 0x4705, 0x169: 0x4796, + 0x16a: 0x470a, 0x16b: 0x479b, 0x16c: 0x31c2, 0x16d: 0x34d8, 0x16e: 0x31cc, 0x16f: 0x34e2, + 0x170: 0x31d1, 0x171: 0x34e7, 0x172: 0x31ef, 0x173: 0x3505, 0x174: 0x3212, 0x175: 0x3528, + 0x176: 0x323a, 0x177: 0x3555, 0x178: 0x324e, 0x179: 0x325d, 0x17a: 0x357d, 0x17b: 0x3267, + 0x17c: 0x3587, 0x17d: 0x326c, 0x17e: 0x358c, 0x17f: 0x00a7, + // Block 0x6, offset 0x180 + 0x184: 0x2dee, 0x185: 0x2df4, + 0x186: 0x2dfa, 0x187: 0x1972, 0x188: 0x1975, 0x189: 0x1a08, 0x18a: 0x1987, 0x18b: 0x198a, + 0x18c: 0x1a3e, 0x18d: 0x2f88, 0x18e: 0x3294, 0x18f: 0x3096, 0x190: 0x33a2, 0x191: 0x3140, + 0x192: 0x3451, 0x193: 0x31d6, 0x194: 0x34ec, 0x195: 0x39cf, 0x196: 0x3b5e, 0x197: 0x39c8, + 0x198: 0x3b57, 0x199: 0x39d6, 0x19a: 0x3b65, 0x19b: 0x39c1, 0x19c: 0x3b50, + 0x19e: 0x38b0, 0x19f: 0x3a3f, 0x1a0: 0x38a9, 0x1a1: 0x3a38, 0x1a2: 0x35b3, 0x1a3: 0x35c5, + 0x1a6: 0x3041, 0x1a7: 0x334d, 0x1a8: 0x30be, 0x1a9: 0x33cf, + 0x1aa: 0x46ec, 0x1ab: 0x477d, 0x1ac: 0x3990, 0x1ad: 0x3b1f, 0x1ae: 0x35d7, 0x1af: 0x35dd, + 0x1b0: 0x33c5, 0x1b1: 0x1942, 0x1b2: 0x1945, 0x1b3: 0x19cf, 0x1b4: 0x3028, 0x1b5: 0x3334, + 0x1b8: 0x30fa, 0x1b9: 0x340b, 0x1ba: 0x38b7, 0x1bb: 0x3a46, + 0x1bc: 0x35ad, 0x1bd: 0x35bf, 0x1be: 0x35b9, 0x1bf: 0x35cb, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2f8d, 0x1c1: 0x3299, 0x1c2: 0x2f92, 0x1c3: 0x329e, 0x1c4: 0x300a, 0x1c5: 0x3316, + 0x1c6: 0x300f, 0x1c7: 0x331b, 0x1c8: 0x309b, 0x1c9: 0x33a7, 0x1ca: 0x30a0, 0x1cb: 0x33ac, + 0x1cc: 0x3145, 0x1cd: 0x3456, 0x1ce: 0x314a, 0x1cf: 0x345b, 0x1d0: 0x3168, 0x1d1: 0x3479, + 0x1d2: 0x316d, 0x1d3: 0x347e, 0x1d4: 0x31db, 0x1d5: 0x34f1, 0x1d6: 0x31e0, 0x1d7: 0x34f6, + 0x1d8: 0x3186, 0x1d9: 0x3497, 0x1da: 0x319f, 0x1db: 0x34b5, + 0x1de: 0x305a, 0x1df: 0x3366, + 0x1e6: 0x4692, 0x1e7: 0x4723, 0x1e8: 0x46ba, 0x1e9: 0x474b, + 0x1ea: 0x395f, 0x1eb: 0x3aee, 0x1ec: 0x393c, 0x1ed: 0x3acb, 0x1ee: 0x46d8, 0x1ef: 0x4769, + 0x1f0: 0x3958, 0x1f1: 0x3ae7, 0x1f2: 0x3244, 0x1f3: 0x355f, + // Block 0x8, offset 0x200 + 0x200: 0x9932, 0x201: 0x9932, 0x202: 0x9932, 0x203: 0x9932, 0x204: 0x9932, 0x205: 0x8132, + 0x206: 0x9932, 0x207: 0x9932, 0x208: 0x9932, 0x209: 0x9932, 0x20a: 0x9932, 0x20b: 0x9932, + 0x20c: 0x9932, 0x20d: 0x8132, 0x20e: 0x8132, 0x20f: 0x9932, 0x210: 0x8132, 0x211: 0x9932, + 0x212: 0x8132, 0x213: 0x9932, 0x214: 0x9932, 0x215: 0x8133, 0x216: 0x812d, 0x217: 0x812d, + 0x218: 0x812d, 0x219: 0x812d, 0x21a: 0x8133, 0x21b: 0x992b, 0x21c: 0x812d, 0x21d: 0x812d, + 0x21e: 0x812d, 0x21f: 0x812d, 0x220: 0x812d, 0x221: 0x8129, 0x222: 0x8129, 0x223: 0x992d, + 0x224: 0x992d, 0x225: 0x992d, 0x226: 0x992d, 0x227: 0x9929, 0x228: 0x9929, 0x229: 0x812d, + 0x22a: 0x812d, 0x22b: 0x812d, 0x22c: 0x812d, 0x22d: 0x992d, 0x22e: 0x992d, 0x22f: 0x812d, + 0x230: 0x992d, 0x231: 0x992d, 0x232: 0x812d, 0x233: 0x812d, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812d, 0x23a: 0x812d, 0x23b: 0x812d, + 0x23c: 0x812d, 0x23d: 0x8132, 0x23e: 0x8132, 0x23f: 0x8132, + // Block 0x9, offset 0x240 + 0x240: 0x49ae, 0x241: 0x49b3, 0x242: 0x9932, 0x243: 0x49b8, 0x244: 0x4a71, 0x245: 0x9936, + 0x246: 0x8132, 0x247: 0x812d, 0x248: 0x812d, 0x249: 0x812d, 0x24a: 0x8132, 0x24b: 0x8132, + 0x24c: 0x8132, 0x24d: 0x812d, 0x24e: 0x812d, 0x250: 0x8132, 0x251: 0x8132, + 0x252: 0x8132, 0x253: 0x812d, 0x254: 0x812d, 0x255: 0x812d, 0x256: 0x812d, 0x257: 0x8132, + 0x258: 0x8133, 0x259: 0x812d, 0x25a: 0x812d, 0x25b: 0x8132, 0x25c: 0x8134, 0x25d: 0x8135, + 0x25e: 0x8135, 0x25f: 0x8134, 0x260: 0x8135, 0x261: 0x8135, 0x262: 0x8134, 0x263: 0x8132, + 0x264: 0x8132, 0x265: 0x8132, 0x266: 0x8132, 0x267: 0x8132, 0x268: 0x8132, 0x269: 0x8132, + 0x26a: 0x8132, 0x26b: 0x8132, 0x26c: 0x8132, 0x26d: 0x8132, 0x26e: 0x8132, 0x26f: 0x8132, + 0x274: 0x0170, + 0x27a: 0x42a5, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x425a, 0x285: 0x447b, + 0x286: 0x35e9, 0x287: 0x00ce, 0x288: 0x3607, 0x289: 0x3613, 0x28a: 0x3625, + 0x28c: 0x3643, 0x28e: 0x3655, 0x28f: 0x3673, 0x290: 0x3e08, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x3637, 0x2ab: 0x3667, 0x2ac: 0x47fe, 0x2ad: 0x3697, 0x2ae: 0x4828, 0x2af: 0x36a9, + 0x2b0: 0x3e70, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c1: 0xa000, 0x2c5: 0xa000, + 0x2c9: 0xa000, 0x2ca: 0x4840, 0x2cb: 0x485e, + 0x2cc: 0x36c7, 0x2cd: 0x36df, 0x2ce: 0x4876, 0x2d0: 0x01be, 0x2d1: 0x01d0, + 0x2d2: 0x01ac, 0x2d3: 0x430c, 0x2d4: 0x4312, 0x2d5: 0x01fa, 0x2d6: 0x01e8, + 0x2f0: 0x01d6, 0x2f1: 0x01eb, 0x2f2: 0x01ee, 0x2f4: 0x0188, 0x2f5: 0x01c7, + 0x2f9: 0x01a6, + // Block 0xc, offset 0x300 + 0x300: 0x3721, 0x301: 0x372d, 0x303: 0x371b, + 0x306: 0xa000, 0x307: 0x3709, + 0x30c: 0x375d, 0x30d: 0x3745, 0x30e: 0x376f, 0x310: 0xa000, + 0x313: 0xa000, 0x315: 0xa000, 0x316: 0xa000, 0x317: 0xa000, + 0x318: 0xa000, 0x319: 0x3751, 0x31a: 0xa000, + 0x31e: 0xa000, 0x323: 0xa000, + 0x327: 0xa000, + 0x32b: 0xa000, 0x32d: 0xa000, + 0x330: 0xa000, 0x333: 0xa000, 0x335: 0xa000, + 0x336: 0xa000, 0x337: 0xa000, 0x338: 0xa000, 0x339: 0x37d5, 0x33a: 0xa000, + 0x33e: 0xa000, + // Block 0xd, offset 0x340 + 0x341: 0x3733, 0x342: 0x37b7, + 0x350: 0x370f, 0x351: 0x3793, + 0x352: 0x3715, 0x353: 0x3799, 0x356: 0x3727, 0x357: 0x37ab, + 0x358: 0xa000, 0x359: 0xa000, 0x35a: 0x3829, 0x35b: 0x382f, 0x35c: 0x3739, 0x35d: 0x37bd, + 0x35e: 0x373f, 0x35f: 0x37c3, 0x362: 0x374b, 0x363: 0x37cf, + 0x364: 0x3757, 0x365: 0x37db, 0x366: 0x3763, 0x367: 0x37e7, 0x368: 0xa000, 0x369: 0xa000, + 0x36a: 0x3835, 0x36b: 0x383b, 0x36c: 0x378d, 0x36d: 0x3811, 0x36e: 0x3769, 0x36f: 0x37ed, + 0x370: 0x3775, 0x371: 0x37f9, 0x372: 0x377b, 0x373: 0x37ff, 0x374: 0x3781, 0x375: 0x3805, + 0x378: 0x3787, 0x379: 0x380b, + // Block 0xe, offset 0x380 + 0x387: 0x1d61, + 0x391: 0x812d, + 0x392: 0x8132, 0x393: 0x8132, 0x394: 0x8132, 0x395: 0x8132, 0x396: 0x812d, 0x397: 0x8132, + 0x398: 0x8132, 0x399: 0x8132, 0x39a: 0x812e, 0x39b: 0x812d, 0x39c: 0x8132, 0x39d: 0x8132, + 0x39e: 0x8132, 0x39f: 0x8132, 0x3a0: 0x8132, 0x3a1: 0x8132, 0x3a2: 0x812d, 0x3a3: 0x812d, + 0x3a4: 0x812d, 0x3a5: 0x812d, 0x3a6: 0x812d, 0x3a7: 0x812d, 0x3a8: 0x8132, 0x3a9: 0x8132, + 0x3aa: 0x812d, 0x3ab: 0x8132, 0x3ac: 0x8132, 0x3ad: 0x812e, 0x3ae: 0x8131, 0x3af: 0x8132, + 0x3b0: 0x8105, 0x3b1: 0x8106, 0x3b2: 0x8107, 0x3b3: 0x8108, 0x3b4: 0x8109, 0x3b5: 0x810a, + 0x3b6: 0x810b, 0x3b7: 0x810c, 0x3b8: 0x810d, 0x3b9: 0x810e, 0x3ba: 0x810e, 0x3bb: 0x810f, + 0x3bc: 0x8110, 0x3bd: 0x8111, 0x3bf: 0x8112, + // Block 0xf, offset 0x3c0 + 0x3c8: 0xa000, 0x3ca: 0xa000, 0x3cb: 0x8116, + 0x3cc: 0x8117, 0x3cd: 0x8118, 0x3ce: 0x8119, 0x3cf: 0x811a, 0x3d0: 0x811b, 0x3d1: 0x811c, + 0x3d2: 0x811d, 0x3d3: 0x9932, 0x3d4: 0x9932, 0x3d5: 0x992d, 0x3d6: 0x812d, 0x3d7: 0x8132, + 0x3d8: 0x8132, 0x3d9: 0x8132, 0x3da: 0x8132, 0x3db: 0x8132, 0x3dc: 0x812d, 0x3dd: 0x8132, + 0x3de: 0x8132, 0x3df: 0x812d, + 0x3f0: 0x811e, 0x3f5: 0x1d84, + 0x3f6: 0x2013, 0x3f7: 0x204f, 0x3f8: 0x204a, + // Block 0x10, offset 0x400 + 0x413: 0x812d, 0x414: 0x8132, 0x415: 0x8132, 0x416: 0x8132, 0x417: 0x8132, + 0x418: 0x8132, 0x419: 0x8132, 0x41a: 0x8132, 0x41b: 0x8132, 0x41c: 0x8132, 0x41d: 0x8132, + 0x41e: 0x8132, 0x41f: 0x8132, 0x420: 0x8132, 0x421: 0x8132, 0x423: 0x812d, + 0x424: 0x8132, 0x425: 0x8132, 0x426: 0x812d, 0x427: 0x8132, 0x428: 0x8132, 0x429: 0x812d, + 0x42a: 0x8132, 0x42b: 0x8132, 0x42c: 0x8132, 0x42d: 0x812d, 0x42e: 0x812d, 0x42f: 0x812d, + 0x430: 0x8116, 0x431: 0x8117, 0x432: 0x8118, 0x433: 0x8132, 0x434: 0x8132, 0x435: 0x8132, + 0x436: 0x812d, 0x437: 0x8132, 0x438: 0x8132, 0x439: 0x812d, 0x43a: 0x812d, 0x43b: 0x8132, + 0x43c: 0x8132, 0x43d: 0x8132, 0x43e: 0x8132, 0x43f: 0x8132, + // Block 0x11, offset 0x440 + 0x445: 0xa000, + 0x446: 0x2d26, 0x447: 0xa000, 0x448: 0x2d2e, 0x449: 0xa000, 0x44a: 0x2d36, 0x44b: 0xa000, + 0x44c: 0x2d3e, 0x44d: 0xa000, 0x44e: 0x2d46, 0x451: 0xa000, + 0x452: 0x2d4e, + 0x474: 0x8102, 0x475: 0x9900, + 0x47a: 0xa000, 0x47b: 0x2d56, + 0x47c: 0xa000, 0x47d: 0x2d5e, 0x47e: 0xa000, 0x47f: 0xa000, + // Block 0x12, offset 0x480 + 0x480: 0x0069, 0x481: 0x006b, 0x482: 0x006f, 0x483: 0x0083, 0x484: 0x00f5, 0x485: 0x00f8, + 0x486: 0x0413, 0x487: 0x0085, 0x488: 0x0089, 0x489: 0x008b, 0x48a: 0x0104, 0x48b: 0x0107, + 0x48c: 0x010a, 0x48d: 0x008f, 0x48f: 0x0097, 0x490: 0x009b, 0x491: 0x00e0, + 0x492: 0x009f, 0x493: 0x00fe, 0x494: 0x0417, 0x495: 0x041b, 0x496: 0x00a1, 0x497: 0x00a9, + 0x498: 0x00ab, 0x499: 0x0423, 0x49a: 0x012b, 0x49b: 0x00ad, 0x49c: 0x0427, 0x49d: 0x01be, + 0x49e: 0x01c1, 0x49f: 0x01c4, 0x4a0: 0x01fa, 0x4a1: 0x01fd, 0x4a2: 0x0093, 0x4a3: 0x00a5, + 0x4a4: 0x00ab, 0x4a5: 0x00ad, 0x4a6: 0x01be, 0x4a7: 0x01c1, 0x4a8: 0x01eb, 0x4a9: 0x01fa, + 0x4aa: 0x01fd, + 0x4b8: 0x020c, + // Block 0x13, offset 0x4c0 + 0x4db: 0x00fb, 0x4dc: 0x0087, 0x4dd: 0x0101, + 0x4de: 0x00d4, 0x4df: 0x010a, 0x4e0: 0x008d, 0x4e1: 0x010d, 0x4e2: 0x0110, 0x4e3: 0x0116, + 0x4e4: 0x011c, 0x4e5: 0x011f, 0x4e6: 0x0122, 0x4e7: 0x042b, 0x4e8: 0x016a, 0x4e9: 0x0128, + 0x4ea: 0x042f, 0x4eb: 0x016d, 0x4ec: 0x0131, 0x4ed: 0x012e, 0x4ee: 0x0134, 0x4ef: 0x0137, + 0x4f0: 0x013a, 0x4f1: 0x013d, 0x4f2: 0x0140, 0x4f3: 0x014c, 0x4f4: 0x014f, 0x4f5: 0x00ec, + 0x4f6: 0x0152, 0x4f7: 0x0155, 0x4f8: 0x041f, 0x4f9: 0x0158, 0x4fa: 0x015b, 0x4fb: 0x00b5, + 0x4fc: 0x015e, 0x4fd: 0x0161, 0x4fe: 0x0164, 0x4ff: 0x01d0, + // Block 0x14, offset 0x500 + 0x500: 0x8132, 0x501: 0x8132, 0x502: 0x812d, 0x503: 0x8132, 0x504: 0x8132, 0x505: 0x8132, + 0x506: 0x8132, 0x507: 0x8132, 0x508: 0x8132, 0x509: 0x8132, 0x50a: 0x812d, 0x50b: 0x8132, + 0x50c: 0x8132, 0x50d: 0x8135, 0x50e: 0x812a, 0x50f: 0x812d, 0x510: 0x8129, 0x511: 0x8132, + 0x512: 0x8132, 0x513: 0x8132, 0x514: 0x8132, 0x515: 0x8132, 0x516: 0x8132, 0x517: 0x8132, + 0x518: 0x8132, 0x519: 0x8132, 0x51a: 0x8132, 0x51b: 0x8132, 0x51c: 0x8132, 0x51d: 0x8132, + 0x51e: 0x8132, 0x51f: 0x8132, 0x520: 0x8132, 0x521: 0x8132, 0x522: 0x8132, 0x523: 0x8132, + 0x524: 0x8132, 0x525: 0x8132, 0x526: 0x8132, 0x527: 0x8132, 0x528: 0x8132, 0x529: 0x8132, + 0x52a: 0x8132, 0x52b: 0x8132, 0x52c: 0x8132, 0x52d: 0x8132, 0x52e: 0x8132, 0x52f: 0x8132, + 0x530: 0x8132, 0x531: 0x8132, 0x532: 0x8132, 0x533: 0x8132, 0x534: 0x8132, 0x535: 0x8132, + 0x536: 0x8133, 0x537: 0x8131, 0x538: 0x8131, 0x539: 0x812d, 0x53b: 0x8132, + 0x53c: 0x8134, 0x53d: 0x812d, 0x53e: 0x8132, 0x53f: 0x812d, + // Block 0x15, offset 0x540 + 0x540: 0x2f97, 0x541: 0x32a3, 0x542: 0x2fa1, 0x543: 0x32ad, 0x544: 0x2fa6, 0x545: 0x32b2, + 0x546: 0x2fab, 0x547: 0x32b7, 0x548: 0x38cc, 0x549: 0x3a5b, 0x54a: 0x2fc4, 0x54b: 0x32d0, + 0x54c: 0x2fce, 0x54d: 0x32da, 0x54e: 0x2fdd, 0x54f: 0x32e9, 0x550: 0x2fd3, 0x551: 0x32df, + 0x552: 0x2fd8, 0x553: 0x32e4, 0x554: 0x38ef, 0x555: 0x3a7e, 0x556: 0x38f6, 0x557: 0x3a85, + 0x558: 0x3019, 0x559: 0x3325, 0x55a: 0x301e, 0x55b: 0x332a, 0x55c: 0x3904, 0x55d: 0x3a93, + 0x55e: 0x3023, 0x55f: 0x332f, 0x560: 0x3032, 0x561: 0x333e, 0x562: 0x3050, 0x563: 0x335c, + 0x564: 0x305f, 0x565: 0x336b, 0x566: 0x3055, 0x567: 0x3361, 0x568: 0x3064, 0x569: 0x3370, + 0x56a: 0x3069, 0x56b: 0x3375, 0x56c: 0x30af, 0x56d: 0x33bb, 0x56e: 0x390b, 0x56f: 0x3a9a, + 0x570: 0x30b9, 0x571: 0x33ca, 0x572: 0x30c3, 0x573: 0x33d4, 0x574: 0x30cd, 0x575: 0x33de, + 0x576: 0x46c4, 0x577: 0x4755, 0x578: 0x3912, 0x579: 0x3aa1, 0x57a: 0x30e6, 0x57b: 0x33f7, + 0x57c: 0x30e1, 0x57d: 0x33f2, 0x57e: 0x30eb, 0x57f: 0x33fc, + // Block 0x16, offset 0x580 + 0x580: 0x30f0, 0x581: 0x3401, 0x582: 0x30f5, 0x583: 0x3406, 0x584: 0x3109, 0x585: 0x341a, + 0x586: 0x3113, 0x587: 0x3424, 0x588: 0x3122, 0x589: 0x3433, 0x58a: 0x311d, 0x58b: 0x342e, + 0x58c: 0x3935, 0x58d: 0x3ac4, 0x58e: 0x3943, 0x58f: 0x3ad2, 0x590: 0x394a, 0x591: 0x3ad9, + 0x592: 0x3951, 0x593: 0x3ae0, 0x594: 0x314f, 0x595: 0x3460, 0x596: 0x3154, 0x597: 0x3465, + 0x598: 0x315e, 0x599: 0x346f, 0x59a: 0x46f1, 0x59b: 0x4782, 0x59c: 0x3997, 0x59d: 0x3b26, + 0x59e: 0x3177, 0x59f: 0x3488, 0x5a0: 0x3181, 0x5a1: 0x3492, 0x5a2: 0x4700, 0x5a3: 0x4791, + 0x5a4: 0x399e, 0x5a5: 0x3b2d, 0x5a6: 0x39a5, 0x5a7: 0x3b34, 0x5a8: 0x39ac, 0x5a9: 0x3b3b, + 0x5aa: 0x3190, 0x5ab: 0x34a1, 0x5ac: 0x319a, 0x5ad: 0x34b0, 0x5ae: 0x31ae, 0x5af: 0x34c4, + 0x5b0: 0x31a9, 0x5b1: 0x34bf, 0x5b2: 0x31ea, 0x5b3: 0x3500, 0x5b4: 0x31f9, 0x5b5: 0x350f, + 0x5b6: 0x31f4, 0x5b7: 0x350a, 0x5b8: 0x39b3, 0x5b9: 0x3b42, 0x5ba: 0x39ba, 0x5bb: 0x3b49, + 0x5bc: 0x31fe, 0x5bd: 0x3514, 0x5be: 0x3203, 0x5bf: 0x3519, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x3208, 0x5c1: 0x351e, 0x5c2: 0x320d, 0x5c3: 0x3523, 0x5c4: 0x321c, 0x5c5: 0x3532, + 0x5c6: 0x3217, 0x5c7: 0x352d, 0x5c8: 0x3221, 0x5c9: 0x353c, 0x5ca: 0x3226, 0x5cb: 0x3541, + 0x5cc: 0x322b, 0x5cd: 0x3546, 0x5ce: 0x3249, 0x5cf: 0x3564, 0x5d0: 0x3262, 0x5d1: 0x3582, + 0x5d2: 0x3271, 0x5d3: 0x3591, 0x5d4: 0x3276, 0x5d5: 0x3596, 0x5d6: 0x337a, 0x5d7: 0x34a6, + 0x5d8: 0x3537, 0x5d9: 0x3573, 0x5da: 0x1be0, 0x5db: 0x42d7, + 0x5e0: 0x46a1, 0x5e1: 0x4732, 0x5e2: 0x2f83, 0x5e3: 0x328f, + 0x5e4: 0x3878, 0x5e5: 0x3a07, 0x5e6: 0x3871, 0x5e7: 0x3a00, 0x5e8: 0x3886, 0x5e9: 0x3a15, + 0x5ea: 0x387f, 0x5eb: 0x3a0e, 0x5ec: 0x38be, 0x5ed: 0x3a4d, 0x5ee: 0x3894, 0x5ef: 0x3a23, + 0x5f0: 0x388d, 0x5f1: 0x3a1c, 0x5f2: 0x38a2, 0x5f3: 0x3a31, 0x5f4: 0x389b, 0x5f5: 0x3a2a, + 0x5f6: 0x38c5, 0x5f7: 0x3a54, 0x5f8: 0x46b5, 0x5f9: 0x4746, 0x5fa: 0x3000, 0x5fb: 0x330c, + 0x5fc: 0x2fec, 0x5fd: 0x32f8, 0x5fe: 0x38da, 0x5ff: 0x3a69, + // Block 0x18, offset 0x600 + 0x600: 0x38d3, 0x601: 0x3a62, 0x602: 0x38e8, 0x603: 0x3a77, 0x604: 0x38e1, 0x605: 0x3a70, + 0x606: 0x38fd, 0x607: 0x3a8c, 0x608: 0x3091, 0x609: 0x339d, 0x60a: 0x30a5, 0x60b: 0x33b1, + 0x60c: 0x46e7, 0x60d: 0x4778, 0x60e: 0x3136, 0x60f: 0x3447, 0x610: 0x3920, 0x611: 0x3aaf, + 0x612: 0x3919, 0x613: 0x3aa8, 0x614: 0x392e, 0x615: 0x3abd, 0x616: 0x3927, 0x617: 0x3ab6, + 0x618: 0x3989, 0x619: 0x3b18, 0x61a: 0x396d, 0x61b: 0x3afc, 0x61c: 0x3966, 0x61d: 0x3af5, + 0x61e: 0x397b, 0x61f: 0x3b0a, 0x620: 0x3974, 0x621: 0x3b03, 0x622: 0x3982, 0x623: 0x3b11, + 0x624: 0x31e5, 0x625: 0x34fb, 0x626: 0x31c7, 0x627: 0x34dd, 0x628: 0x39e4, 0x629: 0x3b73, + 0x62a: 0x39dd, 0x62b: 0x3b6c, 0x62c: 0x39f2, 0x62d: 0x3b81, 0x62e: 0x39eb, 0x62f: 0x3b7a, + 0x630: 0x39f9, 0x631: 0x3b88, 0x632: 0x3230, 0x633: 0x354b, 0x634: 0x3258, 0x635: 0x3578, + 0x636: 0x3253, 0x637: 0x356e, 0x638: 0x323f, 0x639: 0x355a, + // Block 0x19, offset 0x640 + 0x640: 0x4804, 0x641: 0x480a, 0x642: 0x491e, 0x643: 0x4936, 0x644: 0x4926, 0x645: 0x493e, + 0x646: 0x492e, 0x647: 0x4946, 0x648: 0x47aa, 0x649: 0x47b0, 0x64a: 0x488e, 0x64b: 0x48a6, + 0x64c: 0x4896, 0x64d: 0x48ae, 0x64e: 0x489e, 0x64f: 0x48b6, 0x650: 0x4816, 0x651: 0x481c, + 0x652: 0x3db8, 0x653: 0x3dc8, 0x654: 0x3dc0, 0x655: 0x3dd0, + 0x658: 0x47b6, 0x659: 0x47bc, 0x65a: 0x3ce8, 0x65b: 0x3cf8, 0x65c: 0x3cf0, 0x65d: 0x3d00, + 0x660: 0x482e, 0x661: 0x4834, 0x662: 0x494e, 0x663: 0x4966, + 0x664: 0x4956, 0x665: 0x496e, 0x666: 0x495e, 0x667: 0x4976, 0x668: 0x47c2, 0x669: 0x47c8, + 0x66a: 0x48be, 0x66b: 0x48d6, 0x66c: 0x48c6, 0x66d: 0x48de, 0x66e: 0x48ce, 0x66f: 0x48e6, + 0x670: 0x4846, 0x671: 0x484c, 0x672: 0x3e18, 0x673: 0x3e30, 0x674: 0x3e20, 0x675: 0x3e38, + 0x676: 0x3e28, 0x677: 0x3e40, 0x678: 0x47ce, 0x679: 0x47d4, 0x67a: 0x3d18, 0x67b: 0x3d30, + 0x67c: 0x3d20, 0x67d: 0x3d38, 0x67e: 0x3d28, 0x67f: 0x3d40, + // Block 0x1a, offset 0x680 + 0x680: 0x4852, 0x681: 0x4858, 0x682: 0x3e48, 0x683: 0x3e58, 0x684: 0x3e50, 0x685: 0x3e60, + 0x688: 0x47da, 0x689: 0x47e0, 0x68a: 0x3d48, 0x68b: 0x3d58, + 0x68c: 0x3d50, 0x68d: 0x3d60, 0x690: 0x4864, 0x691: 0x486a, + 0x692: 0x3e80, 0x693: 0x3e98, 0x694: 0x3e88, 0x695: 0x3ea0, 0x696: 0x3e90, 0x697: 0x3ea8, + 0x699: 0x47e6, 0x69b: 0x3d68, 0x69d: 0x3d70, + 0x69f: 0x3d78, 0x6a0: 0x487c, 0x6a1: 0x4882, 0x6a2: 0x497e, 0x6a3: 0x4996, + 0x6a4: 0x4986, 0x6a5: 0x499e, 0x6a6: 0x498e, 0x6a7: 0x49a6, 0x6a8: 0x47ec, 0x6a9: 0x47f2, + 0x6aa: 0x48ee, 0x6ab: 0x4906, 0x6ac: 0x48f6, 0x6ad: 0x490e, 0x6ae: 0x48fe, 0x6af: 0x4916, + 0x6b0: 0x47f8, 0x6b1: 0x431e, 0x6b2: 0x3691, 0x6b3: 0x4324, 0x6b4: 0x4822, 0x6b5: 0x432a, + 0x6b6: 0x36a3, 0x6b7: 0x4330, 0x6b8: 0x36c1, 0x6b9: 0x4336, 0x6ba: 0x36d9, 0x6bb: 0x433c, + 0x6bc: 0x4870, 0x6bd: 0x4342, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x3da0, 0x6c1: 0x3da8, 0x6c2: 0x4184, 0x6c3: 0x41a2, 0x6c4: 0x418e, 0x6c5: 0x41ac, + 0x6c6: 0x4198, 0x6c7: 0x41b6, 0x6c8: 0x3cd8, 0x6c9: 0x3ce0, 0x6ca: 0x40d0, 0x6cb: 0x40ee, + 0x6cc: 0x40da, 0x6cd: 0x40f8, 0x6ce: 0x40e4, 0x6cf: 0x4102, 0x6d0: 0x3de8, 0x6d1: 0x3df0, + 0x6d2: 0x41c0, 0x6d3: 0x41de, 0x6d4: 0x41ca, 0x6d5: 0x41e8, 0x6d6: 0x41d4, 0x6d7: 0x41f2, + 0x6d8: 0x3d08, 0x6d9: 0x3d10, 0x6da: 0x410c, 0x6db: 0x412a, 0x6dc: 0x4116, 0x6dd: 0x4134, + 0x6de: 0x4120, 0x6df: 0x413e, 0x6e0: 0x3ec0, 0x6e1: 0x3ec8, 0x6e2: 0x41fc, 0x6e3: 0x421a, + 0x6e4: 0x4206, 0x6e5: 0x4224, 0x6e6: 0x4210, 0x6e7: 0x422e, 0x6e8: 0x3d80, 0x6e9: 0x3d88, + 0x6ea: 0x4148, 0x6eb: 0x4166, 0x6ec: 0x4152, 0x6ed: 0x4170, 0x6ee: 0x415c, 0x6ef: 0x417a, + 0x6f0: 0x3685, 0x6f1: 0x367f, 0x6f2: 0x3d90, 0x6f3: 0x368b, 0x6f4: 0x3d98, + 0x6f6: 0x4810, 0x6f7: 0x3db0, 0x6f8: 0x35f5, 0x6f9: 0x35ef, 0x6fa: 0x35e3, 0x6fb: 0x42ee, + 0x6fc: 0x35fb, 0x6fd: 0x4287, 0x6fe: 0x01d3, 0x6ff: 0x4287, + // Block 0x1c, offset 0x700 + 0x700: 0x42a0, 0x701: 0x4482, 0x702: 0x3dd8, 0x703: 0x369d, 0x704: 0x3de0, + 0x706: 0x483a, 0x707: 0x3df8, 0x708: 0x3601, 0x709: 0x42f4, 0x70a: 0x360d, 0x70b: 0x42fa, + 0x70c: 0x3619, 0x70d: 0x4489, 0x70e: 0x4490, 0x70f: 0x4497, 0x710: 0x36b5, 0x711: 0x36af, + 0x712: 0x3e00, 0x713: 0x44e4, 0x716: 0x36bb, 0x717: 0x3e10, + 0x718: 0x3631, 0x719: 0x362b, 0x71a: 0x361f, 0x71b: 0x4300, 0x71d: 0x449e, + 0x71e: 0x44a5, 0x71f: 0x44ac, 0x720: 0x36eb, 0x721: 0x36e5, 0x722: 0x3e68, 0x723: 0x44ec, + 0x724: 0x36cd, 0x725: 0x36d3, 0x726: 0x36f1, 0x727: 0x3e78, 0x728: 0x3661, 0x729: 0x365b, + 0x72a: 0x364f, 0x72b: 0x430c, 0x72c: 0x3649, 0x72d: 0x4474, 0x72e: 0x447b, 0x72f: 0x0081, + 0x732: 0x3eb0, 0x733: 0x36f7, 0x734: 0x3eb8, + 0x736: 0x4888, 0x737: 0x3ed0, 0x738: 0x363d, 0x739: 0x4306, 0x73a: 0x366d, 0x73b: 0x4318, + 0x73c: 0x3679, 0x73d: 0x425a, 0x73e: 0x428c, + // Block 0x1d, offset 0x740 + 0x740: 0x1bd8, 0x741: 0x1bdc, 0x742: 0x0047, 0x743: 0x1c54, 0x745: 0x1be8, + 0x746: 0x1bec, 0x747: 0x00e9, 0x749: 0x1c58, 0x74a: 0x008f, 0x74b: 0x0051, + 0x74c: 0x0051, 0x74d: 0x0051, 0x74e: 0x0091, 0x74f: 0x00da, 0x750: 0x0053, 0x751: 0x0053, + 0x752: 0x0059, 0x753: 0x0099, 0x755: 0x005d, 0x756: 0x198d, + 0x759: 0x0061, 0x75a: 0x0063, 0x75b: 0x0065, 0x75c: 0x0065, 0x75d: 0x0065, + 0x760: 0x199f, 0x761: 0x1bc8, 0x762: 0x19a8, + 0x764: 0x0075, 0x766: 0x01b8, 0x768: 0x0075, + 0x76a: 0x0057, 0x76b: 0x42d2, 0x76c: 0x0045, 0x76d: 0x0047, 0x76f: 0x008b, + 0x770: 0x004b, 0x771: 0x004d, 0x773: 0x005b, 0x774: 0x009f, 0x775: 0x0215, + 0x776: 0x0218, 0x777: 0x021b, 0x778: 0x021e, 0x779: 0x0093, 0x77b: 0x1b98, + 0x77c: 0x01e8, 0x77d: 0x01c1, 0x77e: 0x0179, 0x77f: 0x01a0, + // Block 0x1e, offset 0x780 + 0x780: 0x0463, 0x785: 0x0049, + 0x786: 0x0089, 0x787: 0x008b, 0x788: 0x0093, 0x789: 0x0095, + 0x790: 0x222e, 0x791: 0x223a, + 0x792: 0x22ee, 0x793: 0x2216, 0x794: 0x229a, 0x795: 0x2222, 0x796: 0x22a0, 0x797: 0x22b8, + 0x798: 0x22c4, 0x799: 0x2228, 0x79a: 0x22ca, 0x79b: 0x2234, 0x79c: 0x22be, 0x79d: 0x22d0, + 0x79e: 0x22d6, 0x79f: 0x1cbc, 0x7a0: 0x0053, 0x7a1: 0x195a, 0x7a2: 0x1ba4, 0x7a3: 0x1963, + 0x7a4: 0x006d, 0x7a5: 0x19ab, 0x7a6: 0x1bd0, 0x7a7: 0x1d48, 0x7a8: 0x1966, 0x7a9: 0x0071, + 0x7aa: 0x19b7, 0x7ab: 0x1bd4, 0x7ac: 0x0059, 0x7ad: 0x0047, 0x7ae: 0x0049, 0x7af: 0x005b, + 0x7b0: 0x0093, 0x7b1: 0x19e4, 0x7b2: 0x1c18, 0x7b3: 0x19ed, 0x7b4: 0x00ad, 0x7b5: 0x1a62, + 0x7b6: 0x1c4c, 0x7b7: 0x1d5c, 0x7b8: 0x19f0, 0x7b9: 0x00b1, 0x7ba: 0x1a65, 0x7bb: 0x1c50, + 0x7bc: 0x0099, 0x7bd: 0x0087, 0x7be: 0x0089, 0x7bf: 0x009b, + // Block 0x1f, offset 0x7c0 + 0x7c1: 0x3c06, 0x7c3: 0xa000, 0x7c4: 0x3c0d, 0x7c5: 0xa000, + 0x7c7: 0x3c14, 0x7c8: 0xa000, 0x7c9: 0x3c1b, + 0x7cd: 0xa000, + 0x7e0: 0x2f65, 0x7e1: 0xa000, 0x7e2: 0x3c29, + 0x7e4: 0xa000, 0x7e5: 0xa000, + 0x7ed: 0x3c22, 0x7ee: 0x2f60, 0x7ef: 0x2f6a, + 0x7f0: 0x3c30, 0x7f1: 0x3c37, 0x7f2: 0xa000, 0x7f3: 0xa000, 0x7f4: 0x3c3e, 0x7f5: 0x3c45, + 0x7f6: 0xa000, 0x7f7: 0xa000, 0x7f8: 0x3c4c, 0x7f9: 0x3c53, 0x7fa: 0xa000, 0x7fb: 0xa000, + 0x7fc: 0xa000, 0x7fd: 0xa000, + // Block 0x20, offset 0x800 + 0x800: 0x3c5a, 0x801: 0x3c61, 0x802: 0xa000, 0x803: 0xa000, 0x804: 0x3c76, 0x805: 0x3c7d, + 0x806: 0xa000, 0x807: 0xa000, 0x808: 0x3c84, 0x809: 0x3c8b, + 0x811: 0xa000, + 0x812: 0xa000, + 0x822: 0xa000, + 0x828: 0xa000, 0x829: 0xa000, + 0x82b: 0xa000, 0x82c: 0x3ca0, 0x82d: 0x3ca7, 0x82e: 0x3cae, 0x82f: 0x3cb5, + 0x832: 0xa000, 0x833: 0xa000, 0x834: 0xa000, 0x835: 0xa000, + // Block 0x21, offset 0x840 + 0x860: 0x0023, 0x861: 0x0025, 0x862: 0x0027, 0x863: 0x0029, + 0x864: 0x002b, 0x865: 0x002d, 0x866: 0x002f, 0x867: 0x0031, 0x868: 0x0033, 0x869: 0x1882, + 0x86a: 0x1885, 0x86b: 0x1888, 0x86c: 0x188b, 0x86d: 0x188e, 0x86e: 0x1891, 0x86f: 0x1894, + 0x870: 0x1897, 0x871: 0x189a, 0x872: 0x189d, 0x873: 0x18a6, 0x874: 0x1a68, 0x875: 0x1a6c, + 0x876: 0x1a70, 0x877: 0x1a74, 0x878: 0x1a78, 0x879: 0x1a7c, 0x87a: 0x1a80, 0x87b: 0x1a84, + 0x87c: 0x1a88, 0x87d: 0x1c80, 0x87e: 0x1c85, 0x87f: 0x1c8a, + // Block 0x22, offset 0x880 + 0x880: 0x1c8f, 0x881: 0x1c94, 0x882: 0x1c99, 0x883: 0x1c9e, 0x884: 0x1ca3, 0x885: 0x1ca8, + 0x886: 0x1cad, 0x887: 0x1cb2, 0x888: 0x187f, 0x889: 0x18a3, 0x88a: 0x18c7, 0x88b: 0x18eb, + 0x88c: 0x190f, 0x88d: 0x1918, 0x88e: 0x191e, 0x88f: 0x1924, 0x890: 0x192a, 0x891: 0x1b60, + 0x892: 0x1b64, 0x893: 0x1b68, 0x894: 0x1b6c, 0x895: 0x1b70, 0x896: 0x1b74, 0x897: 0x1b78, + 0x898: 0x1b7c, 0x899: 0x1b80, 0x89a: 0x1b84, 0x89b: 0x1b88, 0x89c: 0x1af4, 0x89d: 0x1af8, + 0x89e: 0x1afc, 0x89f: 0x1b00, 0x8a0: 0x1b04, 0x8a1: 0x1b08, 0x8a2: 0x1b0c, 0x8a3: 0x1b10, + 0x8a4: 0x1b14, 0x8a5: 0x1b18, 0x8a6: 0x1b1c, 0x8a7: 0x1b20, 0x8a8: 0x1b24, 0x8a9: 0x1b28, + 0x8aa: 0x1b2c, 0x8ab: 0x1b30, 0x8ac: 0x1b34, 0x8ad: 0x1b38, 0x8ae: 0x1b3c, 0x8af: 0x1b40, + 0x8b0: 0x1b44, 0x8b1: 0x1b48, 0x8b2: 0x1b4c, 0x8b3: 0x1b50, 0x8b4: 0x1b54, 0x8b5: 0x1b58, + 0x8b6: 0x0043, 0x8b7: 0x0045, 0x8b8: 0x0047, 0x8b9: 0x0049, 0x8ba: 0x004b, 0x8bb: 0x004d, + 0x8bc: 0x004f, 0x8bd: 0x0051, 0x8be: 0x0053, 0x8bf: 0x0055, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x06bf, 0x8c1: 0x06e3, 0x8c2: 0x06ef, 0x8c3: 0x06ff, 0x8c4: 0x0707, 0x8c5: 0x0713, + 0x8c6: 0x071b, 0x8c7: 0x0723, 0x8c8: 0x072f, 0x8c9: 0x0783, 0x8ca: 0x079b, 0x8cb: 0x07ab, + 0x8cc: 0x07bb, 0x8cd: 0x07cb, 0x8ce: 0x07db, 0x8cf: 0x07fb, 0x8d0: 0x07ff, 0x8d1: 0x0803, + 0x8d2: 0x0837, 0x8d3: 0x085f, 0x8d4: 0x086f, 0x8d5: 0x0877, 0x8d6: 0x087b, 0x8d7: 0x0887, + 0x8d8: 0x08a3, 0x8d9: 0x08a7, 0x8da: 0x08bf, 0x8db: 0x08c3, 0x8dc: 0x08cb, 0x8dd: 0x08db, + 0x8de: 0x0977, 0x8df: 0x098b, 0x8e0: 0x09cb, 0x8e1: 0x09df, 0x8e2: 0x09e7, 0x8e3: 0x09eb, + 0x8e4: 0x09fb, 0x8e5: 0x0a17, 0x8e6: 0x0a43, 0x8e7: 0x0a4f, 0x8e8: 0x0a6f, 0x8e9: 0x0a7b, + 0x8ea: 0x0a7f, 0x8eb: 0x0a83, 0x8ec: 0x0a9b, 0x8ed: 0x0a9f, 0x8ee: 0x0acb, 0x8ef: 0x0ad7, + 0x8f0: 0x0adf, 0x8f1: 0x0ae7, 0x8f2: 0x0af7, 0x8f3: 0x0aff, 0x8f4: 0x0b07, 0x8f5: 0x0b33, + 0x8f6: 0x0b37, 0x8f7: 0x0b3f, 0x8f8: 0x0b43, 0x8f9: 0x0b4b, 0x8fa: 0x0b53, 0x8fb: 0x0b63, + 0x8fc: 0x0b7f, 0x8fd: 0x0bf7, 0x8fe: 0x0c0b, 0x8ff: 0x0c0f, + // Block 0x24, offset 0x900 + 0x900: 0x0c8f, 0x901: 0x0c93, 0x902: 0x0ca7, 0x903: 0x0cab, 0x904: 0x0cb3, 0x905: 0x0cbb, + 0x906: 0x0cc3, 0x907: 0x0ccf, 0x908: 0x0cf7, 0x909: 0x0d07, 0x90a: 0x0d1b, 0x90b: 0x0d8b, + 0x90c: 0x0d97, 0x90d: 0x0da7, 0x90e: 0x0db3, 0x90f: 0x0dbf, 0x910: 0x0dc7, 0x911: 0x0dcb, + 0x912: 0x0dcf, 0x913: 0x0dd3, 0x914: 0x0dd7, 0x915: 0x0e8f, 0x916: 0x0ed7, 0x917: 0x0ee3, + 0x918: 0x0ee7, 0x919: 0x0eeb, 0x91a: 0x0eef, 0x91b: 0x0ef7, 0x91c: 0x0efb, 0x91d: 0x0f0f, + 0x91e: 0x0f2b, 0x91f: 0x0f33, 0x920: 0x0f73, 0x921: 0x0f77, 0x922: 0x0f7f, 0x923: 0x0f83, + 0x924: 0x0f8b, 0x925: 0x0f8f, 0x926: 0x0fb3, 0x927: 0x0fb7, 0x928: 0x0fd3, 0x929: 0x0fd7, + 0x92a: 0x0fdb, 0x92b: 0x0fdf, 0x92c: 0x0ff3, 0x92d: 0x1017, 0x92e: 0x101b, 0x92f: 0x101f, + 0x930: 0x1043, 0x931: 0x1083, 0x932: 0x1087, 0x933: 0x10a7, 0x934: 0x10b7, 0x935: 0x10bf, + 0x936: 0x10df, 0x937: 0x1103, 0x938: 0x1147, 0x939: 0x114f, 0x93a: 0x1163, 0x93b: 0x116f, + 0x93c: 0x1177, 0x93d: 0x117f, 0x93e: 0x1183, 0x93f: 0x1187, + // Block 0x25, offset 0x940 + 0x940: 0x119f, 0x941: 0x11a3, 0x942: 0x11bf, 0x943: 0x11c7, 0x944: 0x11cf, 0x945: 0x11d3, + 0x946: 0x11df, 0x947: 0x11e7, 0x948: 0x11eb, 0x949: 0x11ef, 0x94a: 0x11f7, 0x94b: 0x11fb, + 0x94c: 0x129b, 0x94d: 0x12af, 0x94e: 0x12e3, 0x94f: 0x12e7, 0x950: 0x12ef, 0x951: 0x131b, + 0x952: 0x1323, 0x953: 0x132b, 0x954: 0x1333, 0x955: 0x136f, 0x956: 0x1373, 0x957: 0x137b, + 0x958: 0x137f, 0x959: 0x1383, 0x95a: 0x13af, 0x95b: 0x13b3, 0x95c: 0x13bb, 0x95d: 0x13cf, + 0x95e: 0x13d3, 0x95f: 0x13ef, 0x960: 0x13f7, 0x961: 0x13fb, 0x962: 0x141f, 0x963: 0x143f, + 0x964: 0x1453, 0x965: 0x1457, 0x966: 0x145f, 0x967: 0x148b, 0x968: 0x148f, 0x969: 0x149f, + 0x96a: 0x14c3, 0x96b: 0x14cf, 0x96c: 0x14df, 0x96d: 0x14f7, 0x96e: 0x14ff, 0x96f: 0x1503, + 0x970: 0x1507, 0x971: 0x150b, 0x972: 0x1517, 0x973: 0x151b, 0x974: 0x1523, 0x975: 0x153f, + 0x976: 0x1543, 0x977: 0x1547, 0x978: 0x155f, 0x979: 0x1563, 0x97a: 0x156b, 0x97b: 0x157f, + 0x97c: 0x1583, 0x97d: 0x1587, 0x97e: 0x158f, 0x97f: 0x1593, + // Block 0x26, offset 0x980 + 0x986: 0xa000, 0x98b: 0xa000, + 0x98c: 0x3f08, 0x98d: 0xa000, 0x98e: 0x3f10, 0x98f: 0xa000, 0x990: 0x3f18, 0x991: 0xa000, + 0x992: 0x3f20, 0x993: 0xa000, 0x994: 0x3f28, 0x995: 0xa000, 0x996: 0x3f30, 0x997: 0xa000, + 0x998: 0x3f38, 0x999: 0xa000, 0x99a: 0x3f40, 0x99b: 0xa000, 0x99c: 0x3f48, 0x99d: 0xa000, + 0x99e: 0x3f50, 0x99f: 0xa000, 0x9a0: 0x3f58, 0x9a1: 0xa000, 0x9a2: 0x3f60, + 0x9a4: 0xa000, 0x9a5: 0x3f68, 0x9a6: 0xa000, 0x9a7: 0x3f70, 0x9a8: 0xa000, 0x9a9: 0x3f78, + 0x9af: 0xa000, + 0x9b0: 0x3f80, 0x9b1: 0x3f88, 0x9b2: 0xa000, 0x9b3: 0x3f90, 0x9b4: 0x3f98, 0x9b5: 0xa000, + 0x9b6: 0x3fa0, 0x9b7: 0x3fa8, 0x9b8: 0xa000, 0x9b9: 0x3fb0, 0x9ba: 0x3fb8, 0x9bb: 0xa000, + 0x9bc: 0x3fc0, 0x9bd: 0x3fc8, + // Block 0x27, offset 0x9c0 + 0x9d4: 0x3f00, + 0x9d9: 0x9903, 0x9da: 0x9903, 0x9db: 0x42dc, 0x9dc: 0x42e2, 0x9dd: 0xa000, + 0x9de: 0x3fd0, 0x9df: 0x26b4, + 0x9e6: 0xa000, + 0x9eb: 0xa000, 0x9ec: 0x3fe0, 0x9ed: 0xa000, 0x9ee: 0x3fe8, 0x9ef: 0xa000, + 0x9f0: 0x3ff0, 0x9f1: 0xa000, 0x9f2: 0x3ff8, 0x9f3: 0xa000, 0x9f4: 0x4000, 0x9f5: 0xa000, + 0x9f6: 0x4008, 0x9f7: 0xa000, 0x9f8: 0x4010, 0x9f9: 0xa000, 0x9fa: 0x4018, 0x9fb: 0xa000, + 0x9fc: 0x4020, 0x9fd: 0xa000, 0x9fe: 0x4028, 0x9ff: 0xa000, + // Block 0x28, offset 0xa00 + 0xa00: 0x4030, 0xa01: 0xa000, 0xa02: 0x4038, 0xa04: 0xa000, 0xa05: 0x4040, + 0xa06: 0xa000, 0xa07: 0x4048, 0xa08: 0xa000, 0xa09: 0x4050, + 0xa0f: 0xa000, 0xa10: 0x4058, 0xa11: 0x4060, + 0xa12: 0xa000, 0xa13: 0x4068, 0xa14: 0x4070, 0xa15: 0xa000, 0xa16: 0x4078, 0xa17: 0x4080, + 0xa18: 0xa000, 0xa19: 0x4088, 0xa1a: 0x4090, 0xa1b: 0xa000, 0xa1c: 0x4098, 0xa1d: 0x40a0, + 0xa2f: 0xa000, + 0xa30: 0xa000, 0xa31: 0xa000, 0xa32: 0xa000, 0xa34: 0x3fd8, + 0xa37: 0x40a8, 0xa38: 0x40b0, 0xa39: 0x40b8, 0xa3a: 0x40c0, + 0xa3d: 0xa000, 0xa3e: 0x40c8, 0xa3f: 0x26c9, + // Block 0x29, offset 0xa40 + 0xa40: 0x0367, 0xa41: 0x032b, 0xa42: 0x032f, 0xa43: 0x0333, 0xa44: 0x037b, 0xa45: 0x0337, + 0xa46: 0x033b, 0xa47: 0x033f, 0xa48: 0x0343, 0xa49: 0x0347, 0xa4a: 0x034b, 0xa4b: 0x034f, + 0xa4c: 0x0353, 0xa4d: 0x0357, 0xa4e: 0x035b, 0xa4f: 0x49bd, 0xa50: 0x49c3, 0xa51: 0x49c9, + 0xa52: 0x49cf, 0xa53: 0x49d5, 0xa54: 0x49db, 0xa55: 0x49e1, 0xa56: 0x49e7, 0xa57: 0x49ed, + 0xa58: 0x49f3, 0xa59: 0x49f9, 0xa5a: 0x49ff, 0xa5b: 0x4a05, 0xa5c: 0x4a0b, 0xa5d: 0x4a11, + 0xa5e: 0x4a17, 0xa5f: 0x4a1d, 0xa60: 0x4a23, 0xa61: 0x4a29, 0xa62: 0x4a2f, 0xa63: 0x4a35, + 0xa64: 0x03c3, 0xa65: 0x035f, 0xa66: 0x0363, 0xa67: 0x03e7, 0xa68: 0x03eb, 0xa69: 0x03ef, + 0xa6a: 0x03f3, 0xa6b: 0x03f7, 0xa6c: 0x03fb, 0xa6d: 0x03ff, 0xa6e: 0x036b, 0xa6f: 0x0403, + 0xa70: 0x0407, 0xa71: 0x036f, 0xa72: 0x0373, 0xa73: 0x0377, 0xa74: 0x037f, 0xa75: 0x0383, + 0xa76: 0x0387, 0xa77: 0x038b, 0xa78: 0x038f, 0xa79: 0x0393, 0xa7a: 0x0397, 0xa7b: 0x039b, + 0xa7c: 0x039f, 0xa7d: 0x03a3, 0xa7e: 0x03a7, 0xa7f: 0x03ab, + // Block 0x2a, offset 0xa80 + 0xa80: 0x03af, 0xa81: 0x03b3, 0xa82: 0x040b, 0xa83: 0x040f, 0xa84: 0x03b7, 0xa85: 0x03bb, + 0xa86: 0x03bf, 0xa87: 0x03c7, 0xa88: 0x03cb, 0xa89: 0x03cf, 0xa8a: 0x03d3, 0xa8b: 0x03d7, + 0xa8c: 0x03db, 0xa8d: 0x03df, 0xa8e: 0x03e3, + 0xa92: 0x06bf, 0xa93: 0x071b, 0xa94: 0x06cb, 0xa95: 0x097b, 0xa96: 0x06cf, 0xa97: 0x06e7, + 0xa98: 0x06d3, 0xa99: 0x0f93, 0xa9a: 0x0707, 0xa9b: 0x06db, 0xa9c: 0x06c3, 0xa9d: 0x09ff, + 0xa9e: 0x098f, 0xa9f: 0x072f, + // Block 0x2b, offset 0xac0 + 0xac0: 0x2054, 0xac1: 0x205a, 0xac2: 0x2060, 0xac3: 0x2066, 0xac4: 0x206c, 0xac5: 0x2072, + 0xac6: 0x2078, 0xac7: 0x207e, 0xac8: 0x2084, 0xac9: 0x208a, 0xaca: 0x2090, 0xacb: 0x2096, + 0xacc: 0x209c, 0xacd: 0x20a2, 0xace: 0x2726, 0xacf: 0x272f, 0xad0: 0x2738, 0xad1: 0x2741, + 0xad2: 0x274a, 0xad3: 0x2753, 0xad4: 0x275c, 0xad5: 0x2765, 0xad6: 0x276e, 0xad7: 0x2780, + 0xad8: 0x2789, 0xad9: 0x2792, 0xada: 0x279b, 0xadb: 0x27a4, 0xadc: 0x2777, 0xadd: 0x2bac, + 0xade: 0x2aed, 0xae0: 0x20a8, 0xae1: 0x20c0, 0xae2: 0x20b4, 0xae3: 0x2108, + 0xae4: 0x20c6, 0xae5: 0x20e4, 0xae6: 0x20ae, 0xae7: 0x20de, 0xae8: 0x20ba, 0xae9: 0x20f0, + 0xaea: 0x2120, 0xaeb: 0x213e, 0xaec: 0x2138, 0xaed: 0x212c, 0xaee: 0x217a, 0xaef: 0x210e, + 0xaf0: 0x211a, 0xaf1: 0x2132, 0xaf2: 0x2126, 0xaf3: 0x2150, 0xaf4: 0x20fc, 0xaf5: 0x2144, + 0xaf6: 0x216e, 0xaf7: 0x2156, 0xaf8: 0x20ea, 0xaf9: 0x20cc, 0xafa: 0x2102, 0xafb: 0x2114, + 0xafc: 0x214a, 0xafd: 0x20d2, 0xafe: 0x2174, 0xaff: 0x20f6, + // Block 0x2c, offset 0xb00 + 0xb00: 0x215c, 0xb01: 0x20d8, 0xb02: 0x2162, 0xb03: 0x2168, 0xb04: 0x092f, 0xb05: 0x0b03, + 0xb06: 0x0ca7, 0xb07: 0x10c7, + 0xb10: 0x1bc4, 0xb11: 0x18a9, + 0xb12: 0x18ac, 0xb13: 0x18af, 0xb14: 0x18b2, 0xb15: 0x18b5, 0xb16: 0x18b8, 0xb17: 0x18bb, + 0xb18: 0x18be, 0xb19: 0x18c1, 0xb1a: 0x18ca, 0xb1b: 0x18cd, 0xb1c: 0x18d0, 0xb1d: 0x18d3, + 0xb1e: 0x18d6, 0xb1f: 0x18d9, 0xb20: 0x0313, 0xb21: 0x031b, 0xb22: 0x031f, 0xb23: 0x0327, + 0xb24: 0x032b, 0xb25: 0x032f, 0xb26: 0x0337, 0xb27: 0x033f, 0xb28: 0x0343, 0xb29: 0x034b, + 0xb2a: 0x034f, 0xb2b: 0x0353, 0xb2c: 0x0357, 0xb2d: 0x035b, 0xb2e: 0x2e18, 0xb2f: 0x2e20, + 0xb30: 0x2e28, 0xb31: 0x2e30, 0xb32: 0x2e38, 0xb33: 0x2e40, 0xb34: 0x2e48, 0xb35: 0x2e50, + 0xb36: 0x2e60, 0xb37: 0x2e68, 0xb38: 0x2e70, 0xb39: 0x2e78, 0xb3a: 0x2e80, 0xb3b: 0x2e88, + 0xb3c: 0x2ed3, 0xb3d: 0x2e9b, 0xb3e: 0x2e58, + // Block 0x2d, offset 0xb40 + 0xb40: 0x06bf, 0xb41: 0x071b, 0xb42: 0x06cb, 0xb43: 0x097b, 0xb44: 0x071f, 0xb45: 0x07af, + 0xb46: 0x06c7, 0xb47: 0x07ab, 0xb48: 0x070b, 0xb49: 0x0887, 0xb4a: 0x0d07, 0xb4b: 0x0e8f, + 0xb4c: 0x0dd7, 0xb4d: 0x0d1b, 0xb4e: 0x145f, 0xb4f: 0x098b, 0xb50: 0x0ccf, 0xb51: 0x0d4b, + 0xb52: 0x0d0b, 0xb53: 0x104b, 0xb54: 0x08fb, 0xb55: 0x0f03, 0xb56: 0x1387, 0xb57: 0x105f, + 0xb58: 0x0843, 0xb59: 0x108f, 0xb5a: 0x0f9b, 0xb5b: 0x0a17, 0xb5c: 0x140f, 0xb5d: 0x077f, + 0xb5e: 0x08ab, 0xb5f: 0x0df7, 0xb60: 0x1527, 0xb61: 0x0743, 0xb62: 0x07d3, 0xb63: 0x0d9b, + 0xb64: 0x06cf, 0xb65: 0x06e7, 0xb66: 0x06d3, 0xb67: 0x0adb, 0xb68: 0x08ef, 0xb69: 0x087f, + 0xb6a: 0x0a57, 0xb6b: 0x0a4b, 0xb6c: 0x0feb, 0xb6d: 0x073f, 0xb6e: 0x139b, 0xb6f: 0x089b, + 0xb70: 0x09f3, 0xb71: 0x18dc, 0xb72: 0x18df, 0xb73: 0x18e2, 0xb74: 0x18e5, 0xb75: 0x18ee, + 0xb76: 0x18f1, 0xb77: 0x18f4, 0xb78: 0x18f7, 0xb79: 0x18fa, 0xb7a: 0x18fd, 0xb7b: 0x1900, + 0xb7c: 0x1903, 0xb7d: 0x1906, 0xb7e: 0x1909, 0xb7f: 0x1912, + // Block 0x2e, offset 0xb80 + 0xb80: 0x1cc6, 0xb81: 0x1cd5, 0xb82: 0x1ce4, 0xb83: 0x1cf3, 0xb84: 0x1d02, 0xb85: 0x1d11, + 0xb86: 0x1d20, 0xb87: 0x1d2f, 0xb88: 0x1d3e, 0xb89: 0x218c, 0xb8a: 0x219e, 0xb8b: 0x21b0, + 0xb8c: 0x1954, 0xb8d: 0x1c04, 0xb8e: 0x19d2, 0xb8f: 0x1ba8, 0xb90: 0x04cb, 0xb91: 0x04d3, + 0xb92: 0x04db, 0xb93: 0x04e3, 0xb94: 0x04eb, 0xb95: 0x04ef, 0xb96: 0x04f3, 0xb97: 0x04f7, + 0xb98: 0x04fb, 0xb99: 0x04ff, 0xb9a: 0x0503, 0xb9b: 0x0507, 0xb9c: 0x050b, 0xb9d: 0x050f, + 0xb9e: 0x0513, 0xb9f: 0x0517, 0xba0: 0x051b, 0xba1: 0x0523, 0xba2: 0x0527, 0xba3: 0x052b, + 0xba4: 0x052f, 0xba5: 0x0533, 0xba6: 0x0537, 0xba7: 0x053b, 0xba8: 0x053f, 0xba9: 0x0543, + 0xbaa: 0x0547, 0xbab: 0x054b, 0xbac: 0x054f, 0xbad: 0x0553, 0xbae: 0x0557, 0xbaf: 0x055b, + 0xbb0: 0x055f, 0xbb1: 0x0563, 0xbb2: 0x0567, 0xbb3: 0x056f, 0xbb4: 0x0577, 0xbb5: 0x057f, + 0xbb6: 0x0583, 0xbb7: 0x0587, 0xbb8: 0x058b, 0xbb9: 0x058f, 0xbba: 0x0593, 0xbbb: 0x0597, + 0xbbc: 0x059b, 0xbbd: 0x059f, 0xbbe: 0x05a3, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x2b0c, 0xbc1: 0x29a8, 0xbc2: 0x2b1c, 0xbc3: 0x2880, 0xbc4: 0x2ee4, 0xbc5: 0x288a, + 0xbc6: 0x2894, 0xbc7: 0x2f28, 0xbc8: 0x29b5, 0xbc9: 0x289e, 0xbca: 0x28a8, 0xbcb: 0x28b2, + 0xbcc: 0x29dc, 0xbcd: 0x29e9, 0xbce: 0x29c2, 0xbcf: 0x29cf, 0xbd0: 0x2ea9, 0xbd1: 0x29f6, + 0xbd2: 0x2a03, 0xbd3: 0x2bbe, 0xbd4: 0x26bb, 0xbd5: 0x2bd1, 0xbd6: 0x2be4, 0xbd7: 0x2b2c, + 0xbd8: 0x2a10, 0xbd9: 0x2bf7, 0xbda: 0x2c0a, 0xbdb: 0x2a1d, 0xbdc: 0x28bc, 0xbdd: 0x28c6, + 0xbde: 0x2eb7, 0xbdf: 0x2a2a, 0xbe0: 0x2b3c, 0xbe1: 0x2ef5, 0xbe2: 0x28d0, 0xbe3: 0x28da, + 0xbe4: 0x2a37, 0xbe5: 0x28e4, 0xbe6: 0x28ee, 0xbe7: 0x26d0, 0xbe8: 0x26d7, 0xbe9: 0x28f8, + 0xbea: 0x2902, 0xbeb: 0x2c1d, 0xbec: 0x2a44, 0xbed: 0x2b4c, 0xbee: 0x2c30, 0xbef: 0x2a51, + 0xbf0: 0x2916, 0xbf1: 0x290c, 0xbf2: 0x2f3c, 0xbf3: 0x2a5e, 0xbf4: 0x2c43, 0xbf5: 0x2920, + 0xbf6: 0x2b5c, 0xbf7: 0x292a, 0xbf8: 0x2a78, 0xbf9: 0x2934, 0xbfa: 0x2a85, 0xbfb: 0x2f06, + 0xbfc: 0x2a6b, 0xbfd: 0x2b6c, 0xbfe: 0x2a92, 0xbff: 0x26de, + // Block 0x30, offset 0xc00 + 0xc00: 0x2f17, 0xc01: 0x293e, 0xc02: 0x2948, 0xc03: 0x2a9f, 0xc04: 0x2952, 0xc05: 0x295c, + 0xc06: 0x2966, 0xc07: 0x2b7c, 0xc08: 0x2aac, 0xc09: 0x26e5, 0xc0a: 0x2c56, 0xc0b: 0x2e90, + 0xc0c: 0x2b8c, 0xc0d: 0x2ab9, 0xc0e: 0x2ec5, 0xc0f: 0x2970, 0xc10: 0x297a, 0xc11: 0x2ac6, + 0xc12: 0x26ec, 0xc13: 0x2ad3, 0xc14: 0x2b9c, 0xc15: 0x26f3, 0xc16: 0x2c69, 0xc17: 0x2984, + 0xc18: 0x1cb7, 0xc19: 0x1ccb, 0xc1a: 0x1cda, 0xc1b: 0x1ce9, 0xc1c: 0x1cf8, 0xc1d: 0x1d07, + 0xc1e: 0x1d16, 0xc1f: 0x1d25, 0xc20: 0x1d34, 0xc21: 0x1d43, 0xc22: 0x2192, 0xc23: 0x21a4, + 0xc24: 0x21b6, 0xc25: 0x21c2, 0xc26: 0x21ce, 0xc27: 0x21da, 0xc28: 0x21e6, 0xc29: 0x21f2, + 0xc2a: 0x21fe, 0xc2b: 0x220a, 0xc2c: 0x2246, 0xc2d: 0x2252, 0xc2e: 0x225e, 0xc2f: 0x226a, + 0xc30: 0x2276, 0xc31: 0x1c14, 0xc32: 0x19c6, 0xc33: 0x1936, 0xc34: 0x1be4, 0xc35: 0x1a47, + 0xc36: 0x1a56, 0xc37: 0x19cc, 0xc38: 0x1bfc, 0xc39: 0x1c00, 0xc3a: 0x1960, 0xc3b: 0x2701, + 0xc3c: 0x270f, 0xc3d: 0x26fa, 0xc3e: 0x2708, 0xc3f: 0x2ae0, + // Block 0x31, offset 0xc40 + 0xc40: 0x1a4a, 0xc41: 0x1a32, 0xc42: 0x1c60, 0xc43: 0x1a1a, 0xc44: 0x19f3, 0xc45: 0x1969, + 0xc46: 0x1978, 0xc47: 0x1948, 0xc48: 0x1bf0, 0xc49: 0x1d52, 0xc4a: 0x1a4d, 0xc4b: 0x1a35, + 0xc4c: 0x1c64, 0xc4d: 0x1c70, 0xc4e: 0x1a26, 0xc4f: 0x19fc, 0xc50: 0x1957, 0xc51: 0x1c1c, + 0xc52: 0x1bb0, 0xc53: 0x1b9c, 0xc54: 0x1bcc, 0xc55: 0x1c74, 0xc56: 0x1a29, 0xc57: 0x19c9, + 0xc58: 0x19ff, 0xc59: 0x19de, 0xc5a: 0x1a41, 0xc5b: 0x1c78, 0xc5c: 0x1a2c, 0xc5d: 0x19c0, + 0xc5e: 0x1a02, 0xc5f: 0x1c3c, 0xc60: 0x1bf4, 0xc61: 0x1a14, 0xc62: 0x1c24, 0xc63: 0x1c40, + 0xc64: 0x1bf8, 0xc65: 0x1a17, 0xc66: 0x1c28, 0xc67: 0x22e8, 0xc68: 0x22fc, 0xc69: 0x1996, + 0xc6a: 0x1c20, 0xc6b: 0x1bb4, 0xc6c: 0x1ba0, 0xc6d: 0x1c48, 0xc6e: 0x2716, 0xc6f: 0x27ad, + 0xc70: 0x1a59, 0xc71: 0x1a44, 0xc72: 0x1c7c, 0xc73: 0x1a2f, 0xc74: 0x1a50, 0xc75: 0x1a38, + 0xc76: 0x1c68, 0xc77: 0x1a1d, 0xc78: 0x19f6, 0xc79: 0x1981, 0xc7a: 0x1a53, 0xc7b: 0x1a3b, + 0xc7c: 0x1c6c, 0xc7d: 0x1a20, 0xc7e: 0x19f9, 0xc7f: 0x1984, + // Block 0x32, offset 0xc80 + 0xc80: 0x1c2c, 0xc81: 0x1bb8, 0xc82: 0x1d4d, 0xc83: 0x1939, 0xc84: 0x19ba, 0xc85: 0x19bd, + 0xc86: 0x22f5, 0xc87: 0x1b94, 0xc88: 0x19c3, 0xc89: 0x194b, 0xc8a: 0x19e1, 0xc8b: 0x194e, + 0xc8c: 0x19ea, 0xc8d: 0x196c, 0xc8e: 0x196f, 0xc8f: 0x1a05, 0xc90: 0x1a0b, 0xc91: 0x1a0e, + 0xc92: 0x1c30, 0xc93: 0x1a11, 0xc94: 0x1a23, 0xc95: 0x1c38, 0xc96: 0x1c44, 0xc97: 0x1990, + 0xc98: 0x1d57, 0xc99: 0x1bbc, 0xc9a: 0x1993, 0xc9b: 0x1a5c, 0xc9c: 0x19a5, 0xc9d: 0x19b4, + 0xc9e: 0x22e2, 0xc9f: 0x22dc, 0xca0: 0x1cc1, 0xca1: 0x1cd0, 0xca2: 0x1cdf, 0xca3: 0x1cee, + 0xca4: 0x1cfd, 0xca5: 0x1d0c, 0xca6: 0x1d1b, 0xca7: 0x1d2a, 0xca8: 0x1d39, 0xca9: 0x2186, + 0xcaa: 0x2198, 0xcab: 0x21aa, 0xcac: 0x21bc, 0xcad: 0x21c8, 0xcae: 0x21d4, 0xcaf: 0x21e0, + 0xcb0: 0x21ec, 0xcb1: 0x21f8, 0xcb2: 0x2204, 0xcb3: 0x2240, 0xcb4: 0x224c, 0xcb5: 0x2258, + 0xcb6: 0x2264, 0xcb7: 0x2270, 0xcb8: 0x227c, 0xcb9: 0x2282, 0xcba: 0x2288, 0xcbb: 0x228e, + 0xcbc: 0x2294, 0xcbd: 0x22a6, 0xcbe: 0x22ac, 0xcbf: 0x1c10, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x1377, 0xcc1: 0x0cfb, 0xcc2: 0x13d3, 0xcc3: 0x139f, 0xcc4: 0x0e57, 0xcc5: 0x06eb, + 0xcc6: 0x08df, 0xcc7: 0x162b, 0xcc8: 0x162b, 0xcc9: 0x0a0b, 0xcca: 0x145f, 0xccb: 0x0943, + 0xccc: 0x0a07, 0xccd: 0x0bef, 0xcce: 0x0fcf, 0xccf: 0x115f, 0xcd0: 0x1297, 0xcd1: 0x12d3, + 0xcd2: 0x1307, 0xcd3: 0x141b, 0xcd4: 0x0d73, 0xcd5: 0x0dff, 0xcd6: 0x0eab, 0xcd7: 0x0f43, + 0xcd8: 0x125f, 0xcd9: 0x1447, 0xcda: 0x1573, 0xcdb: 0x070f, 0xcdc: 0x08b3, 0xcdd: 0x0d87, + 0xcde: 0x0ecf, 0xcdf: 0x1293, 0xce0: 0x15c3, 0xce1: 0x0ab3, 0xce2: 0x0e77, 0xce3: 0x1283, + 0xce4: 0x1317, 0xce5: 0x0c23, 0xce6: 0x11bb, 0xce7: 0x12df, 0xce8: 0x0b1f, 0xce9: 0x0d0f, + 0xcea: 0x0e17, 0xceb: 0x0f1b, 0xcec: 0x1427, 0xced: 0x074f, 0xcee: 0x07e7, 0xcef: 0x0853, + 0xcf0: 0x0c8b, 0xcf1: 0x0d7f, 0xcf2: 0x0ecb, 0xcf3: 0x0fef, 0xcf4: 0x1177, 0xcf5: 0x128b, + 0xcf6: 0x12a3, 0xcf7: 0x13c7, 0xcf8: 0x14ef, 0xcf9: 0x15a3, 0xcfa: 0x15bf, 0xcfb: 0x102b, + 0xcfc: 0x106b, 0xcfd: 0x1123, 0xcfe: 0x1243, 0xcff: 0x147b, + // Block 0x34, offset 0xd00 + 0xd00: 0x15cb, 0xd01: 0x134b, 0xd02: 0x09c7, 0xd03: 0x0b3b, 0xd04: 0x10db, 0xd05: 0x119b, + 0xd06: 0x0eff, 0xd07: 0x1033, 0xd08: 0x1397, 0xd09: 0x14e7, 0xd0a: 0x09c3, 0xd0b: 0x0a8f, + 0xd0c: 0x0d77, 0xd0d: 0x0e2b, 0xd0e: 0x0e5f, 0xd0f: 0x1113, 0xd10: 0x113b, 0xd11: 0x14a7, + 0xd12: 0x084f, 0xd13: 0x11a7, 0xd14: 0x07f3, 0xd15: 0x07ef, 0xd16: 0x1097, 0xd17: 0x1127, + 0xd18: 0x125b, 0xd19: 0x14af, 0xd1a: 0x1367, 0xd1b: 0x0c27, 0xd1c: 0x0d73, 0xd1d: 0x1357, + 0xd1e: 0x06f7, 0xd1f: 0x0a63, 0xd20: 0x0b93, 0xd21: 0x0f2f, 0xd22: 0x0faf, 0xd23: 0x0873, + 0xd24: 0x103b, 0xd25: 0x075f, 0xd26: 0x0b77, 0xd27: 0x06d7, 0xd28: 0x0deb, 0xd29: 0x0ca3, + 0xd2a: 0x110f, 0xd2b: 0x08c7, 0xd2c: 0x09b3, 0xd2d: 0x0ffb, 0xd2e: 0x1263, 0xd2f: 0x133b, + 0xd30: 0x0db7, 0xd31: 0x13f7, 0xd32: 0x0de3, 0xd33: 0x0c37, 0xd34: 0x121b, 0xd35: 0x0c57, + 0xd36: 0x0fab, 0xd37: 0x072b, 0xd38: 0x07a7, 0xd39: 0x07eb, 0xd3a: 0x0d53, 0xd3b: 0x10fb, + 0xd3c: 0x11f3, 0xd3d: 0x1347, 0xd3e: 0x145b, 0xd3f: 0x085b, + // Block 0x35, offset 0xd40 + 0xd40: 0x090f, 0xd41: 0x0a17, 0xd42: 0x0b2f, 0xd43: 0x0cbf, 0xd44: 0x0e7b, 0xd45: 0x103f, + 0xd46: 0x1497, 0xd47: 0x157b, 0xd48: 0x15cf, 0xd49: 0x15e7, 0xd4a: 0x0837, 0xd4b: 0x0cf3, + 0xd4c: 0x0da3, 0xd4d: 0x13eb, 0xd4e: 0x0afb, 0xd4f: 0x0bd7, 0xd50: 0x0bf3, 0xd51: 0x0c83, + 0xd52: 0x0e6b, 0xd53: 0x0eb7, 0xd54: 0x0f67, 0xd55: 0x108b, 0xd56: 0x112f, 0xd57: 0x1193, + 0xd58: 0x13db, 0xd59: 0x126b, 0xd5a: 0x1403, 0xd5b: 0x147f, 0xd5c: 0x080f, 0xd5d: 0x083b, + 0xd5e: 0x0923, 0xd5f: 0x0ea7, 0xd60: 0x12f3, 0xd61: 0x133b, 0xd62: 0x0b1b, 0xd63: 0x0b8b, + 0xd64: 0x0c4f, 0xd65: 0x0daf, 0xd66: 0x10d7, 0xd67: 0x0f23, 0xd68: 0x073b, 0xd69: 0x097f, + 0xd6a: 0x0a63, 0xd6b: 0x0ac7, 0xd6c: 0x0b97, 0xd6d: 0x0f3f, 0xd6e: 0x0f5b, 0xd6f: 0x116b, + 0xd70: 0x118b, 0xd71: 0x1463, 0xd72: 0x14e3, 0xd73: 0x14f3, 0xd74: 0x152f, 0xd75: 0x0753, + 0xd76: 0x107f, 0xd77: 0x144f, 0xd78: 0x14cb, 0xd79: 0x0baf, 0xd7a: 0x0717, 0xd7b: 0x0777, + 0xd7c: 0x0a67, 0xd7d: 0x0a87, 0xd7e: 0x0caf, 0xd7f: 0x0d73, + // Block 0x36, offset 0xd80 + 0xd80: 0x0ec3, 0xd81: 0x0fcb, 0xd82: 0x1277, 0xd83: 0x1417, 0xd84: 0x1623, 0xd85: 0x0ce3, + 0xd86: 0x14a3, 0xd87: 0x0833, 0xd88: 0x0d2f, 0xd89: 0x0d3b, 0xd8a: 0x0e0f, 0xd8b: 0x0e47, + 0xd8c: 0x0f4b, 0xd8d: 0x0fa7, 0xd8e: 0x1027, 0xd8f: 0x110b, 0xd90: 0x153b, 0xd91: 0x07af, + 0xd92: 0x0c03, 0xd93: 0x14b3, 0xd94: 0x0767, 0xd95: 0x0aab, 0xd96: 0x0e2f, 0xd97: 0x13df, + 0xd98: 0x0b67, 0xd99: 0x0bb7, 0xd9a: 0x0d43, 0xd9b: 0x0f2f, 0xd9c: 0x14bb, 0xd9d: 0x0817, + 0xd9e: 0x08ff, 0xd9f: 0x0a97, 0xda0: 0x0cd3, 0xda1: 0x0d1f, 0xda2: 0x0d5f, 0xda3: 0x0df3, + 0xda4: 0x0f47, 0xda5: 0x0fbb, 0xda6: 0x1157, 0xda7: 0x12f7, 0xda8: 0x1303, 0xda9: 0x1457, + 0xdaa: 0x14d7, 0xdab: 0x0883, 0xdac: 0x0e4b, 0xdad: 0x0903, 0xdae: 0x0ec7, 0xdaf: 0x0f6b, + 0xdb0: 0x1287, 0xdb1: 0x14bf, 0xdb2: 0x15ab, 0xdb3: 0x15d3, 0xdb4: 0x0d37, 0xdb5: 0x0e27, + 0xdb6: 0x11c3, 0xdb7: 0x10b7, 0xdb8: 0x10c3, 0xdb9: 0x10e7, 0xdba: 0x0f17, 0xdbb: 0x0e9f, + 0xdbc: 0x1363, 0xdbd: 0x0733, 0xdbe: 0x122b, 0xdbf: 0x081b, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x080b, 0xdc1: 0x0b0b, 0xdc2: 0x0c2b, 0xdc3: 0x10f3, 0xdc4: 0x0a53, 0xdc5: 0x0e03, + 0xdc6: 0x0cef, 0xdc7: 0x13e7, 0xdc8: 0x12e7, 0xdc9: 0x14ab, 0xdca: 0x1323, 0xdcb: 0x0b27, + 0xdcc: 0x0787, 0xdcd: 0x095b, 0xdd0: 0x09af, + 0xdd2: 0x0cdf, 0xdd5: 0x07f7, 0xdd6: 0x0f1f, 0xdd7: 0x0fe3, + 0xdd8: 0x1047, 0xdd9: 0x1063, 0xdda: 0x1067, 0xddb: 0x107b, 0xddc: 0x14fb, 0xddd: 0x10eb, + 0xdde: 0x116f, 0xde0: 0x128f, 0xde2: 0x1353, + 0xde5: 0x1407, 0xde6: 0x1433, + 0xdea: 0x154f, 0xdeb: 0x1553, 0xdec: 0x1557, 0xded: 0x15bb, 0xdee: 0x142b, 0xdef: 0x14c7, + 0xdf0: 0x0757, 0xdf1: 0x077b, 0xdf2: 0x078f, 0xdf3: 0x084b, 0xdf4: 0x0857, 0xdf5: 0x0897, + 0xdf6: 0x094b, 0xdf7: 0x0967, 0xdf8: 0x096f, 0xdf9: 0x09ab, 0xdfa: 0x09b7, 0xdfb: 0x0a93, + 0xdfc: 0x0a9b, 0xdfd: 0x0ba3, 0xdfe: 0x0bcb, 0xdff: 0x0bd3, + // Block 0x38, offset 0xe00 + 0xe00: 0x0beb, 0xe01: 0x0c97, 0xe02: 0x0cc7, 0xe03: 0x0ce7, 0xe04: 0x0d57, 0xe05: 0x0e1b, + 0xe06: 0x0e37, 0xe07: 0x0e67, 0xe08: 0x0ebb, 0xe09: 0x0edb, 0xe0a: 0x0f4f, 0xe0b: 0x102f, + 0xe0c: 0x104b, 0xe0d: 0x1053, 0xe0e: 0x104f, 0xe0f: 0x1057, 0xe10: 0x105b, 0xe11: 0x105f, + 0xe12: 0x1073, 0xe13: 0x1077, 0xe14: 0x109b, 0xe15: 0x10af, 0xe16: 0x10cb, 0xe17: 0x112f, + 0xe18: 0x1137, 0xe19: 0x113f, 0xe1a: 0x1153, 0xe1b: 0x117b, 0xe1c: 0x11cb, 0xe1d: 0x11ff, + 0xe1e: 0x11ff, 0xe1f: 0x1267, 0xe20: 0x130f, 0xe21: 0x1327, 0xe22: 0x135b, 0xe23: 0x135f, + 0xe24: 0x13a3, 0xe25: 0x13a7, 0xe26: 0x13ff, 0xe27: 0x1407, 0xe28: 0x14db, 0xe29: 0x151f, + 0xe2a: 0x1537, 0xe2b: 0x0b9b, 0xe2c: 0x171e, 0xe2d: 0x11e3, + 0xe30: 0x06df, 0xe31: 0x07e3, 0xe32: 0x07a3, 0xe33: 0x074b, 0xe34: 0x078b, 0xe35: 0x07b7, + 0xe36: 0x0847, 0xe37: 0x0863, 0xe38: 0x094b, 0xe39: 0x0937, 0xe3a: 0x0947, 0xe3b: 0x0963, + 0xe3c: 0x09af, 0xe3d: 0x09bf, 0xe3e: 0x0a03, 0xe3f: 0x0a0f, + // Block 0x39, offset 0xe40 + 0xe40: 0x0a2b, 0xe41: 0x0a3b, 0xe42: 0x0b23, 0xe43: 0x0b2b, 0xe44: 0x0b5b, 0xe45: 0x0b7b, + 0xe46: 0x0bab, 0xe47: 0x0bc3, 0xe48: 0x0bb3, 0xe49: 0x0bd3, 0xe4a: 0x0bc7, 0xe4b: 0x0beb, + 0xe4c: 0x0c07, 0xe4d: 0x0c5f, 0xe4e: 0x0c6b, 0xe4f: 0x0c73, 0xe50: 0x0c9b, 0xe51: 0x0cdf, + 0xe52: 0x0d0f, 0xe53: 0x0d13, 0xe54: 0x0d27, 0xe55: 0x0da7, 0xe56: 0x0db7, 0xe57: 0x0e0f, + 0xe58: 0x0e5b, 0xe59: 0x0e53, 0xe5a: 0x0e67, 0xe5b: 0x0e83, 0xe5c: 0x0ebb, 0xe5d: 0x1013, + 0xe5e: 0x0edf, 0xe5f: 0x0f13, 0xe60: 0x0f1f, 0xe61: 0x0f5f, 0xe62: 0x0f7b, 0xe63: 0x0f9f, + 0xe64: 0x0fc3, 0xe65: 0x0fc7, 0xe66: 0x0fe3, 0xe67: 0x0fe7, 0xe68: 0x0ff7, 0xe69: 0x100b, + 0xe6a: 0x1007, 0xe6b: 0x1037, 0xe6c: 0x10b3, 0xe6d: 0x10cb, 0xe6e: 0x10e3, 0xe6f: 0x111b, + 0xe70: 0x112f, 0xe71: 0x114b, 0xe72: 0x117b, 0xe73: 0x122f, 0xe74: 0x1257, 0xe75: 0x12cb, + 0xe76: 0x1313, 0xe77: 0x131f, 0xe78: 0x1327, 0xe79: 0x133f, 0xe7a: 0x1353, 0xe7b: 0x1343, + 0xe7c: 0x135b, 0xe7d: 0x1357, 0xe7e: 0x134f, 0xe7f: 0x135f, + // Block 0x3a, offset 0xe80 + 0xe80: 0x136b, 0xe81: 0x13a7, 0xe82: 0x13e3, 0xe83: 0x1413, 0xe84: 0x144b, 0xe85: 0x146b, + 0xe86: 0x14b7, 0xe87: 0x14db, 0xe88: 0x14fb, 0xe89: 0x150f, 0xe8a: 0x151f, 0xe8b: 0x152b, + 0xe8c: 0x1537, 0xe8d: 0x158b, 0xe8e: 0x162b, 0xe8f: 0x16b5, 0xe90: 0x16b0, 0xe91: 0x16e2, + 0xe92: 0x0607, 0xe93: 0x062f, 0xe94: 0x0633, 0xe95: 0x1764, 0xe96: 0x1791, 0xe97: 0x1809, + 0xe98: 0x1617, 0xe99: 0x1627, + // Block 0x3b, offset 0xec0 + 0xec0: 0x19d5, 0xec1: 0x19d8, 0xec2: 0x19db, 0xec3: 0x1c08, 0xec4: 0x1c0c, 0xec5: 0x1a5f, + 0xec6: 0x1a5f, + 0xed3: 0x1d75, 0xed4: 0x1d66, 0xed5: 0x1d6b, 0xed6: 0x1d7a, 0xed7: 0x1d70, + 0xedd: 0x4390, + 0xede: 0x8115, 0xedf: 0x4402, 0xee0: 0x022d, 0xee1: 0x0215, 0xee2: 0x021e, 0xee3: 0x0221, + 0xee4: 0x0224, 0xee5: 0x0227, 0xee6: 0x022a, 0xee7: 0x0230, 0xee8: 0x0233, 0xee9: 0x0017, + 0xeea: 0x43f0, 0xeeb: 0x43f6, 0xeec: 0x44f4, 0xeed: 0x44fc, 0xeee: 0x4348, 0xeef: 0x434e, + 0xef0: 0x4354, 0xef1: 0x435a, 0xef2: 0x4366, 0xef3: 0x436c, 0xef4: 0x4372, 0xef5: 0x437e, + 0xef6: 0x4384, 0xef8: 0x438a, 0xef9: 0x4396, 0xefa: 0x439c, 0xefb: 0x43a2, + 0xefc: 0x43ae, 0xefe: 0x43b4, + // Block 0x3c, offset 0xf00 + 0xf00: 0x43ba, 0xf01: 0x43c0, 0xf03: 0x43c6, 0xf04: 0x43cc, + 0xf06: 0x43d8, 0xf07: 0x43de, 0xf08: 0x43e4, 0xf09: 0x43ea, 0xf0a: 0x43fc, 0xf0b: 0x4378, + 0xf0c: 0x4360, 0xf0d: 0x43a8, 0xf0e: 0x43d2, 0xf0f: 0x1d7f, 0xf10: 0x0299, 0xf11: 0x0299, + 0xf12: 0x02a2, 0xf13: 0x02a2, 0xf14: 0x02a2, 0xf15: 0x02a2, 0xf16: 0x02a5, 0xf17: 0x02a5, + 0xf18: 0x02a5, 0xf19: 0x02a5, 0xf1a: 0x02ab, 0xf1b: 0x02ab, 0xf1c: 0x02ab, 0xf1d: 0x02ab, + 0xf1e: 0x029f, 0xf1f: 0x029f, 0xf20: 0x029f, 0xf21: 0x029f, 0xf22: 0x02a8, 0xf23: 0x02a8, + 0xf24: 0x02a8, 0xf25: 0x02a8, 0xf26: 0x029c, 0xf27: 0x029c, 0xf28: 0x029c, 0xf29: 0x029c, + 0xf2a: 0x02cf, 0xf2b: 0x02cf, 0xf2c: 0x02cf, 0xf2d: 0x02cf, 0xf2e: 0x02d2, 0xf2f: 0x02d2, + 0xf30: 0x02d2, 0xf31: 0x02d2, 0xf32: 0x02b1, 0xf33: 0x02b1, 0xf34: 0x02b1, 0xf35: 0x02b1, + 0xf36: 0x02ae, 0xf37: 0x02ae, 0xf38: 0x02ae, 0xf39: 0x02ae, 0xf3a: 0x02b4, 0xf3b: 0x02b4, + 0xf3c: 0x02b4, 0xf3d: 0x02b4, 0xf3e: 0x02b7, 0xf3f: 0x02b7, + // Block 0x3d, offset 0xf40 + 0xf40: 0x02b7, 0xf41: 0x02b7, 0xf42: 0x02c0, 0xf43: 0x02c0, 0xf44: 0x02bd, 0xf45: 0x02bd, + 0xf46: 0x02c3, 0xf47: 0x02c3, 0xf48: 0x02ba, 0xf49: 0x02ba, 0xf4a: 0x02c9, 0xf4b: 0x02c9, + 0xf4c: 0x02c6, 0xf4d: 0x02c6, 0xf4e: 0x02d5, 0xf4f: 0x02d5, 0xf50: 0x02d5, 0xf51: 0x02d5, + 0xf52: 0x02db, 0xf53: 0x02db, 0xf54: 0x02db, 0xf55: 0x02db, 0xf56: 0x02e1, 0xf57: 0x02e1, + 0xf58: 0x02e1, 0xf59: 0x02e1, 0xf5a: 0x02de, 0xf5b: 0x02de, 0xf5c: 0x02de, 0xf5d: 0x02de, + 0xf5e: 0x02e4, 0xf5f: 0x02e4, 0xf60: 0x02e7, 0xf61: 0x02e7, 0xf62: 0x02e7, 0xf63: 0x02e7, + 0xf64: 0x446e, 0xf65: 0x446e, 0xf66: 0x02ed, 0xf67: 0x02ed, 0xf68: 0x02ed, 0xf69: 0x02ed, + 0xf6a: 0x02ea, 0xf6b: 0x02ea, 0xf6c: 0x02ea, 0xf6d: 0x02ea, 0xf6e: 0x0308, 0xf6f: 0x0308, + 0xf70: 0x4468, 0xf71: 0x4468, + // Block 0x3e, offset 0xf80 + 0xf93: 0x02d8, 0xf94: 0x02d8, 0xf95: 0x02d8, 0xf96: 0x02d8, 0xf97: 0x02f6, + 0xf98: 0x02f6, 0xf99: 0x02f3, 0xf9a: 0x02f3, 0xf9b: 0x02f9, 0xf9c: 0x02f9, 0xf9d: 0x204f, + 0xf9e: 0x02ff, 0xf9f: 0x02ff, 0xfa0: 0x02f0, 0xfa1: 0x02f0, 0xfa2: 0x02fc, 0xfa3: 0x02fc, + 0xfa4: 0x0305, 0xfa5: 0x0305, 0xfa6: 0x0305, 0xfa7: 0x0305, 0xfa8: 0x028d, 0xfa9: 0x028d, + 0xfaa: 0x25aa, 0xfab: 0x25aa, 0xfac: 0x261a, 0xfad: 0x261a, 0xfae: 0x25e9, 0xfaf: 0x25e9, + 0xfb0: 0x2605, 0xfb1: 0x2605, 0xfb2: 0x25fe, 0xfb3: 0x25fe, 0xfb4: 0x260c, 0xfb5: 0x260c, + 0xfb6: 0x2613, 0xfb7: 0x2613, 0xfb8: 0x2613, 0xfb9: 0x25f0, 0xfba: 0x25f0, 0xfbb: 0x25f0, + 0xfbc: 0x0302, 0xfbd: 0x0302, 0xfbe: 0x0302, 0xfbf: 0x0302, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x25b1, 0xfc1: 0x25b8, 0xfc2: 0x25d4, 0xfc3: 0x25f0, 0xfc4: 0x25f7, 0xfc5: 0x1d89, + 0xfc6: 0x1d8e, 0xfc7: 0x1d93, 0xfc8: 0x1da2, 0xfc9: 0x1db1, 0xfca: 0x1db6, 0xfcb: 0x1dbb, + 0xfcc: 0x1dc0, 0xfcd: 0x1dc5, 0xfce: 0x1dd4, 0xfcf: 0x1de3, 0xfd0: 0x1de8, 0xfd1: 0x1ded, + 0xfd2: 0x1dfc, 0xfd3: 0x1e0b, 0xfd4: 0x1e10, 0xfd5: 0x1e15, 0xfd6: 0x1e1a, 0xfd7: 0x1e29, + 0xfd8: 0x1e2e, 0xfd9: 0x1e3d, 0xfda: 0x1e42, 0xfdb: 0x1e47, 0xfdc: 0x1e56, 0xfdd: 0x1e5b, + 0xfde: 0x1e60, 0xfdf: 0x1e6a, 0xfe0: 0x1ea6, 0xfe1: 0x1eb5, 0xfe2: 0x1ec4, 0xfe3: 0x1ec9, + 0xfe4: 0x1ece, 0xfe5: 0x1ed8, 0xfe6: 0x1ee7, 0xfe7: 0x1eec, 0xfe8: 0x1efb, 0xfe9: 0x1f00, + 0xfea: 0x1f05, 0xfeb: 0x1f14, 0xfec: 0x1f19, 0xfed: 0x1f28, 0xfee: 0x1f2d, 0xfef: 0x1f32, + 0xff0: 0x1f37, 0xff1: 0x1f3c, 0xff2: 0x1f41, 0xff3: 0x1f46, 0xff4: 0x1f4b, 0xff5: 0x1f50, + 0xff6: 0x1f55, 0xff7: 0x1f5a, 0xff8: 0x1f5f, 0xff9: 0x1f64, 0xffa: 0x1f69, 0xffb: 0x1f6e, + 0xffc: 0x1f73, 0xffd: 0x1f78, 0xffe: 0x1f7d, 0xfff: 0x1f87, + // Block 0x40, offset 0x1000 + 0x1000: 0x1f8c, 0x1001: 0x1f91, 0x1002: 0x1f96, 0x1003: 0x1fa0, 0x1004: 0x1fa5, 0x1005: 0x1faf, + 0x1006: 0x1fb4, 0x1007: 0x1fb9, 0x1008: 0x1fbe, 0x1009: 0x1fc3, 0x100a: 0x1fc8, 0x100b: 0x1fcd, + 0x100c: 0x1fd2, 0x100d: 0x1fd7, 0x100e: 0x1fe6, 0x100f: 0x1ff5, 0x1010: 0x1ffa, 0x1011: 0x1fff, + 0x1012: 0x2004, 0x1013: 0x2009, 0x1014: 0x200e, 0x1015: 0x2018, 0x1016: 0x201d, 0x1017: 0x2022, + 0x1018: 0x2031, 0x1019: 0x2040, 0x101a: 0x2045, 0x101b: 0x4420, 0x101c: 0x4426, 0x101d: 0x445c, + 0x101e: 0x44b3, 0x101f: 0x44ba, 0x1020: 0x44c1, 0x1021: 0x44c8, 0x1022: 0x44cf, 0x1023: 0x44d6, + 0x1024: 0x25c6, 0x1025: 0x25cd, 0x1026: 0x25d4, 0x1027: 0x25db, 0x1028: 0x25f0, 0x1029: 0x25f7, + 0x102a: 0x1d98, 0x102b: 0x1d9d, 0x102c: 0x1da2, 0x102d: 0x1da7, 0x102e: 0x1db1, 0x102f: 0x1db6, + 0x1030: 0x1dca, 0x1031: 0x1dcf, 0x1032: 0x1dd4, 0x1033: 0x1dd9, 0x1034: 0x1de3, 0x1035: 0x1de8, + 0x1036: 0x1df2, 0x1037: 0x1df7, 0x1038: 0x1dfc, 0x1039: 0x1e01, 0x103a: 0x1e0b, 0x103b: 0x1e10, + 0x103c: 0x1f3c, 0x103d: 0x1f41, 0x103e: 0x1f50, 0x103f: 0x1f55, + // Block 0x41, offset 0x1040 + 0x1040: 0x1f5a, 0x1041: 0x1f6e, 0x1042: 0x1f73, 0x1043: 0x1f78, 0x1044: 0x1f7d, 0x1045: 0x1f96, + 0x1046: 0x1fa0, 0x1047: 0x1fa5, 0x1048: 0x1faa, 0x1049: 0x1fbe, 0x104a: 0x1fdc, 0x104b: 0x1fe1, + 0x104c: 0x1fe6, 0x104d: 0x1feb, 0x104e: 0x1ff5, 0x104f: 0x1ffa, 0x1050: 0x445c, 0x1051: 0x2027, + 0x1052: 0x202c, 0x1053: 0x2031, 0x1054: 0x2036, 0x1055: 0x2040, 0x1056: 0x2045, 0x1057: 0x25b1, + 0x1058: 0x25b8, 0x1059: 0x25bf, 0x105a: 0x25d4, 0x105b: 0x25e2, 0x105c: 0x1d89, 0x105d: 0x1d8e, + 0x105e: 0x1d93, 0x105f: 0x1da2, 0x1060: 0x1dac, 0x1061: 0x1dbb, 0x1062: 0x1dc0, 0x1063: 0x1dc5, + 0x1064: 0x1dd4, 0x1065: 0x1dde, 0x1066: 0x1dfc, 0x1067: 0x1e15, 0x1068: 0x1e1a, 0x1069: 0x1e29, + 0x106a: 0x1e2e, 0x106b: 0x1e3d, 0x106c: 0x1e47, 0x106d: 0x1e56, 0x106e: 0x1e5b, 0x106f: 0x1e60, + 0x1070: 0x1e6a, 0x1071: 0x1ea6, 0x1072: 0x1eab, 0x1073: 0x1eb5, 0x1074: 0x1ec4, 0x1075: 0x1ec9, + 0x1076: 0x1ece, 0x1077: 0x1ed8, 0x1078: 0x1ee7, 0x1079: 0x1efb, 0x107a: 0x1f00, 0x107b: 0x1f05, + 0x107c: 0x1f14, 0x107d: 0x1f19, 0x107e: 0x1f28, 0x107f: 0x1f2d, + // Block 0x42, offset 0x1080 + 0x1080: 0x1f32, 0x1081: 0x1f37, 0x1082: 0x1f46, 0x1083: 0x1f4b, 0x1084: 0x1f5f, 0x1085: 0x1f64, + 0x1086: 0x1f69, 0x1087: 0x1f6e, 0x1088: 0x1f73, 0x1089: 0x1f87, 0x108a: 0x1f8c, 0x108b: 0x1f91, + 0x108c: 0x1f96, 0x108d: 0x1f9b, 0x108e: 0x1faf, 0x108f: 0x1fb4, 0x1090: 0x1fb9, 0x1091: 0x1fbe, + 0x1092: 0x1fcd, 0x1093: 0x1fd2, 0x1094: 0x1fd7, 0x1095: 0x1fe6, 0x1096: 0x1ff0, 0x1097: 0x1fff, + 0x1098: 0x2004, 0x1099: 0x4450, 0x109a: 0x2018, 0x109b: 0x201d, 0x109c: 0x2022, 0x109d: 0x2031, + 0x109e: 0x203b, 0x109f: 0x25d4, 0x10a0: 0x25e2, 0x10a1: 0x1da2, 0x10a2: 0x1dac, 0x10a3: 0x1dd4, + 0x10a4: 0x1dde, 0x10a5: 0x1dfc, 0x10a6: 0x1e06, 0x10a7: 0x1e6a, 0x10a8: 0x1e6f, 0x10a9: 0x1e92, + 0x10aa: 0x1e97, 0x10ab: 0x1f6e, 0x10ac: 0x1f73, 0x10ad: 0x1f96, 0x10ae: 0x1fe6, 0x10af: 0x1ff0, + 0x10b0: 0x2031, 0x10b1: 0x203b, 0x10b2: 0x4504, 0x10b3: 0x450c, 0x10b4: 0x4514, 0x10b5: 0x1ef1, + 0x10b6: 0x1ef6, 0x10b7: 0x1f0a, 0x10b8: 0x1f0f, 0x10b9: 0x1f1e, 0x10ba: 0x1f23, 0x10bb: 0x1e74, + 0x10bc: 0x1e79, 0x10bd: 0x1e9c, 0x10be: 0x1ea1, 0x10bf: 0x1e33, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x1e38, 0x10c1: 0x1e1f, 0x10c2: 0x1e24, 0x10c3: 0x1e4c, 0x10c4: 0x1e51, 0x10c5: 0x1eba, + 0x10c6: 0x1ebf, 0x10c7: 0x1edd, 0x10c8: 0x1ee2, 0x10c9: 0x1e7e, 0x10ca: 0x1e83, 0x10cb: 0x1e88, + 0x10cc: 0x1e92, 0x10cd: 0x1e8d, 0x10ce: 0x1e65, 0x10cf: 0x1eb0, 0x10d0: 0x1ed3, 0x10d1: 0x1ef1, + 0x10d2: 0x1ef6, 0x10d3: 0x1f0a, 0x10d4: 0x1f0f, 0x10d5: 0x1f1e, 0x10d6: 0x1f23, 0x10d7: 0x1e74, + 0x10d8: 0x1e79, 0x10d9: 0x1e9c, 0x10da: 0x1ea1, 0x10db: 0x1e33, 0x10dc: 0x1e38, 0x10dd: 0x1e1f, + 0x10de: 0x1e24, 0x10df: 0x1e4c, 0x10e0: 0x1e51, 0x10e1: 0x1eba, 0x10e2: 0x1ebf, 0x10e3: 0x1edd, + 0x10e4: 0x1ee2, 0x10e5: 0x1e7e, 0x10e6: 0x1e83, 0x10e7: 0x1e88, 0x10e8: 0x1e92, 0x10e9: 0x1e8d, + 0x10ea: 0x1e65, 0x10eb: 0x1eb0, 0x10ec: 0x1ed3, 0x10ed: 0x1e7e, 0x10ee: 0x1e83, 0x10ef: 0x1e88, + 0x10f0: 0x1e92, 0x10f1: 0x1e6f, 0x10f2: 0x1e97, 0x10f3: 0x1eec, 0x10f4: 0x1e56, 0x10f5: 0x1e5b, + 0x10f6: 0x1e60, 0x10f7: 0x1e7e, 0x10f8: 0x1e83, 0x10f9: 0x1e88, 0x10fa: 0x1eec, 0x10fb: 0x1efb, + 0x10fc: 0x4408, 0x10fd: 0x4408, + // Block 0x44, offset 0x1100 + 0x1110: 0x2311, 0x1111: 0x2326, + 0x1112: 0x2326, 0x1113: 0x232d, 0x1114: 0x2334, 0x1115: 0x2349, 0x1116: 0x2350, 0x1117: 0x2357, + 0x1118: 0x237a, 0x1119: 0x237a, 0x111a: 0x239d, 0x111b: 0x2396, 0x111c: 0x23b2, 0x111d: 0x23a4, + 0x111e: 0x23ab, 0x111f: 0x23ce, 0x1120: 0x23ce, 0x1121: 0x23c7, 0x1122: 0x23d5, 0x1123: 0x23d5, + 0x1124: 0x23ff, 0x1125: 0x23ff, 0x1126: 0x241b, 0x1127: 0x23e3, 0x1128: 0x23e3, 0x1129: 0x23dc, + 0x112a: 0x23f1, 0x112b: 0x23f1, 0x112c: 0x23f8, 0x112d: 0x23f8, 0x112e: 0x2422, 0x112f: 0x2430, + 0x1130: 0x2430, 0x1131: 0x2437, 0x1132: 0x2437, 0x1133: 0x243e, 0x1134: 0x2445, 0x1135: 0x244c, + 0x1136: 0x2453, 0x1137: 0x2453, 0x1138: 0x245a, 0x1139: 0x2468, 0x113a: 0x2476, 0x113b: 0x246f, + 0x113c: 0x247d, 0x113d: 0x247d, 0x113e: 0x2492, 0x113f: 0x2499, + // Block 0x45, offset 0x1140 + 0x1140: 0x24ca, 0x1141: 0x24d8, 0x1142: 0x24d1, 0x1143: 0x24b5, 0x1144: 0x24b5, 0x1145: 0x24df, + 0x1146: 0x24df, 0x1147: 0x24e6, 0x1148: 0x24e6, 0x1149: 0x2510, 0x114a: 0x2517, 0x114b: 0x251e, + 0x114c: 0x24f4, 0x114d: 0x2502, 0x114e: 0x2525, 0x114f: 0x252c, + 0x1152: 0x24fb, 0x1153: 0x2580, 0x1154: 0x2587, 0x1155: 0x255d, 0x1156: 0x2564, 0x1157: 0x2548, + 0x1158: 0x2548, 0x1159: 0x254f, 0x115a: 0x2579, 0x115b: 0x2572, 0x115c: 0x259c, 0x115d: 0x259c, + 0x115e: 0x230a, 0x115f: 0x231f, 0x1160: 0x2318, 0x1161: 0x2342, 0x1162: 0x233b, 0x1163: 0x2365, + 0x1164: 0x235e, 0x1165: 0x2388, 0x1166: 0x236c, 0x1167: 0x2381, 0x1168: 0x23b9, 0x1169: 0x2406, + 0x116a: 0x23ea, 0x116b: 0x2429, 0x116c: 0x24c3, 0x116d: 0x24ed, 0x116e: 0x2595, 0x116f: 0x258e, + 0x1170: 0x25a3, 0x1171: 0x253a, 0x1172: 0x24a0, 0x1173: 0x256b, 0x1174: 0x2492, 0x1175: 0x24ca, + 0x1176: 0x2461, 0x1177: 0x24ae, 0x1178: 0x2541, 0x1179: 0x2533, 0x117a: 0x24bc, 0x117b: 0x24a7, + 0x117c: 0x24bc, 0x117d: 0x2541, 0x117e: 0x2373, 0x117f: 0x238f, + // Block 0x46, offset 0x1180 + 0x1180: 0x2509, 0x1181: 0x2484, 0x1182: 0x2303, 0x1183: 0x24a7, 0x1184: 0x244c, 0x1185: 0x241b, + 0x1186: 0x23c0, 0x1187: 0x2556, + 0x11b0: 0x2414, 0x11b1: 0x248b, 0x11b2: 0x27bf, 0x11b3: 0x27b6, 0x11b4: 0x27ec, 0x11b5: 0x27da, + 0x11b6: 0x27c8, 0x11b7: 0x27e3, 0x11b8: 0x27f5, 0x11b9: 0x240d, 0x11ba: 0x2c7c, 0x11bb: 0x2afc, + 0x11bc: 0x27d1, + // Block 0x47, offset 0x11c0 + 0x11d0: 0x0019, 0x11d1: 0x0483, + 0x11d2: 0x0487, 0x11d3: 0x0035, 0x11d4: 0x0037, 0x11d5: 0x0003, 0x11d6: 0x003f, 0x11d7: 0x04bf, + 0x11d8: 0x04c3, 0x11d9: 0x1b5c, + 0x11e0: 0x8132, 0x11e1: 0x8132, 0x11e2: 0x8132, 0x11e3: 0x8132, + 0x11e4: 0x8132, 0x11e5: 0x8132, 0x11e6: 0x8132, 0x11e7: 0x812d, 0x11e8: 0x812d, 0x11e9: 0x812d, + 0x11ea: 0x812d, 0x11eb: 0x812d, 0x11ec: 0x812d, 0x11ed: 0x812d, 0x11ee: 0x8132, 0x11ef: 0x8132, + 0x11f0: 0x1873, 0x11f1: 0x0443, 0x11f2: 0x043f, 0x11f3: 0x007f, 0x11f4: 0x007f, 0x11f5: 0x0011, + 0x11f6: 0x0013, 0x11f7: 0x00b7, 0x11f8: 0x00bb, 0x11f9: 0x04b7, 0x11fa: 0x04bb, 0x11fb: 0x04ab, + 0x11fc: 0x04af, 0x11fd: 0x0493, 0x11fe: 0x0497, 0x11ff: 0x048b, + // Block 0x48, offset 0x1200 + 0x1200: 0x048f, 0x1201: 0x049b, 0x1202: 0x049f, 0x1203: 0x04a3, 0x1204: 0x04a7, + 0x1207: 0x0077, 0x1208: 0x007b, 0x1209: 0x4269, 0x120a: 0x4269, 0x120b: 0x4269, + 0x120c: 0x4269, 0x120d: 0x007f, 0x120e: 0x007f, 0x120f: 0x007f, 0x1210: 0x0019, 0x1211: 0x0483, + 0x1212: 0x001d, 0x1214: 0x0037, 0x1215: 0x0035, 0x1216: 0x003f, 0x1217: 0x0003, + 0x1218: 0x0443, 0x1219: 0x0011, 0x121a: 0x0013, 0x121b: 0x00b7, 0x121c: 0x00bb, 0x121d: 0x04b7, + 0x121e: 0x04bb, 0x121f: 0x0007, 0x1220: 0x000d, 0x1221: 0x0015, 0x1222: 0x0017, 0x1223: 0x001b, + 0x1224: 0x0039, 0x1225: 0x003d, 0x1226: 0x003b, 0x1228: 0x0079, 0x1229: 0x0009, + 0x122a: 0x000b, 0x122b: 0x0041, + 0x1230: 0x42aa, 0x1231: 0x442c, 0x1232: 0x42af, 0x1234: 0x42b4, + 0x1236: 0x42b9, 0x1237: 0x4432, 0x1238: 0x42be, 0x1239: 0x4438, 0x123a: 0x42c3, 0x123b: 0x443e, + 0x123c: 0x42c8, 0x123d: 0x4444, 0x123e: 0x42cd, 0x123f: 0x444a, + // Block 0x49, offset 0x1240 + 0x1240: 0x0236, 0x1241: 0x440e, 0x1242: 0x440e, 0x1243: 0x4414, 0x1244: 0x4414, 0x1245: 0x4456, + 0x1246: 0x4456, 0x1247: 0x441a, 0x1248: 0x441a, 0x1249: 0x4462, 0x124a: 0x4462, 0x124b: 0x4462, + 0x124c: 0x4462, 0x124d: 0x0239, 0x124e: 0x0239, 0x124f: 0x023c, 0x1250: 0x023c, 0x1251: 0x023c, + 0x1252: 0x023c, 0x1253: 0x023f, 0x1254: 0x023f, 0x1255: 0x0242, 0x1256: 0x0242, 0x1257: 0x0242, + 0x1258: 0x0242, 0x1259: 0x0245, 0x125a: 0x0245, 0x125b: 0x0245, 0x125c: 0x0245, 0x125d: 0x0248, + 0x125e: 0x0248, 0x125f: 0x0248, 0x1260: 0x0248, 0x1261: 0x024b, 0x1262: 0x024b, 0x1263: 0x024b, + 0x1264: 0x024b, 0x1265: 0x024e, 0x1266: 0x024e, 0x1267: 0x024e, 0x1268: 0x024e, 0x1269: 0x0251, + 0x126a: 0x0251, 0x126b: 0x0254, 0x126c: 0x0254, 0x126d: 0x0257, 0x126e: 0x0257, 0x126f: 0x025a, + 0x1270: 0x025a, 0x1271: 0x025d, 0x1272: 0x025d, 0x1273: 0x025d, 0x1274: 0x025d, 0x1275: 0x0260, + 0x1276: 0x0260, 0x1277: 0x0260, 0x1278: 0x0260, 0x1279: 0x0263, 0x127a: 0x0263, 0x127b: 0x0263, + 0x127c: 0x0263, 0x127d: 0x0266, 0x127e: 0x0266, 0x127f: 0x0266, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0266, 0x1281: 0x0269, 0x1282: 0x0269, 0x1283: 0x0269, 0x1284: 0x0269, 0x1285: 0x026c, + 0x1286: 0x026c, 0x1287: 0x026c, 0x1288: 0x026c, 0x1289: 0x026f, 0x128a: 0x026f, 0x128b: 0x026f, + 0x128c: 0x026f, 0x128d: 0x0272, 0x128e: 0x0272, 0x128f: 0x0272, 0x1290: 0x0272, 0x1291: 0x0275, + 0x1292: 0x0275, 0x1293: 0x0275, 0x1294: 0x0275, 0x1295: 0x0278, 0x1296: 0x0278, 0x1297: 0x0278, + 0x1298: 0x0278, 0x1299: 0x027b, 0x129a: 0x027b, 0x129b: 0x027b, 0x129c: 0x027b, 0x129d: 0x027e, + 0x129e: 0x027e, 0x129f: 0x027e, 0x12a0: 0x027e, 0x12a1: 0x0281, 0x12a2: 0x0281, 0x12a3: 0x0281, + 0x12a4: 0x0281, 0x12a5: 0x0284, 0x12a6: 0x0284, 0x12a7: 0x0284, 0x12a8: 0x0284, 0x12a9: 0x0287, + 0x12aa: 0x0287, 0x12ab: 0x0287, 0x12ac: 0x0287, 0x12ad: 0x028a, 0x12ae: 0x028a, 0x12af: 0x028d, + 0x12b0: 0x028d, 0x12b1: 0x0290, 0x12b2: 0x0290, 0x12b3: 0x0290, 0x12b4: 0x0290, 0x12b5: 0x2e00, + 0x12b6: 0x2e00, 0x12b7: 0x2e08, 0x12b8: 0x2e08, 0x12b9: 0x2e10, 0x12ba: 0x2e10, 0x12bb: 0x1f82, + 0x12bc: 0x1f82, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x0081, 0x12c1: 0x0083, 0x12c2: 0x0085, 0x12c3: 0x0087, 0x12c4: 0x0089, 0x12c5: 0x008b, + 0x12c6: 0x008d, 0x12c7: 0x008f, 0x12c8: 0x0091, 0x12c9: 0x0093, 0x12ca: 0x0095, 0x12cb: 0x0097, + 0x12cc: 0x0099, 0x12cd: 0x009b, 0x12ce: 0x009d, 0x12cf: 0x009f, 0x12d0: 0x00a1, 0x12d1: 0x00a3, + 0x12d2: 0x00a5, 0x12d3: 0x00a7, 0x12d4: 0x00a9, 0x12d5: 0x00ab, 0x12d6: 0x00ad, 0x12d7: 0x00af, + 0x12d8: 0x00b1, 0x12d9: 0x00b3, 0x12da: 0x00b5, 0x12db: 0x00b7, 0x12dc: 0x00b9, 0x12dd: 0x00bb, + 0x12de: 0x00bd, 0x12df: 0x0477, 0x12e0: 0x047b, 0x12e1: 0x0487, 0x12e2: 0x049b, 0x12e3: 0x049f, + 0x12e4: 0x0483, 0x12e5: 0x05ab, 0x12e6: 0x05a3, 0x12e7: 0x04c7, 0x12e8: 0x04cf, 0x12e9: 0x04d7, + 0x12ea: 0x04df, 0x12eb: 0x04e7, 0x12ec: 0x056b, 0x12ed: 0x0573, 0x12ee: 0x057b, 0x12ef: 0x051f, + 0x12f0: 0x05af, 0x12f1: 0x04cb, 0x12f2: 0x04d3, 0x12f3: 0x04db, 0x12f4: 0x04e3, 0x12f5: 0x04eb, + 0x12f6: 0x04ef, 0x12f7: 0x04f3, 0x12f8: 0x04f7, 0x12f9: 0x04fb, 0x12fa: 0x04ff, 0x12fb: 0x0503, + 0x12fc: 0x0507, 0x12fd: 0x050b, 0x12fe: 0x050f, 0x12ff: 0x0513, + // Block 0x4c, offset 0x1300 + 0x1300: 0x0517, 0x1301: 0x051b, 0x1302: 0x0523, 0x1303: 0x0527, 0x1304: 0x052b, 0x1305: 0x052f, + 0x1306: 0x0533, 0x1307: 0x0537, 0x1308: 0x053b, 0x1309: 0x053f, 0x130a: 0x0543, 0x130b: 0x0547, + 0x130c: 0x054b, 0x130d: 0x054f, 0x130e: 0x0553, 0x130f: 0x0557, 0x1310: 0x055b, 0x1311: 0x055f, + 0x1312: 0x0563, 0x1313: 0x0567, 0x1314: 0x056f, 0x1315: 0x0577, 0x1316: 0x057f, 0x1317: 0x0583, + 0x1318: 0x0587, 0x1319: 0x058b, 0x131a: 0x058f, 0x131b: 0x0593, 0x131c: 0x0597, 0x131d: 0x05a7, + 0x131e: 0x4a78, 0x131f: 0x4a7e, 0x1320: 0x03c3, 0x1321: 0x0313, 0x1322: 0x0317, 0x1323: 0x4a3b, + 0x1324: 0x031b, 0x1325: 0x4a41, 0x1326: 0x4a47, 0x1327: 0x031f, 0x1328: 0x0323, 0x1329: 0x0327, + 0x132a: 0x4a4d, 0x132b: 0x4a53, 0x132c: 0x4a59, 0x132d: 0x4a5f, 0x132e: 0x4a65, 0x132f: 0x4a6b, + 0x1330: 0x0367, 0x1331: 0x032b, 0x1332: 0x032f, 0x1333: 0x0333, 0x1334: 0x037b, 0x1335: 0x0337, + 0x1336: 0x033b, 0x1337: 0x033f, 0x1338: 0x0343, 0x1339: 0x0347, 0x133a: 0x034b, 0x133b: 0x034f, + 0x133c: 0x0353, 0x133d: 0x0357, 0x133e: 0x035b, + // Block 0x4d, offset 0x1340 + 0x1342: 0x49bd, 0x1343: 0x49c3, 0x1344: 0x49c9, 0x1345: 0x49cf, + 0x1346: 0x49d5, 0x1347: 0x49db, 0x134a: 0x49e1, 0x134b: 0x49e7, + 0x134c: 0x49ed, 0x134d: 0x49f3, 0x134e: 0x49f9, 0x134f: 0x49ff, + 0x1352: 0x4a05, 0x1353: 0x4a0b, 0x1354: 0x4a11, 0x1355: 0x4a17, 0x1356: 0x4a1d, 0x1357: 0x4a23, + 0x135a: 0x4a29, 0x135b: 0x4a2f, 0x135c: 0x4a35, + 0x1360: 0x00bf, 0x1361: 0x00c2, 0x1362: 0x00cb, 0x1363: 0x4264, + 0x1364: 0x00c8, 0x1365: 0x00c5, 0x1366: 0x0447, 0x1368: 0x046b, 0x1369: 0x044b, + 0x136a: 0x044f, 0x136b: 0x0453, 0x136c: 0x0457, 0x136d: 0x046f, 0x136e: 0x0473, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0063, 0x1381: 0x0065, 0x1382: 0x0067, 0x1383: 0x0069, 0x1384: 0x006b, 0x1385: 0x006d, + 0x1386: 0x006f, 0x1387: 0x0071, 0x1388: 0x0073, 0x1389: 0x0075, 0x138a: 0x0083, 0x138b: 0x0085, + 0x138c: 0x0087, 0x138d: 0x0089, 0x138e: 0x008b, 0x138f: 0x008d, 0x1390: 0x008f, 0x1391: 0x0091, + 0x1392: 0x0093, 0x1393: 0x0095, 0x1394: 0x0097, 0x1395: 0x0099, 0x1396: 0x009b, 0x1397: 0x009d, + 0x1398: 0x009f, 0x1399: 0x00a1, 0x139a: 0x00a3, 0x139b: 0x00a5, 0x139c: 0x00a7, 0x139d: 0x00a9, + 0x139e: 0x00ab, 0x139f: 0x00ad, 0x13a0: 0x00af, 0x13a1: 0x00b1, 0x13a2: 0x00b3, 0x13a3: 0x00b5, + 0x13a4: 0x00dd, 0x13a5: 0x00f2, 0x13a8: 0x0173, 0x13a9: 0x0176, + 0x13aa: 0x0179, 0x13ab: 0x017c, 0x13ac: 0x017f, 0x13ad: 0x0182, 0x13ae: 0x0185, 0x13af: 0x0188, + 0x13b0: 0x018b, 0x13b1: 0x018e, 0x13b2: 0x0191, 0x13b3: 0x0194, 0x13b4: 0x0197, 0x13b5: 0x019a, + 0x13b6: 0x019d, 0x13b7: 0x01a0, 0x13b8: 0x01a3, 0x13b9: 0x0188, 0x13ba: 0x01a6, 0x13bb: 0x01a9, + 0x13bc: 0x01ac, 0x13bd: 0x01af, 0x13be: 0x01b2, 0x13bf: 0x01b5, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x01fd, 0x13c1: 0x0200, 0x13c2: 0x0203, 0x13c3: 0x045b, 0x13c4: 0x01c7, 0x13c5: 0x01d0, + 0x13c6: 0x01d6, 0x13c7: 0x01fa, 0x13c8: 0x01eb, 0x13c9: 0x01e8, 0x13ca: 0x0206, 0x13cb: 0x0209, + 0x13ce: 0x0021, 0x13cf: 0x0023, 0x13d0: 0x0025, 0x13d1: 0x0027, + 0x13d2: 0x0029, 0x13d3: 0x002b, 0x13d4: 0x002d, 0x13d5: 0x002f, 0x13d6: 0x0031, 0x13d7: 0x0033, + 0x13d8: 0x0021, 0x13d9: 0x0023, 0x13da: 0x0025, 0x13db: 0x0027, 0x13dc: 0x0029, 0x13dd: 0x002b, + 0x13de: 0x002d, 0x13df: 0x002f, 0x13e0: 0x0031, 0x13e1: 0x0033, 0x13e2: 0x0021, 0x13e3: 0x0023, + 0x13e4: 0x0025, 0x13e5: 0x0027, 0x13e6: 0x0029, 0x13e7: 0x002b, 0x13e8: 0x002d, 0x13e9: 0x002f, + 0x13ea: 0x0031, 0x13eb: 0x0033, 0x13ec: 0x0021, 0x13ed: 0x0023, 0x13ee: 0x0025, 0x13ef: 0x0027, + 0x13f0: 0x0029, 0x13f1: 0x002b, 0x13f2: 0x002d, 0x13f3: 0x002f, 0x13f4: 0x0031, 0x13f5: 0x0033, + 0x13f6: 0x0021, 0x13f7: 0x0023, 0x13f8: 0x0025, 0x13f9: 0x0027, 0x13fa: 0x0029, 0x13fb: 0x002b, + 0x13fc: 0x002d, 0x13fd: 0x002f, 0x13fe: 0x0031, 0x13ff: 0x0033, + // Block 0x50, offset 0x1400 + 0x1400: 0x0239, 0x1401: 0x023c, 0x1402: 0x0248, 0x1403: 0x0251, 0x1405: 0x028a, + 0x1406: 0x025a, 0x1407: 0x024b, 0x1408: 0x0269, 0x1409: 0x0290, 0x140a: 0x027b, 0x140b: 0x027e, + 0x140c: 0x0281, 0x140d: 0x0284, 0x140e: 0x025d, 0x140f: 0x026f, 0x1410: 0x0275, 0x1411: 0x0263, + 0x1412: 0x0278, 0x1413: 0x0257, 0x1414: 0x0260, 0x1415: 0x0242, 0x1416: 0x0245, 0x1417: 0x024e, + 0x1418: 0x0254, 0x1419: 0x0266, 0x141a: 0x026c, 0x141b: 0x0272, 0x141c: 0x0293, 0x141d: 0x02e4, + 0x141e: 0x02cc, 0x141f: 0x0296, 0x1421: 0x023c, 0x1422: 0x0248, + 0x1424: 0x0287, 0x1427: 0x024b, 0x1429: 0x0290, + 0x142a: 0x027b, 0x142b: 0x027e, 0x142c: 0x0281, 0x142d: 0x0284, 0x142e: 0x025d, 0x142f: 0x026f, + 0x1430: 0x0275, 0x1431: 0x0263, 0x1432: 0x0278, 0x1434: 0x0260, 0x1435: 0x0242, + 0x1436: 0x0245, 0x1437: 0x024e, 0x1439: 0x0266, 0x143b: 0x0272, + // Block 0x51, offset 0x1440 + 0x1442: 0x0248, + 0x1447: 0x024b, 0x1449: 0x0290, 0x144b: 0x027e, + 0x144d: 0x0284, 0x144e: 0x025d, 0x144f: 0x026f, 0x1451: 0x0263, + 0x1452: 0x0278, 0x1454: 0x0260, 0x1457: 0x024e, + 0x1459: 0x0266, 0x145b: 0x0272, 0x145d: 0x02e4, + 0x145f: 0x0296, 0x1461: 0x023c, 0x1462: 0x0248, + 0x1464: 0x0287, 0x1467: 0x024b, 0x1468: 0x0269, 0x1469: 0x0290, + 0x146a: 0x027b, 0x146c: 0x0281, 0x146d: 0x0284, 0x146e: 0x025d, 0x146f: 0x026f, + 0x1470: 0x0275, 0x1471: 0x0263, 0x1472: 0x0278, 0x1474: 0x0260, 0x1475: 0x0242, + 0x1476: 0x0245, 0x1477: 0x024e, 0x1479: 0x0266, 0x147a: 0x026c, 0x147b: 0x0272, + 0x147c: 0x0293, 0x147e: 0x02cc, + // Block 0x52, offset 0x1480 + 0x1480: 0x0239, 0x1481: 0x023c, 0x1482: 0x0248, 0x1483: 0x0251, 0x1484: 0x0287, 0x1485: 0x028a, + 0x1486: 0x025a, 0x1487: 0x024b, 0x1488: 0x0269, 0x1489: 0x0290, 0x148b: 0x027e, + 0x148c: 0x0281, 0x148d: 0x0284, 0x148e: 0x025d, 0x148f: 0x026f, 0x1490: 0x0275, 0x1491: 0x0263, + 0x1492: 0x0278, 0x1493: 0x0257, 0x1494: 0x0260, 0x1495: 0x0242, 0x1496: 0x0245, 0x1497: 0x024e, + 0x1498: 0x0254, 0x1499: 0x0266, 0x149a: 0x026c, 0x149b: 0x0272, + 0x14a1: 0x023c, 0x14a2: 0x0248, 0x14a3: 0x0251, + 0x14a5: 0x028a, 0x14a6: 0x025a, 0x14a7: 0x024b, 0x14a8: 0x0269, 0x14a9: 0x0290, + 0x14ab: 0x027e, 0x14ac: 0x0281, 0x14ad: 0x0284, 0x14ae: 0x025d, 0x14af: 0x026f, + 0x14b0: 0x0275, 0x14b1: 0x0263, 0x14b2: 0x0278, 0x14b3: 0x0257, 0x14b4: 0x0260, 0x14b5: 0x0242, + 0x14b6: 0x0245, 0x14b7: 0x024e, 0x14b8: 0x0254, 0x14b9: 0x0266, 0x14ba: 0x026c, 0x14bb: 0x0272, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x1879, 0x14c1: 0x1876, 0x14c2: 0x187c, 0x14c3: 0x18a0, 0x14c4: 0x18c4, 0x14c5: 0x18e8, + 0x14c6: 0x190c, 0x14c7: 0x1915, 0x14c8: 0x191b, 0x14c9: 0x1921, 0x14ca: 0x1927, + 0x14d0: 0x1a8c, 0x14d1: 0x1a90, + 0x14d2: 0x1a94, 0x14d3: 0x1a98, 0x14d4: 0x1a9c, 0x14d5: 0x1aa0, 0x14d6: 0x1aa4, 0x14d7: 0x1aa8, + 0x14d8: 0x1aac, 0x14d9: 0x1ab0, 0x14da: 0x1ab4, 0x14db: 0x1ab8, 0x14dc: 0x1abc, 0x14dd: 0x1ac0, + 0x14de: 0x1ac4, 0x14df: 0x1ac8, 0x14e0: 0x1acc, 0x14e1: 0x1ad0, 0x14e2: 0x1ad4, 0x14e3: 0x1ad8, + 0x14e4: 0x1adc, 0x14e5: 0x1ae0, 0x14e6: 0x1ae4, 0x14e7: 0x1ae8, 0x14e8: 0x1aec, 0x14e9: 0x1af0, + 0x14ea: 0x271e, 0x14eb: 0x0047, 0x14ec: 0x0065, 0x14ed: 0x193c, 0x14ee: 0x19b1, + 0x14f0: 0x0043, 0x14f1: 0x0045, 0x14f2: 0x0047, 0x14f3: 0x0049, 0x14f4: 0x004b, 0x14f5: 0x004d, + 0x14f6: 0x004f, 0x14f7: 0x0051, 0x14f8: 0x0053, 0x14f9: 0x0055, 0x14fa: 0x0057, 0x14fb: 0x0059, + 0x14fc: 0x005b, 0x14fd: 0x005d, 0x14fe: 0x005f, 0x14ff: 0x0061, + // Block 0x54, offset 0x1500 + 0x1500: 0x26ad, 0x1501: 0x26c2, 0x1502: 0x0503, + 0x1510: 0x0c0f, 0x1511: 0x0a47, + 0x1512: 0x08d3, 0x1513: 0x45c4, 0x1514: 0x071b, 0x1515: 0x09ef, 0x1516: 0x132f, 0x1517: 0x09ff, + 0x1518: 0x0727, 0x1519: 0x0cd7, 0x151a: 0x0eaf, 0x151b: 0x0caf, 0x151c: 0x0827, 0x151d: 0x0b6b, + 0x151e: 0x07bf, 0x151f: 0x0cb7, 0x1520: 0x0813, 0x1521: 0x1117, 0x1522: 0x0f83, 0x1523: 0x138b, + 0x1524: 0x09d3, 0x1525: 0x090b, 0x1526: 0x0e63, 0x1527: 0x0c1b, 0x1528: 0x0c47, 0x1529: 0x06bf, + 0x152a: 0x06cb, 0x152b: 0x140b, 0x152c: 0x0adb, 0x152d: 0x06e7, 0x152e: 0x08ef, 0x152f: 0x0c3b, + 0x1530: 0x13b3, 0x1531: 0x0c13, 0x1532: 0x106f, 0x1533: 0x10ab, 0x1534: 0x08f7, 0x1535: 0x0e43, + 0x1536: 0x0d0b, 0x1537: 0x0d07, 0x1538: 0x0f97, 0x1539: 0x082b, 0x153a: 0x0957, 0x153b: 0x1443, + // Block 0x55, offset 0x1540 + 0x1540: 0x06fb, 0x1541: 0x06f3, 0x1542: 0x0703, 0x1543: 0x1647, 0x1544: 0x0747, 0x1545: 0x0757, + 0x1546: 0x075b, 0x1547: 0x0763, 0x1548: 0x076b, 0x1549: 0x076f, 0x154a: 0x077b, 0x154b: 0x0773, + 0x154c: 0x05b3, 0x154d: 0x165b, 0x154e: 0x078f, 0x154f: 0x0793, 0x1550: 0x0797, 0x1551: 0x07b3, + 0x1552: 0x164c, 0x1553: 0x05b7, 0x1554: 0x079f, 0x1555: 0x07bf, 0x1556: 0x1656, 0x1557: 0x07cf, + 0x1558: 0x07d7, 0x1559: 0x0737, 0x155a: 0x07df, 0x155b: 0x07e3, 0x155c: 0x1831, 0x155d: 0x07ff, + 0x155e: 0x0807, 0x155f: 0x05bf, 0x1560: 0x081f, 0x1561: 0x0823, 0x1562: 0x082b, 0x1563: 0x082f, + 0x1564: 0x05c3, 0x1565: 0x0847, 0x1566: 0x084b, 0x1567: 0x0857, 0x1568: 0x0863, 0x1569: 0x0867, + 0x156a: 0x086b, 0x156b: 0x0873, 0x156c: 0x0893, 0x156d: 0x0897, 0x156e: 0x089f, 0x156f: 0x08af, + 0x1570: 0x08b7, 0x1571: 0x08bb, 0x1572: 0x08bb, 0x1573: 0x08bb, 0x1574: 0x166a, 0x1575: 0x0e93, + 0x1576: 0x08cf, 0x1577: 0x08d7, 0x1578: 0x166f, 0x1579: 0x08e3, 0x157a: 0x08eb, 0x157b: 0x08f3, + 0x157c: 0x091b, 0x157d: 0x0907, 0x157e: 0x0913, 0x157f: 0x0917, + // Block 0x56, offset 0x1580 + 0x1580: 0x091f, 0x1581: 0x0927, 0x1582: 0x092b, 0x1583: 0x0933, 0x1584: 0x093b, 0x1585: 0x093f, + 0x1586: 0x093f, 0x1587: 0x0947, 0x1588: 0x094f, 0x1589: 0x0953, 0x158a: 0x095f, 0x158b: 0x0983, + 0x158c: 0x0967, 0x158d: 0x0987, 0x158e: 0x096b, 0x158f: 0x0973, 0x1590: 0x080b, 0x1591: 0x09cf, + 0x1592: 0x0997, 0x1593: 0x099b, 0x1594: 0x099f, 0x1595: 0x0993, 0x1596: 0x09a7, 0x1597: 0x09a3, + 0x1598: 0x09bb, 0x1599: 0x1674, 0x159a: 0x09d7, 0x159b: 0x09db, 0x159c: 0x09e3, 0x159d: 0x09ef, + 0x159e: 0x09f7, 0x159f: 0x0a13, 0x15a0: 0x1679, 0x15a1: 0x167e, 0x15a2: 0x0a1f, 0x15a3: 0x0a23, + 0x15a4: 0x0a27, 0x15a5: 0x0a1b, 0x15a6: 0x0a2f, 0x15a7: 0x05c7, 0x15a8: 0x05cb, 0x15a9: 0x0a37, + 0x15aa: 0x0a3f, 0x15ab: 0x0a3f, 0x15ac: 0x1683, 0x15ad: 0x0a5b, 0x15ae: 0x0a5f, 0x15af: 0x0a63, + 0x15b0: 0x0a6b, 0x15b1: 0x1688, 0x15b2: 0x0a73, 0x15b3: 0x0a77, 0x15b4: 0x0b4f, 0x15b5: 0x0a7f, + 0x15b6: 0x05cf, 0x15b7: 0x0a8b, 0x15b8: 0x0a9b, 0x15b9: 0x0aa7, 0x15ba: 0x0aa3, 0x15bb: 0x1692, + 0x15bc: 0x0aaf, 0x15bd: 0x1697, 0x15be: 0x0abb, 0x15bf: 0x0ab7, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x0abf, 0x15c1: 0x0acf, 0x15c2: 0x0ad3, 0x15c3: 0x05d3, 0x15c4: 0x0ae3, 0x15c5: 0x0aeb, + 0x15c6: 0x0aef, 0x15c7: 0x0af3, 0x15c8: 0x05d7, 0x15c9: 0x169c, 0x15ca: 0x05db, 0x15cb: 0x0b0f, + 0x15cc: 0x0b13, 0x15cd: 0x0b17, 0x15ce: 0x0b1f, 0x15cf: 0x1863, 0x15d0: 0x0b37, 0x15d1: 0x16a6, + 0x15d2: 0x16a6, 0x15d3: 0x11d7, 0x15d4: 0x0b47, 0x15d5: 0x0b47, 0x15d6: 0x05df, 0x15d7: 0x16c9, + 0x15d8: 0x179b, 0x15d9: 0x0b57, 0x15da: 0x0b5f, 0x15db: 0x05e3, 0x15dc: 0x0b73, 0x15dd: 0x0b83, + 0x15de: 0x0b87, 0x15df: 0x0b8f, 0x15e0: 0x0b9f, 0x15e1: 0x05eb, 0x15e2: 0x05e7, 0x15e3: 0x0ba3, + 0x15e4: 0x16ab, 0x15e5: 0x0ba7, 0x15e6: 0x0bbb, 0x15e7: 0x0bbf, 0x15e8: 0x0bc3, 0x15e9: 0x0bbf, + 0x15ea: 0x0bcf, 0x15eb: 0x0bd3, 0x15ec: 0x0be3, 0x15ed: 0x0bdb, 0x15ee: 0x0bdf, 0x15ef: 0x0be7, + 0x15f0: 0x0beb, 0x15f1: 0x0bef, 0x15f2: 0x0bfb, 0x15f3: 0x0bff, 0x15f4: 0x0c17, 0x15f5: 0x0c1f, + 0x15f6: 0x0c2f, 0x15f7: 0x0c43, 0x15f8: 0x16ba, 0x15f9: 0x0c3f, 0x15fa: 0x0c33, 0x15fb: 0x0c4b, + 0x15fc: 0x0c53, 0x15fd: 0x0c67, 0x15fe: 0x16bf, 0x15ff: 0x0c6f, + // Block 0x58, offset 0x1600 + 0x1600: 0x0c63, 0x1601: 0x0c5b, 0x1602: 0x05ef, 0x1603: 0x0c77, 0x1604: 0x0c7f, 0x1605: 0x0c87, + 0x1606: 0x0c7b, 0x1607: 0x05f3, 0x1608: 0x0c97, 0x1609: 0x0c9f, 0x160a: 0x16c4, 0x160b: 0x0ccb, + 0x160c: 0x0cff, 0x160d: 0x0cdb, 0x160e: 0x05ff, 0x160f: 0x0ce7, 0x1610: 0x05fb, 0x1611: 0x05f7, + 0x1612: 0x07c3, 0x1613: 0x07c7, 0x1614: 0x0d03, 0x1615: 0x0ceb, 0x1616: 0x11ab, 0x1617: 0x0663, + 0x1618: 0x0d0f, 0x1619: 0x0d13, 0x161a: 0x0d17, 0x161b: 0x0d2b, 0x161c: 0x0d23, 0x161d: 0x16dd, + 0x161e: 0x0603, 0x161f: 0x0d3f, 0x1620: 0x0d33, 0x1621: 0x0d4f, 0x1622: 0x0d57, 0x1623: 0x16e7, + 0x1624: 0x0d5b, 0x1625: 0x0d47, 0x1626: 0x0d63, 0x1627: 0x0607, 0x1628: 0x0d67, 0x1629: 0x0d6b, + 0x162a: 0x0d6f, 0x162b: 0x0d7b, 0x162c: 0x16ec, 0x162d: 0x0d83, 0x162e: 0x060b, 0x162f: 0x0d8f, + 0x1630: 0x16f1, 0x1631: 0x0d93, 0x1632: 0x060f, 0x1633: 0x0d9f, 0x1634: 0x0dab, 0x1635: 0x0db7, + 0x1636: 0x0dbb, 0x1637: 0x16f6, 0x1638: 0x168d, 0x1639: 0x16fb, 0x163a: 0x0ddb, 0x163b: 0x1700, + 0x163c: 0x0de7, 0x163d: 0x0def, 0x163e: 0x0ddf, 0x163f: 0x0dfb, + // Block 0x59, offset 0x1640 + 0x1640: 0x0e0b, 0x1641: 0x0e1b, 0x1642: 0x0e0f, 0x1643: 0x0e13, 0x1644: 0x0e1f, 0x1645: 0x0e23, + 0x1646: 0x1705, 0x1647: 0x0e07, 0x1648: 0x0e3b, 0x1649: 0x0e3f, 0x164a: 0x0613, 0x164b: 0x0e53, + 0x164c: 0x0e4f, 0x164d: 0x170a, 0x164e: 0x0e33, 0x164f: 0x0e6f, 0x1650: 0x170f, 0x1651: 0x1714, + 0x1652: 0x0e73, 0x1653: 0x0e87, 0x1654: 0x0e83, 0x1655: 0x0e7f, 0x1656: 0x0617, 0x1657: 0x0e8b, + 0x1658: 0x0e9b, 0x1659: 0x0e97, 0x165a: 0x0ea3, 0x165b: 0x1651, 0x165c: 0x0eb3, 0x165d: 0x1719, + 0x165e: 0x0ebf, 0x165f: 0x1723, 0x1660: 0x0ed3, 0x1661: 0x0edf, 0x1662: 0x0ef3, 0x1663: 0x1728, + 0x1664: 0x0f07, 0x1665: 0x0f0b, 0x1666: 0x172d, 0x1667: 0x1732, 0x1668: 0x0f27, 0x1669: 0x0f37, + 0x166a: 0x061b, 0x166b: 0x0f3b, 0x166c: 0x061f, 0x166d: 0x061f, 0x166e: 0x0f53, 0x166f: 0x0f57, + 0x1670: 0x0f5f, 0x1671: 0x0f63, 0x1672: 0x0f6f, 0x1673: 0x0623, 0x1674: 0x0f87, 0x1675: 0x1737, + 0x1676: 0x0fa3, 0x1677: 0x173c, 0x1678: 0x0faf, 0x1679: 0x16a1, 0x167a: 0x0fbf, 0x167b: 0x1741, + 0x167c: 0x1746, 0x167d: 0x174b, 0x167e: 0x0627, 0x167f: 0x062b, + // Block 0x5a, offset 0x1680 + 0x1680: 0x0ff7, 0x1681: 0x1755, 0x1682: 0x1750, 0x1683: 0x175a, 0x1684: 0x175f, 0x1685: 0x0fff, + 0x1686: 0x1003, 0x1687: 0x1003, 0x1688: 0x100b, 0x1689: 0x0633, 0x168a: 0x100f, 0x168b: 0x0637, + 0x168c: 0x063b, 0x168d: 0x1769, 0x168e: 0x1023, 0x168f: 0x102b, 0x1690: 0x1037, 0x1691: 0x063f, + 0x1692: 0x176e, 0x1693: 0x105b, 0x1694: 0x1773, 0x1695: 0x1778, 0x1696: 0x107b, 0x1697: 0x1093, + 0x1698: 0x0643, 0x1699: 0x109b, 0x169a: 0x109f, 0x169b: 0x10a3, 0x169c: 0x177d, 0x169d: 0x1782, + 0x169e: 0x1782, 0x169f: 0x10bb, 0x16a0: 0x0647, 0x16a1: 0x1787, 0x16a2: 0x10cf, 0x16a3: 0x10d3, + 0x16a4: 0x064b, 0x16a5: 0x178c, 0x16a6: 0x10ef, 0x16a7: 0x064f, 0x16a8: 0x10ff, 0x16a9: 0x10f7, + 0x16aa: 0x1107, 0x16ab: 0x1796, 0x16ac: 0x111f, 0x16ad: 0x0653, 0x16ae: 0x112b, 0x16af: 0x1133, + 0x16b0: 0x1143, 0x16b1: 0x0657, 0x16b2: 0x17a0, 0x16b3: 0x17a5, 0x16b4: 0x065b, 0x16b5: 0x17aa, + 0x16b6: 0x115b, 0x16b7: 0x17af, 0x16b8: 0x1167, 0x16b9: 0x1173, 0x16ba: 0x117b, 0x16bb: 0x17b4, + 0x16bc: 0x17b9, 0x16bd: 0x118f, 0x16be: 0x17be, 0x16bf: 0x1197, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x16ce, 0x16c1: 0x065f, 0x16c2: 0x11af, 0x16c3: 0x11b3, 0x16c4: 0x0667, 0x16c5: 0x11b7, + 0x16c6: 0x0a33, 0x16c7: 0x17c3, 0x16c8: 0x17c8, 0x16c9: 0x16d3, 0x16ca: 0x16d8, 0x16cb: 0x11d7, + 0x16cc: 0x11db, 0x16cd: 0x13f3, 0x16ce: 0x066b, 0x16cf: 0x1207, 0x16d0: 0x1203, 0x16d1: 0x120b, + 0x16d2: 0x083f, 0x16d3: 0x120f, 0x16d4: 0x1213, 0x16d5: 0x1217, 0x16d6: 0x121f, 0x16d7: 0x17cd, + 0x16d8: 0x121b, 0x16d9: 0x1223, 0x16da: 0x1237, 0x16db: 0x123b, 0x16dc: 0x1227, 0x16dd: 0x123f, + 0x16de: 0x1253, 0x16df: 0x1267, 0x16e0: 0x1233, 0x16e1: 0x1247, 0x16e2: 0x124b, 0x16e3: 0x124f, + 0x16e4: 0x17d2, 0x16e5: 0x17dc, 0x16e6: 0x17d7, 0x16e7: 0x066f, 0x16e8: 0x126f, 0x16e9: 0x1273, + 0x16ea: 0x127b, 0x16eb: 0x17f0, 0x16ec: 0x127f, 0x16ed: 0x17e1, 0x16ee: 0x0673, 0x16ef: 0x0677, + 0x16f0: 0x17e6, 0x16f1: 0x17eb, 0x16f2: 0x067b, 0x16f3: 0x129f, 0x16f4: 0x12a3, 0x16f5: 0x12a7, + 0x16f6: 0x12ab, 0x16f7: 0x12b7, 0x16f8: 0x12b3, 0x16f9: 0x12bf, 0x16fa: 0x12bb, 0x16fb: 0x12cb, + 0x16fc: 0x12c3, 0x16fd: 0x12c7, 0x16fe: 0x12cf, 0x16ff: 0x067f, + // Block 0x5c, offset 0x1700 + 0x1700: 0x12d7, 0x1701: 0x12db, 0x1702: 0x0683, 0x1703: 0x12eb, 0x1704: 0x12ef, 0x1705: 0x17f5, + 0x1706: 0x12fb, 0x1707: 0x12ff, 0x1708: 0x0687, 0x1709: 0x130b, 0x170a: 0x05bb, 0x170b: 0x17fa, + 0x170c: 0x17ff, 0x170d: 0x068b, 0x170e: 0x068f, 0x170f: 0x1337, 0x1710: 0x134f, 0x1711: 0x136b, + 0x1712: 0x137b, 0x1713: 0x1804, 0x1714: 0x138f, 0x1715: 0x1393, 0x1716: 0x13ab, 0x1717: 0x13b7, + 0x1718: 0x180e, 0x1719: 0x1660, 0x171a: 0x13c3, 0x171b: 0x13bf, 0x171c: 0x13cb, 0x171d: 0x1665, + 0x171e: 0x13d7, 0x171f: 0x13e3, 0x1720: 0x1813, 0x1721: 0x1818, 0x1722: 0x1423, 0x1723: 0x142f, + 0x1724: 0x1437, 0x1725: 0x181d, 0x1726: 0x143b, 0x1727: 0x1467, 0x1728: 0x1473, 0x1729: 0x1477, + 0x172a: 0x146f, 0x172b: 0x1483, 0x172c: 0x1487, 0x172d: 0x1822, 0x172e: 0x1493, 0x172f: 0x0693, + 0x1730: 0x149b, 0x1731: 0x1827, 0x1732: 0x0697, 0x1733: 0x14d3, 0x1734: 0x0ac3, 0x1735: 0x14eb, + 0x1736: 0x182c, 0x1737: 0x1836, 0x1738: 0x069b, 0x1739: 0x069f, 0x173a: 0x1513, 0x173b: 0x183b, + 0x173c: 0x06a3, 0x173d: 0x1840, 0x173e: 0x152b, 0x173f: 0x152b, + // Block 0x5d, offset 0x1740 + 0x1740: 0x1533, 0x1741: 0x1845, 0x1742: 0x154b, 0x1743: 0x06a7, 0x1744: 0x155b, 0x1745: 0x1567, + 0x1746: 0x156f, 0x1747: 0x1577, 0x1748: 0x06ab, 0x1749: 0x184a, 0x174a: 0x158b, 0x174b: 0x15a7, + 0x174c: 0x15b3, 0x174d: 0x06af, 0x174e: 0x06b3, 0x174f: 0x15b7, 0x1750: 0x184f, 0x1751: 0x06b7, + 0x1752: 0x1854, 0x1753: 0x1859, 0x1754: 0x185e, 0x1755: 0x15db, 0x1756: 0x06bb, 0x1757: 0x15ef, + 0x1758: 0x15f7, 0x1759: 0x15fb, 0x175a: 0x1603, 0x175b: 0x160b, 0x175c: 0x1613, 0x175d: 0x1868, +} + +// nfkcIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var nfkcIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x5c, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5d, 0xc7: 0x04, + 0xc8: 0x05, 0xca: 0x5e, 0xcb: 0x5f, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09, + 0xd0: 0x0a, 0xd1: 0x60, 0xd2: 0x61, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x62, + 0xd8: 0x63, 0xd9: 0x0d, 0xdb: 0x64, 0xdc: 0x65, 0xdd: 0x66, 0xdf: 0x67, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, + 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a, + 0xf0: 0x13, + // Block 0x4, offset 0x100 + 0x120: 0x68, 0x121: 0x69, 0x123: 0x0e, 0x124: 0x6a, 0x125: 0x6b, 0x126: 0x6c, 0x127: 0x6d, + 0x128: 0x6e, 0x129: 0x6f, 0x12a: 0x70, 0x12b: 0x71, 0x12c: 0x6c, 0x12d: 0x72, 0x12e: 0x73, 0x12f: 0x74, + 0x131: 0x75, 0x132: 0x76, 0x133: 0x77, 0x134: 0x78, 0x135: 0x79, 0x137: 0x7a, + 0x138: 0x7b, 0x139: 0x7c, 0x13a: 0x7d, 0x13b: 0x7e, 0x13c: 0x7f, 0x13d: 0x80, 0x13e: 0x81, 0x13f: 0x82, + // Block 0x5, offset 0x140 + 0x140: 0x83, 0x142: 0x84, 0x143: 0x85, 0x144: 0x86, 0x145: 0x87, 0x146: 0x88, 0x147: 0x89, + 0x14d: 0x8a, + 0x15c: 0x8b, 0x15f: 0x8c, + 0x162: 0x8d, 0x164: 0x8e, + 0x168: 0x8f, 0x169: 0x90, 0x16a: 0x91, 0x16c: 0x0f, 0x16d: 0x92, 0x16e: 0x93, 0x16f: 0x94, + 0x170: 0x95, 0x173: 0x96, 0x174: 0x97, 0x175: 0x10, 0x176: 0x11, 0x177: 0x12, + 0x178: 0x13, 0x179: 0x14, 0x17a: 0x15, 0x17b: 0x16, 0x17c: 0x17, 0x17d: 0x18, 0x17e: 0x19, 0x17f: 0x1a, + // Block 0x6, offset 0x180 + 0x180: 0x98, 0x181: 0x99, 0x182: 0x9a, 0x183: 0x9b, 0x184: 0x1b, 0x185: 0x1c, 0x186: 0x9c, 0x187: 0x9d, + 0x188: 0x9e, 0x189: 0x1d, 0x18a: 0x1e, 0x18b: 0x9f, 0x18c: 0xa0, + 0x191: 0x1f, 0x192: 0x20, 0x193: 0xa1, + 0x1a8: 0xa2, 0x1a9: 0xa3, 0x1ab: 0xa4, + 0x1b1: 0xa5, 0x1b3: 0xa6, 0x1b5: 0xa7, 0x1b7: 0xa8, + 0x1ba: 0xa9, 0x1bb: 0xaa, 0x1bc: 0x21, 0x1bd: 0x22, 0x1be: 0x23, 0x1bf: 0xab, + // Block 0x7, offset 0x1c0 + 0x1c0: 0xac, 0x1c1: 0x24, 0x1c2: 0x25, 0x1c3: 0x26, 0x1c4: 0xad, 0x1c5: 0x27, 0x1c6: 0x28, + 0x1c8: 0x29, 0x1c9: 0x2a, 0x1ca: 0x2b, 0x1cb: 0x2c, 0x1cc: 0x2d, 0x1cd: 0x2e, 0x1ce: 0x2f, 0x1cf: 0x30, + // Block 0x8, offset 0x200 + 0x219: 0xae, 0x21a: 0xaf, 0x21b: 0xb0, 0x21d: 0xb1, 0x21f: 0xb2, + 0x220: 0xb3, 0x223: 0xb4, 0x224: 0xb5, 0x225: 0xb6, 0x226: 0xb7, 0x227: 0xb8, + 0x22a: 0xb9, 0x22b: 0xba, 0x22d: 0xbb, 0x22f: 0xbc, + 0x230: 0xbd, 0x231: 0xbe, 0x232: 0xbf, 0x233: 0xc0, 0x234: 0xc1, 0x235: 0xc2, 0x236: 0xc3, 0x237: 0xbd, + 0x238: 0xbe, 0x239: 0xbf, 0x23a: 0xc0, 0x23b: 0xc1, 0x23c: 0xc2, 0x23d: 0xc3, 0x23e: 0xbd, 0x23f: 0xbe, + // Block 0x9, offset 0x240 + 0x240: 0xbf, 0x241: 0xc0, 0x242: 0xc1, 0x243: 0xc2, 0x244: 0xc3, 0x245: 0xbd, 0x246: 0xbe, 0x247: 0xbf, + 0x248: 0xc0, 0x249: 0xc1, 0x24a: 0xc2, 0x24b: 0xc3, 0x24c: 0xbd, 0x24d: 0xbe, 0x24e: 0xbf, 0x24f: 0xc0, + 0x250: 0xc1, 0x251: 0xc2, 0x252: 0xc3, 0x253: 0xbd, 0x254: 0xbe, 0x255: 0xbf, 0x256: 0xc0, 0x257: 0xc1, + 0x258: 0xc2, 0x259: 0xc3, 0x25a: 0xbd, 0x25b: 0xbe, 0x25c: 0xbf, 0x25d: 0xc0, 0x25e: 0xc1, 0x25f: 0xc2, + 0x260: 0xc3, 0x261: 0xbd, 0x262: 0xbe, 0x263: 0xbf, 0x264: 0xc0, 0x265: 0xc1, 0x266: 0xc2, 0x267: 0xc3, + 0x268: 0xbd, 0x269: 0xbe, 0x26a: 0xbf, 0x26b: 0xc0, 0x26c: 0xc1, 0x26d: 0xc2, 0x26e: 0xc3, 0x26f: 0xbd, + 0x270: 0xbe, 0x271: 0xbf, 0x272: 0xc0, 0x273: 0xc1, 0x274: 0xc2, 0x275: 0xc3, 0x276: 0xbd, 0x277: 0xbe, + 0x278: 0xbf, 0x279: 0xc0, 0x27a: 0xc1, 0x27b: 0xc2, 0x27c: 0xc3, 0x27d: 0xbd, 0x27e: 0xbe, 0x27f: 0xbf, + // Block 0xa, offset 0x280 + 0x280: 0xc0, 0x281: 0xc1, 0x282: 0xc2, 0x283: 0xc3, 0x284: 0xbd, 0x285: 0xbe, 0x286: 0xbf, 0x287: 0xc0, + 0x288: 0xc1, 0x289: 0xc2, 0x28a: 0xc3, 0x28b: 0xbd, 0x28c: 0xbe, 0x28d: 0xbf, 0x28e: 0xc0, 0x28f: 0xc1, + 0x290: 0xc2, 0x291: 0xc3, 0x292: 0xbd, 0x293: 0xbe, 0x294: 0xbf, 0x295: 0xc0, 0x296: 0xc1, 0x297: 0xc2, + 0x298: 0xc3, 0x299: 0xbd, 0x29a: 0xbe, 0x29b: 0xbf, 0x29c: 0xc0, 0x29d: 0xc1, 0x29e: 0xc2, 0x29f: 0xc3, + 0x2a0: 0xbd, 0x2a1: 0xbe, 0x2a2: 0xbf, 0x2a3: 0xc0, 0x2a4: 0xc1, 0x2a5: 0xc2, 0x2a6: 0xc3, 0x2a7: 0xbd, + 0x2a8: 0xbe, 0x2a9: 0xbf, 0x2aa: 0xc0, 0x2ab: 0xc1, 0x2ac: 0xc2, 0x2ad: 0xc3, 0x2ae: 0xbd, 0x2af: 0xbe, + 0x2b0: 0xbf, 0x2b1: 0xc0, 0x2b2: 0xc1, 0x2b3: 0xc2, 0x2b4: 0xc3, 0x2b5: 0xbd, 0x2b6: 0xbe, 0x2b7: 0xbf, + 0x2b8: 0xc0, 0x2b9: 0xc1, 0x2ba: 0xc2, 0x2bb: 0xc3, 0x2bc: 0xbd, 0x2bd: 0xbe, 0x2be: 0xbf, 0x2bf: 0xc0, + // Block 0xb, offset 0x2c0 + 0x2c0: 0xc1, 0x2c1: 0xc2, 0x2c2: 0xc3, 0x2c3: 0xbd, 0x2c4: 0xbe, 0x2c5: 0xbf, 0x2c6: 0xc0, 0x2c7: 0xc1, + 0x2c8: 0xc2, 0x2c9: 0xc3, 0x2ca: 0xbd, 0x2cb: 0xbe, 0x2cc: 0xbf, 0x2cd: 0xc0, 0x2ce: 0xc1, 0x2cf: 0xc2, + 0x2d0: 0xc3, 0x2d1: 0xbd, 0x2d2: 0xbe, 0x2d3: 0xbf, 0x2d4: 0xc0, 0x2d5: 0xc1, 0x2d6: 0xc2, 0x2d7: 0xc3, + 0x2d8: 0xbd, 0x2d9: 0xbe, 0x2da: 0xbf, 0x2db: 0xc0, 0x2dc: 0xc1, 0x2dd: 0xc2, 0x2de: 0xc4, + // Block 0xc, offset 0x300 + 0x324: 0x31, 0x325: 0x32, 0x326: 0x33, 0x327: 0x34, + 0x328: 0x35, 0x329: 0x36, 0x32a: 0x37, 0x32b: 0x38, 0x32c: 0x39, 0x32d: 0x3a, 0x32e: 0x3b, 0x32f: 0x3c, + 0x330: 0x3d, 0x331: 0x3e, 0x332: 0x3f, 0x333: 0x40, 0x334: 0x41, 0x335: 0x42, 0x336: 0x43, 0x337: 0x44, + 0x338: 0x45, 0x339: 0x46, 0x33a: 0x47, 0x33b: 0x48, 0x33c: 0xc5, 0x33d: 0x49, 0x33e: 0x4a, 0x33f: 0x4b, + // Block 0xd, offset 0x340 + 0x347: 0xc6, + 0x34b: 0xc7, 0x34d: 0xc8, + 0x368: 0xc9, 0x36b: 0xca, + 0x374: 0xcb, + 0x37d: 0xcc, + // Block 0xe, offset 0x380 + 0x381: 0xcd, 0x382: 0xce, 0x384: 0xcf, 0x385: 0xb7, 0x387: 0xd0, + 0x388: 0xd1, 0x38b: 0xd2, 0x38c: 0xd3, 0x38d: 0xd4, + 0x391: 0xd5, 0x392: 0xd6, 0x393: 0xd7, 0x396: 0xd8, 0x397: 0xd9, + 0x398: 0xda, 0x39a: 0xdb, 0x39c: 0xdc, + 0x3a0: 0xdd, + 0x3a8: 0xde, 0x3a9: 0xdf, 0x3aa: 0xe0, + 0x3b0: 0xda, 0x3b5: 0xe1, 0x3b6: 0xe2, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xe3, 0x3ec: 0xe4, + // Block 0x10, offset 0x400 + 0x432: 0xe5, + // Block 0x11, offset 0x440 + 0x445: 0xe6, 0x446: 0xe7, 0x447: 0xe8, + 0x449: 0xe9, + 0x450: 0xea, 0x451: 0xeb, 0x452: 0xec, 0x453: 0xed, 0x454: 0xee, 0x455: 0xef, 0x456: 0xf0, 0x457: 0xf1, + 0x458: 0xf2, 0x459: 0xf3, 0x45a: 0x4c, 0x45b: 0xf4, 0x45c: 0xf5, 0x45d: 0xf6, 0x45e: 0xf7, 0x45f: 0x4d, + // Block 0x12, offset 0x480 + 0x480: 0xf8, + 0x4a3: 0xf9, 0x4a5: 0xfa, + 0x4b8: 0x4e, 0x4b9: 0x4f, 0x4ba: 0x50, + // Block 0x13, offset 0x4c0 + 0x4c4: 0x51, 0x4c5: 0xfb, 0x4c6: 0xfc, + 0x4c8: 0x52, 0x4c9: 0xfd, + // Block 0x14, offset 0x500 + 0x520: 0x53, 0x521: 0x54, 0x522: 0x55, 0x523: 0x56, 0x524: 0x57, 0x525: 0x58, 0x526: 0x59, 0x527: 0x5a, + 0x528: 0x5b, + // Block 0x15, offset 0x540 + 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d, + 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11, + 0x56f: 0x12, +} + +// nfkcSparseOffset: 162 entries, 324 bytes +var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x70, 0x75, 0x77, 0x7f, 0x86, 0x89, 0x91, 0x95, 0x99, 0x9b, 0x9d, 0xa6, 0xaa, 0xb1, 0xb6, 0xb9, 0xc3, 0xc6, 0xcd, 0xd5, 0xd9, 0xdb, 0xde, 0xe2, 0xe8, 0xf9, 0x105, 0x107, 0x10d, 0x10f, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11b, 0x11e, 0x121, 0x123, 0x126, 0x129, 0x12d, 0x132, 0x13b, 0x13d, 0x140, 0x142, 0x14d, 0x158, 0x166, 0x174, 0x184, 0x192, 0x199, 0x19f, 0x1ae, 0x1b2, 0x1b4, 0x1b8, 0x1ba, 0x1bd, 0x1bf, 0x1c2, 0x1c4, 0x1c7, 0x1c9, 0x1cb, 0x1cd, 0x1d9, 0x1e3, 0x1ed, 0x1f0, 0x1f4, 0x1f6, 0x1f8, 0x1fa, 0x1fc, 0x1ff, 0x201, 0x203, 0x205, 0x207, 0x20d, 0x210, 0x214, 0x216, 0x21d, 0x223, 0x229, 0x231, 0x237, 0x23d, 0x243, 0x247, 0x249, 0x24b, 0x24d, 0x24f, 0x255, 0x258, 0x25a, 0x260, 0x263, 0x26b, 0x272, 0x275, 0x278, 0x27a, 0x27d, 0x285, 0x289, 0x290, 0x293, 0x299, 0x29b, 0x29d, 0x2a0, 0x2a2, 0x2a5, 0x2a7, 0x2a9, 0x2ab, 0x2ae, 0x2b0, 0x2b2, 0x2b4, 0x2b6, 0x2c3, 0x2cd, 0x2cf, 0x2d1, 0x2d5, 0x2da, 0x2e6, 0x2eb, 0x2f4, 0x2fa, 0x2ff, 0x303, 0x308, 0x30c, 0x31c, 0x32a, 0x338, 0x346, 0x34c, 0x34e, 0x351, 0x35b, 0x35d} + +// nfkcSparseValues: 871 entries, 3484 bytes +var nfkcSparseValues = [871]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0002, lo: 0x0d}, + {value: 0x0001, lo: 0xa0, hi: 0xa0}, + {value: 0x4278, lo: 0xa8, hi: 0xa8}, + {value: 0x0083, lo: 0xaa, hi: 0xaa}, + {value: 0x4264, lo: 0xaf, hi: 0xaf}, + {value: 0x0025, lo: 0xb2, hi: 0xb3}, + {value: 0x425a, lo: 0xb4, hi: 0xb4}, + {value: 0x01dc, lo: 0xb5, hi: 0xb5}, + {value: 0x4291, lo: 0xb8, hi: 0xb8}, + {value: 0x0023, lo: 0xb9, hi: 0xb9}, + {value: 0x009f, lo: 0xba, hi: 0xba}, + {value: 0x221c, lo: 0xbc, hi: 0xbc}, + {value: 0x2210, lo: 0xbd, hi: 0xbd}, + {value: 0x22b2, lo: 0xbe, hi: 0xbe}, + // Block 0x1, offset 0xe + {value: 0x0091, lo: 0x03}, + {value: 0x46e2, lo: 0xa0, hi: 0xa1}, + {value: 0x4714, lo: 0xaf, hi: 0xb0}, + {value: 0xa000, lo: 0xb7, hi: 0xb7}, + // Block 0x2, offset 0x12 + {value: 0x0003, lo: 0x08}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x0091, lo: 0xb0, hi: 0xb0}, + {value: 0x0119, lo: 0xb1, hi: 0xb1}, + {value: 0x0095, lo: 0xb2, hi: 0xb2}, + {value: 0x00a5, lo: 0xb3, hi: 0xb3}, + {value: 0x0143, lo: 0xb4, hi: 0xb6}, + {value: 0x00af, lo: 0xb7, hi: 0xb7}, + {value: 0x00b3, lo: 0xb8, hi: 0xb8}, + // Block 0x3, offset 0x1b + {value: 0x000a, lo: 0x09}, + {value: 0x426e, lo: 0x98, hi: 0x98}, + {value: 0x4273, lo: 0x99, hi: 0x9a}, + {value: 0x4296, lo: 0x9b, hi: 0x9b}, + {value: 0x425f, lo: 0x9c, hi: 0x9c}, + {value: 0x4282, lo: 0x9d, hi: 0x9d}, + {value: 0x0113, lo: 0xa0, hi: 0xa0}, + {value: 0x0099, lo: 0xa1, hi: 0xa1}, + {value: 0x00a7, lo: 0xa2, hi: 0xa3}, + {value: 0x0167, lo: 0xa4, hi: 0xa4}, + // Block 0x4, offset 0x25 + {value: 0x0000, lo: 0x0f}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0xa000, lo: 0x8d, hi: 0x8d}, + {value: 0x37a5, lo: 0x90, hi: 0x90}, + {value: 0x37b1, lo: 0x91, hi: 0x91}, + {value: 0x379f, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x3817, lo: 0x97, hi: 0x97}, + {value: 0x37e1, lo: 0x9c, hi: 0x9c}, + {value: 0x37c9, lo: 0x9d, hi: 0x9d}, + {value: 0x37f3, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x381d, lo: 0xb6, hi: 0xb6}, + {value: 0x3823, lo: 0xb7, hi: 0xb7}, + // Block 0x5, offset 0x35 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x83, hi: 0x87}, + // Block 0x6, offset 0x37 + {value: 0x0001, lo: 0x04}, + {value: 0x8113, lo: 0x81, hi: 0x82}, + {value: 0x8132, lo: 0x84, hi: 0x84}, + {value: 0x812d, lo: 0x85, hi: 0x85}, + {value: 0x810d, lo: 0x87, hi: 0x87}, + // Block 0x7, offset 0x3c + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x97}, + {value: 0x8119, lo: 0x98, hi: 0x98}, + {value: 0x811a, lo: 0x99, hi: 0x99}, + {value: 0x811b, lo: 0x9a, hi: 0x9a}, + {value: 0x3841, lo: 0xa2, hi: 0xa2}, + {value: 0x3847, lo: 0xa3, hi: 0xa3}, + {value: 0x3853, lo: 0xa4, hi: 0xa4}, + {value: 0x384d, lo: 0xa5, hi: 0xa5}, + {value: 0x3859, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x8, offset 0x47 + {value: 0x0000, lo: 0x0e}, + {value: 0x386b, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x385f, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3865, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8132, lo: 0x96, hi: 0x9c}, + {value: 0x8132, lo: 0x9f, hi: 0xa2}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa4}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + // Block 0x9, offset 0x56 + {value: 0x0000, lo: 0x0c}, + {value: 0x811f, lo: 0x91, hi: 0x91}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x812d, lo: 0xb1, hi: 0xb1}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb5, hi: 0xb6}, + {value: 0x812d, lo: 0xb7, hi: 0xb9}, + {value: 0x8132, lo: 0xba, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbc}, + {value: 0x8132, lo: 0xbd, hi: 0xbd}, + {value: 0x812d, lo: 0xbe, hi: 0xbe}, + {value: 0x8132, lo: 0xbf, hi: 0xbf}, + // Block 0xa, offset 0x63 + {value: 0x0005, lo: 0x07}, + {value: 0x8132, lo: 0x80, hi: 0x80}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x83}, + {value: 0x812d, lo: 0x84, hi: 0x85}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x812d, lo: 0x88, hi: 0x89}, + {value: 0x8132, lo: 0x8a, hi: 0x8a}, + // Block 0xb, offset 0x6b + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xab, hi: 0xb1}, + {value: 0x812d, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb3}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0xc, offset 0x70 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0x96, hi: 0x99}, + {value: 0x8132, lo: 0x9b, hi: 0xa3}, + {value: 0x8132, lo: 0xa5, hi: 0xa7}, + {value: 0x8132, lo: 0xa9, hi: 0xad}, + // Block 0xd, offset 0x75 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x99, hi: 0x9b}, + // Block 0xe, offset 0x77 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3ed8, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ee0, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3ee8, lo: 0xb4, hi: 0xb4}, + {value: 0x9902, lo: 0xbc, hi: 0xbc}, + // Block 0xf, offset 0x7f + {value: 0x0008, lo: 0x06}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x91, hi: 0x91}, + {value: 0x812d, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x93, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x94}, + {value: 0x451c, lo: 0x98, hi: 0x9f}, + // Block 0x10, offset 0x86 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x11, offset 0x89 + {value: 0x0008, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2c9e, lo: 0x8b, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x455c, lo: 0x9c, hi: 0x9d}, + {value: 0x456c, lo: 0x9f, hi: 0x9f}, + {value: 0x8132, lo: 0xbe, hi: 0xbe}, + // Block 0x12, offset 0x91 + {value: 0x0000, lo: 0x03}, + {value: 0x4594, lo: 0xb3, hi: 0xb3}, + {value: 0x459c, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x13, offset 0x95 + {value: 0x0008, lo: 0x03}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x4574, lo: 0x99, hi: 0x9b}, + {value: 0x458c, lo: 0x9e, hi: 0x9e}, + // Block 0x14, offset 0x99 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x15, offset 0x9b + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + // Block 0x16, offset 0x9d + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cb6, lo: 0x88, hi: 0x88}, + {value: 0x2cae, lo: 0x8b, hi: 0x8b}, + {value: 0x2cbe, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45a4, lo: 0x9c, hi: 0x9c}, + {value: 0x45ac, lo: 0x9d, hi: 0x9d}, + // Block 0x17, offset 0xa6 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cc6, lo: 0x94, hi: 0x94}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x18, offset 0xaa + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cce, lo: 0x8a, hi: 0x8a}, + {value: 0x2cde, lo: 0x8b, hi: 0x8b}, + {value: 0x2cd6, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x19, offset 0xb1 + {value: 0x1801, lo: 0x04}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x3ef0, lo: 0x88, hi: 0x88}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8120, lo: 0x95, hi: 0x96}, + // Block 0x1a, offset 0xb6 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1b, offset 0xb9 + {value: 0x0000, lo: 0x09}, + {value: 0x2ce6, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cee, lo: 0x87, hi: 0x87}, + {value: 0x2cf6, lo: 0x88, hi: 0x88}, + {value: 0x2f50, lo: 0x8a, hi: 0x8a}, + {value: 0x2dd8, lo: 0x8b, hi: 0x8b}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1c, offset 0xc3 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1d, offset 0xc6 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cfe, lo: 0x8a, hi: 0x8a}, + {value: 0x2d0e, lo: 0x8b, hi: 0x8b}, + {value: 0x2d06, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1e, offset 0xcd + {value: 0x6bea, lo: 0x07}, + {value: 0x9904, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3ef8, lo: 0x9a, hi: 0x9a}, + {value: 0x2f58, lo: 0x9c, hi: 0x9c}, + {value: 0x2de3, lo: 0x9d, hi: 0x9d}, + {value: 0x2d16, lo: 0x9e, hi: 0x9f}, + // Block 0x1f, offset 0xd5 + {value: 0x0000, lo: 0x03}, + {value: 0x2621, lo: 0xb3, hi: 0xb3}, + {value: 0x8122, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x20, offset 0xd9 + {value: 0x0000, lo: 0x01}, + {value: 0x8123, lo: 0x88, hi: 0x8b}, + // Block 0x21, offset 0xdb + {value: 0x0000, lo: 0x02}, + {value: 0x2636, lo: 0xb3, hi: 0xb3}, + {value: 0x8124, lo: 0xb8, hi: 0xb9}, + // Block 0x22, offset 0xde + {value: 0x0000, lo: 0x03}, + {value: 0x8125, lo: 0x88, hi: 0x8b}, + {value: 0x2628, lo: 0x9c, hi: 0x9c}, + {value: 0x262f, lo: 0x9d, hi: 0x9d}, + // Block 0x23, offset 0xe2 + {value: 0x0000, lo: 0x05}, + {value: 0x030b, lo: 0x8c, hi: 0x8c}, + {value: 0x812d, lo: 0x98, hi: 0x99}, + {value: 0x812d, lo: 0xb5, hi: 0xb5}, + {value: 0x812d, lo: 0xb7, hi: 0xb7}, + {value: 0x812b, lo: 0xb9, hi: 0xb9}, + // Block 0x24, offset 0xe8 + {value: 0x0000, lo: 0x10}, + {value: 0x2644, lo: 0x83, hi: 0x83}, + {value: 0x264b, lo: 0x8d, hi: 0x8d}, + {value: 0x2652, lo: 0x92, hi: 0x92}, + {value: 0x2659, lo: 0x97, hi: 0x97}, + {value: 0x2660, lo: 0x9c, hi: 0x9c}, + {value: 0x263d, lo: 0xa9, hi: 0xa9}, + {value: 0x8126, lo: 0xb1, hi: 0xb1}, + {value: 0x8127, lo: 0xb2, hi: 0xb2}, + {value: 0x4a84, lo: 0xb3, hi: 0xb3}, + {value: 0x8128, lo: 0xb4, hi: 0xb4}, + {value: 0x4a8d, lo: 0xb5, hi: 0xb5}, + {value: 0x45b4, lo: 0xb6, hi: 0xb6}, + {value: 0x45f4, lo: 0xb7, hi: 0xb7}, + {value: 0x45bc, lo: 0xb8, hi: 0xb8}, + {value: 0x45ff, lo: 0xb9, hi: 0xb9}, + {value: 0x8127, lo: 0xba, hi: 0xbd}, + // Block 0x25, offset 0xf9 + {value: 0x0000, lo: 0x0b}, + {value: 0x8127, lo: 0x80, hi: 0x80}, + {value: 0x4a96, lo: 0x81, hi: 0x81}, + {value: 0x8132, lo: 0x82, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0x86, hi: 0x87}, + {value: 0x266e, lo: 0x93, hi: 0x93}, + {value: 0x2675, lo: 0x9d, hi: 0x9d}, + {value: 0x267c, lo: 0xa2, hi: 0xa2}, + {value: 0x2683, lo: 0xa7, hi: 0xa7}, + {value: 0x268a, lo: 0xac, hi: 0xac}, + {value: 0x2667, lo: 0xb9, hi: 0xb9}, + // Block 0x26, offset 0x105 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x86, hi: 0x86}, + // Block 0x27, offset 0x107 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d1e, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x28, offset 0x10d + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + // Block 0x29, offset 0x10f + {value: 0x0000, lo: 0x01}, + {value: 0x030f, lo: 0xbc, hi: 0xbc}, + // Block 0x2a, offset 0x111 + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x80, hi: 0x92}, + // Block 0x2b, offset 0x113 + {value: 0x0000, lo: 0x01}, + {value: 0xb900, lo: 0xa1, hi: 0xb5}, + // Block 0x2c, offset 0x115 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xa8, hi: 0xbf}, + // Block 0x2d, offset 0x117 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0x80, hi: 0x82}, + // Block 0x2e, offset 0x119 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9d, hi: 0x9f}, + // Block 0x2f, offset 0x11b + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x94, hi: 0x94}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x30, offset 0x11e + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x9d, hi: 0x9d}, + // Block 0x31, offset 0x121 + {value: 0x0000, lo: 0x01}, + {value: 0x8131, lo: 0xa9, hi: 0xa9}, + // Block 0x32, offset 0x123 + {value: 0x0004, lo: 0x02}, + {value: 0x812e, lo: 0xb9, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbb}, + // Block 0x33, offset 0x126 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x97, hi: 0x97}, + {value: 0x812d, lo: 0x98, hi: 0x98}, + // Block 0x34, offset 0x129 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + {value: 0x8132, lo: 0xb5, hi: 0xbc}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x35, offset 0x12d + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + {value: 0x812d, lo: 0xb5, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x36, offset 0x132 + {value: 0x0000, lo: 0x08}, + {value: 0x2d66, lo: 0x80, hi: 0x80}, + {value: 0x2d6e, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d76, lo: 0x83, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xac}, + {value: 0x8132, lo: 0xad, hi: 0xb3}, + // Block 0x37, offset 0x13b + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xaa, hi: 0xab}, + // Block 0x38, offset 0x13d + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xa6, hi: 0xa6}, + {value: 0x8104, lo: 0xb2, hi: 0xb3}, + // Block 0x39, offset 0x140 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x3a, offset 0x142 + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812d, lo: 0x95, hi: 0x99}, + {value: 0x8132, lo: 0x9a, hi: 0x9b}, + {value: 0x812d, lo: 0x9c, hi: 0x9f}, + {value: 0x8132, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + {value: 0x8132, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb8, hi: 0xb9}, + // Block 0x3b, offset 0x14d + {value: 0x0002, lo: 0x0a}, + {value: 0x0043, lo: 0xac, hi: 0xac}, + {value: 0x00d1, lo: 0xad, hi: 0xad}, + {value: 0x0045, lo: 0xae, hi: 0xae}, + {value: 0x0049, lo: 0xb0, hi: 0xb1}, + {value: 0x00e6, lo: 0xb2, hi: 0xb2}, + {value: 0x004f, lo: 0xb3, hi: 0xba}, + {value: 0x005f, lo: 0xbc, hi: 0xbc}, + {value: 0x00ef, lo: 0xbd, hi: 0xbd}, + {value: 0x0061, lo: 0xbe, hi: 0xbe}, + {value: 0x0065, lo: 0xbf, hi: 0xbf}, + // Block 0x3c, offset 0x158 + {value: 0x0000, lo: 0x0d}, + {value: 0x0001, lo: 0x80, hi: 0x8a}, + {value: 0x043b, lo: 0x91, hi: 0x91}, + {value: 0x429b, lo: 0x97, hi: 0x97}, + {value: 0x001d, lo: 0xa4, hi: 0xa4}, + {value: 0x1873, lo: 0xa5, hi: 0xa5}, + {value: 0x1b5c, lo: 0xa6, hi: 0xa6}, + {value: 0x0001, lo: 0xaf, hi: 0xaf}, + {value: 0x2691, lo: 0xb3, hi: 0xb3}, + {value: 0x27fe, lo: 0xb4, hi: 0xb4}, + {value: 0x2698, lo: 0xb6, hi: 0xb6}, + {value: 0x2808, lo: 0xb7, hi: 0xb7}, + {value: 0x186d, lo: 0xbc, hi: 0xbc}, + {value: 0x4269, lo: 0xbe, hi: 0xbe}, + // Block 0x3d, offset 0x166 + {value: 0x0002, lo: 0x0d}, + {value: 0x1933, lo: 0x87, hi: 0x87}, + {value: 0x1930, lo: 0x88, hi: 0x88}, + {value: 0x1870, lo: 0x89, hi: 0x89}, + {value: 0x298e, lo: 0x97, hi: 0x97}, + {value: 0x0001, lo: 0x9f, hi: 0x9f}, + {value: 0x0021, lo: 0xb0, hi: 0xb0}, + {value: 0x0093, lo: 0xb1, hi: 0xb1}, + {value: 0x0029, lo: 0xb4, hi: 0xb9}, + {value: 0x0017, lo: 0xba, hi: 0xba}, + {value: 0x0467, lo: 0xbb, hi: 0xbb}, + {value: 0x003b, lo: 0xbc, hi: 0xbc}, + {value: 0x0011, lo: 0xbd, hi: 0xbe}, + {value: 0x009d, lo: 0xbf, hi: 0xbf}, + // Block 0x3e, offset 0x174 + {value: 0x0002, lo: 0x0f}, + {value: 0x0021, lo: 0x80, hi: 0x89}, + {value: 0x0017, lo: 0x8a, hi: 0x8a}, + {value: 0x0467, lo: 0x8b, hi: 0x8b}, + {value: 0x003b, lo: 0x8c, hi: 0x8c}, + {value: 0x0011, lo: 0x8d, hi: 0x8e}, + {value: 0x0083, lo: 0x90, hi: 0x90}, + {value: 0x008b, lo: 0x91, hi: 0x91}, + {value: 0x009f, lo: 0x92, hi: 0x92}, + {value: 0x00b1, lo: 0x93, hi: 0x93}, + {value: 0x0104, lo: 0x94, hi: 0x94}, + {value: 0x0091, lo: 0x95, hi: 0x95}, + {value: 0x0097, lo: 0x96, hi: 0x99}, + {value: 0x00a1, lo: 0x9a, hi: 0x9a}, + {value: 0x00a7, lo: 0x9b, hi: 0x9c}, + {value: 0x1999, lo: 0xa8, hi: 0xa8}, + // Block 0x3f, offset 0x184 + {value: 0x0000, lo: 0x0d}, + {value: 0x8132, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8132, lo: 0x9b, hi: 0x9c}, + {value: 0x8132, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa7}, + {value: 0x812d, lo: 0xa8, hi: 0xa8}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xaf}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + // Block 0x40, offset 0x192 + {value: 0x0007, lo: 0x06}, + {value: 0x2180, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bb9, lo: 0x9a, hi: 0x9b}, + {value: 0x3bc7, lo: 0xae, hi: 0xae}, + // Block 0x41, offset 0x199 + {value: 0x000e, lo: 0x05}, + {value: 0x3bce, lo: 0x8d, hi: 0x8e}, + {value: 0x3bd5, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x42, offset 0x19f + {value: 0x0173, lo: 0x0e}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3be3, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3bea, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3bf1, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3bf8, lo: 0xa4, hi: 0xa4}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x3bff, lo: 0xa6, hi: 0xa6}, + {value: 0x269f, lo: 0xac, hi: 0xad}, + {value: 0x26a6, lo: 0xaf, hi: 0xaf}, + {value: 0x281c, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x43, offset 0x1ae + {value: 0x0007, lo: 0x03}, + {value: 0x3c68, lo: 0xa0, hi: 0xa1}, + {value: 0x3c92, lo: 0xa2, hi: 0xa3}, + {value: 0x3cbc, lo: 0xaa, hi: 0xad}, + // Block 0x44, offset 0x1b2 + {value: 0x0004, lo: 0x01}, + {value: 0x048b, lo: 0xa9, hi: 0xaa}, + // Block 0x45, offset 0x1b4 + {value: 0x0002, lo: 0x03}, + {value: 0x0057, lo: 0x80, hi: 0x8f}, + {value: 0x0083, lo: 0x90, hi: 0xa9}, + {value: 0x0021, lo: 0xaa, hi: 0xaa}, + // Block 0x46, offset 0x1b8 + {value: 0x0000, lo: 0x01}, + {value: 0x299b, lo: 0x8c, hi: 0x8c}, + // Block 0x47, offset 0x1ba + {value: 0x0263, lo: 0x02}, + {value: 0x1b8c, lo: 0xb4, hi: 0xb4}, + {value: 0x192d, lo: 0xb5, hi: 0xb6}, + // Block 0x48, offset 0x1bd + {value: 0x0000, lo: 0x01}, + {value: 0x44dd, lo: 0x9c, hi: 0x9c}, + // Block 0x49, offset 0x1bf + {value: 0x0000, lo: 0x02}, + {value: 0x0095, lo: 0xbc, hi: 0xbc}, + {value: 0x006d, lo: 0xbd, hi: 0xbd}, + // Block 0x4a, offset 0x1c2 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xaf, hi: 0xb1}, + // Block 0x4b, offset 0x1c4 + {value: 0x0000, lo: 0x02}, + {value: 0x047f, lo: 0xaf, hi: 0xaf}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x4c, offset 0x1c7 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa0, hi: 0xbf}, + // Block 0x4d, offset 0x1c9 + {value: 0x0000, lo: 0x01}, + {value: 0x0dc3, lo: 0x9f, hi: 0x9f}, + // Block 0x4e, offset 0x1cb + {value: 0x0000, lo: 0x01}, + {value: 0x162f, lo: 0xb3, hi: 0xb3}, + // Block 0x4f, offset 0x1cd + {value: 0x0004, lo: 0x0b}, + {value: 0x1597, lo: 0x80, hi: 0x82}, + {value: 0x15af, lo: 0x83, hi: 0x83}, + {value: 0x15c7, lo: 0x84, hi: 0x85}, + {value: 0x15d7, lo: 0x86, hi: 0x89}, + {value: 0x15eb, lo: 0x8a, hi: 0x8c}, + {value: 0x15ff, lo: 0x8d, hi: 0x8d}, + {value: 0x1607, lo: 0x8e, hi: 0x8e}, + {value: 0x160f, lo: 0x8f, hi: 0x90}, + {value: 0x161b, lo: 0x91, hi: 0x93}, + {value: 0x162b, lo: 0x94, hi: 0x94}, + {value: 0x1633, lo: 0x95, hi: 0x95}, + // Block 0x50, offset 0x1d9 + {value: 0x0004, lo: 0x09}, + {value: 0x0001, lo: 0x80, hi: 0x80}, + {value: 0x812c, lo: 0xaa, hi: 0xaa}, + {value: 0x8131, lo: 0xab, hi: 0xab}, + {value: 0x8133, lo: 0xac, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x812f, lo: 0xae, hi: 0xae}, + {value: 0x812f, lo: 0xaf, hi: 0xaf}, + {value: 0x04b3, lo: 0xb6, hi: 0xb6}, + {value: 0x0887, lo: 0xb8, hi: 0xba}, + // Block 0x51, offset 0x1e3 + {value: 0x0006, lo: 0x09}, + {value: 0x0313, lo: 0xb1, hi: 0xb1}, + {value: 0x0317, lo: 0xb2, hi: 0xb2}, + {value: 0x4a3b, lo: 0xb3, hi: 0xb3}, + {value: 0x031b, lo: 0xb4, hi: 0xb4}, + {value: 0x4a41, lo: 0xb5, hi: 0xb6}, + {value: 0x031f, lo: 0xb7, hi: 0xb7}, + {value: 0x0323, lo: 0xb8, hi: 0xb8}, + {value: 0x0327, lo: 0xb9, hi: 0xb9}, + {value: 0x4a4d, lo: 0xba, hi: 0xbf}, + // Block 0x52, offset 0x1ed + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xaf, hi: 0xaf}, + {value: 0x8132, lo: 0xb4, hi: 0xbd}, + // Block 0x53, offset 0x1f0 + {value: 0x0000, lo: 0x03}, + {value: 0x020f, lo: 0x9c, hi: 0x9c}, + {value: 0x0212, lo: 0x9d, hi: 0x9d}, + {value: 0x8132, lo: 0x9e, hi: 0x9f}, + // Block 0x54, offset 0x1f4 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb1}, + // Block 0x55, offset 0x1f6 + {value: 0x0000, lo: 0x01}, + {value: 0x163b, lo: 0xb0, hi: 0xb0}, + // Block 0x56, offset 0x1f8 + {value: 0x000c, lo: 0x01}, + {value: 0x00d7, lo: 0xb8, hi: 0xb9}, + // Block 0x57, offset 0x1fa + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + // Block 0x58, offset 0x1fc + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xa0, hi: 0xb1}, + // Block 0x59, offset 0x1ff + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xab, hi: 0xad}, + // Block 0x5a, offset 0x201 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x93, hi: 0x93}, + // Block 0x5b, offset 0x203 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb3, hi: 0xb3}, + // Block 0x5c, offset 0x205 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + // Block 0x5d, offset 0x207 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x8132, lo: 0xbe, hi: 0xbf}, + // Block 0x5e, offset 0x20d + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + // Block 0x5f, offset 0x210 + {value: 0x0008, lo: 0x03}, + {value: 0x1637, lo: 0x9c, hi: 0x9d}, + {value: 0x0125, lo: 0x9e, hi: 0x9e}, + {value: 0x1643, lo: 0x9f, hi: 0x9f}, + // Block 0x60, offset 0x214 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xad, hi: 0xad}, + // Block 0x61, offset 0x216 + {value: 0x0000, lo: 0x06}, + {value: 0xe500, lo: 0x80, hi: 0x80}, + {value: 0xc600, lo: 0x81, hi: 0x9b}, + {value: 0xe500, lo: 0x9c, hi: 0x9c}, + {value: 0xc600, lo: 0x9d, hi: 0xb7}, + {value: 0xe500, lo: 0xb8, hi: 0xb8}, + {value: 0xc600, lo: 0xb9, hi: 0xbf}, + // Block 0x62, offset 0x21d + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x93}, + {value: 0xe500, lo: 0x94, hi: 0x94}, + {value: 0xc600, lo: 0x95, hi: 0xaf}, + {value: 0xe500, lo: 0xb0, hi: 0xb0}, + {value: 0xc600, lo: 0xb1, hi: 0xbf}, + // Block 0x63, offset 0x223 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8b}, + {value: 0xe500, lo: 0x8c, hi: 0x8c}, + {value: 0xc600, lo: 0x8d, hi: 0xa7}, + {value: 0xe500, lo: 0xa8, hi: 0xa8}, + {value: 0xc600, lo: 0xa9, hi: 0xbf}, + // Block 0x64, offset 0x229 + {value: 0x0000, lo: 0x07}, + {value: 0xc600, lo: 0x80, hi: 0x83}, + {value: 0xe500, lo: 0x84, hi: 0x84}, + {value: 0xc600, lo: 0x85, hi: 0x9f}, + {value: 0xe500, lo: 0xa0, hi: 0xa0}, + {value: 0xc600, lo: 0xa1, hi: 0xbb}, + {value: 0xe500, lo: 0xbc, hi: 0xbc}, + {value: 0xc600, lo: 0xbd, hi: 0xbf}, + // Block 0x65, offset 0x231 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x97}, + {value: 0xe500, lo: 0x98, hi: 0x98}, + {value: 0xc600, lo: 0x99, hi: 0xb3}, + {value: 0xe500, lo: 0xb4, hi: 0xb4}, + {value: 0xc600, lo: 0xb5, hi: 0xbf}, + // Block 0x66, offset 0x237 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8f}, + {value: 0xe500, lo: 0x90, hi: 0x90}, + {value: 0xc600, lo: 0x91, hi: 0xab}, + {value: 0xe500, lo: 0xac, hi: 0xac}, + {value: 0xc600, lo: 0xad, hi: 0xbf}, + // Block 0x67, offset 0x23d + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + {value: 0xe500, lo: 0xa4, hi: 0xa4}, + {value: 0xc600, lo: 0xa5, hi: 0xbf}, + // Block 0x68, offset 0x243 + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x69, offset 0x247 + {value: 0x0002, lo: 0x01}, + {value: 0x0003, lo: 0x81, hi: 0xbf}, + // Block 0x6a, offset 0x249 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x6b, offset 0x24b + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xa0, hi: 0xa0}, + // Block 0x6c, offset 0x24d + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb6, hi: 0xba}, + // Block 0x6d, offset 0x24f + {value: 0x002c, lo: 0x05}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x8f, hi: 0x8f}, + {value: 0x8132, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x6e, offset 0x255 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xa5, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + // Block 0x6f, offset 0x258 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa4, hi: 0xa7}, + // Block 0x70, offset 0x25a + {value: 0x0000, lo: 0x05}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x8132, lo: 0x88, hi: 0x8a}, + {value: 0x812d, lo: 0x8b, hi: 0x8b}, + {value: 0x8132, lo: 0x8c, hi: 0x8c}, + {value: 0x812d, lo: 0x8d, hi: 0x90}, + // Block 0x71, offset 0x260 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x72, offset 0x263 + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x4238, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4242, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x424c, lo: 0xab, hi: 0xab}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x73, offset 0x26b + {value: 0x0000, lo: 0x06}, + {value: 0x8132, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d7e, lo: 0xae, hi: 0xae}, + {value: 0x2d88, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8104, lo: 0xb3, hi: 0xb4}, + // Block 0x74, offset 0x272 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x75, offset 0x275 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb5, hi: 0xb5}, + {value: 0x8102, lo: 0xb6, hi: 0xb6}, + // Block 0x76, offset 0x278 + {value: 0x0002, lo: 0x01}, + {value: 0x8102, lo: 0xa9, hi: 0xaa}, + // Block 0x77, offset 0x27a + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x78, offset 0x27d + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d92, lo: 0x8b, hi: 0x8b}, + {value: 0x2d9c, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8132, lo: 0xa6, hi: 0xac}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + // Block 0x79, offset 0x285 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x86, hi: 0x86}, + {value: 0x8132, lo: 0x9e, hi: 0x9e}, + // Block 0x7a, offset 0x289 + {value: 0x6b5a, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2db0, lo: 0xbb, hi: 0xbb}, + {value: 0x2da6, lo: 0xbc, hi: 0xbd}, + {value: 0x2dba, lo: 0xbe, hi: 0xbe}, + // Block 0x7b, offset 0x290 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x83, hi: 0x83}, + // Block 0x7c, offset 0x293 + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dc4, lo: 0xba, hi: 0xba}, + {value: 0x2dce, lo: 0xbb, hi: 0xbb}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7d, offset 0x299 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0x80, hi: 0x80}, + // Block 0x7e, offset 0x29b + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7f, offset 0x29d + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x80, offset 0x2a0 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xab, hi: 0xab}, + // Block 0x81, offset 0x2a2 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb9, hi: 0xb9}, + {value: 0x8102, lo: 0xba, hi: 0xba}, + // Block 0x82, offset 0x2a5 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x83, offset 0x2a7 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x87, hi: 0x87}, + // Block 0x84, offset 0x2a9 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x99, hi: 0x99}, + // Block 0x85, offset 0x2ab + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0x82, hi: 0x82}, + {value: 0x8104, lo: 0x84, hi: 0x85}, + // Block 0x86, offset 0x2ae + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x97, hi: 0x97}, + // Block 0x87, offset 0x2b0 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x88, offset 0x2b2 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb6}, + // Block 0x89, offset 0x2b4 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x8a, offset 0x2b6 + {value: 0x0000, lo: 0x0c}, + {value: 0x45cc, lo: 0x9e, hi: 0x9e}, + {value: 0x45d6, lo: 0x9f, hi: 0x9f}, + {value: 0x460a, lo: 0xa0, hi: 0xa0}, + {value: 0x4618, lo: 0xa1, hi: 0xa1}, + {value: 0x4626, lo: 0xa2, hi: 0xa2}, + {value: 0x4634, lo: 0xa3, hi: 0xa3}, + {value: 0x4642, lo: 0xa4, hi: 0xa4}, + {value: 0x812b, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8130, lo: 0xad, hi: 0xad}, + {value: 0x812b, lo: 0xae, hi: 0xb2}, + {value: 0x812d, lo: 0xbb, hi: 0xbf}, + // Block 0x8b, offset 0x2c3 + {value: 0x0000, lo: 0x09}, + {value: 0x812d, lo: 0x80, hi: 0x82}, + {value: 0x8132, lo: 0x85, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8b}, + {value: 0x8132, lo: 0xaa, hi: 0xad}, + {value: 0x45e0, lo: 0xbb, hi: 0xbb}, + {value: 0x45ea, lo: 0xbc, hi: 0xbc}, + {value: 0x4650, lo: 0xbd, hi: 0xbd}, + {value: 0x466c, lo: 0xbe, hi: 0xbe}, + {value: 0x465e, lo: 0xbf, hi: 0xbf}, + // Block 0x8c, offset 0x2cd + {value: 0x0000, lo: 0x01}, + {value: 0x467a, lo: 0x80, hi: 0x80}, + // Block 0x8d, offset 0x2cf + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x82, hi: 0x84}, + // Block 0x8e, offset 0x2d1 + {value: 0x0002, lo: 0x03}, + {value: 0x0043, lo: 0x80, hi: 0x99}, + {value: 0x0083, lo: 0x9a, hi: 0xb3}, + {value: 0x0043, lo: 0xb4, hi: 0xbf}, + // Block 0x8f, offset 0x2d5 + {value: 0x0002, lo: 0x04}, + {value: 0x005b, lo: 0x80, hi: 0x8d}, + {value: 0x0083, lo: 0x8e, hi: 0x94}, + {value: 0x0093, lo: 0x96, hi: 0xa7}, + {value: 0x0043, lo: 0xa8, hi: 0xbf}, + // Block 0x90, offset 0x2da + {value: 0x0002, lo: 0x0b}, + {value: 0x0073, lo: 0x80, hi: 0x81}, + {value: 0x0083, lo: 0x82, hi: 0x9b}, + {value: 0x0043, lo: 0x9c, hi: 0x9c}, + {value: 0x0047, lo: 0x9e, hi: 0x9f}, + {value: 0x004f, lo: 0xa2, hi: 0xa2}, + {value: 0x0055, lo: 0xa5, hi: 0xa6}, + {value: 0x005d, lo: 0xa9, hi: 0xac}, + {value: 0x0067, lo: 0xae, hi: 0xb5}, + {value: 0x0083, lo: 0xb6, hi: 0xb9}, + {value: 0x008d, lo: 0xbb, hi: 0xbb}, + {value: 0x0091, lo: 0xbd, hi: 0xbf}, + // Block 0x91, offset 0x2e6 + {value: 0x0002, lo: 0x04}, + {value: 0x0097, lo: 0x80, hi: 0x83}, + {value: 0x00a1, lo: 0x85, hi: 0x8f}, + {value: 0x0043, lo: 0x90, hi: 0xa9}, + {value: 0x0083, lo: 0xaa, hi: 0xbf}, + // Block 0x92, offset 0x2eb + {value: 0x0002, lo: 0x08}, + {value: 0x00af, lo: 0x80, hi: 0x83}, + {value: 0x0043, lo: 0x84, hi: 0x85}, + {value: 0x0049, lo: 0x87, hi: 0x8a}, + {value: 0x0055, lo: 0x8d, hi: 0x94}, + {value: 0x0067, lo: 0x96, hi: 0x9c}, + {value: 0x0083, lo: 0x9e, hi: 0xb7}, + {value: 0x0043, lo: 0xb8, hi: 0xb9}, + {value: 0x0049, lo: 0xbb, hi: 0xbe}, + // Block 0x93, offset 0x2f4 + {value: 0x0002, lo: 0x05}, + {value: 0x0053, lo: 0x80, hi: 0x84}, + {value: 0x005f, lo: 0x86, hi: 0x86}, + {value: 0x0067, lo: 0x8a, hi: 0x90}, + {value: 0x0083, lo: 0x92, hi: 0xab}, + {value: 0x0043, lo: 0xac, hi: 0xbf}, + // Block 0x94, offset 0x2fa + {value: 0x0002, lo: 0x04}, + {value: 0x006b, lo: 0x80, hi: 0x85}, + {value: 0x0083, lo: 0x86, hi: 0x9f}, + {value: 0x0043, lo: 0xa0, hi: 0xb9}, + {value: 0x0083, lo: 0xba, hi: 0xbf}, + // Block 0x95, offset 0x2ff + {value: 0x0002, lo: 0x03}, + {value: 0x008f, lo: 0x80, hi: 0x93}, + {value: 0x0043, lo: 0x94, hi: 0xad}, + {value: 0x0083, lo: 0xae, hi: 0xbf}, + // Block 0x96, offset 0x303 + {value: 0x0002, lo: 0x04}, + {value: 0x00a7, lo: 0x80, hi: 0x87}, + {value: 0x0043, lo: 0x88, hi: 0xa1}, + {value: 0x0083, lo: 0xa2, hi: 0xbb}, + {value: 0x0043, lo: 0xbc, hi: 0xbf}, + // Block 0x97, offset 0x308 + {value: 0x0002, lo: 0x03}, + {value: 0x004b, lo: 0x80, hi: 0x95}, + {value: 0x0083, lo: 0x96, hi: 0xaf}, + {value: 0x0043, lo: 0xb0, hi: 0xbf}, + // Block 0x98, offset 0x30c + {value: 0x0003, lo: 0x0f}, + {value: 0x01b8, lo: 0x80, hi: 0x80}, + {value: 0x045f, lo: 0x81, hi: 0x81}, + {value: 0x01bb, lo: 0x82, hi: 0x9a}, + {value: 0x045b, lo: 0x9b, hi: 0x9b}, + {value: 0x01c7, lo: 0x9c, hi: 0x9c}, + {value: 0x01d0, lo: 0x9d, hi: 0x9d}, + {value: 0x01d6, lo: 0x9e, hi: 0x9e}, + {value: 0x01fa, lo: 0x9f, hi: 0x9f}, + {value: 0x01eb, lo: 0xa0, hi: 0xa0}, + {value: 0x01e8, lo: 0xa1, hi: 0xa1}, + {value: 0x0173, lo: 0xa2, hi: 0xb2}, + {value: 0x0188, lo: 0xb3, hi: 0xb3}, + {value: 0x01a6, lo: 0xb4, hi: 0xba}, + {value: 0x045f, lo: 0xbb, hi: 0xbb}, + {value: 0x01bb, lo: 0xbc, hi: 0xbf}, + // Block 0x99, offset 0x31c + {value: 0x0003, lo: 0x0d}, + {value: 0x01c7, lo: 0x80, hi: 0x94}, + {value: 0x045b, lo: 0x95, hi: 0x95}, + {value: 0x01c7, lo: 0x96, hi: 0x96}, + {value: 0x01d0, lo: 0x97, hi: 0x97}, + {value: 0x01d6, lo: 0x98, hi: 0x98}, + {value: 0x01fa, lo: 0x99, hi: 0x99}, + {value: 0x01eb, lo: 0x9a, hi: 0x9a}, + {value: 0x01e8, lo: 0x9b, hi: 0x9b}, + {value: 0x0173, lo: 0x9c, hi: 0xac}, + {value: 0x0188, lo: 0xad, hi: 0xad}, + {value: 0x01a6, lo: 0xae, hi: 0xb4}, + {value: 0x045f, lo: 0xb5, hi: 0xb5}, + {value: 0x01bb, lo: 0xb6, hi: 0xbf}, + // Block 0x9a, offset 0x32a + {value: 0x0003, lo: 0x0d}, + {value: 0x01d9, lo: 0x80, hi: 0x8e}, + {value: 0x045b, lo: 0x8f, hi: 0x8f}, + {value: 0x01c7, lo: 0x90, hi: 0x90}, + {value: 0x01d0, lo: 0x91, hi: 0x91}, + {value: 0x01d6, lo: 0x92, hi: 0x92}, + {value: 0x01fa, lo: 0x93, hi: 0x93}, + {value: 0x01eb, lo: 0x94, hi: 0x94}, + {value: 0x01e8, lo: 0x95, hi: 0x95}, + {value: 0x0173, lo: 0x96, hi: 0xa6}, + {value: 0x0188, lo: 0xa7, hi: 0xa7}, + {value: 0x01a6, lo: 0xa8, hi: 0xae}, + {value: 0x045f, lo: 0xaf, hi: 0xaf}, + {value: 0x01bb, lo: 0xb0, hi: 0xbf}, + // Block 0x9b, offset 0x338 + {value: 0x0003, lo: 0x0d}, + {value: 0x01eb, lo: 0x80, hi: 0x88}, + {value: 0x045b, lo: 0x89, hi: 0x89}, + {value: 0x01c7, lo: 0x8a, hi: 0x8a}, + {value: 0x01d0, lo: 0x8b, hi: 0x8b}, + {value: 0x01d6, lo: 0x8c, hi: 0x8c}, + {value: 0x01fa, lo: 0x8d, hi: 0x8d}, + {value: 0x01eb, lo: 0x8e, hi: 0x8e}, + {value: 0x01e8, lo: 0x8f, hi: 0x8f}, + {value: 0x0173, lo: 0x90, hi: 0xa0}, + {value: 0x0188, lo: 0xa1, hi: 0xa1}, + {value: 0x01a6, lo: 0xa2, hi: 0xa8}, + {value: 0x045f, lo: 0xa9, hi: 0xa9}, + {value: 0x01bb, lo: 0xaa, hi: 0xbf}, + // Block 0x9c, offset 0x346 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0x80, hi: 0x86}, + {value: 0x8132, lo: 0x88, hi: 0x98}, + {value: 0x8132, lo: 0x9b, hi: 0xa1}, + {value: 0x8132, lo: 0xa3, hi: 0xa4}, + {value: 0x8132, lo: 0xa6, hi: 0xaa}, + // Block 0x9d, offset 0x34c + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x90, hi: 0x96}, + // Block 0x9e, offset 0x34e + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x84, hi: 0x89}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x9f, offset 0x351 + {value: 0x0002, lo: 0x09}, + {value: 0x0063, lo: 0x80, hi: 0x89}, + {value: 0x1951, lo: 0x8a, hi: 0x8a}, + {value: 0x1981, lo: 0x8b, hi: 0x8b}, + {value: 0x199c, lo: 0x8c, hi: 0x8c}, + {value: 0x19a2, lo: 0x8d, hi: 0x8d}, + {value: 0x1bc0, lo: 0x8e, hi: 0x8e}, + {value: 0x19ae, lo: 0x8f, hi: 0x8f}, + {value: 0x197b, lo: 0xaa, hi: 0xaa}, + {value: 0x197e, lo: 0xab, hi: 0xab}, + // Block 0xa0, offset 0x35b + {value: 0x0000, lo: 0x01}, + {value: 0x193f, lo: 0x90, hi: 0x90}, + // Block 0xa1, offset 0x35d + {value: 0x0028, lo: 0x09}, + {value: 0x2862, lo: 0x80, hi: 0x80}, + {value: 0x2826, lo: 0x81, hi: 0x81}, + {value: 0x2830, lo: 0x82, hi: 0x82}, + {value: 0x2844, lo: 0x83, hi: 0x84}, + {value: 0x284e, lo: 0x85, hi: 0x86}, + {value: 0x283a, lo: 0x87, hi: 0x87}, + {value: 0x2858, lo: 0x88, hi: 0x88}, + {value: 0x0b6f, lo: 0x90, hi: 0x90}, + {value: 0x08e7, lo: 0x91, hi: 0x91}, +} + +// recompMap: 7520 bytes (entries only) +var recompMap map[uint32]rune +var recompMapOnce sync.Once + +const recompMapPacked = "" + + "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0 + "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1 + "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2 + "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3 + "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4 + "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5 + "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7 + "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8 + "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9 + "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA + "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB + "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC + "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD + "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE + "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF + "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1 + "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2 + "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3 + "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4 + "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5 + "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6 + "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9 + "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA + "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB + "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC + "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD + "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0 + "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1 + "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2 + "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3 + "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4 + "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5 + "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7 + "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8 + "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9 + "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA + "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB + "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC + "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED + "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE + "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF + "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1 + "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2 + "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3 + "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4 + "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5 + "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6 + "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9 + "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA + "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB + "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC + "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD + "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF + "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100 + "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101 + "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102 + "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103 + "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104 + "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105 + "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106 + "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107 + "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108 + "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109 + "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A + "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B + "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C + "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D + "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E + "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F + "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112 + "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113 + "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114 + "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115 + "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116 + "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117 + "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118 + "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119 + "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A + "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B + "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C + "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D + "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E + "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F + "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120 + "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121 + "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122 + "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123 + "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124 + "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125 + "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128 + "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129 + "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A + "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B + "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C + "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D + "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E + "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F + "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130 + "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134 + "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135 + "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136 + "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137 + "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139 + "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A + "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B + "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C + "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D + "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E + "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143 + "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144 + "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145 + "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146 + "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147 + "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148 + "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C + "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D + "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E + "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F + "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150 + "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151 + "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154 + "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155 + "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156 + "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157 + "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158 + "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159 + "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A + "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B + "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C + "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D + "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E + "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F + "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160 + "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161 + "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162 + "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163 + "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164 + "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165 + "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168 + "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169 + "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A + "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B + "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C + "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D + "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E + "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F + "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170 + "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171 + "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172 + "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173 + "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174 + "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175 + "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176 + "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177 + "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178 + "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179 + "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A + "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B + "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C + "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D + "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E + "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0 + "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1 + "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF + "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0 + "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD + "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE + "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF + "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0 + "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1 + "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2 + "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3 + "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4 + "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5 + "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6 + "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7 + "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8 + "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9 + "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA + "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB + "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC + "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE + "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF + "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0 + "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1 + "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2 + "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3 + "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6 + "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7 + "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8 + "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9 + "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA + "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB + "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC + "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED + "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE + "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF + "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0 + "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4 + "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5 + "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8 + "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9 + "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA + "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB + "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC + "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD + "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE + "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF + "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200 + "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201 + "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202 + "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203 + "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204 + "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205 + "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206 + "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207 + "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208 + "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209 + "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A + "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B + "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C + "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D + "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E + "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F + "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210 + "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211 + "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212 + "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213 + "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214 + "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215 + "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216 + "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217 + "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218 + "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219 + "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A + "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B + "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E + "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F + "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226 + "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227 + "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228 + "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229 + "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A + "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B + "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C + "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D + "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E + "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F + "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230 + "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231 + "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232 + "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233 + "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385 + "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386 + "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388 + "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389 + "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A + "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C + "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E + "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F + "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390 + "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA + "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB + "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC + "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD + "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE + "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF + "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0 + "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA + "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB + "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC + "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD + "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE + "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3 + "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4 + "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400 + "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401 + "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403 + "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407 + "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C + "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D + "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E + "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419 + "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439 + "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450 + "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451 + "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453 + "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457 + "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C + "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D + "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E + "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476 + "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477 + "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1 + "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2 + "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0 + "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1 + "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2 + "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3 + "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6 + "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7 + "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA + "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB + "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC + "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD + "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE + "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF + "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2 + "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3 + "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4 + "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5 + "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6 + "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7 + "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA + "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB + "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC + "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED + "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE + "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF + "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0 + "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1 + "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2 + "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3 + "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4 + "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5 + "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8 + "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9 + "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622 + "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623 + "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624 + "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625 + "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626 + "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0 + "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2 + "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3 + "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929 + "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931 + "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934 + "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB + "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC + "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48 + "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B + "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C + "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94 + "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA + "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB + "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC + "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48 + "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0 + "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7 + "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8 + "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA + "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB + "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A + "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B + "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C + "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA + "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC + "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD + "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE + "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026 + "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06 + "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08 + "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A + "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C + "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E + "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12 + "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B + "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D + "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40 + "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41 + "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43 + "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00 + "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01 + "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02 + "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03 + "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04 + "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05 + "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06 + "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07 + "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08 + "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09 + "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A + "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B + "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C + "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D + "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E + "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F + "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10 + "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11 + "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12 + "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13 + "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14 + "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15 + "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16 + "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17 + "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18 + "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19 + "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A + "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B + "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C + "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D + "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E + "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F + "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20 + "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21 + "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22 + "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23 + "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24 + "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25 + "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26 + "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27 + "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28 + "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29 + "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A + "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B + "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C + "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D + "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E + "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F + "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30 + "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31 + "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32 + "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33 + "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34 + "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35 + "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36 + "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37 + "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38 + "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39 + "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A + "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B + "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C + "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D + "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E + "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F + "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40 + "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41 + "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42 + "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43 + "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44 + "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45 + "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46 + "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47 + "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48 + "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49 + "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A + "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B + "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C + "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D + "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E + "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F + "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50 + "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51 + "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52 + "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53 + "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54 + "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55 + "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56 + "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57 + "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58 + "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59 + "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A + "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B + "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C + "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D + "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E + "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F + "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60 + "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61 + "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62 + "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63 + "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64 + "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65 + "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66 + "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67 + "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68 + "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69 + "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A + "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B + "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C + "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D + "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E + "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F + "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70 + "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71 + "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72 + "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73 + "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74 + "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75 + "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76 + "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77 + "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78 + "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79 + "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A + "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B + "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C + "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D + "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E + "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F + "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 + "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 + "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 + "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83 + "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84 + "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85 + "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86 + "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87 + "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88 + "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89 + "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A + "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B + "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C + "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D + "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E + "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F + "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90 + "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91 + "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92 + "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93 + "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94 + "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95 + "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96 + "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 + "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 + "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 + "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B + "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 + "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 + "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 + "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3 + "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4 + "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5 + "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6 + "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7 + "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8 + "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9 + "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA + "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB + "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC + "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD + "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE + "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF + "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0 + "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1 + "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2 + "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3 + "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4 + "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5 + "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6 + "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7 + "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8 + "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9 + "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA + "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB + "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC + "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD + "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE + "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF + "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0 + "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1 + "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2 + "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3 + "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4 + "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5 + "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6 + "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7 + "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8 + "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9 + "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA + "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB + "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC + "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD + "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE + "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF + "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0 + "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1 + "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2 + "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3 + "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4 + "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5 + "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6 + "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7 + "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8 + "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9 + "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA + "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB + "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC + "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD + "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE + "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF + "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0 + "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1 + "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2 + "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3 + "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4 + "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5 + "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6 + "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7 + "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8 + "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9 + "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA + "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB + "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC + "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED + "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE + "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF + "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0 + "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1 + "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2 + "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3 + "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4 + "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5 + "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6 + "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7 + "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8 + "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9 + "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00 + "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01 + "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02 + "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03 + "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04 + "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05 + "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06 + "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07 + "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08 + "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09 + "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A + "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B + "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C + "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D + "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E + "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F + "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10 + "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11 + "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12 + "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13 + "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14 + "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15 + "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18 + "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19 + "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A + "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B + "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C + "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D + "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20 + "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21 + "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22 + "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23 + "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24 + "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25 + "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26 + "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27 + "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28 + "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29 + "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A + "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B + "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C + "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D + "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E + "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F + "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30 + "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31 + "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32 + "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33 + "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34 + "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35 + "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36 + "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37 + "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38 + "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39 + "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A + "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B + "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C + "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D + "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E + "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F + "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40 + "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41 + "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42 + "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43 + "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44 + "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45 + "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48 + "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49 + "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A + "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B + "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C + "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D + "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50 + "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51 + "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52 + "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53 + "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54 + "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55 + "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56 + "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57 + "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59 + "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B + "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D + "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F + "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60 + "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61 + "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62 + "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63 + "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64 + "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65 + "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66 + "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67 + "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68 + "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69 + "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A + "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B + "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C + "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D + "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E + "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F + "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70 + "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72 + "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74 + "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76 + "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78 + "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A + "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C + "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80 + "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81 + "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82 + "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83 + "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84 + "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85 + "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86 + "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87 + "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88 + "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89 + "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A + "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B + "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C + "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D + "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E + "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F + "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90 + "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91 + "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92 + "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93 + "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94 + "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95 + "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96 + "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97 + "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98 + "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99 + "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A + "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B + "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C + "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D + "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E + "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F + "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0 + "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1 + "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2 + "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3 + "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4 + "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5 + "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6 + "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7 + "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8 + "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9 + "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA + "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB + "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC + "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD + "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE + "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF + "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0 + "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1 + "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2 + "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3 + "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4 + "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6 + "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7 + "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8 + "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9 + "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA + "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC + "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1 + "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2 + "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3 + "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4 + "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6 + "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7 + "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8 + "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA + "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC + "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD + "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE + "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF + "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0 + "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1 + "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2 + "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6 + "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7 + "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8 + "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9 + "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA + "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD + "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE + "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF + "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0 + "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1 + "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2 + "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4 + "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5 + "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6 + "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7 + "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8 + "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9 + "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA + "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC + "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED + "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2 + "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3 + "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4 + "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6 + "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7 + "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8 + "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA + "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC + "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A + "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B + "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE + "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD + "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE + "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF + "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204 + "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209 + "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C + "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224 + "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226 + "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241 + "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244 + "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247 + "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249 + "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260 + "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262 + "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D + "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E + "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F + "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270 + "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271 + "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274 + "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275 + "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278 + "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279 + "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280 + "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281 + "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284 + "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285 + "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288 + "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289 + "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC + "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD + "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE + "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF + "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0 + "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1 + "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2 + "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3 + "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA + "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB + "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC + "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED + "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C + "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E + "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050 + "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052 + "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054 + "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056 + "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058 + "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A + "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C + "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E + "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060 + "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062 + "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065 + "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067 + "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069 + "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070 + "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071 + "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073 + "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074 + "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076 + "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077 + "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079 + "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A + "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C + "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D + "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094 + "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E + "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC + "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE + "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0 + "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2 + "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4 + "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6 + "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8 + "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA + "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC + "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE + "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0 + "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2 + "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5 + "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7 + "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9 + "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0 + "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1 + "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3 + "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4 + "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6 + "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7 + "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9 + "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA + "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC + "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD + "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4 + "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7 + "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8 + "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9 + "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA + "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE + "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A + "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C + "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB + "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E + "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F + "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B + "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C + "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB + "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC + "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE + "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA + "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB + "" + // Total size of tables: 53KB (54514 bytes) diff --git a/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go index a01274a8e87b..942906929135 100644 --- a/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go +++ b/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go @@ -4,6 +4,8 @@ package norm +import "sync" + const ( // Version is the Unicode edition from which the tables are derived. Version = "9.0.0" @@ -6687,947 +6689,949 @@ var nfkcSparseValues = [875]valueRange{ } // recompMap: 7520 bytes (entries only) -var recompMap = map[uint32]rune{ - 0x00410300: 0x00C0, - 0x00410301: 0x00C1, - 0x00410302: 0x00C2, - 0x00410303: 0x00C3, - 0x00410308: 0x00C4, - 0x0041030A: 0x00C5, - 0x00430327: 0x00C7, - 0x00450300: 0x00C8, - 0x00450301: 0x00C9, - 0x00450302: 0x00CA, - 0x00450308: 0x00CB, - 0x00490300: 0x00CC, - 0x00490301: 0x00CD, - 0x00490302: 0x00CE, - 0x00490308: 0x00CF, - 0x004E0303: 0x00D1, - 0x004F0300: 0x00D2, - 0x004F0301: 0x00D3, - 0x004F0302: 0x00D4, - 0x004F0303: 0x00D5, - 0x004F0308: 0x00D6, - 0x00550300: 0x00D9, - 0x00550301: 0x00DA, - 0x00550302: 0x00DB, - 0x00550308: 0x00DC, - 0x00590301: 0x00DD, - 0x00610300: 0x00E0, - 0x00610301: 0x00E1, - 0x00610302: 0x00E2, - 0x00610303: 0x00E3, - 0x00610308: 0x00E4, - 0x0061030A: 0x00E5, - 0x00630327: 0x00E7, - 0x00650300: 0x00E8, - 0x00650301: 0x00E9, - 0x00650302: 0x00EA, - 0x00650308: 0x00EB, - 0x00690300: 0x00EC, - 0x00690301: 0x00ED, - 0x00690302: 0x00EE, - 0x00690308: 0x00EF, - 0x006E0303: 0x00F1, - 0x006F0300: 0x00F2, - 0x006F0301: 0x00F3, - 0x006F0302: 0x00F4, - 0x006F0303: 0x00F5, - 0x006F0308: 0x00F6, - 0x00750300: 0x00F9, - 0x00750301: 0x00FA, - 0x00750302: 0x00FB, - 0x00750308: 0x00FC, - 0x00790301: 0x00FD, - 0x00790308: 0x00FF, - 0x00410304: 0x0100, - 0x00610304: 0x0101, - 0x00410306: 0x0102, - 0x00610306: 0x0103, - 0x00410328: 0x0104, - 0x00610328: 0x0105, - 0x00430301: 0x0106, - 0x00630301: 0x0107, - 0x00430302: 0x0108, - 0x00630302: 0x0109, - 0x00430307: 0x010A, - 0x00630307: 0x010B, - 0x0043030C: 0x010C, - 0x0063030C: 0x010D, - 0x0044030C: 0x010E, - 0x0064030C: 0x010F, - 0x00450304: 0x0112, - 0x00650304: 0x0113, - 0x00450306: 0x0114, - 0x00650306: 0x0115, - 0x00450307: 0x0116, - 0x00650307: 0x0117, - 0x00450328: 0x0118, - 0x00650328: 0x0119, - 0x0045030C: 0x011A, - 0x0065030C: 0x011B, - 0x00470302: 0x011C, - 0x00670302: 0x011D, - 0x00470306: 0x011E, - 0x00670306: 0x011F, - 0x00470307: 0x0120, - 0x00670307: 0x0121, - 0x00470327: 0x0122, - 0x00670327: 0x0123, - 0x00480302: 0x0124, - 0x00680302: 0x0125, - 0x00490303: 0x0128, - 0x00690303: 0x0129, - 0x00490304: 0x012A, - 0x00690304: 0x012B, - 0x00490306: 0x012C, - 0x00690306: 0x012D, - 0x00490328: 0x012E, - 0x00690328: 0x012F, - 0x00490307: 0x0130, - 0x004A0302: 0x0134, - 0x006A0302: 0x0135, - 0x004B0327: 0x0136, - 0x006B0327: 0x0137, - 0x004C0301: 0x0139, - 0x006C0301: 0x013A, - 0x004C0327: 0x013B, - 0x006C0327: 0x013C, - 0x004C030C: 0x013D, - 0x006C030C: 0x013E, - 0x004E0301: 0x0143, - 0x006E0301: 0x0144, - 0x004E0327: 0x0145, - 0x006E0327: 0x0146, - 0x004E030C: 0x0147, - 0x006E030C: 0x0148, - 0x004F0304: 0x014C, - 0x006F0304: 0x014D, - 0x004F0306: 0x014E, - 0x006F0306: 0x014F, - 0x004F030B: 0x0150, - 0x006F030B: 0x0151, - 0x00520301: 0x0154, - 0x00720301: 0x0155, - 0x00520327: 0x0156, - 0x00720327: 0x0157, - 0x0052030C: 0x0158, - 0x0072030C: 0x0159, - 0x00530301: 0x015A, - 0x00730301: 0x015B, - 0x00530302: 0x015C, - 0x00730302: 0x015D, - 0x00530327: 0x015E, - 0x00730327: 0x015F, - 0x0053030C: 0x0160, - 0x0073030C: 0x0161, - 0x00540327: 0x0162, - 0x00740327: 0x0163, - 0x0054030C: 0x0164, - 0x0074030C: 0x0165, - 0x00550303: 0x0168, - 0x00750303: 0x0169, - 0x00550304: 0x016A, - 0x00750304: 0x016B, - 0x00550306: 0x016C, - 0x00750306: 0x016D, - 0x0055030A: 0x016E, - 0x0075030A: 0x016F, - 0x0055030B: 0x0170, - 0x0075030B: 0x0171, - 0x00550328: 0x0172, - 0x00750328: 0x0173, - 0x00570302: 0x0174, - 0x00770302: 0x0175, - 0x00590302: 0x0176, - 0x00790302: 0x0177, - 0x00590308: 0x0178, - 0x005A0301: 0x0179, - 0x007A0301: 0x017A, - 0x005A0307: 0x017B, - 0x007A0307: 0x017C, - 0x005A030C: 0x017D, - 0x007A030C: 0x017E, - 0x004F031B: 0x01A0, - 0x006F031B: 0x01A1, - 0x0055031B: 0x01AF, - 0x0075031B: 0x01B0, - 0x0041030C: 0x01CD, - 0x0061030C: 0x01CE, - 0x0049030C: 0x01CF, - 0x0069030C: 0x01D0, - 0x004F030C: 0x01D1, - 0x006F030C: 0x01D2, - 0x0055030C: 0x01D3, - 0x0075030C: 0x01D4, - 0x00DC0304: 0x01D5, - 0x00FC0304: 0x01D6, - 0x00DC0301: 0x01D7, - 0x00FC0301: 0x01D8, - 0x00DC030C: 0x01D9, - 0x00FC030C: 0x01DA, - 0x00DC0300: 0x01DB, - 0x00FC0300: 0x01DC, - 0x00C40304: 0x01DE, - 0x00E40304: 0x01DF, - 0x02260304: 0x01E0, - 0x02270304: 0x01E1, - 0x00C60304: 0x01E2, - 0x00E60304: 0x01E3, - 0x0047030C: 0x01E6, - 0x0067030C: 0x01E7, - 0x004B030C: 0x01E8, - 0x006B030C: 0x01E9, - 0x004F0328: 0x01EA, - 0x006F0328: 0x01EB, - 0x01EA0304: 0x01EC, - 0x01EB0304: 0x01ED, - 0x01B7030C: 0x01EE, - 0x0292030C: 0x01EF, - 0x006A030C: 0x01F0, - 0x00470301: 0x01F4, - 0x00670301: 0x01F5, - 0x004E0300: 0x01F8, - 0x006E0300: 0x01F9, - 0x00C50301: 0x01FA, - 0x00E50301: 0x01FB, - 0x00C60301: 0x01FC, - 0x00E60301: 0x01FD, - 0x00D80301: 0x01FE, - 0x00F80301: 0x01FF, - 0x0041030F: 0x0200, - 0x0061030F: 0x0201, - 0x00410311: 0x0202, - 0x00610311: 0x0203, - 0x0045030F: 0x0204, - 0x0065030F: 0x0205, - 0x00450311: 0x0206, - 0x00650311: 0x0207, - 0x0049030F: 0x0208, - 0x0069030F: 0x0209, - 0x00490311: 0x020A, - 0x00690311: 0x020B, - 0x004F030F: 0x020C, - 0x006F030F: 0x020D, - 0x004F0311: 0x020E, - 0x006F0311: 0x020F, - 0x0052030F: 0x0210, - 0x0072030F: 0x0211, - 0x00520311: 0x0212, - 0x00720311: 0x0213, - 0x0055030F: 0x0214, - 0x0075030F: 0x0215, - 0x00550311: 0x0216, - 0x00750311: 0x0217, - 0x00530326: 0x0218, - 0x00730326: 0x0219, - 0x00540326: 0x021A, - 0x00740326: 0x021B, - 0x0048030C: 0x021E, - 0x0068030C: 0x021F, - 0x00410307: 0x0226, - 0x00610307: 0x0227, - 0x00450327: 0x0228, - 0x00650327: 0x0229, - 0x00D60304: 0x022A, - 0x00F60304: 0x022B, - 0x00D50304: 0x022C, - 0x00F50304: 0x022D, - 0x004F0307: 0x022E, - 0x006F0307: 0x022F, - 0x022E0304: 0x0230, - 0x022F0304: 0x0231, - 0x00590304: 0x0232, - 0x00790304: 0x0233, - 0x00A80301: 0x0385, - 0x03910301: 0x0386, - 0x03950301: 0x0388, - 0x03970301: 0x0389, - 0x03990301: 0x038A, - 0x039F0301: 0x038C, - 0x03A50301: 0x038E, - 0x03A90301: 0x038F, - 0x03CA0301: 0x0390, - 0x03990308: 0x03AA, - 0x03A50308: 0x03AB, - 0x03B10301: 0x03AC, - 0x03B50301: 0x03AD, - 0x03B70301: 0x03AE, - 0x03B90301: 0x03AF, - 0x03CB0301: 0x03B0, - 0x03B90308: 0x03CA, - 0x03C50308: 0x03CB, - 0x03BF0301: 0x03CC, - 0x03C50301: 0x03CD, - 0x03C90301: 0x03CE, - 0x03D20301: 0x03D3, - 0x03D20308: 0x03D4, - 0x04150300: 0x0400, - 0x04150308: 0x0401, - 0x04130301: 0x0403, - 0x04060308: 0x0407, - 0x041A0301: 0x040C, - 0x04180300: 0x040D, - 0x04230306: 0x040E, - 0x04180306: 0x0419, - 0x04380306: 0x0439, - 0x04350300: 0x0450, - 0x04350308: 0x0451, - 0x04330301: 0x0453, - 0x04560308: 0x0457, - 0x043A0301: 0x045C, - 0x04380300: 0x045D, - 0x04430306: 0x045E, - 0x0474030F: 0x0476, - 0x0475030F: 0x0477, - 0x04160306: 0x04C1, - 0x04360306: 0x04C2, - 0x04100306: 0x04D0, - 0x04300306: 0x04D1, - 0x04100308: 0x04D2, - 0x04300308: 0x04D3, - 0x04150306: 0x04D6, - 0x04350306: 0x04D7, - 0x04D80308: 0x04DA, - 0x04D90308: 0x04DB, - 0x04160308: 0x04DC, - 0x04360308: 0x04DD, - 0x04170308: 0x04DE, - 0x04370308: 0x04DF, - 0x04180304: 0x04E2, - 0x04380304: 0x04E3, - 0x04180308: 0x04E4, - 0x04380308: 0x04E5, - 0x041E0308: 0x04E6, - 0x043E0308: 0x04E7, - 0x04E80308: 0x04EA, - 0x04E90308: 0x04EB, - 0x042D0308: 0x04EC, - 0x044D0308: 0x04ED, - 0x04230304: 0x04EE, - 0x04430304: 0x04EF, - 0x04230308: 0x04F0, - 0x04430308: 0x04F1, - 0x0423030B: 0x04F2, - 0x0443030B: 0x04F3, - 0x04270308: 0x04F4, - 0x04470308: 0x04F5, - 0x042B0308: 0x04F8, - 0x044B0308: 0x04F9, - 0x06270653: 0x0622, - 0x06270654: 0x0623, - 0x06480654: 0x0624, - 0x06270655: 0x0625, - 0x064A0654: 0x0626, - 0x06D50654: 0x06C0, - 0x06C10654: 0x06C2, - 0x06D20654: 0x06D3, - 0x0928093C: 0x0929, - 0x0930093C: 0x0931, - 0x0933093C: 0x0934, - 0x09C709BE: 0x09CB, - 0x09C709D7: 0x09CC, - 0x0B470B56: 0x0B48, - 0x0B470B3E: 0x0B4B, - 0x0B470B57: 0x0B4C, - 0x0B920BD7: 0x0B94, - 0x0BC60BBE: 0x0BCA, - 0x0BC70BBE: 0x0BCB, - 0x0BC60BD7: 0x0BCC, - 0x0C460C56: 0x0C48, - 0x0CBF0CD5: 0x0CC0, - 0x0CC60CD5: 0x0CC7, - 0x0CC60CD6: 0x0CC8, - 0x0CC60CC2: 0x0CCA, - 0x0CCA0CD5: 0x0CCB, - 0x0D460D3E: 0x0D4A, - 0x0D470D3E: 0x0D4B, - 0x0D460D57: 0x0D4C, - 0x0DD90DCA: 0x0DDA, - 0x0DD90DCF: 0x0DDC, - 0x0DDC0DCA: 0x0DDD, - 0x0DD90DDF: 0x0DDE, - 0x1025102E: 0x1026, - 0x1B051B35: 0x1B06, - 0x1B071B35: 0x1B08, - 0x1B091B35: 0x1B0A, - 0x1B0B1B35: 0x1B0C, - 0x1B0D1B35: 0x1B0E, - 0x1B111B35: 0x1B12, - 0x1B3A1B35: 0x1B3B, - 0x1B3C1B35: 0x1B3D, - 0x1B3E1B35: 0x1B40, - 0x1B3F1B35: 0x1B41, - 0x1B421B35: 0x1B43, - 0x00410325: 0x1E00, - 0x00610325: 0x1E01, - 0x00420307: 0x1E02, - 0x00620307: 0x1E03, - 0x00420323: 0x1E04, - 0x00620323: 0x1E05, - 0x00420331: 0x1E06, - 0x00620331: 0x1E07, - 0x00C70301: 0x1E08, - 0x00E70301: 0x1E09, - 0x00440307: 0x1E0A, - 0x00640307: 0x1E0B, - 0x00440323: 0x1E0C, - 0x00640323: 0x1E0D, - 0x00440331: 0x1E0E, - 0x00640331: 0x1E0F, - 0x00440327: 0x1E10, - 0x00640327: 0x1E11, - 0x0044032D: 0x1E12, - 0x0064032D: 0x1E13, - 0x01120300: 0x1E14, - 0x01130300: 0x1E15, - 0x01120301: 0x1E16, - 0x01130301: 0x1E17, - 0x0045032D: 0x1E18, - 0x0065032D: 0x1E19, - 0x00450330: 0x1E1A, - 0x00650330: 0x1E1B, - 0x02280306: 0x1E1C, - 0x02290306: 0x1E1D, - 0x00460307: 0x1E1E, - 0x00660307: 0x1E1F, - 0x00470304: 0x1E20, - 0x00670304: 0x1E21, - 0x00480307: 0x1E22, - 0x00680307: 0x1E23, - 0x00480323: 0x1E24, - 0x00680323: 0x1E25, - 0x00480308: 0x1E26, - 0x00680308: 0x1E27, - 0x00480327: 0x1E28, - 0x00680327: 0x1E29, - 0x0048032E: 0x1E2A, - 0x0068032E: 0x1E2B, - 0x00490330: 0x1E2C, - 0x00690330: 0x1E2D, - 0x00CF0301: 0x1E2E, - 0x00EF0301: 0x1E2F, - 0x004B0301: 0x1E30, - 0x006B0301: 0x1E31, - 0x004B0323: 0x1E32, - 0x006B0323: 0x1E33, - 0x004B0331: 0x1E34, - 0x006B0331: 0x1E35, - 0x004C0323: 0x1E36, - 0x006C0323: 0x1E37, - 0x1E360304: 0x1E38, - 0x1E370304: 0x1E39, - 0x004C0331: 0x1E3A, - 0x006C0331: 0x1E3B, - 0x004C032D: 0x1E3C, - 0x006C032D: 0x1E3D, - 0x004D0301: 0x1E3E, - 0x006D0301: 0x1E3F, - 0x004D0307: 0x1E40, - 0x006D0307: 0x1E41, - 0x004D0323: 0x1E42, - 0x006D0323: 0x1E43, - 0x004E0307: 0x1E44, - 0x006E0307: 0x1E45, - 0x004E0323: 0x1E46, - 0x006E0323: 0x1E47, - 0x004E0331: 0x1E48, - 0x006E0331: 0x1E49, - 0x004E032D: 0x1E4A, - 0x006E032D: 0x1E4B, - 0x00D50301: 0x1E4C, - 0x00F50301: 0x1E4D, - 0x00D50308: 0x1E4E, - 0x00F50308: 0x1E4F, - 0x014C0300: 0x1E50, - 0x014D0300: 0x1E51, - 0x014C0301: 0x1E52, - 0x014D0301: 0x1E53, - 0x00500301: 0x1E54, - 0x00700301: 0x1E55, - 0x00500307: 0x1E56, - 0x00700307: 0x1E57, - 0x00520307: 0x1E58, - 0x00720307: 0x1E59, - 0x00520323: 0x1E5A, - 0x00720323: 0x1E5B, - 0x1E5A0304: 0x1E5C, - 0x1E5B0304: 0x1E5D, - 0x00520331: 0x1E5E, - 0x00720331: 0x1E5F, - 0x00530307: 0x1E60, - 0x00730307: 0x1E61, - 0x00530323: 0x1E62, - 0x00730323: 0x1E63, - 0x015A0307: 0x1E64, - 0x015B0307: 0x1E65, - 0x01600307: 0x1E66, - 0x01610307: 0x1E67, - 0x1E620307: 0x1E68, - 0x1E630307: 0x1E69, - 0x00540307: 0x1E6A, - 0x00740307: 0x1E6B, - 0x00540323: 0x1E6C, - 0x00740323: 0x1E6D, - 0x00540331: 0x1E6E, - 0x00740331: 0x1E6F, - 0x0054032D: 0x1E70, - 0x0074032D: 0x1E71, - 0x00550324: 0x1E72, - 0x00750324: 0x1E73, - 0x00550330: 0x1E74, - 0x00750330: 0x1E75, - 0x0055032D: 0x1E76, - 0x0075032D: 0x1E77, - 0x01680301: 0x1E78, - 0x01690301: 0x1E79, - 0x016A0308: 0x1E7A, - 0x016B0308: 0x1E7B, - 0x00560303: 0x1E7C, - 0x00760303: 0x1E7D, - 0x00560323: 0x1E7E, - 0x00760323: 0x1E7F, - 0x00570300: 0x1E80, - 0x00770300: 0x1E81, - 0x00570301: 0x1E82, - 0x00770301: 0x1E83, - 0x00570308: 0x1E84, - 0x00770308: 0x1E85, - 0x00570307: 0x1E86, - 0x00770307: 0x1E87, - 0x00570323: 0x1E88, - 0x00770323: 0x1E89, - 0x00580307: 0x1E8A, - 0x00780307: 0x1E8B, - 0x00580308: 0x1E8C, - 0x00780308: 0x1E8D, - 0x00590307: 0x1E8E, - 0x00790307: 0x1E8F, - 0x005A0302: 0x1E90, - 0x007A0302: 0x1E91, - 0x005A0323: 0x1E92, - 0x007A0323: 0x1E93, - 0x005A0331: 0x1E94, - 0x007A0331: 0x1E95, - 0x00680331: 0x1E96, - 0x00740308: 0x1E97, - 0x0077030A: 0x1E98, - 0x0079030A: 0x1E99, - 0x017F0307: 0x1E9B, - 0x00410323: 0x1EA0, - 0x00610323: 0x1EA1, - 0x00410309: 0x1EA2, - 0x00610309: 0x1EA3, - 0x00C20301: 0x1EA4, - 0x00E20301: 0x1EA5, - 0x00C20300: 0x1EA6, - 0x00E20300: 0x1EA7, - 0x00C20309: 0x1EA8, - 0x00E20309: 0x1EA9, - 0x00C20303: 0x1EAA, - 0x00E20303: 0x1EAB, - 0x1EA00302: 0x1EAC, - 0x1EA10302: 0x1EAD, - 0x01020301: 0x1EAE, - 0x01030301: 0x1EAF, - 0x01020300: 0x1EB0, - 0x01030300: 0x1EB1, - 0x01020309: 0x1EB2, - 0x01030309: 0x1EB3, - 0x01020303: 0x1EB4, - 0x01030303: 0x1EB5, - 0x1EA00306: 0x1EB6, - 0x1EA10306: 0x1EB7, - 0x00450323: 0x1EB8, - 0x00650323: 0x1EB9, - 0x00450309: 0x1EBA, - 0x00650309: 0x1EBB, - 0x00450303: 0x1EBC, - 0x00650303: 0x1EBD, - 0x00CA0301: 0x1EBE, - 0x00EA0301: 0x1EBF, - 0x00CA0300: 0x1EC0, - 0x00EA0300: 0x1EC1, - 0x00CA0309: 0x1EC2, - 0x00EA0309: 0x1EC3, - 0x00CA0303: 0x1EC4, - 0x00EA0303: 0x1EC5, - 0x1EB80302: 0x1EC6, - 0x1EB90302: 0x1EC7, - 0x00490309: 0x1EC8, - 0x00690309: 0x1EC9, - 0x00490323: 0x1ECA, - 0x00690323: 0x1ECB, - 0x004F0323: 0x1ECC, - 0x006F0323: 0x1ECD, - 0x004F0309: 0x1ECE, - 0x006F0309: 0x1ECF, - 0x00D40301: 0x1ED0, - 0x00F40301: 0x1ED1, - 0x00D40300: 0x1ED2, - 0x00F40300: 0x1ED3, - 0x00D40309: 0x1ED4, - 0x00F40309: 0x1ED5, - 0x00D40303: 0x1ED6, - 0x00F40303: 0x1ED7, - 0x1ECC0302: 0x1ED8, - 0x1ECD0302: 0x1ED9, - 0x01A00301: 0x1EDA, - 0x01A10301: 0x1EDB, - 0x01A00300: 0x1EDC, - 0x01A10300: 0x1EDD, - 0x01A00309: 0x1EDE, - 0x01A10309: 0x1EDF, - 0x01A00303: 0x1EE0, - 0x01A10303: 0x1EE1, - 0x01A00323: 0x1EE2, - 0x01A10323: 0x1EE3, - 0x00550323: 0x1EE4, - 0x00750323: 0x1EE5, - 0x00550309: 0x1EE6, - 0x00750309: 0x1EE7, - 0x01AF0301: 0x1EE8, - 0x01B00301: 0x1EE9, - 0x01AF0300: 0x1EEA, - 0x01B00300: 0x1EEB, - 0x01AF0309: 0x1EEC, - 0x01B00309: 0x1EED, - 0x01AF0303: 0x1EEE, - 0x01B00303: 0x1EEF, - 0x01AF0323: 0x1EF0, - 0x01B00323: 0x1EF1, - 0x00590300: 0x1EF2, - 0x00790300: 0x1EF3, - 0x00590323: 0x1EF4, - 0x00790323: 0x1EF5, - 0x00590309: 0x1EF6, - 0x00790309: 0x1EF7, - 0x00590303: 0x1EF8, - 0x00790303: 0x1EF9, - 0x03B10313: 0x1F00, - 0x03B10314: 0x1F01, - 0x1F000300: 0x1F02, - 0x1F010300: 0x1F03, - 0x1F000301: 0x1F04, - 0x1F010301: 0x1F05, - 0x1F000342: 0x1F06, - 0x1F010342: 0x1F07, - 0x03910313: 0x1F08, - 0x03910314: 0x1F09, - 0x1F080300: 0x1F0A, - 0x1F090300: 0x1F0B, - 0x1F080301: 0x1F0C, - 0x1F090301: 0x1F0D, - 0x1F080342: 0x1F0E, - 0x1F090342: 0x1F0F, - 0x03B50313: 0x1F10, - 0x03B50314: 0x1F11, - 0x1F100300: 0x1F12, - 0x1F110300: 0x1F13, - 0x1F100301: 0x1F14, - 0x1F110301: 0x1F15, - 0x03950313: 0x1F18, - 0x03950314: 0x1F19, - 0x1F180300: 0x1F1A, - 0x1F190300: 0x1F1B, - 0x1F180301: 0x1F1C, - 0x1F190301: 0x1F1D, - 0x03B70313: 0x1F20, - 0x03B70314: 0x1F21, - 0x1F200300: 0x1F22, - 0x1F210300: 0x1F23, - 0x1F200301: 0x1F24, - 0x1F210301: 0x1F25, - 0x1F200342: 0x1F26, - 0x1F210342: 0x1F27, - 0x03970313: 0x1F28, - 0x03970314: 0x1F29, - 0x1F280300: 0x1F2A, - 0x1F290300: 0x1F2B, - 0x1F280301: 0x1F2C, - 0x1F290301: 0x1F2D, - 0x1F280342: 0x1F2E, - 0x1F290342: 0x1F2F, - 0x03B90313: 0x1F30, - 0x03B90314: 0x1F31, - 0x1F300300: 0x1F32, - 0x1F310300: 0x1F33, - 0x1F300301: 0x1F34, - 0x1F310301: 0x1F35, - 0x1F300342: 0x1F36, - 0x1F310342: 0x1F37, - 0x03990313: 0x1F38, - 0x03990314: 0x1F39, - 0x1F380300: 0x1F3A, - 0x1F390300: 0x1F3B, - 0x1F380301: 0x1F3C, - 0x1F390301: 0x1F3D, - 0x1F380342: 0x1F3E, - 0x1F390342: 0x1F3F, - 0x03BF0313: 0x1F40, - 0x03BF0314: 0x1F41, - 0x1F400300: 0x1F42, - 0x1F410300: 0x1F43, - 0x1F400301: 0x1F44, - 0x1F410301: 0x1F45, - 0x039F0313: 0x1F48, - 0x039F0314: 0x1F49, - 0x1F480300: 0x1F4A, - 0x1F490300: 0x1F4B, - 0x1F480301: 0x1F4C, - 0x1F490301: 0x1F4D, - 0x03C50313: 0x1F50, - 0x03C50314: 0x1F51, - 0x1F500300: 0x1F52, - 0x1F510300: 0x1F53, - 0x1F500301: 0x1F54, - 0x1F510301: 0x1F55, - 0x1F500342: 0x1F56, - 0x1F510342: 0x1F57, - 0x03A50314: 0x1F59, - 0x1F590300: 0x1F5B, - 0x1F590301: 0x1F5D, - 0x1F590342: 0x1F5F, - 0x03C90313: 0x1F60, - 0x03C90314: 0x1F61, - 0x1F600300: 0x1F62, - 0x1F610300: 0x1F63, - 0x1F600301: 0x1F64, - 0x1F610301: 0x1F65, - 0x1F600342: 0x1F66, - 0x1F610342: 0x1F67, - 0x03A90313: 0x1F68, - 0x03A90314: 0x1F69, - 0x1F680300: 0x1F6A, - 0x1F690300: 0x1F6B, - 0x1F680301: 0x1F6C, - 0x1F690301: 0x1F6D, - 0x1F680342: 0x1F6E, - 0x1F690342: 0x1F6F, - 0x03B10300: 0x1F70, - 0x03B50300: 0x1F72, - 0x03B70300: 0x1F74, - 0x03B90300: 0x1F76, - 0x03BF0300: 0x1F78, - 0x03C50300: 0x1F7A, - 0x03C90300: 0x1F7C, - 0x1F000345: 0x1F80, - 0x1F010345: 0x1F81, - 0x1F020345: 0x1F82, - 0x1F030345: 0x1F83, - 0x1F040345: 0x1F84, - 0x1F050345: 0x1F85, - 0x1F060345: 0x1F86, - 0x1F070345: 0x1F87, - 0x1F080345: 0x1F88, - 0x1F090345: 0x1F89, - 0x1F0A0345: 0x1F8A, - 0x1F0B0345: 0x1F8B, - 0x1F0C0345: 0x1F8C, - 0x1F0D0345: 0x1F8D, - 0x1F0E0345: 0x1F8E, - 0x1F0F0345: 0x1F8F, - 0x1F200345: 0x1F90, - 0x1F210345: 0x1F91, - 0x1F220345: 0x1F92, - 0x1F230345: 0x1F93, - 0x1F240345: 0x1F94, - 0x1F250345: 0x1F95, - 0x1F260345: 0x1F96, - 0x1F270345: 0x1F97, - 0x1F280345: 0x1F98, - 0x1F290345: 0x1F99, - 0x1F2A0345: 0x1F9A, - 0x1F2B0345: 0x1F9B, - 0x1F2C0345: 0x1F9C, - 0x1F2D0345: 0x1F9D, - 0x1F2E0345: 0x1F9E, - 0x1F2F0345: 0x1F9F, - 0x1F600345: 0x1FA0, - 0x1F610345: 0x1FA1, - 0x1F620345: 0x1FA2, - 0x1F630345: 0x1FA3, - 0x1F640345: 0x1FA4, - 0x1F650345: 0x1FA5, - 0x1F660345: 0x1FA6, - 0x1F670345: 0x1FA7, - 0x1F680345: 0x1FA8, - 0x1F690345: 0x1FA9, - 0x1F6A0345: 0x1FAA, - 0x1F6B0345: 0x1FAB, - 0x1F6C0345: 0x1FAC, - 0x1F6D0345: 0x1FAD, - 0x1F6E0345: 0x1FAE, - 0x1F6F0345: 0x1FAF, - 0x03B10306: 0x1FB0, - 0x03B10304: 0x1FB1, - 0x1F700345: 0x1FB2, - 0x03B10345: 0x1FB3, - 0x03AC0345: 0x1FB4, - 0x03B10342: 0x1FB6, - 0x1FB60345: 0x1FB7, - 0x03910306: 0x1FB8, - 0x03910304: 0x1FB9, - 0x03910300: 0x1FBA, - 0x03910345: 0x1FBC, - 0x00A80342: 0x1FC1, - 0x1F740345: 0x1FC2, - 0x03B70345: 0x1FC3, - 0x03AE0345: 0x1FC4, - 0x03B70342: 0x1FC6, - 0x1FC60345: 0x1FC7, - 0x03950300: 0x1FC8, - 0x03970300: 0x1FCA, - 0x03970345: 0x1FCC, - 0x1FBF0300: 0x1FCD, - 0x1FBF0301: 0x1FCE, - 0x1FBF0342: 0x1FCF, - 0x03B90306: 0x1FD0, - 0x03B90304: 0x1FD1, - 0x03CA0300: 0x1FD2, - 0x03B90342: 0x1FD6, - 0x03CA0342: 0x1FD7, - 0x03990306: 0x1FD8, - 0x03990304: 0x1FD9, - 0x03990300: 0x1FDA, - 0x1FFE0300: 0x1FDD, - 0x1FFE0301: 0x1FDE, - 0x1FFE0342: 0x1FDF, - 0x03C50306: 0x1FE0, - 0x03C50304: 0x1FE1, - 0x03CB0300: 0x1FE2, - 0x03C10313: 0x1FE4, - 0x03C10314: 0x1FE5, - 0x03C50342: 0x1FE6, - 0x03CB0342: 0x1FE7, - 0x03A50306: 0x1FE8, - 0x03A50304: 0x1FE9, - 0x03A50300: 0x1FEA, - 0x03A10314: 0x1FEC, - 0x00A80300: 0x1FED, - 0x1F7C0345: 0x1FF2, - 0x03C90345: 0x1FF3, - 0x03CE0345: 0x1FF4, - 0x03C90342: 0x1FF6, - 0x1FF60345: 0x1FF7, - 0x039F0300: 0x1FF8, - 0x03A90300: 0x1FFA, - 0x03A90345: 0x1FFC, - 0x21900338: 0x219A, - 0x21920338: 0x219B, - 0x21940338: 0x21AE, - 0x21D00338: 0x21CD, - 0x21D40338: 0x21CE, - 0x21D20338: 0x21CF, - 0x22030338: 0x2204, - 0x22080338: 0x2209, - 0x220B0338: 0x220C, - 0x22230338: 0x2224, - 0x22250338: 0x2226, - 0x223C0338: 0x2241, - 0x22430338: 0x2244, - 0x22450338: 0x2247, - 0x22480338: 0x2249, - 0x003D0338: 0x2260, - 0x22610338: 0x2262, - 0x224D0338: 0x226D, - 0x003C0338: 0x226E, - 0x003E0338: 0x226F, - 0x22640338: 0x2270, - 0x22650338: 0x2271, - 0x22720338: 0x2274, - 0x22730338: 0x2275, - 0x22760338: 0x2278, - 0x22770338: 0x2279, - 0x227A0338: 0x2280, - 0x227B0338: 0x2281, - 0x22820338: 0x2284, - 0x22830338: 0x2285, - 0x22860338: 0x2288, - 0x22870338: 0x2289, - 0x22A20338: 0x22AC, - 0x22A80338: 0x22AD, - 0x22A90338: 0x22AE, - 0x22AB0338: 0x22AF, - 0x227C0338: 0x22E0, - 0x227D0338: 0x22E1, - 0x22910338: 0x22E2, - 0x22920338: 0x22E3, - 0x22B20338: 0x22EA, - 0x22B30338: 0x22EB, - 0x22B40338: 0x22EC, - 0x22B50338: 0x22ED, - 0x304B3099: 0x304C, - 0x304D3099: 0x304E, - 0x304F3099: 0x3050, - 0x30513099: 0x3052, - 0x30533099: 0x3054, - 0x30553099: 0x3056, - 0x30573099: 0x3058, - 0x30593099: 0x305A, - 0x305B3099: 0x305C, - 0x305D3099: 0x305E, - 0x305F3099: 0x3060, - 0x30613099: 0x3062, - 0x30643099: 0x3065, - 0x30663099: 0x3067, - 0x30683099: 0x3069, - 0x306F3099: 0x3070, - 0x306F309A: 0x3071, - 0x30723099: 0x3073, - 0x3072309A: 0x3074, - 0x30753099: 0x3076, - 0x3075309A: 0x3077, - 0x30783099: 0x3079, - 0x3078309A: 0x307A, - 0x307B3099: 0x307C, - 0x307B309A: 0x307D, - 0x30463099: 0x3094, - 0x309D3099: 0x309E, - 0x30AB3099: 0x30AC, - 0x30AD3099: 0x30AE, - 0x30AF3099: 0x30B0, - 0x30B13099: 0x30B2, - 0x30B33099: 0x30B4, - 0x30B53099: 0x30B6, - 0x30B73099: 0x30B8, - 0x30B93099: 0x30BA, - 0x30BB3099: 0x30BC, - 0x30BD3099: 0x30BE, - 0x30BF3099: 0x30C0, - 0x30C13099: 0x30C2, - 0x30C43099: 0x30C5, - 0x30C63099: 0x30C7, - 0x30C83099: 0x30C9, - 0x30CF3099: 0x30D0, - 0x30CF309A: 0x30D1, - 0x30D23099: 0x30D3, - 0x30D2309A: 0x30D4, - 0x30D53099: 0x30D6, - 0x30D5309A: 0x30D7, - 0x30D83099: 0x30D9, - 0x30D8309A: 0x30DA, - 0x30DB3099: 0x30DC, - 0x30DB309A: 0x30DD, - 0x30A63099: 0x30F4, - 0x30EF3099: 0x30F7, - 0x30F03099: 0x30F8, - 0x30F13099: 0x30F9, - 0x30F23099: 0x30FA, - 0x30FD3099: 0x30FE, - 0x109910BA: 0x1109A, - 0x109B10BA: 0x1109C, - 0x10A510BA: 0x110AB, - 0x11311127: 0x1112E, - 0x11321127: 0x1112F, - 0x1347133E: 0x1134B, - 0x13471357: 0x1134C, - 0x14B914BA: 0x114BB, - 0x14B914B0: 0x114BC, - 0x14B914BD: 0x114BE, - 0x15B815AF: 0x115BA, - 0x15B915AF: 0x115BB, -} +var recompMap map[uint32]rune +var recompMapOnce sync.Once -// Total size of tables: 53KB (54006 bytes) +const recompMapPacked = "" + + "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0 + "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1 + "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2 + "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3 + "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4 + "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5 + "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7 + "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8 + "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9 + "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA + "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB + "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC + "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD + "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE + "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF + "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1 + "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2 + "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3 + "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4 + "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5 + "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6 + "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9 + "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA + "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB + "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC + "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD + "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0 + "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1 + "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2 + "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3 + "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4 + "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5 + "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7 + "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8 + "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9 + "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA + "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB + "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC + "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED + "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE + "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF + "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1 + "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2 + "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3 + "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4 + "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5 + "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6 + "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9 + "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA + "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB + "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC + "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD + "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF + "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100 + "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101 + "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102 + "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103 + "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104 + "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105 + "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106 + "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107 + "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108 + "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109 + "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A + "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B + "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C + "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D + "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E + "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F + "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112 + "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113 + "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114 + "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115 + "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116 + "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117 + "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118 + "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119 + "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A + "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B + "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C + "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D + "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E + "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F + "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120 + "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121 + "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122 + "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123 + "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124 + "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125 + "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128 + "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129 + "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A + "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B + "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C + "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D + "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E + "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F + "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130 + "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134 + "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135 + "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136 + "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137 + "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139 + "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A + "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B + "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C + "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D + "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E + "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143 + "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144 + "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145 + "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146 + "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147 + "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148 + "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C + "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D + "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E + "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F + "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150 + "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151 + "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154 + "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155 + "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156 + "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157 + "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158 + "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159 + "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A + "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B + "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C + "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D + "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E + "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F + "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160 + "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161 + "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162 + "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163 + "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164 + "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165 + "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168 + "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169 + "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A + "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B + "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C + "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D + "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E + "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F + "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170 + "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171 + "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172 + "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173 + "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174 + "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175 + "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176 + "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177 + "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178 + "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179 + "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A + "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B + "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C + "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D + "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E + "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0 + "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1 + "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF + "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0 + "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD + "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE + "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF + "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0 + "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1 + "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2 + "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3 + "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4 + "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5 + "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6 + "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7 + "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8 + "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9 + "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA + "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB + "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC + "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE + "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF + "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0 + "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1 + "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2 + "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3 + "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6 + "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7 + "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8 + "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9 + "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA + "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB + "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC + "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED + "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE + "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF + "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0 + "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4 + "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5 + "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8 + "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9 + "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA + "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB + "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC + "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD + "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE + "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF + "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200 + "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201 + "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202 + "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203 + "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204 + "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205 + "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206 + "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207 + "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208 + "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209 + "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A + "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B + "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C + "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D + "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E + "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F + "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210 + "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211 + "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212 + "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213 + "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214 + "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215 + "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216 + "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217 + "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218 + "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219 + "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A + "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B + "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E + "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F + "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226 + "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227 + "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228 + "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229 + "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A + "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B + "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C + "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D + "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E + "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F + "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230 + "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231 + "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232 + "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233 + "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385 + "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386 + "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388 + "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389 + "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A + "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C + "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E + "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F + "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390 + "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA + "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB + "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC + "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD + "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE + "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF + "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0 + "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA + "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB + "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC + "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD + "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE + "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3 + "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4 + "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400 + "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401 + "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403 + "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407 + "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C + "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D + "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E + "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419 + "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439 + "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450 + "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451 + "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453 + "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457 + "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C + "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D + "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E + "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476 + "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477 + "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1 + "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2 + "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0 + "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1 + "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2 + "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3 + "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6 + "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7 + "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA + "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB + "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC + "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD + "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE + "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF + "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2 + "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3 + "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4 + "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5 + "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6 + "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7 + "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA + "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB + "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC + "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED + "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE + "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF + "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0 + "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1 + "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2 + "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3 + "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4 + "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5 + "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8 + "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9 + "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622 + "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623 + "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624 + "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625 + "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626 + "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0 + "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2 + "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3 + "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929 + "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931 + "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934 + "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB + "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC + "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48 + "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B + "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C + "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94 + "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA + "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB + "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC + "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48 + "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0 + "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7 + "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8 + "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA + "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB + "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A + "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B + "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C + "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA + "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC + "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD + "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE + "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026 + "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06 + "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08 + "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A + "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C + "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E + "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12 + "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B + "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D + "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40 + "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41 + "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43 + "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00 + "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01 + "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02 + "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03 + "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04 + "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05 + "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06 + "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07 + "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08 + "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09 + "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A + "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B + "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C + "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D + "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E + "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F + "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10 + "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11 + "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12 + "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13 + "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14 + "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15 + "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16 + "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17 + "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18 + "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19 + "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A + "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B + "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C + "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D + "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E + "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F + "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20 + "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21 + "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22 + "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23 + "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24 + "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25 + "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26 + "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27 + "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28 + "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29 + "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A + "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B + "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C + "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D + "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E + "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F + "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30 + "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31 + "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32 + "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33 + "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34 + "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35 + "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36 + "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37 + "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38 + "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39 + "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A + "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B + "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C + "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D + "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E + "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F + "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40 + "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41 + "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42 + "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43 + "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44 + "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45 + "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46 + "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47 + "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48 + "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49 + "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A + "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B + "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C + "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D + "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E + "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F + "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50 + "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51 + "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52 + "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53 + "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54 + "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55 + "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56 + "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57 + "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58 + "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59 + "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A + "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B + "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C + "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D + "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E + "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F + "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60 + "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61 + "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62 + "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63 + "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64 + "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65 + "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66 + "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67 + "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68 + "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69 + "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A + "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B + "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C + "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D + "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E + "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F + "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70 + "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71 + "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72 + "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73 + "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74 + "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75 + "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76 + "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77 + "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78 + "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79 + "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A + "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B + "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C + "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D + "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E + "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F + "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 + "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 + "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 + "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83 + "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84 + "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85 + "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86 + "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87 + "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88 + "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89 + "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A + "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B + "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C + "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D + "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E + "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F + "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90 + "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91 + "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92 + "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93 + "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94 + "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95 + "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96 + "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 + "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 + "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 + "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B + "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 + "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 + "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 + "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3 + "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4 + "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5 + "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6 + "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7 + "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8 + "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9 + "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA + "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB + "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC + "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD + "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE + "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF + "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0 + "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1 + "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2 + "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3 + "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4 + "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5 + "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6 + "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7 + "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8 + "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9 + "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA + "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB + "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC + "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD + "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE + "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF + "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0 + "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1 + "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2 + "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3 + "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4 + "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5 + "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6 + "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7 + "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8 + "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9 + "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA + "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB + "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC + "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD + "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE + "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF + "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0 + "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1 + "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2 + "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3 + "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4 + "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5 + "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6 + "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7 + "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8 + "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9 + "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA + "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB + "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC + "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD + "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE + "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF + "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0 + "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1 + "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2 + "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3 + "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4 + "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5 + "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6 + "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7 + "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8 + "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9 + "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA + "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB + "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC + "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED + "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE + "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF + "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0 + "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1 + "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2 + "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3 + "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4 + "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5 + "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6 + "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7 + "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8 + "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9 + "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00 + "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01 + "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02 + "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03 + "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04 + "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05 + "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06 + "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07 + "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08 + "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09 + "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A + "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B + "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C + "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D + "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E + "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F + "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10 + "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11 + "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12 + "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13 + "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14 + "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15 + "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18 + "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19 + "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A + "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B + "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C + "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D + "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20 + "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21 + "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22 + "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23 + "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24 + "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25 + "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26 + "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27 + "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28 + "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29 + "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A + "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B + "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C + "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D + "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E + "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F + "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30 + "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31 + "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32 + "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33 + "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34 + "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35 + "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36 + "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37 + "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38 + "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39 + "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A + "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B + "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C + "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D + "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E + "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F + "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40 + "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41 + "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42 + "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43 + "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44 + "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45 + "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48 + "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49 + "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A + "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B + "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C + "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D + "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50 + "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51 + "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52 + "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53 + "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54 + "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55 + "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56 + "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57 + "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59 + "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B + "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D + "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F + "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60 + "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61 + "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62 + "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63 + "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64 + "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65 + "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66 + "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67 + "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68 + "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69 + "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A + "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B + "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C + "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D + "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E + "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F + "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70 + "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72 + "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74 + "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76 + "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78 + "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A + "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C + "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80 + "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81 + "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82 + "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83 + "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84 + "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85 + "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86 + "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87 + "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88 + "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89 + "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A + "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B + "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C + "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D + "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E + "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F + "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90 + "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91 + "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92 + "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93 + "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94 + "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95 + "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96 + "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97 + "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98 + "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99 + "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A + "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B + "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C + "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D + "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E + "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F + "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0 + "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1 + "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2 + "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3 + "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4 + "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5 + "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6 + "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7 + "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8 + "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9 + "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA + "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB + "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC + "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD + "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE + "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF + "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0 + "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1 + "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2 + "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3 + "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4 + "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6 + "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7 + "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8 + "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9 + "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA + "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC + "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1 + "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2 + "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3 + "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4 + "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6 + "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7 + "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8 + "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA + "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC + "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD + "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE + "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF + "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0 + "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1 + "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2 + "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6 + "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7 + "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8 + "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9 + "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA + "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD + "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE + "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF + "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0 + "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1 + "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2 + "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4 + "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5 + "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6 + "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7 + "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8 + "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9 + "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA + "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC + "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED + "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2 + "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3 + "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4 + "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6 + "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7 + "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8 + "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA + "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC + "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A + "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B + "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE + "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD + "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE + "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF + "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204 + "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209 + "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C + "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224 + "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226 + "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241 + "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244 + "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247 + "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249 + "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260 + "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262 + "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D + "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E + "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F + "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270 + "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271 + "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274 + "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275 + "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278 + "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279 + "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280 + "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281 + "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284 + "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285 + "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288 + "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289 + "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC + "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD + "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE + "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF + "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0 + "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1 + "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2 + "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3 + "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA + "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB + "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC + "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED + "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C + "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E + "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050 + "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052 + "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054 + "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056 + "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058 + "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A + "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C + "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E + "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060 + "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062 + "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065 + "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067 + "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069 + "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070 + "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071 + "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073 + "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074 + "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076 + "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077 + "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079 + "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A + "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C + "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D + "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094 + "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E + "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC + "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE + "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0 + "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2 + "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4 + "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6 + "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8 + "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA + "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC + "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE + "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0 + "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2 + "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5 + "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7 + "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9 + "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0 + "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1 + "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3 + "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4 + "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6 + "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7 + "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9 + "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA + "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC + "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD + "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4 + "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7 + "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8 + "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9 + "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA + "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE + "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A + "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C + "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB + "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E + "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F + "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B + "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C + "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB + "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC + "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE + "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA + "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB + "" + // Total size of tables: 53KB (54006 bytes) diff --git a/vendor/golang.org/x/text/unicode/norm/transform.go b/vendor/golang.org/x/text/unicode/norm/transform.go index 9f47efbaf65f..a1d366ae4872 100644 --- a/vendor/golang.org/x/text/unicode/norm/transform.go +++ b/vendor/golang.org/x/text/unicode/norm/transform.go @@ -18,7 +18,6 @@ func (Form) Reset() {} // Users should either catch ErrShortDst and allow dst to grow or have dst be at // least of size MaxTransformChunkSize to be guaranteed of progress. func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { - n := 0 // Cap the maximum number of src bytes to check. b := src eof := atEOF @@ -27,13 +26,14 @@ func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) eof = false b = b[:ns] } - i, ok := formTable[f].quickSpan(inputBytes(b), n, len(b), eof) - n += copy(dst[n:], b[n:i]) + i, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), eof) + n := copy(dst, b[:i]) if !ok { nDst, nSrc, err = f.transform(dst[n:], src[n:], atEOF) return nDst + n, nSrc + n, err } - if n < len(src) && !atEOF { + + if err == nil && n < len(src) && !atEOF { err = transform.ErrShortSrc } return n, n, err @@ -79,7 +79,7 @@ func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) nSrc += n nDst += n if ok { - if n < rb.nsrc && !atEOF { + if err == nil && n < rb.nsrc && !atEOF { err = transform.ErrShortSrc } return nDst, nSrc, err diff --git a/vendor/google.golang.org/api/gensupport/backoff.go b/vendor/google.golang.org/api/gensupport/backoff.go new file mode 100644 index 000000000000..94b7789eea7f --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/backoff.go @@ -0,0 +1,51 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gensupport + +import ( + "math/rand" + "time" +) + +// BackoffStrategy defines the set of functions that a backoff-er must +// implement. +type BackoffStrategy interface { + // Pause returns the duration of the next pause and true if the operation should be + // retried, or false if no further retries should be attempted. + Pause() (time.Duration, bool) + + // Reset restores the strategy to its initial state. + Reset() +} + +// ExponentialBackoff performs exponential backoff as per https://en.wikipedia.org/wiki/Exponential_backoff. +// The initial pause time is given by Base. +// Once the total pause time exceeds Max, Pause will indicate no further retries. +type ExponentialBackoff struct { + Base time.Duration + Max time.Duration + total time.Duration + n uint +} + +// Pause returns the amount of time the caller should wait. +func (eb *ExponentialBackoff) Pause() (time.Duration, bool) { + if eb.total > eb.Max { + return 0, false + } + + // The next pause is selected from randomly from [0, 2^n * Base). + d := time.Duration(rand.Int63n((1 << eb.n) * int64(eb.Base))) + eb.total += d + eb.n++ + return d, true +} + +// Reset resets the backoff strategy such that the next Pause call will begin +// counting from the start. It is not safe to call concurrently with Pause. +func (eb *ExponentialBackoff) Reset() { + eb.n = 0 + eb.total = 0 +} diff --git a/vendor/google.golang.org/api/gensupport/buffer.go b/vendor/google.golang.org/api/gensupport/buffer.go new file mode 100644 index 000000000000..3d0817ede98a --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/buffer.go @@ -0,0 +1,79 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gensupport + +import ( + "bytes" + "io" + + "google.golang.org/api/googleapi" +) + +// MediaBuffer buffers data from an io.Reader to support uploading media in +// retryable chunks. It should be created with NewMediaBuffer. +type MediaBuffer struct { + media io.Reader + + chunk []byte // The current chunk which is pending upload. The capacity is the chunk size. + err error // Any error generated when populating chunk by reading media. + + // The absolute position of chunk in the underlying media. + off int64 +} + +// NewMediaBuffer initializes a MediaBuffer. +func NewMediaBuffer(media io.Reader, chunkSize int) *MediaBuffer { + return &MediaBuffer{media: media, chunk: make([]byte, 0, chunkSize)} +} + +// Chunk returns the current buffered chunk, the offset in the underlying media +// from which the chunk is drawn, and the size of the chunk. +// Successive calls to Chunk return the same chunk between calls to Next. +func (mb *MediaBuffer) Chunk() (chunk io.Reader, off int64, size int, err error) { + // There may already be data in chunk if Next has not been called since the previous call to Chunk. + if mb.err == nil && len(mb.chunk) == 0 { + mb.err = mb.loadChunk() + } + return bytes.NewReader(mb.chunk), mb.off, len(mb.chunk), mb.err +} + +// loadChunk will read from media into chunk, up to the capacity of chunk. +func (mb *MediaBuffer) loadChunk() error { + bufSize := cap(mb.chunk) + mb.chunk = mb.chunk[:bufSize] + + read := 0 + var err error + for err == nil && read < bufSize { + var n int + n, err = mb.media.Read(mb.chunk[read:]) + read += n + } + mb.chunk = mb.chunk[:read] + return err +} + +// Next advances to the next chunk, which will be returned by the next call to Chunk. +// Calls to Next without a corresponding prior call to Chunk will have no effect. +func (mb *MediaBuffer) Next() { + mb.off += int64(len(mb.chunk)) + mb.chunk = mb.chunk[0:0] +} + +type readerTyper struct { + io.Reader + googleapi.ContentTyper +} + +// ReaderAtToReader adapts a ReaderAt to be used as a Reader. +// If ra implements googleapi.ContentTyper, then the returned reader +// will also implement googleapi.ContentTyper, delegating to ra. +func ReaderAtToReader(ra io.ReaderAt, size int64) io.Reader { + r := io.NewSectionReader(ra, 0, size) + if typer, ok := ra.(googleapi.ContentTyper); ok { + return readerTyper{r, typer} + } + return r +} diff --git a/vendor/google.golang.org/api/gensupport/doc.go b/vendor/google.golang.org/api/gensupport/doc.go new file mode 100644 index 000000000000..752c4b411b24 --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/doc.go @@ -0,0 +1,10 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gensupport is an internal implementation detail used by code +// generated by the google-api-go-generator tool. +// +// This package may be modified at any time without regard for backwards +// compatibility. It should not be used directly by API users. +package gensupport diff --git a/vendor/google.golang.org/api/gensupport/header.go b/vendor/google.golang.org/api/gensupport/header.go new file mode 100644 index 000000000000..cb5e67c77a21 --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/header.go @@ -0,0 +1,22 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gensupport + +import ( + "fmt" + "runtime" + "strings" +) + +// GoogleClientHeader returns the value to use for the x-goog-api-client +// header, which is used internally by Google. +func GoogleClientHeader(generatorVersion, clientElement string) string { + elts := []string{"gl-go/" + strings.Replace(runtime.Version(), " ", "_", -1)} + if clientElement != "" { + elts = append(elts, clientElement) + } + elts = append(elts, fmt.Sprintf("gdcl/%s", generatorVersion)) + return strings.Join(elts, " ") +} diff --git a/vendor/google.golang.org/api/gensupport/json.go b/vendor/google.golang.org/api/gensupport/json.go new file mode 100644 index 000000000000..c01e32189f44 --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/json.go @@ -0,0 +1,211 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gensupport + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" +) + +// MarshalJSON returns a JSON encoding of schema containing only selected fields. +// A field is selected if any of the following is true: +// * it has a non-empty value +// * its field name is present in forceSendFields and it is not a nil pointer or nil interface +// * its field name is present in nullFields. +// The JSON key for each selected field is taken from the field's json: struct tag. +func MarshalJSON(schema interface{}, forceSendFields, nullFields []string) ([]byte, error) { + if len(forceSendFields) == 0 && len(nullFields) == 0 { + return json.Marshal(schema) + } + + mustInclude := make(map[string]bool) + for _, f := range forceSendFields { + mustInclude[f] = true + } + useNull := make(map[string]bool) + useNullMaps := make(map[string]map[string]bool) + for _, nf := range nullFields { + parts := strings.SplitN(nf, ".", 2) + field := parts[0] + if len(parts) == 1 { + useNull[field] = true + } else { + if useNullMaps[field] == nil { + useNullMaps[field] = map[string]bool{} + } + useNullMaps[field][parts[1]] = true + } + } + + dataMap, err := schemaToMap(schema, mustInclude, useNull, useNullMaps) + if err != nil { + return nil, err + } + return json.Marshal(dataMap) +} + +func schemaToMap(schema interface{}, mustInclude, useNull map[string]bool, useNullMaps map[string]map[string]bool) (map[string]interface{}, error) { + m := make(map[string]interface{}) + s := reflect.ValueOf(schema) + st := s.Type() + + for i := 0; i < s.NumField(); i++ { + jsonTag := st.Field(i).Tag.Get("json") + if jsonTag == "" { + continue + } + tag, err := parseJSONTag(jsonTag) + if err != nil { + return nil, err + } + if tag.ignore { + continue + } + + v := s.Field(i) + f := st.Field(i) + + if useNull[f.Name] { + if !isEmptyValue(v) { + return nil, fmt.Errorf("field %q in NullFields has non-empty value", f.Name) + } + m[tag.apiName] = nil + continue + } + + if !includeField(v, f, mustInclude) { + continue + } + + // If map fields are explicitly set to null, use a map[string]interface{}. + if f.Type.Kind() == reflect.Map && useNullMaps[f.Name] != nil { + ms, ok := v.Interface().(map[string]string) + if !ok { + return nil, fmt.Errorf("field %q has keys in NullFields but is not a map[string]string", f.Name) + } + mi := map[string]interface{}{} + for k, v := range ms { + mi[k] = v + } + for k := range useNullMaps[f.Name] { + mi[k] = nil + } + m[tag.apiName] = mi + continue + } + + // nil maps are treated as empty maps. + if f.Type.Kind() == reflect.Map && v.IsNil() { + m[tag.apiName] = map[string]string{} + continue + } + + // nil slices are treated as empty slices. + if f.Type.Kind() == reflect.Slice && v.IsNil() { + m[tag.apiName] = []bool{} + continue + } + + if tag.stringFormat { + m[tag.apiName] = formatAsString(v, f.Type.Kind()) + } else { + m[tag.apiName] = v.Interface() + } + } + return m, nil +} + +// formatAsString returns a string representation of v, dereferencing it first if possible. +func formatAsString(v reflect.Value, kind reflect.Kind) string { + if kind == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + + return fmt.Sprintf("%v", v.Interface()) +} + +// jsonTag represents a restricted version of the struct tag format used by encoding/json. +// It is used to describe the JSON encoding of fields in a Schema struct. +type jsonTag struct { + apiName string + stringFormat bool + ignore bool +} + +// parseJSONTag parses a restricted version of the struct tag format used by encoding/json. +// The format of the tag must match that generated by the Schema.writeSchemaStruct method +// in the api generator. +func parseJSONTag(val string) (jsonTag, error) { + if val == "-" { + return jsonTag{ignore: true}, nil + } + + var tag jsonTag + + i := strings.Index(val, ",") + if i == -1 || val[:i] == "" { + return tag, fmt.Errorf("malformed json tag: %s", val) + } + + tag = jsonTag{ + apiName: val[:i], + } + + switch val[i+1:] { + case "omitempty": + case "omitempty,string": + tag.stringFormat = true + default: + return tag, fmt.Errorf("malformed json tag: %s", val) + } + + return tag, nil +} + +// Reports whether the struct field "f" with value "v" should be included in JSON output. +func includeField(v reflect.Value, f reflect.StructField, mustInclude map[string]bool) bool { + // The regular JSON encoding of a nil pointer is "null", which means "delete this field". + // Therefore, we could enable field deletion by honoring pointer fields' presence in the mustInclude set. + // However, many fields are not pointers, so there would be no way to delete these fields. + // Rather than partially supporting field deletion, we ignore mustInclude for nil pointer fields. + // Deletion will be handled by a separate mechanism. + if f.Type.Kind() == reflect.Ptr && v.IsNil() { + return false + } + + // The "any" type is represented as an interface{}. If this interface + // is nil, there is no reasonable representation to send. We ignore + // these fields, for the same reasons as given above for pointers. + if f.Type.Kind() == reflect.Interface && v.IsNil() { + return false + } + + return mustInclude[f.Name] || !isEmptyValue(v) +} + +// isEmptyValue reports whether v is the empty value for its type. This +// implementation is based on that of the encoding/json package, but its +// correctness does not depend on it being identical. What's important is that +// this function return false in situations where v should not be sent as part +// of a PATCH operation. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} diff --git a/vendor/google.golang.org/api/gensupport/jsonfloat.go b/vendor/google.golang.org/api/gensupport/jsonfloat.go new file mode 100644 index 000000000000..8377850811f0 --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/jsonfloat.go @@ -0,0 +1,57 @@ +// Copyright 2016 Google LLC +// +// 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 gensupport + +import ( + "encoding/json" + "errors" + "fmt" + "math" +) + +// JSONFloat64 is a float64 that supports proper unmarshaling of special float +// values in JSON, according to +// https://developers.google.com/protocol-buffers/docs/proto3#json. Although +// that is a proto-to-JSON spec, it applies to all Google APIs. +// +// The jsonpb package +// (https://github.com/golang/protobuf/blob/master/jsonpb/jsonpb.go) has +// similar functionality, but only for direct translation from proto messages +// to JSON. +type JSONFloat64 float64 + +func (f *JSONFloat64) UnmarshalJSON(data []byte) error { + var ff float64 + if err := json.Unmarshal(data, &ff); err == nil { + *f = JSONFloat64(ff) + return nil + } + var s string + if err := json.Unmarshal(data, &s); err == nil { + switch s { + case "NaN": + ff = math.NaN() + case "Infinity": + ff = math.Inf(1) + case "-Infinity": + ff = math.Inf(-1) + default: + return fmt.Errorf("google.golang.org/api/internal: bad float string %q", s) + } + *f = JSONFloat64(ff) + return nil + } + return errors.New("google.golang.org/api/internal: data not float or string") +} diff --git a/vendor/google.golang.org/api/gensupport/media.go b/vendor/google.golang.org/api/gensupport/media.go new file mode 100644 index 000000000000..0ef96b3f102b --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/media.go @@ -0,0 +1,363 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gensupport + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "mime" + "mime/multipart" + "net/http" + "net/textproto" + "strings" + "sync" + + "google.golang.org/api/googleapi" +) + +const sniffBuffSize = 512 + +func newContentSniffer(r io.Reader) *contentSniffer { + return &contentSniffer{r: r} +} + +// contentSniffer wraps a Reader, and reports the content type determined by sniffing up to 512 bytes from the Reader. +type contentSniffer struct { + r io.Reader + start []byte // buffer for the sniffed bytes. + err error // set to any error encountered while reading bytes to be sniffed. + + ctype string // set on first sniff. + sniffed bool // set to true on first sniff. +} + +func (cs *contentSniffer) Read(p []byte) (n int, err error) { + // Ensure that the content type is sniffed before any data is consumed from Reader. + _, _ = cs.ContentType() + + if len(cs.start) > 0 { + n := copy(p, cs.start) + cs.start = cs.start[n:] + return n, nil + } + + // We may have read some bytes into start while sniffing, even if the read ended in an error. + // We should first return those bytes, then the error. + if cs.err != nil { + return 0, cs.err + } + + // Now we have handled all bytes that were buffered while sniffing. Now just delegate to the underlying reader. + return cs.r.Read(p) +} + +// ContentType returns the sniffed content type, and whether the content type was succesfully sniffed. +func (cs *contentSniffer) ContentType() (string, bool) { + if cs.sniffed { + return cs.ctype, cs.ctype != "" + } + cs.sniffed = true + // If ReadAll hits EOF, it returns err==nil. + cs.start, cs.err = ioutil.ReadAll(io.LimitReader(cs.r, sniffBuffSize)) + + // Don't try to detect the content type based on possibly incomplete data. + if cs.err != nil { + return "", false + } + + cs.ctype = http.DetectContentType(cs.start) + return cs.ctype, true +} + +// DetermineContentType determines the content type of the supplied reader. +// If the content type is already known, it can be specified via ctype. +// Otherwise, the content of media will be sniffed to determine the content type. +// If media implements googleapi.ContentTyper (deprecated), this will be used +// instead of sniffing the content. +// After calling DetectContentType the caller must not perform further reads on +// media, but rather read from the Reader that is returned. +func DetermineContentType(media io.Reader, ctype string) (io.Reader, string) { + // Note: callers could avoid calling DetectContentType if ctype != "", + // but doing the check inside this function reduces the amount of + // generated code. + if ctype != "" { + return media, ctype + } + + // For backwards compatability, allow clients to set content + // type by providing a ContentTyper for media. + if typer, ok := media.(googleapi.ContentTyper); ok { + return media, typer.ContentType() + } + + sniffer := newContentSniffer(media) + if ctype, ok := sniffer.ContentType(); ok { + return sniffer, ctype + } + // If content type could not be sniffed, reads from sniffer will eventually fail with an error. + return sniffer, "" +} + +type typeReader struct { + io.Reader + typ string +} + +// multipartReader combines the contents of multiple readers to create a multipart/related HTTP body. +// Close must be called if reads from the multipartReader are abandoned before reaching EOF. +type multipartReader struct { + pr *io.PipeReader + ctype string + mu sync.Mutex + pipeOpen bool +} + +// boundary optionally specifies the MIME boundary +func newMultipartReader(parts []typeReader, boundary string) *multipartReader { + mp := &multipartReader{pipeOpen: true} + var pw *io.PipeWriter + mp.pr, pw = io.Pipe() + mpw := multipart.NewWriter(pw) + if boundary != "" { + mpw.SetBoundary(boundary) + } + mp.ctype = "multipart/related; boundary=" + mpw.Boundary() + go func() { + for _, part := range parts { + w, err := mpw.CreatePart(typeHeader(part.typ)) + if err != nil { + mpw.Close() + pw.CloseWithError(fmt.Errorf("googleapi: CreatePart failed: %v", err)) + return + } + _, err = io.Copy(w, part.Reader) + if err != nil { + mpw.Close() + pw.CloseWithError(fmt.Errorf("googleapi: Copy failed: %v", err)) + return + } + } + + mpw.Close() + pw.Close() + }() + return mp +} + +func (mp *multipartReader) Read(data []byte) (n int, err error) { + return mp.pr.Read(data) +} + +func (mp *multipartReader) Close() error { + mp.mu.Lock() + if !mp.pipeOpen { + mp.mu.Unlock() + return nil + } + mp.pipeOpen = false + mp.mu.Unlock() + return mp.pr.Close() +} + +// CombineBodyMedia combines a json body with media content to create a multipart/related HTTP body. +// It returns a ReadCloser containing the combined body, and the overall "multipart/related" content type, with random boundary. +// +// The caller must call Close on the returned ReadCloser if reads are abandoned before reaching EOF. +func CombineBodyMedia(body io.Reader, bodyContentType string, media io.Reader, mediaContentType string) (io.ReadCloser, string) { + return combineBodyMedia(body, bodyContentType, media, mediaContentType, "") +} + +// combineBodyMedia is CombineBodyMedia but with an optional mimeBoundary field. +func combineBodyMedia(body io.Reader, bodyContentType string, media io.Reader, mediaContentType, mimeBoundary string) (io.ReadCloser, string) { + mp := newMultipartReader([]typeReader{ + {body, bodyContentType}, + {media, mediaContentType}, + }, mimeBoundary) + return mp, mp.ctype +} + +func typeHeader(contentType string) textproto.MIMEHeader { + h := make(textproto.MIMEHeader) + if contentType != "" { + h.Set("Content-Type", contentType) + } + return h +} + +// PrepareUpload determines whether the data in the supplied reader should be +// uploaded in a single request, or in sequential chunks. +// chunkSize is the size of the chunk that media should be split into. +// +// If chunkSize is zero, media is returned as the first value, and the other +// two return values are nil, true. +// +// Otherwise, a MediaBuffer is returned, along with a bool indicating whether the +// contents of media fit in a single chunk. +// +// After PrepareUpload has been called, media should no longer be used: the +// media content should be accessed via one of the return values. +func PrepareUpload(media io.Reader, chunkSize int) (r io.Reader, mb *MediaBuffer, singleChunk bool) { + if chunkSize == 0 { // do not chunk + return media, nil, true + } + mb = NewMediaBuffer(media, chunkSize) + _, _, _, err := mb.Chunk() + // If err is io.EOF, we can upload this in a single request. Otherwise, err is + // either nil or a non-EOF error. If it is the latter, then the next call to + // mb.Chunk will return the same error. Returning a MediaBuffer ensures that this + // error will be handled at some point. + return nil, mb, err == io.EOF +} + +// MediaInfo holds information for media uploads. It is intended for use by generated +// code only. +type MediaInfo struct { + // At most one of Media and MediaBuffer will be set. + media io.Reader + buffer *MediaBuffer + singleChunk bool + mType string + size int64 // mediaSize, if known. Used only for calls to progressUpdater_. + progressUpdater googleapi.ProgressUpdater +} + +// NewInfoFromMedia should be invoked from the Media method of a call. It returns a +// MediaInfo populated with chunk size and content type, and a reader or MediaBuffer +// if needed. +func NewInfoFromMedia(r io.Reader, options []googleapi.MediaOption) *MediaInfo { + mi := &MediaInfo{} + opts := googleapi.ProcessMediaOptions(options) + if !opts.ForceEmptyContentType { + r, mi.mType = DetermineContentType(r, opts.ContentType) + } + mi.media, mi.buffer, mi.singleChunk = PrepareUpload(r, opts.ChunkSize) + return mi +} + +// NewInfoFromResumableMedia should be invoked from the ResumableMedia method of a +// call. It returns a MediaInfo using the given reader, size and media type. +func NewInfoFromResumableMedia(r io.ReaderAt, size int64, mediaType string) *MediaInfo { + rdr := ReaderAtToReader(r, size) + rdr, mType := DetermineContentType(rdr, mediaType) + return &MediaInfo{ + size: size, + mType: mType, + buffer: NewMediaBuffer(rdr, googleapi.DefaultUploadChunkSize), + media: nil, + singleChunk: false, + } +} + +// SetProgressUpdater sets the progress updater for the media info. +func (mi *MediaInfo) SetProgressUpdater(pu googleapi.ProgressUpdater) { + if mi != nil { + mi.progressUpdater = pu + } +} + +// UploadType determines the type of upload: a single request, or a resumable +// series of requests. +func (mi *MediaInfo) UploadType() string { + if mi.singleChunk { + return "multipart" + } + return "resumable" +} + +// UploadRequest sets up an HTTP request for media upload. It adds headers +// as necessary, and returns a replacement for the body and a function for http.Request.GetBody. +func (mi *MediaInfo) UploadRequest(reqHeaders http.Header, body io.Reader) (newBody io.Reader, getBody func() (io.ReadCloser, error), cleanup func()) { + cleanup = func() {} + if mi == nil { + return body, nil, cleanup + } + var media io.Reader + if mi.media != nil { + // This only happens when the caller has turned off chunking. In that + // case, we write all of media in a single non-retryable request. + media = mi.media + } else if mi.singleChunk { + // The data fits in a single chunk, which has now been read into the MediaBuffer. + // We obtain that chunk so we can write it in a single request. The request can + // be retried because the data is stored in the MediaBuffer. + media, _, _, _ = mi.buffer.Chunk() + } + if media != nil { + fb := readerFunc(body) + fm := readerFunc(media) + combined, ctype := CombineBodyMedia(body, "application/json", media, mi.mType) + if fb != nil && fm != nil { + getBody = func() (io.ReadCloser, error) { + rb := ioutil.NopCloser(fb()) + rm := ioutil.NopCloser(fm()) + var mimeBoundary string + if _, params, err := mime.ParseMediaType(ctype); err == nil { + mimeBoundary = params["boundary"] + } + r, _ := combineBodyMedia(rb, "application/json", rm, mi.mType, mimeBoundary) + return r, nil + } + } + cleanup = func() { combined.Close() } + reqHeaders.Set("Content-Type", ctype) + body = combined + } + if mi.buffer != nil && mi.mType != "" && !mi.singleChunk { + reqHeaders.Set("X-Upload-Content-Type", mi.mType) + } + return body, getBody, cleanup +} + +// readerFunc returns a function that always returns an io.Reader that has the same +// contents as r, provided that can be done without consuming r. Otherwise, it +// returns nil. +// See http.NewRequest (in net/http/request.go). +func readerFunc(r io.Reader) func() io.Reader { + switch r := r.(type) { + case *bytes.Buffer: + buf := r.Bytes() + return func() io.Reader { return bytes.NewReader(buf) } + case *bytes.Reader: + snapshot := *r + return func() io.Reader { r := snapshot; return &r } + case *strings.Reader: + snapshot := *r + return func() io.Reader { r := snapshot; return &r } + default: + return nil + } +} + +// ResumableUpload returns an appropriately configured ResumableUpload value if the +// upload is resumable, or nil otherwise. +func (mi *MediaInfo) ResumableUpload(locURI string) *ResumableUpload { + if mi == nil || mi.singleChunk { + return nil + } + return &ResumableUpload{ + URI: locURI, + Media: mi.buffer, + MediaType: mi.mType, + Callback: func(curr int64) { + if mi.progressUpdater != nil { + mi.progressUpdater(curr, mi.size) + } + }, + } +} + +// SetGetBody sets the GetBody field of req to f. This was once needed +// to gracefully support Go 1.7 and earlier which didn't have that +// field. +// +// Deprecated: the code generator no longer uses this as of +// 2019-02-19. Nothing else should be calling this anyway, but we +// won't delete this immediately; it will be deleted in as early as 6 +// months. +func SetGetBody(req *http.Request, f func() (io.ReadCloser, error)) { + req.GetBody = f +} diff --git a/vendor/google.golang.org/api/gensupport/params.go b/vendor/google.golang.org/api/gensupport/params.go new file mode 100644 index 000000000000..0e878a4255bf --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/params.go @@ -0,0 +1,51 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gensupport + +import ( + "net/url" + + "google.golang.org/api/googleapi" +) + +// URLParams is a simplified replacement for url.Values +// that safely builds up URL parameters for encoding. +type URLParams map[string][]string + +// Get returns the first value for the given key, or "". +func (u URLParams) Get(key string) string { + vs := u[key] + if len(vs) == 0 { + return "" + } + return vs[0] +} + +// Set sets the key to value. +// It replaces any existing values. +func (u URLParams) Set(key, value string) { + u[key] = []string{value} +} + +// SetMulti sets the key to an array of values. +// It replaces any existing values. +// Note that values must not be modified after calling SetMulti +// so the caller is responsible for making a copy if necessary. +func (u URLParams) SetMulti(key string, values []string) { + u[key] = values +} + +// Encode encodes the values into ``URL encoded'' form +// ("bar=baz&foo=quux") sorted by key. +func (u URLParams) Encode() string { + return url.Values(u).Encode() +} + +// SetOptions sets the URL params and any additional call options. +func SetOptions(u URLParams, opts ...googleapi.CallOption) { + for _, o := range opts { + u.Set(o.Get()) + } +} diff --git a/vendor/google.golang.org/api/gensupport/resumable.go b/vendor/google.golang.org/api/gensupport/resumable.go new file mode 100644 index 000000000000..2552a6acaca9 --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/resumable.go @@ -0,0 +1,216 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gensupport + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "sync" + "time" +) + +const ( + // statusTooManyRequests is returned by the storage API if the + // per-project limits have been temporarily exceeded. The request + // should be retried. + // https://cloud.google.com/storage/docs/json_api/v1/status-codes#standardcodes + statusTooManyRequests = 429 +) + +// ResumableUpload is used by the generated APIs to provide resumable uploads. +// It is not used by developers directly. +type ResumableUpload struct { + Client *http.Client + // URI is the resumable resource destination provided by the server after specifying "&uploadType=resumable". + URI string + UserAgent string // User-Agent for header of the request + // Media is the object being uploaded. + Media *MediaBuffer + // MediaType defines the media type, e.g. "image/jpeg". + MediaType string + + mu sync.Mutex // guards progress + progress int64 // number of bytes uploaded so far + + // Callback is an optional function that will be periodically called with the cumulative number of bytes uploaded. + Callback func(int64) + + // If not specified, a default exponential backoff strategy will be used. + Backoff BackoffStrategy +} + +// Progress returns the number of bytes uploaded at this point. +func (rx *ResumableUpload) Progress() int64 { + rx.mu.Lock() + defer rx.mu.Unlock() + return rx.progress +} + +// doUploadRequest performs a single HTTP request to upload data. +// off specifies the offset in rx.Media from which data is drawn. +// size is the number of bytes in data. +// final specifies whether data is the final chunk to be uploaded. +func (rx *ResumableUpload) doUploadRequest(ctx context.Context, data io.Reader, off, size int64, final bool) (*http.Response, error) { + req, err := http.NewRequest("POST", rx.URI, data) + if err != nil { + return nil, err + } + + req.ContentLength = size + var contentRange string + if final { + if size == 0 { + contentRange = fmt.Sprintf("bytes */%v", off) + } else { + contentRange = fmt.Sprintf("bytes %v-%v/%v", off, off+size-1, off+size) + } + } else { + contentRange = fmt.Sprintf("bytes %v-%v/*", off, off+size-1) + } + req.Header.Set("Content-Range", contentRange) + req.Header.Set("Content-Type", rx.MediaType) + req.Header.Set("User-Agent", rx.UserAgent) + + // Google's upload endpoint uses status code 308 for a + // different purpose than the "308 Permanent Redirect" + // since-standardized in RFC 7238. Because of the conflict in + // semantics, Google added this new request header which + // causes it to not use "308" and instead reply with 200 OK + // and sets the upload-specific "X-HTTP-Status-Code-Override: + // 308" response header. + req.Header.Set("X-GUploader-No-308", "yes") + + return SendRequest(ctx, rx.Client, req) +} + +func statusResumeIncomplete(resp *http.Response) bool { + // This is how the server signals "status resume incomplete" + // when X-GUploader-No-308 is set to "yes": + return resp != nil && resp.Header.Get("X-Http-Status-Code-Override") == "308" +} + +// reportProgress calls a user-supplied callback to report upload progress. +// If old==updated, the callback is not called. +func (rx *ResumableUpload) reportProgress(old, updated int64) { + if updated-old == 0 { + return + } + rx.mu.Lock() + rx.progress = updated + rx.mu.Unlock() + if rx.Callback != nil { + rx.Callback(updated) + } +} + +// transferChunk performs a single HTTP request to upload a single chunk from rx.Media. +func (rx *ResumableUpload) transferChunk(ctx context.Context) (*http.Response, error) { + chunk, off, size, err := rx.Media.Chunk() + + done := err == io.EOF + if !done && err != nil { + return nil, err + } + + res, err := rx.doUploadRequest(ctx, chunk, off, int64(size), done) + if err != nil { + return res, err + } + + // We sent "X-GUploader-No-308: yes" (see comment elsewhere in + // this file), so we don't expect to get a 308. + if res.StatusCode == 308 { + return nil, errors.New("unexpected 308 response status code") + } + + if res.StatusCode == http.StatusOK { + rx.reportProgress(off, off+int64(size)) + } + + if statusResumeIncomplete(res) { + rx.Media.Next() + } + return res, nil +} + +func contextDone(ctx context.Context) bool { + select { + case <-ctx.Done(): + return true + default: + return false + } +} + +// Upload starts the process of a resumable upload with a cancellable context. +// It retries using the provided back off strategy until cancelled or the +// strategy indicates to stop retrying. +// It is called from the auto-generated API code and is not visible to the user. +// Before sending an HTTP request, Upload calls any registered hook functions, +// and calls the returned functions after the request returns (see send.go). +// rx is private to the auto-generated API code. +// Exactly one of resp or err will be nil. If resp is non-nil, the caller must call resp.Body.Close. +func (rx *ResumableUpload) Upload(ctx context.Context) (resp *http.Response, err error) { + var pause time.Duration + backoff := rx.Backoff + if backoff == nil { + backoff = DefaultBackoffStrategy() + } + + for { + // Ensure that we return in the case of cancelled context, even if pause is 0. + if contextDone(ctx) { + return nil, ctx.Err() + } + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(pause): + } + + resp, err = rx.transferChunk(ctx) + + var status int + if resp != nil { + status = resp.StatusCode + } + + // Check if we should retry the request. + if shouldRetry(status, err) { + var retry bool + pause, retry = backoff.Pause() + if retry { + if resp != nil && resp.Body != nil { + resp.Body.Close() + } + continue + } + } + + // If the chunk was uploaded successfully, but there's still + // more to go, upload the next chunk without any delay. + if statusResumeIncomplete(resp) { + pause = 0 + backoff.Reset() + resp.Body.Close() + continue + } + + // It's possible for err and resp to both be non-nil here, but we expose a simpler + // contract to our callers: exactly one of resp and err will be non-nil. This means + // that any response body must be closed here before returning a non-nil error. + if err != nil { + if resp != nil && resp.Body != nil { + resp.Body.Close() + } + return nil, err + } + + return resp, nil + } +} diff --git a/vendor/google.golang.org/api/gensupport/retry.go b/vendor/google.golang.org/api/gensupport/retry.go new file mode 100644 index 000000000000..fdde3f42c699 --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/retry.go @@ -0,0 +1,84 @@ +// Copyright 2017 Google LLC +// +// 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 gensupport + +import ( + "context" + "io" + "net" + "net/http" + "time" +) + +// Retry invokes the given function, retrying it multiple times if the connection failed or +// the HTTP status response indicates the request should be attempted again. ctx may be nil. +func Retry(ctx context.Context, f func() (*http.Response, error), backoff BackoffStrategy) (*http.Response, error) { + for { + resp, err := f() + + var status int + if resp != nil { + status = resp.StatusCode + } + + // Return if we shouldn't retry. + pause, retry := backoff.Pause() + if !shouldRetry(status, err) || !retry { + return resp, err + } + + // Ensure the response body is closed, if any. + if resp != nil && resp.Body != nil { + resp.Body.Close() + } + + // Pause, but still listen to ctx.Done if context is not nil. + var done <-chan struct{} + if ctx != nil { + done = ctx.Done() + } + select { + case <-done: + return nil, ctx.Err() + case <-time.After(pause): + } + } +} + +// DefaultBackoffStrategy returns a default strategy to use for retrying failed upload requests. +func DefaultBackoffStrategy() BackoffStrategy { + return &ExponentialBackoff{ + Base: 250 * time.Millisecond, + Max: 16 * time.Second, + } +} + +// shouldRetry returns true if the HTTP response / error indicates that the +// request should be attempted again. +func shouldRetry(status int, err error) bool { + if 500 <= status && status <= 599 { + return true + } + if status == statusTooManyRequests { + return true + } + if err == io.ErrUnexpectedEOF { + return true + } + if err, ok := err.(net.Error); ok { + return err.Temporary() + } + return false +} diff --git a/vendor/google.golang.org/api/gensupport/send.go b/vendor/google.golang.org/api/gensupport/send.go new file mode 100644 index 000000000000..5799393093d4 --- /dev/null +++ b/vendor/google.golang.org/api/gensupport/send.go @@ -0,0 +1,87 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gensupport + +import ( + "context" + "encoding/json" + "errors" + "net/http" +) + +// Hook is the type of a function that is called once before each HTTP request +// that is sent by a generated API. It returns a function that is called after +// the request returns. +// Hooks are not called if the context is nil. +type Hook func(ctx context.Context, req *http.Request) func(resp *http.Response) + +var hooks []Hook + +// RegisterHook registers a Hook to be called before each HTTP request by a +// generated API. Hooks are called in the order they are registered. Each +// hook can return a function; if it is non-nil, it is called after the HTTP +// request returns. These functions are called in the reverse order. +// RegisterHook should not be called concurrently with itself or SendRequest. +func RegisterHook(h Hook) { + hooks = append(hooks, h) +} + +// SendRequest sends a single HTTP request using the given client. +// If ctx is non-nil, it calls all hooks, then sends the request with +// req.WithContext, then calls any functions returned by the hooks in +// reverse order. +func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + // Disallow Accept-Encoding because it interferes with the automatic gzip handling + // done by the default http.Transport. See https://github.com/google/google-api-go-client/issues/219. + if _, ok := req.Header["Accept-Encoding"]; ok { + return nil, errors.New("google api: custom Accept-Encoding headers not allowed") + } + if ctx == nil { + return client.Do(req) + } + // Call hooks in order of registration, store returned funcs. + post := make([]func(resp *http.Response), len(hooks)) + for i, h := range hooks { + fn := h(ctx, req) + post[i] = fn + } + + // Send request. + resp, err := send(ctx, client, req) + + // Call returned funcs in reverse order. + for i := len(post) - 1; i >= 0; i-- { + if fn := post[i]; fn != nil { + fn(resp) + } + } + return resp, err +} + +func send(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + if client == nil { + client = http.DefaultClient + } + resp, err := client.Do(req.WithContext(ctx)) + // If we got an error, and the context has been canceled, + // the context's error is probably more useful. + if err != nil { + select { + case <-ctx.Done(): + err = ctx.Err() + default: + } + } + return resp, err +} + +// DecodeResponse decodes the body of res into target. If there is no body, +// target is unchanged. +func DecodeResponse(target interface{}, res *http.Response) error { + if res.StatusCode == http.StatusNoContent { + return nil + } + return json.NewDecoder(res.Body).Decode(target) +} diff --git a/vendor/google.golang.org/api/googleapi/googleapi.go b/vendor/google.golang.org/api/googleapi/googleapi.go new file mode 100644 index 000000000000..ab53767624a3 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/googleapi.go @@ -0,0 +1,403 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package googleapi contains the common code shared by all Google API +// libraries. +package googleapi // import "google.golang.org/api/googleapi" + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strings" + + "google.golang.org/api/googleapi/internal/uritemplates" +) + +// ContentTyper is an interface for Readers which know (or would like +// to override) their Content-Type. If a media body doesn't implement +// ContentTyper, the type is sniffed from the content using +// http.DetectContentType. +type ContentTyper interface { + ContentType() string +} + +// A SizeReaderAt is a ReaderAt with a Size method. +// An io.SectionReader implements SizeReaderAt. +type SizeReaderAt interface { + io.ReaderAt + Size() int64 +} + +// ServerResponse is embedded in each Do response and +// provides the HTTP status code and header sent by the server. +type ServerResponse struct { + // HTTPStatusCode is the server's response status code. When using a + // resource method's Do call, this will always be in the 2xx range. + HTTPStatusCode int + // Header contains the response header fields from the server. + Header http.Header +} + +const ( + // Version defines the gax version being used. This is typically sent + // in an HTTP header to services. + Version = "0.5" + + // UserAgent is the header string used to identify this package. + UserAgent = "google-api-go-client/" + Version + + // DefaultUploadChunkSize is the default chunk size to use for resumable + // uploads if not specified by the user. + DefaultUploadChunkSize = 8 * 1024 * 1024 + + // MinUploadChunkSize is the minimum chunk size that can be used for + // resumable uploads. All user-specified chunk sizes must be multiple of + // this value. + MinUploadChunkSize = 256 * 1024 +) + +// Error contains an error response from the server. +type Error struct { + // Code is the HTTP response status code and will always be populated. + Code int `json:"code"` + // Message is the server response message and is only populated when + // explicitly referenced by the JSON server response. + Message string `json:"message"` + // Body is the raw response returned by the server. + // It is often but not always JSON, depending on how the request fails. + Body string + // Header contains the response header fields from the server. + Header http.Header + + Errors []ErrorItem +} + +// ErrorItem is a detailed error code & message from the Google API frontend. +type ErrorItem struct { + // Reason is the typed error code. For example: "some_example". + Reason string `json:"reason"` + // Message is the human-readable description of the error. + Message string `json:"message"` +} + +func (e *Error) Error() string { + if len(e.Errors) == 0 && e.Message == "" { + return fmt.Sprintf("googleapi: got HTTP response code %d with body: %v", e.Code, e.Body) + } + var buf bytes.Buffer + fmt.Fprintf(&buf, "googleapi: Error %d: ", e.Code) + if e.Message != "" { + fmt.Fprintf(&buf, "%s", e.Message) + } + if len(e.Errors) == 0 { + return strings.TrimSpace(buf.String()) + } + if len(e.Errors) == 1 && e.Errors[0].Message == e.Message { + fmt.Fprintf(&buf, ", %s", e.Errors[0].Reason) + return buf.String() + } + fmt.Fprintln(&buf, "\nMore details:") + for _, v := range e.Errors { + fmt.Fprintf(&buf, "Reason: %s, Message: %s\n", v.Reason, v.Message) + } + return buf.String() +} + +type errorReply struct { + Error *Error `json:"error"` +} + +// CheckResponse returns an error (of type *Error) if the response +// status code is not 2xx. +func CheckResponse(res *http.Response) error { + if res.StatusCode >= 200 && res.StatusCode <= 299 { + return nil + } + slurp, err := ioutil.ReadAll(res.Body) + if err == nil { + jerr := new(errorReply) + err = json.Unmarshal(slurp, jerr) + if err == nil && jerr.Error != nil { + if jerr.Error.Code == 0 { + jerr.Error.Code = res.StatusCode + } + jerr.Error.Body = string(slurp) + return jerr.Error + } + } + return &Error{ + Code: res.StatusCode, + Body: string(slurp), + Header: res.Header, + } +} + +// IsNotModified reports whether err is the result of the +// server replying with http.StatusNotModified. +// Such error values are sometimes returned by "Do" methods +// on calls when If-None-Match is used. +func IsNotModified(err error) bool { + if err == nil { + return false + } + ae, ok := err.(*Error) + return ok && ae.Code == http.StatusNotModified +} + +// CheckMediaResponse returns an error (of type *Error) if the response +// status code is not 2xx. Unlike CheckResponse it does not assume the +// body is a JSON error document. +// It is the caller's responsibility to close res.Body. +func CheckMediaResponse(res *http.Response) error { + if res.StatusCode >= 200 && res.StatusCode <= 299 { + return nil + } + slurp, _ := ioutil.ReadAll(io.LimitReader(res.Body, 1<<20)) + return &Error{ + Code: res.StatusCode, + Body: string(slurp), + } +} + +// MarshalStyle defines whether to marshal JSON with a {"data": ...} wrapper. +type MarshalStyle bool + +// WithDataWrapper marshals JSON with a {"data": ...} wrapper. +var WithDataWrapper = MarshalStyle(true) + +// WithoutDataWrapper marshals JSON without a {"data": ...} wrapper. +var WithoutDataWrapper = MarshalStyle(false) + +func (wrap MarshalStyle) JSONReader(v interface{}) (io.Reader, error) { + buf := new(bytes.Buffer) + if wrap { + buf.Write([]byte(`{"data": `)) + } + err := json.NewEncoder(buf).Encode(v) + if err != nil { + return nil, err + } + if wrap { + buf.Write([]byte(`}`)) + } + return buf, nil +} + +// ProgressUpdater is a function that is called upon every progress update of a resumable upload. +// This is the only part of a resumable upload (from googleapi) that is usable by the developer. +// The remaining usable pieces of resumable uploads is exposed in each auto-generated API. +type ProgressUpdater func(current, total int64) + +// MediaOption defines the interface for setting media options. +type MediaOption interface { + setOptions(o *MediaOptions) +} + +type contentTypeOption string + +func (ct contentTypeOption) setOptions(o *MediaOptions) { + o.ContentType = string(ct) + if o.ContentType == "" { + o.ForceEmptyContentType = true + } +} + +// ContentType returns a MediaOption which sets the Content-Type header for media uploads. +// If ctype is empty, the Content-Type header will be omitted. +func ContentType(ctype string) MediaOption { + return contentTypeOption(ctype) +} + +type chunkSizeOption int + +func (cs chunkSizeOption) setOptions(o *MediaOptions) { + size := int(cs) + if size%MinUploadChunkSize != 0 { + size += MinUploadChunkSize - (size % MinUploadChunkSize) + } + o.ChunkSize = size +} + +// ChunkSize returns a MediaOption which sets the chunk size for media uploads. +// size will be rounded up to the nearest multiple of 256K. +// Media which contains fewer than size bytes will be uploaded in a single request. +// Media which contains size bytes or more will be uploaded in separate chunks. +// If size is zero, media will be uploaded in a single request. +func ChunkSize(size int) MediaOption { + return chunkSizeOption(size) +} + +// MediaOptions stores options for customizing media upload. It is not used by developers directly. +type MediaOptions struct { + ContentType string + ForceEmptyContentType bool + + ChunkSize int +} + +// ProcessMediaOptions stores options from opts in a MediaOptions. +// It is not used by developers directly. +func ProcessMediaOptions(opts []MediaOption) *MediaOptions { + mo := &MediaOptions{ChunkSize: DefaultUploadChunkSize} + for _, o := range opts { + o.setOptions(mo) + } + return mo +} + +// ResolveRelative resolves relatives such as "http://www.golang.org/" and +// "topics/myproject/mytopic" into a single string, such as +// "http://www.golang.org/topics/myproject/mytopic". It strips all parent +// references (e.g. ../..) as well as anything after the host +// (e.g. /bar/gaz gets stripped out of foo.com/bar/gaz). +func ResolveRelative(basestr, relstr string) string { + u, _ := url.Parse(basestr) + afterColonPath := "" + if i := strings.IndexRune(relstr, ':'); i > 0 { + afterColonPath = relstr[i+1:] + relstr = relstr[:i] + } + rel, _ := url.Parse(relstr) + u = u.ResolveReference(rel) + us := u.String() + if afterColonPath != "" { + us = fmt.Sprintf("%s:%s", us, afterColonPath) + } + us = strings.Replace(us, "%7B", "{", -1) + us = strings.Replace(us, "%7D", "}", -1) + us = strings.Replace(us, "%2A", "*", -1) + return us +} + +// Expand subsitutes any {encoded} strings in the URL passed in using +// the map supplied. +// +// This calls SetOpaque to avoid encoding of the parameters in the URL path. +func Expand(u *url.URL, expansions map[string]string) { + escaped, unescaped, err := uritemplates.Expand(u.Path, expansions) + if err == nil { + u.Path = unescaped + u.RawPath = escaped + } +} + +// CloseBody is used to close res.Body. +// Prior to calling Close, it also tries to Read a small amount to see an EOF. +// Not seeing an EOF can prevent HTTP Transports from reusing connections. +func CloseBody(res *http.Response) { + if res == nil || res.Body == nil { + return + } + // Justification for 3 byte reads: two for up to "\r\n" after + // a JSON/XML document, and then 1 to see EOF if we haven't yet. + // TODO(bradfitz): detect Go 1.3+ and skip these reads. + // See https://codereview.appspot.com/58240043 + // and https://codereview.appspot.com/49570044 + buf := make([]byte, 1) + for i := 0; i < 3; i++ { + _, err := res.Body.Read(buf) + if err != nil { + break + } + } + res.Body.Close() + +} + +// VariantType returns the type name of the given variant. +// If the map doesn't contain the named key or the value is not a []interface{}, "" is returned. +// This is used to support "variant" APIs that can return one of a number of different types. +func VariantType(t map[string]interface{}) string { + s, _ := t["type"].(string) + return s +} + +// ConvertVariant uses the JSON encoder/decoder to fill in the struct 'dst' with the fields found in variant 'v'. +// This is used to support "variant" APIs that can return one of a number of different types. +// It reports whether the conversion was successful. +func ConvertVariant(v map[string]interface{}, dst interface{}) bool { + var buf bytes.Buffer + err := json.NewEncoder(&buf).Encode(v) + if err != nil { + return false + } + return json.Unmarshal(buf.Bytes(), dst) == nil +} + +// A Field names a field to be retrieved with a partial response. +// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// +// Partial responses can dramatically reduce the amount of data that must be sent to your application. +// In order to request partial responses, you can specify the full list of fields +// that your application needs by adding the Fields option to your request. +// +// Field strings use camelCase with leading lower-case characters to identify fields within the response. +// +// For example, if your response has a "NextPageToken" and a slice of "Items" with "Id" fields, +// you could request just those fields like this: +// +// svc.Events.List().Fields("nextPageToken", "items/id").Do() +// +// or if you were also interested in each Item's "Updated" field, you can combine them like this: +// +// svc.Events.List().Fields("nextPageToken", "items(id,updated)").Do() +// +// More information about field formatting can be found here: +// https://developers.google.com/+/api/#fields-syntax +// +// Another way to find field names is through the Google API explorer: +// https://developers.google.com/apis-explorer/#p/ +type Field string + +// CombineFields combines fields into a single string. +func CombineFields(s []Field) string { + r := make([]string, len(s)) + for i, v := range s { + r[i] = string(v) + } + return strings.Join(r, ",") +} + +// A CallOption is an optional argument to an API call. +// It should be treated as an opaque value by users of Google APIs. +// +// A CallOption is something that configures an API call in a way that is +// not specific to that API; for instance, controlling the quota user for +// an API call is common across many APIs, and is thus a CallOption. +type CallOption interface { + Get() (key, value string) +} + +// QuotaUser returns a CallOption that will set the quota user for a call. +// The quota user can be used by server-side applications to control accounting. +// It can be an arbitrary string up to 40 characters, and will override UserIP +// if both are provided. +func QuotaUser(u string) CallOption { return quotaUser(u) } + +type quotaUser string + +func (q quotaUser) Get() (string, string) { return "quotaUser", string(q) } + +// UserIP returns a CallOption that will set the "userIp" parameter of a call. +// This should be the IP address of the originating request. +func UserIP(ip string) CallOption { return userIP(ip) } + +type userIP string + +func (i userIP) Get() (string, string) { return "userIp", string(i) } + +// Trace returns a CallOption that enables diagnostic tracing for a call. +// traceToken is an ID supplied by Google support. +func Trace(traceToken string) CallOption { return traceTok(traceToken) } + +type traceTok string + +func (t traceTok) Get() (string, string) { return "trace", "token:" + string(t) } + +// TODO: Fields too diff --git a/vendor/google.golang.org/api/googleapi/internal/uritemplates/LICENSE b/vendor/google.golang.org/api/googleapi/internal/uritemplates/LICENSE new file mode 100644 index 000000000000..de9c88cb65cb --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/internal/uritemplates/LICENSE @@ -0,0 +1,18 @@ +Copyright (c) 2013 Joshua Tacoma + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go b/vendor/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go new file mode 100644 index 000000000000..63bf0538301a --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go @@ -0,0 +1,248 @@ +// Copyright 2013 Joshua Tacoma. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package uritemplates is a level 3 implementation of RFC 6570 (URI +// Template, http://tools.ietf.org/html/rfc6570). +// uritemplates does not support composite values (in Go: slices or maps) +// and so does not qualify as a level 4 implementation. +package uritemplates + +import ( + "bytes" + "errors" + "regexp" + "strconv" + "strings" +) + +var ( + unreserved = regexp.MustCompile("[^A-Za-z0-9\\-._~]") + reserved = regexp.MustCompile("[^A-Za-z0-9\\-._~:/?#[\\]@!$&'()*+,;=]") + validname = regexp.MustCompile("^([A-Za-z0-9_\\.]|%[0-9A-Fa-f][0-9A-Fa-f])+$") + hex = []byte("0123456789ABCDEF") +) + +func pctEncode(src []byte) []byte { + dst := make([]byte, len(src)*3) + for i, b := range src { + buf := dst[i*3 : i*3+3] + buf[0] = 0x25 + buf[1] = hex[b/16] + buf[2] = hex[b%16] + } + return dst +} + +// pairWriter is a convenience struct which allows escaped and unescaped +// versions of the template to be written in parallel. +type pairWriter struct { + escaped, unescaped bytes.Buffer +} + +// Write writes the provided string directly without any escaping. +func (w *pairWriter) Write(s string) { + w.escaped.WriteString(s) + w.unescaped.WriteString(s) +} + +// Escape writes the provided string, escaping the string for the +// escaped output. +func (w *pairWriter) Escape(s string, allowReserved bool) { + w.unescaped.WriteString(s) + if allowReserved { + w.escaped.Write(reserved.ReplaceAllFunc([]byte(s), pctEncode)) + } else { + w.escaped.Write(unreserved.ReplaceAllFunc([]byte(s), pctEncode)) + } +} + +// Escaped returns the escaped string. +func (w *pairWriter) Escaped() string { + return w.escaped.String() +} + +// Unescaped returns the unescaped string. +func (w *pairWriter) Unescaped() string { + return w.unescaped.String() +} + +// A uriTemplate is a parsed representation of a URI template. +type uriTemplate struct { + raw string + parts []templatePart +} + +// parse parses a URI template string into a uriTemplate object. +func parse(rawTemplate string) (*uriTemplate, error) { + split := strings.Split(rawTemplate, "{") + parts := make([]templatePart, len(split)*2-1) + for i, s := range split { + if i == 0 { + if strings.Contains(s, "}") { + return nil, errors.New("unexpected }") + } + parts[i].raw = s + continue + } + subsplit := strings.Split(s, "}") + if len(subsplit) != 2 { + return nil, errors.New("malformed template") + } + expression := subsplit[0] + var err error + parts[i*2-1], err = parseExpression(expression) + if err != nil { + return nil, err + } + parts[i*2].raw = subsplit[1] + } + return &uriTemplate{ + raw: rawTemplate, + parts: parts, + }, nil +} + +type templatePart struct { + raw string + terms []templateTerm + first string + sep string + named bool + ifemp string + allowReserved bool +} + +type templateTerm struct { + name string + explode bool + truncate int +} + +func parseExpression(expression string) (result templatePart, err error) { + switch expression[0] { + case '+': + result.sep = "," + result.allowReserved = true + expression = expression[1:] + case '.': + result.first = "." + result.sep = "." + expression = expression[1:] + case '/': + result.first = "/" + result.sep = "/" + expression = expression[1:] + case ';': + result.first = ";" + result.sep = ";" + result.named = true + expression = expression[1:] + case '?': + result.first = "?" + result.sep = "&" + result.named = true + result.ifemp = "=" + expression = expression[1:] + case '&': + result.first = "&" + result.sep = "&" + result.named = true + result.ifemp = "=" + expression = expression[1:] + case '#': + result.first = "#" + result.sep = "," + result.allowReserved = true + expression = expression[1:] + default: + result.sep = "," + } + rawterms := strings.Split(expression, ",") + result.terms = make([]templateTerm, len(rawterms)) + for i, raw := range rawterms { + result.terms[i], err = parseTerm(raw) + if err != nil { + break + } + } + return result, err +} + +func parseTerm(term string) (result templateTerm, err error) { + // TODO(djd): Remove "*" suffix parsing once we check that no APIs have + // mistakenly used that attribute. + if strings.HasSuffix(term, "*") { + result.explode = true + term = term[:len(term)-1] + } + split := strings.Split(term, ":") + if len(split) == 1 { + result.name = term + } else if len(split) == 2 { + result.name = split[0] + var parsed int64 + parsed, err = strconv.ParseInt(split[1], 10, 0) + result.truncate = int(parsed) + } else { + err = errors.New("multiple colons in same term") + } + if !validname.MatchString(result.name) { + err = errors.New("not a valid name: " + result.name) + } + if result.explode && result.truncate > 0 { + err = errors.New("both explode and prefix modifers on same term") + } + return result, err +} + +// Expand expands a URI template with a set of values to produce the +// resultant URI. Two forms of the result are returned: one with all the +// elements escaped, and one with the elements unescaped. +func (t *uriTemplate) Expand(values map[string]string) (escaped, unescaped string) { + var w pairWriter + for _, p := range t.parts { + p.expand(&w, values) + } + return w.Escaped(), w.Unescaped() +} + +func (tp *templatePart) expand(w *pairWriter, values map[string]string) { + if len(tp.raw) > 0 { + w.Write(tp.raw) + return + } + var first = true + for _, term := range tp.terms { + value, exists := values[term.name] + if !exists { + continue + } + if first { + w.Write(tp.first) + first = false + } else { + w.Write(tp.sep) + } + tp.expandString(w, term, value) + } +} + +func (tp *templatePart) expandName(w *pairWriter, name string, empty bool) { + if tp.named { + w.Write(name) + if empty { + w.Write(tp.ifemp) + } else { + w.Write("=") + } + } +} + +func (tp *templatePart) expandString(w *pairWriter, t templateTerm, s string) { + if len(s) > t.truncate && t.truncate > 0 { + s = s[:t.truncate] + } + tp.expandName(w, t.name, len(s) == 0) + w.Escape(s, tp.allowReserved) +} diff --git a/vendor/google.golang.org/api/googleapi/internal/uritemplates/utils.go b/vendor/google.golang.org/api/googleapi/internal/uritemplates/utils.go new file mode 100644 index 000000000000..2e70b81543d0 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/internal/uritemplates/utils.go @@ -0,0 +1,17 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uritemplates + +// Expand parses then expands a URI template with a set of values to produce +// the resultant URI. Two forms of the result are returned: one with all the +// elements escaped, and one with the elements unescaped. +func Expand(path string, values map[string]string) (escaped, unescaped string, err error) { + template, err := parse(path) + if err != nil { + return "", "", err + } + escaped, unescaped = template.Expand(values) + return escaped, unescaped, nil +} diff --git a/vendor/google.golang.org/api/googleapi/transport/apikey.go b/vendor/google.golang.org/api/googleapi/transport/apikey.go new file mode 100644 index 000000000000..eca1ea250771 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/transport/apikey.go @@ -0,0 +1,38 @@ +// Copyright 2012 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package transport contains HTTP transports used to make +// authenticated API requests. +package transport + +import ( + "errors" + "net/http" +) + +// APIKey is an HTTP Transport which wraps an underlying transport and +// appends an API Key "key" parameter to the URL of outgoing requests. +type APIKey struct { + // Key is the API Key to set on requests. + Key string + + // Transport is the underlying HTTP transport. + // If nil, http.DefaultTransport is used. + Transport http.RoundTripper +} + +func (t *APIKey) RoundTrip(req *http.Request) (*http.Response, error) { + rt := t.Transport + if rt == nil { + rt = http.DefaultTransport + if rt == nil { + return nil, errors.New("googleapi/transport: no Transport specified or available") + } + } + newReq := *req + args := newReq.URL.Query() + args.Set("key", t.Key) + newReq.URL.RawQuery = args.Encode() + return rt.RoundTrip(&newReq) +} diff --git a/vendor/google.golang.org/api/googleapi/types.go b/vendor/google.golang.org/api/googleapi/types.go new file mode 100644 index 000000000000..a280e3021a15 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/types.go @@ -0,0 +1,202 @@ +// Copyright 2013 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package googleapi + +import ( + "encoding/json" + "errors" + "strconv" +) + +// Int64s is a slice of int64s that marshal as quoted strings in JSON. +type Int64s []int64 + +func (q *Int64s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + *q = append(*q, int64(v)) + } + return nil +} + +// Int32s is a slice of int32s that marshal as quoted strings in JSON. +type Int32s []int32 + +func (q *Int32s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return err + } + *q = append(*q, int32(v)) + } + return nil +} + +// Uint64s is a slice of uint64s that marshal as quoted strings in JSON. +type Uint64s []uint64 + +func (q *Uint64s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return err + } + *q = append(*q, uint64(v)) + } + return nil +} + +// Uint32s is a slice of uint32s that marshal as quoted strings in JSON. +type Uint32s []uint32 + +func (q *Uint32s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseUint(s, 10, 32) + if err != nil { + return err + } + *q = append(*q, uint32(v)) + } + return nil +} + +// Float64s is a slice of float64s that marshal as quoted strings in JSON. +type Float64s []float64 + +func (q *Float64s) UnmarshalJSON(raw []byte) error { + *q = (*q)[:0] + var ss []string + if err := json.Unmarshal(raw, &ss); err != nil { + return err + } + for _, s := range ss { + v, err := strconv.ParseFloat(s, 64) + if err != nil { + return err + } + *q = append(*q, float64(v)) + } + return nil +} + +func quotedList(n int, fn func(dst []byte, i int) []byte) ([]byte, error) { + dst := make([]byte, 0, 2+n*10) // somewhat arbitrary + dst = append(dst, '[') + for i := 0; i < n; i++ { + if i > 0 { + dst = append(dst, ',') + } + dst = append(dst, '"') + dst = fn(dst, i) + dst = append(dst, '"') + } + dst = append(dst, ']') + return dst, nil +} + +func (q Int64s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendInt(dst, q[i], 10) + }) +} + +func (q Int32s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendInt(dst, int64(q[i]), 10) + }) +} + +func (q Uint64s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendUint(dst, q[i], 10) + }) +} + +func (q Uint32s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendUint(dst, uint64(q[i]), 10) + }) +} + +func (q Float64s) MarshalJSON() ([]byte, error) { + return quotedList(len(q), func(dst []byte, i int) []byte { + return strconv.AppendFloat(dst, q[i], 'g', -1, 64) + }) +} + +// RawMessage is a raw encoded JSON value. +// It is identical to json.RawMessage, except it does not suffer from +// https://golang.org/issue/14493. +type RawMessage []byte + +// MarshalJSON returns m. +func (m RawMessage) MarshalJSON() ([]byte, error) { + return m, nil +} + +// UnmarshalJSON sets *m to a copy of data. +func (m *RawMessage) UnmarshalJSON(data []byte) error { + if m == nil { + return errors.New("googleapi.RawMessage: UnmarshalJSON on nil pointer") + } + *m = append((*m)[:0], data...) + return nil +} + +/* + * Helper routines for simplifying the creation of optional fields of basic type. + */ + +// 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 { return &v } + +// Int32 is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it. +func Int32(v int32) *int32 { return &v } + +// Int64 is a helper routine that allocates a new int64 value +// to store v and returns a pointer to it. +func Int64(v int64) *int64 { return &v } + +// Float64 is a helper routine that allocates a new float64 value +// to store v and returns a pointer to it. +func Float64(v float64) *float64 { return &v } + +// Uint32 is a helper routine that allocates a new uint32 value +// to store v and returns a pointer to it. +func Uint32(v uint32) *uint32 { return &v } + +// Uint64 is a helper routine that allocates a new uint64 value +// to store v and returns a pointer to it. +func Uint64(v uint64) *uint64 { return &v } + +// 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 { return &v } diff --git a/vendor/google.golang.org/api/internal/creds.go b/vendor/google.golang.org/api/internal/creds.go new file mode 100644 index 000000000000..69b8659fddbd --- /dev/null +++ b/vendor/google.golang.org/api/internal/creds.go @@ -0,0 +1,102 @@ +// Copyright 2017 Google LLC +// +// 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 internal + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + + "golang.org/x/oauth2" + + "golang.org/x/oauth2/google" +) + +// Creds returns credential information obtained from DialSettings, or if none, then +// it returns default credential information. +func Creds(ctx context.Context, ds *DialSettings) (*google.Credentials, error) { + if ds.Credentials != nil { + return ds.Credentials, nil + } + if ds.CredentialsJSON != nil { + return credentialsFromJSON(ctx, ds.CredentialsJSON, ds.Endpoint, ds.Scopes, ds.Audiences) + } + if ds.CredentialsFile != "" { + data, err := ioutil.ReadFile(ds.CredentialsFile) + if err != nil { + return nil, fmt.Errorf("cannot read credentials file: %v", err) + } + return credentialsFromJSON(ctx, data, ds.Endpoint, ds.Scopes, ds.Audiences) + } + if ds.TokenSource != nil { + return &google.Credentials{TokenSource: ds.TokenSource}, nil + } + cred, err := google.FindDefaultCredentials(ctx, ds.Scopes...) + if err != nil { + return nil, err + } + if len(cred.JSON) > 0 { + return credentialsFromJSON(ctx, cred.JSON, ds.Endpoint, ds.Scopes, ds.Audiences) + } + // For GAE and GCE, the JSON is empty so return the default credentials directly. + return cred, nil +} + +// JSON key file type. +const ( + serviceAccountKey = "service_account" +) + +// credentialsFromJSON returns a google.Credentials based on the input. +// +// - If the JSON is a service account and no scopes provided, returns self-signed JWT auth flow +// - Otherwise, returns OAuth 2.0 flow. +func credentialsFromJSON(ctx context.Context, data []byte, endpoint string, scopes []string, audiences []string) (*google.Credentials, error) { + cred, err := google.CredentialsFromJSON(ctx, data, scopes...) + if err != nil { + return nil, err + } + if len(data) > 0 && len(scopes) == 0 { + var f struct { + Type string `json:"type"` + // The rest JSON fields are omitted because they are not used. + } + if err := json.Unmarshal(cred.JSON, &f); err != nil { + return nil, err + } + if f.Type == serviceAccountKey { + ts, err := selfSignedJWTTokenSource(data, endpoint, audiences) + if err != nil { + return nil, err + } + cred.TokenSource = ts + } + } + return cred, err +} + +func selfSignedJWTTokenSource(data []byte, endpoint string, audiences []string) (oauth2.TokenSource, error) { + // Use the API endpoint as the default audience + audience := endpoint + if len(audiences) > 0 { + // TODO(shinfan): Update golang oauth to support multiple audiences. + if len(audiences) > 1 { + return nil, fmt.Errorf("multiple audiences support is not implemented") + } + audience = audiences[0] + } + return google.JWTAccessTokenSourceFromJSON(data, audience) +} diff --git a/vendor/google.golang.org/api/internal/pool.go b/vendor/google.golang.org/api/internal/pool.go new file mode 100644 index 000000000000..a4426dcb700f --- /dev/null +++ b/vendor/google.golang.org/api/internal/pool.go @@ -0,0 +1,61 @@ +// Copyright 2016 Google LLC +// +// 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 internal + +import ( + "errors" + + "google.golang.org/grpc/naming" +) + +// PoolResolver provides a fixed list of addresses to load balance between +// and does not provide further updates. +type PoolResolver struct { + poolSize int + dialOpt *DialSettings + ch chan []*naming.Update +} + +// NewPoolResolver returns a PoolResolver +// This is an EXPERIMENTAL API and may be changed or removed in the future. +func NewPoolResolver(size int, o *DialSettings) *PoolResolver { + return &PoolResolver{poolSize: size, dialOpt: o} +} + +// Resolve returns a Watcher for the endpoint defined by the DialSettings +// provided to NewPoolResolver. +func (r *PoolResolver) Resolve(target string) (naming.Watcher, error) { + if r.dialOpt.Endpoint == "" { + return nil, errors.New("no endpoint configured") + } + addrs := make([]*naming.Update, 0, r.poolSize) + for i := 0; i < r.poolSize; i++ { + addrs = append(addrs, &naming.Update{Op: naming.Add, Addr: r.dialOpt.Endpoint, Metadata: i}) + } + r.ch = make(chan []*naming.Update, 1) + r.ch <- addrs + return r, nil +} + +// Next returns a static list of updates on the first call, +// and blocks indefinitely until Close is called on subsequent calls. +func (r *PoolResolver) Next() ([]*naming.Update, error) { + return <-r.ch, nil +} + +// Close releases resources associated with the pool and causes Next to unblock. +func (r *PoolResolver) Close() { + close(r.ch) +} diff --git a/vendor/google.golang.org/api/internal/service-account.json b/vendor/google.golang.org/api/internal/service-account.json new file mode 100644 index 000000000000..6b36a92961ea --- /dev/null +++ b/vendor/google.golang.org/api/internal/service-account.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "project_id", + "private_key_id": "private_key_id", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzd9ZdbPLAR4/g\nj+Rodu15kEasMpxf/Mz+gKRb2fmgR2Y18Y/iRBYZ4SkmF2pBSfzvwE/aTCzSPBGl\njHhPzohXnSN029eWoItmxVONlqCbR29pD07aLzv08LGeIGdHIEdhVjhvRwTkYZIF\ndXmlHNDRUU/EbJN9D+3ahw22BNnC4PaDgfIWTs3xIlTCSf2rL39I4DSNLTS/LzxK\n/XrQfBMtfwMWwyQaemXbc7gRgzOy8L56wa1W1zyXx99th97j1bLnoAXBGplhB4Co\n25ohyDAuhxRm+XGMEaO0Mzo7u97kvhj48a569RH1QRhOf7EBf60jO4h5eOmfi5P5\nPV3l7041AgMBAAECggEAEZ0RTNoEeRqM5F067YW+iM/AH+ZXspP9Cn1VpC4gcbqQ\nLXsnw+0qvh97CmIB66Z3TJBzRdl0DK4YjUbcB/kdKHwjnrR01DOtesijCqJd4N+B\n762w73jzSXbV9872U+S3HLZ5k3JE6KUqz55X8fyCAgkY6w4862lEzs2yasrPFHEV\nRoQp3PM0Miif8R3hGDhOWcHxcobullthG6JHAQFfc1ctwEjZI4TK0iWqlzfWGyKN\nT9UgvjUDud5cGvS9el0AiLN6keAf77tcPn1zetUVhxN1KN4bVAm1Q+6O8esl63Rj\n7JXpHzxaRnit9S6/aH/twHsGGtLg5Puw6jey6xs4AQKBgQD2JNy1wzewCRkD+jug\n8CHbJ+LIJVRNIaWa/RK1QD8/UjmFPkIzRQSF3AKC5mRAWSa2FL3yVK3N/DD7hazW\n85XSBB7IDcnoJnA9SkUeWwqQGkDx3EntlU3gX8Kn/+ofF8O9jLXxAa901MAVXVuf\n5YDzrl4PNE3bFnPCdiNmSdRfhQKBgQC6p4DsCpwqbeTu9f5ak9VW/fQP47Fgt+Mf\nwGjBnKP5PbbNJpHCfamF7jqSRH83Xy0KNssH7jD/NZ2oT594sMmiQPUC5ni9VYY6\nsuYB0JbD5Mq+EjKIVhYtxaQJ76LzHreEI+G4z6k3H7/hRpr3/C48n9G/uVkT9DbJ\noplxxEx68QKBgQCdJ23vcwO0Firtmi/GEmtbVHz70rGfSXNFoHz4UlvPXv0wsE5u\nE4vOt2i3EMhDOWh46odYGG6bzH+tp2xyFTW70Dui+QLHgPs6dpfoyLHWzZxXj5F3\n6lK9hgZvYvqk/XRRKmzjwnK2wjsdqOyeC1covlR5mqh20D/6kZkKbur0TQKBgAwy\nCZBimRWEnKKoW/gbFKNccGfhXqONID/g2Hdd/rC4QYth68AjacIgcJ9B7nX1uAGk\n1tsryvPB0w0+NpMyKdp6GAgaeuUUA3MuYSzZLiCagEyu77JMvaI7+Z3UlHcCGMd/\neK4Uk1/QqT7U2Cc/yN2ZK6E1QQa2vCWshA4U31JhAoGAbtbSSSsul1c+PsJ13Cfk\n6qVnqYzPqt23QTyOZmGAvUHH/M4xRiQpOE0cDF4t/r5PwenAQPQzTvMmWRzj6uAY\n3eaU0eAK7ZfoweCoOIAPnpFbbRLrXfoY46H7MYh7euWGXOKEpxz5yzuEkd9ByNUE\n86vSEidqbMIiXVgEgnu/k08=\n-----END PRIVATE KEY-----\n", + "client_email": "xyz@developer.gserviceaccount.com", + "client_id": "123", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://accounts.google.com/o/oauth2/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/xyz%40developer.gserviceaccount.com" +} diff --git a/vendor/google.golang.org/api/internal/settings.go b/vendor/google.golang.org/api/internal/settings.go new file mode 100644 index 000000000000..062301c65fd5 --- /dev/null +++ b/vendor/google.golang.org/api/internal/settings.go @@ -0,0 +1,96 @@ +// Copyright 2017 Google LLC +// +// 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 internal supports the options and transport packages. +package internal + +import ( + "errors" + "net/http" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "google.golang.org/grpc" +) + +// DialSettings holds information needed to establish a connection with a +// Google API service. +type DialSettings struct { + Endpoint string + Scopes []string + TokenSource oauth2.TokenSource + Credentials *google.Credentials + CredentialsFile string // if set, Token Source is ignored. + CredentialsJSON []byte + UserAgent string + APIKey string + Audiences []string + HTTPClient *http.Client + GRPCDialOpts []grpc.DialOption + GRPCConn *grpc.ClientConn + NoAuth bool + + // Google API system parameters. For more information please read: + // https://cloud.google.com/apis/docs/system-parameters + QuotaProject string + RequestReason string +} + +// Validate reports an error if ds is invalid. +func (ds *DialSettings) Validate() error { + hasCreds := ds.APIKey != "" || ds.TokenSource != nil || ds.CredentialsFile != "" || ds.Credentials != nil + if ds.NoAuth && hasCreds { + return errors.New("options.WithoutAuthentication is incompatible with any option that provides credentials") + } + // Credentials should not appear with other options. + // We currently allow TokenSource and CredentialsFile to coexist. + // TODO(jba): make TokenSource & CredentialsFile an error (breaking change). + nCreds := 0 + if ds.Credentials != nil { + nCreds++ + } + if ds.CredentialsJSON != nil { + nCreds++ + } + if ds.CredentialsFile != "" { + nCreds++ + } + if ds.APIKey != "" { + nCreds++ + } + if ds.TokenSource != nil { + nCreds++ + } + if len(ds.Scopes) > 0 && len(ds.Audiences) > 0 { + return errors.New("WithScopes is incompatible with WithAudience") + } + // Accept only one form of credentials, except we allow TokenSource and CredentialsFile for backwards compatibility. + if nCreds > 1 && !(nCreds == 2 && ds.TokenSource != nil && ds.CredentialsFile != "") { + return errors.New("multiple credential options provided") + } + if ds.HTTPClient != nil && ds.GRPCConn != nil { + return errors.New("WithHTTPClient is incompatible with WithGRPCConn") + } + if ds.HTTPClient != nil && ds.GRPCDialOpts != nil { + return errors.New("WithHTTPClient is incompatible with gRPC dial options") + } + if ds.HTTPClient != nil && ds.QuotaProject != "" { + return errors.New("WithHTTPClient is incompatible with QuotaProject") + } + if ds.HTTPClient != nil && ds.RequestReason != "" { + return errors.New("WithHTTPClient is incompatible with RequestReason") + } + + return nil +} diff --git a/vendor/google.golang.org/api/iterator/iterator.go b/vendor/google.golang.org/api/iterator/iterator.go new file mode 100644 index 000000000000..3c8ea7732af2 --- /dev/null +++ b/vendor/google.golang.org/api/iterator/iterator.go @@ -0,0 +1,231 @@ +// Copyright 2016 Google LLC +// +// 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 iterator provides support for standard Google API iterators. +// See https://github.com/GoogleCloudPlatform/gcloud-golang/wiki/Iterator-Guidelines. +package iterator + +import ( + "errors" + "fmt" + "reflect" +) + +// Done is returned by an iterator's Next method when the iteration is +// complete; when there are no more items to return. +var Done = errors.New("no more items in iterator") + +// We don't support mixed calls to Next and NextPage because they play +// with the paging state in incompatible ways. +var errMixed = errors.New("iterator: Next and NextPage called on same iterator") + +// PageInfo contains information about an iterator's paging state. +type PageInfo struct { + // Token is the token used to retrieve the next page of items from the + // API. You may set Token immediately after creating an iterator to + // begin iteration at a particular point. If Token is the empty string, + // the iterator will begin with the first eligible item. + // + // The result of setting Token after the first call to Next is undefined. + // + // After the underlying API method is called to retrieve a page of items, + // Token is set to the next-page token in the response. + Token string + + // MaxSize is the maximum number of items returned by a call to the API. + // Set MaxSize as a hint to optimize the buffering behavior of the iterator. + // If zero, the page size is determined by the underlying service. + // + // Use Pager to retrieve a page of a specific, exact size. + MaxSize int + + // The error state of the iterator. Manipulated by PageInfo.next and Pager. + // This is a latch: it starts as nil, and once set should never change. + err error + + // If true, no more calls to fetch should be made. Set to true when fetch + // returns an empty page token. The iterator is Done when this is true AND + // the buffer is empty. + atEnd bool + + // Function that fetches a page from the underlying service. It should pass + // the pageSize and pageToken arguments to the service, fill the buffer + // with the results from the call, and return the next-page token returned + // by the service. The function must not remove any existing items from the + // buffer. If the underlying RPC takes an int32 page size, pageSize should + // be silently truncated. + fetch func(pageSize int, pageToken string) (nextPageToken string, err error) + + // Function that returns the number of currently buffered items. + bufLen func() int + + // Function that returns the buffer, after setting the buffer variable to nil. + takeBuf func() interface{} + + // Set to true on first call to PageInfo.next or Pager.NextPage. Used to check + // for calls to both Next and NextPage with the same iterator. + nextCalled, nextPageCalled bool +} + +// NewPageInfo exposes internals for iterator implementations. +// It is not a stable interface. +var NewPageInfo = newPageInfo + +// If an iterator can support paging, its iterator-creating method should call +// this (via the NewPageInfo variable above). +// +// The fetch, bufLen and takeBuf arguments provide access to the +// iterator's internal slice of buffered items. They behave as described in +// PageInfo, above. +// +// The return value is the PageInfo.next method bound to the returned PageInfo value. +// (Returning it avoids exporting PageInfo.next.) +func newPageInfo(fetch func(int, string) (string, error), bufLen func() int, takeBuf func() interface{}) (*PageInfo, func() error) { + pi := &PageInfo{ + fetch: fetch, + bufLen: bufLen, + takeBuf: takeBuf, + } + return pi, pi.next +} + +// Remaining returns the number of items available before the iterator makes another API call. +func (pi *PageInfo) Remaining() int { return pi.bufLen() } + +// next provides support for an iterator's Next function. An iterator's Next +// should return the error returned by next if non-nil; else it can assume +// there is at least one item in its buffer, and it should return that item and +// remove it from the buffer. +func (pi *PageInfo) next() error { + pi.nextCalled = true + if pi.err != nil { // Once we get an error, always return it. + // TODO(jba): fix so users can retry on transient errors? Probably not worth it. + return pi.err + } + if pi.nextPageCalled { + pi.err = errMixed + return pi.err + } + // Loop until we get some items or reach the end. + for pi.bufLen() == 0 && !pi.atEnd { + if err := pi.fill(pi.MaxSize); err != nil { + pi.err = err + return pi.err + } + if pi.Token == "" { + pi.atEnd = true + } + } + // Either the buffer is non-empty or pi.atEnd is true (or both). + if pi.bufLen() == 0 { + // The buffer is empty and pi.atEnd is true, i.e. the service has no + // more items. + pi.err = Done + } + return pi.err +} + +// Call the service to fill the buffer, using size and pi.Token. Set pi.Token to the +// next-page token returned by the call. +// If fill returns a non-nil error, the buffer will be empty. +func (pi *PageInfo) fill(size int) error { + tok, err := pi.fetch(size, pi.Token) + if err != nil { + pi.takeBuf() // clear the buffer + return err + } + pi.Token = tok + return nil +} + +// Pageable is implemented by iterators that support paging. +type Pageable interface { + // PageInfo returns paging information associated with the iterator. + PageInfo() *PageInfo +} + +// Pager supports retrieving iterator items a page at a time. +type Pager struct { + pageInfo *PageInfo + pageSize int +} + +// NewPager returns a pager that uses iter. Calls to its NextPage method will +// obtain exactly pageSize items, unless fewer remain. The pageToken argument +// indicates where to start the iteration. Pass the empty string to start at +// the beginning, or pass a token retrieved from a call to Pager.NextPage. +// +// If you use an iterator with a Pager, you must not call Next on the iterator. +func NewPager(iter Pageable, pageSize int, pageToken string) *Pager { + p := &Pager{ + pageInfo: iter.PageInfo(), + pageSize: pageSize, + } + p.pageInfo.Token = pageToken + if pageSize <= 0 { + p.pageInfo.err = errors.New("iterator: page size must be positive") + } + return p +} + +// NextPage retrieves a sequence of items from the iterator and appends them +// to slicep, which must be a pointer to a slice of the iterator's item type. +// Exactly p.pageSize items will be appended, unless fewer remain. +// +// The first return value is the page token to use for the next page of items. +// If empty, there are no more pages. Aside from checking for the end of the +// iteration, the returned page token is only needed if the iteration is to be +// resumed a later time, in another context (possibly another process). +// +// The second return value is non-nil if an error occurred. It will never be +// the special iterator sentinel value Done. To recognize the end of the +// iteration, compare nextPageToken to the empty string. +// +// It is possible for NextPage to return a single zero-length page along with +// an empty page token when there are no more items in the iteration. +func (p *Pager) NextPage(slicep interface{}) (nextPageToken string, err error) { + p.pageInfo.nextPageCalled = true + if p.pageInfo.err != nil { + return "", p.pageInfo.err + } + if p.pageInfo.nextCalled { + p.pageInfo.err = errMixed + return "", p.pageInfo.err + } + if p.pageInfo.bufLen() > 0 { + return "", errors.New("must call NextPage with an empty buffer") + } + // The buffer must be empty here, so takeBuf is a no-op. We call it just to get + // the buffer's type. + wantSliceType := reflect.PtrTo(reflect.ValueOf(p.pageInfo.takeBuf()).Type()) + if slicep == nil { + return "", errors.New("nil passed to Pager.NextPage") + } + vslicep := reflect.ValueOf(slicep) + if vslicep.Type() != wantSliceType { + return "", fmt.Errorf("slicep should be of type %s, got %T", wantSliceType, slicep) + } + for p.pageInfo.bufLen() < p.pageSize { + if err := p.pageInfo.fill(p.pageSize - p.pageInfo.bufLen()); err != nil { + p.pageInfo.err = err + return "", p.pageInfo.err + } + if p.pageInfo.Token == "" { + break + } + } + e := vslicep.Elem() + e.Set(reflect.AppendSlice(e, reflect.ValueOf(p.pageInfo.takeBuf()))) + return p.pageInfo.Token, nil +} diff --git a/vendor/google.golang.org/api/option/credentials_go19.go b/vendor/google.golang.org/api/option/credentials_go19.go new file mode 100644 index 000000000000..0636a8294547 --- /dev/null +++ b/vendor/google.golang.org/api/option/credentials_go19.go @@ -0,0 +1,33 @@ +// Copyright 2018 Google LLC +// +// 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. + +// +build go1.9 + +package option + +import ( + "golang.org/x/oauth2/google" + "google.golang.org/api/internal" +) + +type withCreds google.Credentials + +func (w *withCreds) Apply(o *internal.DialSettings) { + o.Credentials = (*google.Credentials)(w) +} + +// WithCredentials returns a ClientOption that authenticates API calls. +func WithCredentials(creds *google.Credentials) ClientOption { + return (*withCreds)(creds) +} diff --git a/vendor/google.golang.org/api/option/credentials_notgo19.go b/vendor/google.golang.org/api/option/credentials_notgo19.go new file mode 100644 index 000000000000..74d3a4b5b918 --- /dev/null +++ b/vendor/google.golang.org/api/option/credentials_notgo19.go @@ -0,0 +1,32 @@ +// Copyright 2018 Google LLC +// +// 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. + +// +build !go1.9 + +package option + +import ( + "golang.org/x/oauth2/google" + "google.golang.org/api/internal" +) + +type withCreds google.DefaultCredentials + +func (w *withCreds) Apply(o *internal.DialSettings) { + o.Credentials = (*google.DefaultCredentials)(w) +} + +func WithCredentials(creds *google.DefaultCredentials) ClientOption { + return (*withCreds)(creds) +} diff --git a/vendor/google.golang.org/api/option/option.go b/vendor/google.golang.org/api/option/option.go new file mode 100644 index 000000000000..0a1c2dba9e38 --- /dev/null +++ b/vendor/google.golang.org/api/option/option.go @@ -0,0 +1,235 @@ +// Copyright 2017 Google LLC +// +// 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 option contains options for Google API clients. +package option + +import ( + "net/http" + + "golang.org/x/oauth2" + "google.golang.org/api/internal" + "google.golang.org/grpc" +) + +// A ClientOption is an option for a Google API client. +type ClientOption interface { + Apply(*internal.DialSettings) +} + +// WithTokenSource returns a ClientOption that specifies an OAuth2 token +// source to be used as the basis for authentication. +func WithTokenSource(s oauth2.TokenSource) ClientOption { + return withTokenSource{s} +} + +type withTokenSource struct{ ts oauth2.TokenSource } + +func (w withTokenSource) Apply(o *internal.DialSettings) { + o.TokenSource = w.ts +} + +type withCredFile string + +func (w withCredFile) Apply(o *internal.DialSettings) { + o.CredentialsFile = string(w) +} + +// WithCredentialsFile returns a ClientOption that authenticates +// API calls with the given service account or refresh token JSON +// credentials file. +func WithCredentialsFile(filename string) ClientOption { + return withCredFile(filename) +} + +// WithServiceAccountFile returns a ClientOption that uses a Google service +// account credentials file to authenticate. +// +// Deprecated: Use WithCredentialsFile instead. +func WithServiceAccountFile(filename string) ClientOption { + return WithCredentialsFile(filename) +} + +// WithCredentialsJSON returns a ClientOption that authenticates +// API calls with the given service account or refresh token JSON +// credentials. +func WithCredentialsJSON(p []byte) ClientOption { + return withCredentialsJSON(p) +} + +type withCredentialsJSON []byte + +func (w withCredentialsJSON) Apply(o *internal.DialSettings) { + o.CredentialsJSON = make([]byte, len(w)) + copy(o.CredentialsJSON, w) +} + +// WithEndpoint returns a ClientOption that overrides the default endpoint +// to be used for a service. +func WithEndpoint(url string) ClientOption { + return withEndpoint(url) +} + +type withEndpoint string + +func (w withEndpoint) Apply(o *internal.DialSettings) { + o.Endpoint = string(w) +} + +// WithScopes returns a ClientOption that overrides the default OAuth2 scopes +// to be used for a service. +func WithScopes(scope ...string) ClientOption { + return withScopes(scope) +} + +type withScopes []string + +func (w withScopes) Apply(o *internal.DialSettings) { + o.Scopes = make([]string, len(w)) + copy(o.Scopes, w) +} + +// WithUserAgent returns a ClientOption that sets the User-Agent. +func WithUserAgent(ua string) ClientOption { + return withUA(ua) +} + +type withUA string + +func (w withUA) Apply(o *internal.DialSettings) { o.UserAgent = string(w) } + +// WithHTTPClient returns a ClientOption that specifies the HTTP client to use +// as the basis of communications. This option may only be used with services +// that support HTTP as their communication transport. When used, the +// WithHTTPClient option takes precedent over all other supplied options. +func WithHTTPClient(client *http.Client) ClientOption { + return withHTTPClient{client} +} + +type withHTTPClient struct{ client *http.Client } + +func (w withHTTPClient) Apply(o *internal.DialSettings) { + o.HTTPClient = w.client +} + +// WithGRPCConn returns a ClientOption that specifies the gRPC client +// connection to use as the basis of communications. This option many only be +// used with services that support gRPC as their communication transport. When +// used, the WithGRPCConn option takes precedent over all other supplied +// options. +func WithGRPCConn(conn *grpc.ClientConn) ClientOption { + return withGRPCConn{conn} +} + +type withGRPCConn struct{ conn *grpc.ClientConn } + +func (w withGRPCConn) Apply(o *internal.DialSettings) { + o.GRPCConn = w.conn +} + +// WithGRPCDialOption returns a ClientOption that appends a new grpc.DialOption +// to an underlying gRPC dial. It does not work with WithGRPCConn. +func WithGRPCDialOption(opt grpc.DialOption) ClientOption { + return withGRPCDialOption{opt} +} + +type withGRPCDialOption struct{ opt grpc.DialOption } + +func (w withGRPCDialOption) Apply(o *internal.DialSettings) { + o.GRPCDialOpts = append(o.GRPCDialOpts, w.opt) +} + +// WithGRPCConnectionPool returns a ClientOption that creates a pool of gRPC +// connections that requests will be balanced between. +// This is an EXPERIMENTAL API and may be changed or removed in the future. +func WithGRPCConnectionPool(size int) ClientOption { + return withGRPCConnectionPool(size) +} + +type withGRPCConnectionPool int + +func (w withGRPCConnectionPool) Apply(o *internal.DialSettings) { + balancer := grpc.RoundRobin(internal.NewPoolResolver(int(w), o)) + o.GRPCDialOpts = append(o.GRPCDialOpts, grpc.WithBalancer(balancer)) +} + +// WithAPIKey returns a ClientOption that specifies an API key to be used +// as the basis for authentication. +// +// API Keys can only be used for JSON-over-HTTP APIs, including those under +// the import path google.golang.org/api/.... +func WithAPIKey(apiKey string) ClientOption { + return withAPIKey(apiKey) +} + +type withAPIKey string + +func (w withAPIKey) Apply(o *internal.DialSettings) { o.APIKey = string(w) } + +// WithAudiences returns a ClientOption that specifies an audience to be used +// as the audience field ("aud") for the JWT token authentication. +func WithAudiences(audience ...string) ClientOption { + return withAudiences(audience) +} + +type withAudiences []string + +func (w withAudiences) Apply(o *internal.DialSettings) { + o.Audiences = make([]string, len(w)) + copy(o.Audiences, w) +} + +// WithoutAuthentication returns a ClientOption that specifies that no +// authentication should be used. It is suitable only for testing and for +// accessing public resources, like public Google Cloud Storage buckets. +// It is an error to provide both WithoutAuthentication and any of WithAPIKey, +// WithTokenSource, WithCredentialsFile or WithServiceAccountFile. +func WithoutAuthentication() ClientOption { + return withoutAuthentication{} +} + +type withoutAuthentication struct{} + +func (w withoutAuthentication) Apply(o *internal.DialSettings) { o.NoAuth = true } + +// WithQuotaProject returns a ClientOption that specifies the project used +// for quota and billing purposes. +// +// For more information please read: +// https://cloud.google.com/apis/docs/system-parameters +func WithQuotaProject(quotaProject string) ClientOption { + return withQuotaProject(quotaProject) +} + +type withQuotaProject string + +func (w withQuotaProject) Apply(o *internal.DialSettings) { + o.QuotaProject = string(w) +} + +// WithRequestReason returns a ClientOption that specifies a reason for +// making the request, which is intended to be recorded in audit logging. +// An example reason would be a support-case ticket number. +// +// For more information please read: +// https://cloud.google.com/apis/docs/system-parameters +func WithRequestReason(requestReason string) ClientOption { + return withRequestReason(requestReason) +} + +type withRequestReason string + +func (w withRequestReason) Apply(o *internal.DialSettings) { + o.RequestReason = string(w) +} diff --git a/vendor/google.golang.org/api/storage/v1/storage-api.json b/vendor/google.golang.org/api/storage/v1/storage-api.json new file mode 100644 index 000000000000..e771f9b1340d --- /dev/null +++ b/vendor/google.golang.org/api/storage/v1/storage-api.json @@ -0,0 +1,4118 @@ +{ + "auth": { + "oauth2": { + "scopes": { + "https://www.googleapis.com/auth/cloud-platform": { + "description": "View and manage your data across Google Cloud Platform services" + }, + "https://www.googleapis.com/auth/cloud-platform.read-only": { + "description": "View your data across Google Cloud Platform services" + }, + "https://www.googleapis.com/auth/devstorage.full_control": { + "description": "Manage your data and permissions in Google Cloud Storage" + }, + "https://www.googleapis.com/auth/devstorage.read_only": { + "description": "View your data in Google Cloud Storage" + }, + "https://www.googleapis.com/auth/devstorage.read_write": { + "description": "Manage your data in Google Cloud Storage" + } + } + } + }, + "basePath": "/storage/v1/", + "baseUrl": "https://www.googleapis.com/storage/v1/", + "batchPath": "batch/storage/v1", + "description": "Stores and retrieves potentially large, immutable data objects.", + "discoveryVersion": "v1", + "documentationLink": "https://developers.google.com/storage/docs/json_api/", + "etag": "\"VPK3KBfpaEgZ16pozGOoMYfKc0U/0oTiRxFg5a8IRGYou40wPCps2h4\"", + "icons": { + "x16": "https://www.google.com/images/icons/product/cloud_storage-16.png", + "x32": "https://www.google.com/images/icons/product/cloud_storage-32.png" + }, + "id": "storage:v1", + "kind": "discovery#restDescription", + "labels": [ + "labs" + ], + "name": "storage", + "ownerDomain": "google.com", + "ownerName": "Google", + "parameters": { + "alt": { + "default": "json", + "description": "Data format for the response.", + "enum": [ + "json" + ], + "enumDescriptions": [ + "Responses with Content-Type of application/json" + ], + "location": "query", + "type": "string" + }, + "fields": { + "description": "Selector specifying which fields to include in a partial response.", + "location": "query", + "type": "string" + }, + "key": { + "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", + "location": "query", + "type": "string" + }, + "oauth_token": { + "description": "OAuth 2.0 token for the current user.", + "location": "query", + "type": "string" + }, + "prettyPrint": { + "default": "true", + "description": "Returns response with indentations and line breaks.", + "location": "query", + "type": "boolean" + }, + "quotaUser": { + "description": "An opaque string that represents a user for quota purposes. Must not exceed 40 characters.", + "location": "query", + "type": "string" + }, + "userIp": { + "description": "Deprecated. Please use quotaUser instead.", + "location": "query", + "type": "string" + } + }, + "protocol": "rest", + "resources": { + "bucketAccessControls": { + "methods": { + "delete": { + "description": "Permanently deletes the ACL entry for the specified entity on the specified bucket.", + "httpMethod": "DELETE", + "id": "storage.bucketAccessControls.delete", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl/{entity}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "description": "Returns the ACL entry for the specified entity on the specified bucket.", + "httpMethod": "GET", + "id": "storage.bucketAccessControls.get", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl/{entity}", + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "description": "Creates a new ACL entry on the specified bucket.", + "httpMethod": "POST", + "id": "storage.bucketAccessControls.insert", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl", + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "description": "Retrieves ACL entries on the specified bucket.", + "httpMethod": "GET", + "id": "storage.bucketAccessControls.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl", + "response": { + "$ref": "BucketAccessControls" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "description": "Patches an ACL entry on the specified bucket.", + "httpMethod": "PATCH", + "id": "storage.bucketAccessControls.patch", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl/{entity}", + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "description": "Updates an ACL entry on the specified bucket.", + "httpMethod": "PUT", + "id": "storage.bucketAccessControls.update", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/acl/{entity}", + "request": { + "$ref": "BucketAccessControl" + }, + "response": { + "$ref": "BucketAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "buckets": { + "methods": { + "delete": { + "description": "Permanently deletes an empty bucket.", + "httpMethod": "DELETE", + "id": "storage.buckets.delete", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "If set, only deletes the bucket if its metageneration matches this value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "If set, only deletes the bucket if its metageneration does not match this value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "description": "Returns metadata for the specified bucket.", + "httpMethod": "GET", + "id": "storage.buckets.get", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}", + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "getIamPolicy": { + "description": "Returns an IAM policy for the specified bucket.", + "httpMethod": "GET", + "id": "storage.buckets.getIamPolicy", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/iam", + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "description": "Creates a new bucket.", + "httpMethod": "POST", + "id": "storage.buckets.insert", + "parameterOrder": [ + "project" + ], + "parameters": { + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query", + "type": "string" + }, + "predefinedDefaultObjectAcl": { + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "project": { + "description": "A valid API project identifier.", + "location": "query", + "required": true, + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl, unless the bucket resource specifies acl or defaultObjectAcl properties, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request.", + "location": "query", + "type": "string" + } + }, + "path": "b", + "request": { + "$ref": "Bucket" + }, + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "description": "Retrieves a list of buckets for a given project.", + "httpMethod": "GET", + "id": "storage.buckets.list", + "parameterOrder": [ + "project" + ], + "parameters": { + "maxResults": { + "default": "1000", + "description": "Maximum number of buckets to return in a single response. The service will use this parameter or 1,000 items, whichever is smaller.", + "format": "uint32", + "location": "query", + "minimum": "0", + "type": "integer" + }, + "pageToken": { + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query", + "type": "string" + }, + "prefix": { + "description": "Filter results to buckets whose names begin with this prefix.", + "location": "query", + "type": "string" + }, + "project": { + "description": "A valid API project identifier.", + "location": "query", + "required": true, + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request.", + "location": "query", + "type": "string" + } + }, + "path": "b", + "response": { + "$ref": "Buckets" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "lockRetentionPolicy": { + "description": "Locks retention policy on a bucket.", + "httpMethod": "POST", + "id": "storage.buckets.lockRetentionPolicy", + "parameterOrder": [ + "bucket", + "ifMetagenerationMatch" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/lockRetentionPolicy", + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "patch": { + "description": "Patches a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", + "httpMethod": "PATCH", + "id": "storage.buckets.patch", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query", + "type": "string" + }, + "predefinedDefaultObjectAcl": { + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}", + "request": { + "$ref": "Bucket" + }, + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "setIamPolicy": { + "description": "Updates an IAM policy for the specified bucket.", + "httpMethod": "PUT", + "id": "storage.buckets.setIamPolicy", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/iam", + "request": { + "$ref": "Policy" + }, + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "testIamPermissions": { + "description": "Tests a set of permissions on the given bucket to see which, if any, are held by the caller.", + "httpMethod": "GET", + "id": "storage.buckets.testIamPermissions", + "parameterOrder": [ + "bucket", + "permissions" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "permissions": { + "description": "Permissions to test.", + "location": "query", + "repeated": true, + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/iam/testPermissions", + "response": { + "$ref": "TestIamPermissionsResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "update": { + "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", + "httpMethod": "PUT", + "id": "storage.buckets.update", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this bucket.", + "enum": [ + "authenticatedRead", + "private", + "projectPrivate", + "publicRead", + "publicReadWrite" + ], + "enumDescriptions": [ + "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + "Project team owners get OWNER access.", + "Project team members get access according to their roles.", + "Project team owners get OWNER access, and allUsers get READER access.", + "Project team owners get OWNER access, and allUsers get WRITER access." + ], + "location": "query", + "type": "string" + }, + "predefinedDefaultObjectAcl": { + "description": "Apply a predefined set of default object access controls to this bucket.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit owner, acl and defaultObjectAcl properties." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}", + "request": { + "$ref": "Bucket" + }, + "response": { + "$ref": "Bucket" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "channels": { + "methods": { + "stop": { + "description": "Stop watching resources through this channel", + "httpMethod": "POST", + "id": "storage.channels.stop", + "path": "channels/stop", + "request": { + "$ref": "Channel", + "parameterName": "resource" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + } + } + }, + "defaultObjectAccessControls": { + "methods": { + "delete": { + "description": "Permanently deletes the default object ACL entry for the specified entity on the specified bucket.", + "httpMethod": "DELETE", + "id": "storage.defaultObjectAccessControls.delete", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "description": "Returns the default object ACL entry for the specified entity on the specified bucket.", + "httpMethod": "GET", + "id": "storage.defaultObjectAccessControls.get", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "description": "Creates a new default object ACL entry on the specified bucket.", + "httpMethod": "POST", + "id": "storage.defaultObjectAccessControls.insert", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "description": "Retrieves default object ACL entries on the specified bucket.", + "httpMethod": "GET", + "id": "storage.defaultObjectAccessControls.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "If present, only return default ACL listing if the bucket's current metageneration matches this value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "If present, only return default ACL listing if the bucket's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl", + "response": { + "$ref": "ObjectAccessControls" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "description": "Patches a default object ACL entry on the specified bucket.", + "httpMethod": "PATCH", + "id": "storage.defaultObjectAccessControls.patch", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "description": "Updates a default object ACL entry on the specified bucket.", + "httpMethod": "PUT", + "id": "storage.defaultObjectAccessControls.update", + "parameterOrder": [ + "bucket", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/defaultObjectAcl/{entity}", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "notifications": { + "methods": { + "delete": { + "description": "Permanently deletes a notification subscription.", + "httpMethod": "DELETE", + "id": "storage.notifications.delete", + "parameterOrder": [ + "bucket", + "notification" + ], + "parameters": { + "bucket": { + "description": "The parent bucket of the notification.", + "location": "path", + "required": true, + "type": "string" + }, + "notification": { + "description": "ID of the notification to delete.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/notificationConfigs/{notification}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "description": "View a notification configuration.", + "httpMethod": "GET", + "id": "storage.notifications.get", + "parameterOrder": [ + "bucket", + "notification" + ], + "parameters": { + "bucket": { + "description": "The parent bucket of the notification.", + "location": "path", + "required": true, + "type": "string" + }, + "notification": { + "description": "Notification ID", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/notificationConfigs/{notification}", + "response": { + "$ref": "Notification" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "description": "Creates a notification subscription for a given bucket.", + "httpMethod": "POST", + "id": "storage.notifications.insert", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "The parent bucket of the notification.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/notificationConfigs", + "request": { + "$ref": "Notification" + }, + "response": { + "$ref": "Notification" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "list": { + "description": "Retrieves a list of notification subscriptions for a given bucket.", + "httpMethod": "GET", + "id": "storage.notifications.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of a Google Cloud Storage bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/notificationConfigs", + "response": { + "$ref": "Notifications" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + } + } + }, + "objectAccessControls": { + "methods": { + "delete": { + "description": "Permanently deletes the ACL entry for the specified entity on the specified object.", + "httpMethod": "DELETE", + "id": "storage.objectAccessControls.delete", + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl/{entity}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "get": { + "description": "Returns the ACL entry for the specified entity on the specified object.", + "httpMethod": "GET", + "id": "storage.objectAccessControls.get", + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl/{entity}", + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "insert": { + "description": "Creates a new ACL entry on the specified object.", + "httpMethod": "POST", + "id": "storage.objectAccessControls.insert", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "list": { + "description": "Retrieves ACL entries on the specified object.", + "httpMethod": "GET", + "id": "storage.objectAccessControls.list", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl", + "response": { + "$ref": "ObjectAccessControls" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "patch": { + "description": "Patches an ACL entry on the specified object.", + "httpMethod": "PATCH", + "id": "storage.objectAccessControls.patch", + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl/{entity}", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "update": { + "description": "Updates an ACL entry on the specified object.", + "httpMethod": "PUT", + "id": "storage.objectAccessControls.update", + "parameterOrder": [ + "bucket", + "object", + "entity" + ], + "parameters": { + "bucket": { + "description": "Name of a bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "entity": { + "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/acl/{entity}", + "request": { + "$ref": "ObjectAccessControl" + }, + "response": { + "$ref": "ObjectAccessControl" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "objects": { + "methods": { + "compose": { + "description": "Concatenates a list of existing objects into a new object in the same bucket.", + "httpMethod": "POST", + "id": "storage.objects.compose", + "parameterOrder": [ + "destinationBucket", + "destinationObject" + ], + "parameters": { + "destinationBucket": { + "description": "Name of the bucket containing the source objects. The destination object is stored in this bucket.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationObject": { + "description": "Name of the new object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationPredefinedAcl": { + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "kmsKeyName": { + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{destinationBucket}/o/{destinationObject}/compose", + "request": { + "$ref": "ComposeRequest" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "copy": { + "description": "Copies a source object to a destination object. Optionally overrides metadata.", + "httpMethod": "POST", + "id": "storage.objects.copy", + "parameterOrder": [ + "sourceBucket", + "sourceObject", + "destinationBucket", + "destinationObject" + ], + "parameters": { + "destinationBucket": { + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationObject": { + "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationPredefinedAcl": { + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the destination object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the destination object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceGenerationMatch": { + "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceGenerationNotMatch": { + "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceMetagenerationMatch": { + "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "sourceBucket": { + "description": "Name of the bucket in which to find the source object.", + "location": "path", + "required": true, + "type": "string" + }, + "sourceGeneration": { + "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "sourceObject": { + "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "delete": { + "description": "Deletes an object and its metadata. Deletions are permanent if versioning is not enabled for the bucket, or if the generation parameter is used.", + "httpMethod": "DELETE", + "id": "storage.objects.delete", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, permanently deletes a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "description": "Retrieves an object or its metadata.", + "httpMethod": "GET", + "id": "storage.objects.get", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}", + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsMediaDownload": true, + "useMediaDownloadService": true + }, + "getIamPolicy": { + "description": "Returns an IAM policy for the specified object.", + "httpMethod": "GET", + "id": "storage.objects.getIamPolicy", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/iam", + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "insert": { + "description": "Stores a new object and metadata.", + "httpMethod": "POST", + "id": "storage.objects.insert", + "mediaUpload": { + "accept": [ + "*/*" + ], + "protocols": { + "resumable": { + "multipart": true, + "path": "/resumable/upload/storage/v1/b/{bucket}/o" + }, + "simple": { + "multipart": true, + "path": "/upload/storage/v1/b/{bucket}/o" + } + } + }, + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + "location": "path", + "required": true, + "type": "string" + }, + "contentEncoding": { + "description": "If set, sets the contentEncoding property of the final object to this value. Setting this parameter is equivalent to setting the contentEncoding metadata property. This can be useful when uploading an object with uploadType=media to indicate the encoding of the content being uploaded.", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "kmsKeyName": { + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query", + "type": "string" + }, + "name": { + "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "query", + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsMediaUpload": true + }, + "list": { + "description": "Retrieves a list of objects matching the criteria.", + "httpMethod": "GET", + "id": "storage.objects.list", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which to look for objects.", + "location": "path", + "required": true, + "type": "string" + }, + "delimiter": { + "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + "location": "query", + "type": "string" + }, + "includeTrailingDelimiter": { + "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", + "location": "query", + "type": "boolean" + }, + "maxResults": { + "default": "1000", + "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + "format": "uint32", + "location": "query", + "minimum": "0", + "type": "integer" + }, + "pageToken": { + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query", + "type": "string" + }, + "prefix": { + "description": "Filter results to objects whose names begin with this prefix.", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + }, + "versions": { + "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + "location": "query", + "type": "boolean" + } + }, + "path": "b/{bucket}/o", + "response": { + "$ref": "Objects" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsSubscription": true + }, + "patch": { + "description": "Patches an object's metadata.", + "httpMethod": "PATCH", + "id": "storage.objects.patch", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request, for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "rewrite": { + "description": "Rewrites a source object to a destination object. Optionally overrides metadata.", + "httpMethod": "POST", + "id": "storage.objects.rewrite", + "parameterOrder": [ + "sourceBucket", + "sourceObject", + "destinationBucket", + "destinationObject" + ], + "parameters": { + "destinationBucket": { + "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationKmsKeyName": { + "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + "location": "query", + "type": "string" + }, + "destinationObject": { + "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "destinationPredefinedAcl": { + "description": "Apply a predefined set of access controls to the destination object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceGenerationMatch": { + "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceGenerationNotMatch": { + "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceMetagenerationMatch": { + "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifSourceMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "maxBytesRewrittenPerCall": { + "description": "The maximum number of bytes that will be rewritten per rewrite request. Most callers shouldn't need to specify this parameter - it is primarily in place to support testing. If specified the value must be an integral multiple of 1 MiB (1048576). Also, this only applies to requests where the source and destination span locations and/or storage classes. Finally, this value must not change across rewrite calls else you'll get an error that the rewriteToken is invalid.", + "format": "int64", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "rewriteToken": { + "description": "Include this field (from the previous rewrite response) on each rewrite request after the first one, until the rewrite response 'done' flag is true. Calls that provide a rewriteToken can omit all other request fields, but if included those fields must match the values provided in the first rewrite request.", + "location": "query", + "type": "string" + }, + "sourceBucket": { + "description": "Name of the bucket in which to find the source object.", + "location": "path", + "required": true, + "type": "string" + }, + "sourceGeneration": { + "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "sourceObject": { + "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "RewriteResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "setIamPolicy": { + "description": "Updates an IAM policy for the specified object.", + "httpMethod": "PUT", + "id": "storage.objects.setIamPolicy", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/iam", + "request": { + "$ref": "Policy" + }, + "response": { + "$ref": "Policy" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "testIamPermissions": { + "description": "Tests a set of permissions on the given object to see which, if any, are held by the caller.", + "httpMethod": "GET", + "id": "storage.objects.testIamPermissions", + "parameterOrder": [ + "bucket", + "object", + "permissions" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "permissions": { + "description": "Permissions to test.", + "location": "query", + "repeated": true, + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}/iam/testPermissions", + "response": { + "$ref": "TestIamPermissionsResponse" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "update": { + "description": "Updates an object's metadata.", + "httpMethod": "PUT", + "id": "storage.objects.update", + "parameterOrder": [ + "bucket", + "object" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which the object resides.", + "location": "path", + "required": true, + "type": "string" + }, + "generation": { + "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationMatch": { + "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifGenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "ifMetagenerationNotMatch": { + "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + "format": "int64", + "location": "query", + "type": "string" + }, + "object": { + "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + "location": "path", + "required": true, + "type": "string" + }, + "predefinedAcl": { + "description": "Apply a predefined set of access controls to this object.", + "enum": [ + "authenticatedRead", + "bucketOwnerFullControl", + "bucketOwnerRead", + "private", + "projectPrivate", + "publicRead" + ], + "enumDescriptions": [ + "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + "Object owner gets OWNER access, and project team owners get OWNER access.", + "Object owner gets OWNER access, and project team owners get READER access.", + "Object owner gets OWNER access.", + "Object owner gets OWNER access, and project team members get access according to their roles.", + "Object owner gets OWNER access, and allUsers get READER access." + ], + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to full.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + } + }, + "path": "b/{bucket}/o/{object}", + "request": { + "$ref": "Object" + }, + "response": { + "$ref": "Object" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "watchAll": { + "description": "Watch for changes on all objects in a bucket.", + "httpMethod": "POST", + "id": "storage.objects.watchAll", + "parameterOrder": [ + "bucket" + ], + "parameters": { + "bucket": { + "description": "Name of the bucket in which to look for objects.", + "location": "path", + "required": true, + "type": "string" + }, + "delimiter": { + "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + "location": "query", + "type": "string" + }, + "includeTrailingDelimiter": { + "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", + "location": "query", + "type": "boolean" + }, + "maxResults": { + "default": "1000", + "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + "format": "uint32", + "location": "query", + "minimum": "0", + "type": "integer" + }, + "pageToken": { + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query", + "type": "string" + }, + "prefix": { + "description": "Filter results to objects whose names begin with this prefix.", + "location": "query", + "type": "string" + }, + "projection": { + "description": "Set of properties to return. Defaults to noAcl.", + "enum": [ + "full", + "noAcl" + ], + "enumDescriptions": [ + "Include all properties.", + "Omit the owner, acl property." + ], + "location": "query", + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request. Required for Requester Pays buckets.", + "location": "query", + "type": "string" + }, + "versions": { + "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + "location": "query", + "type": "boolean" + } + }, + "path": "b/{bucket}/o/watch", + "request": { + "$ref": "Channel", + "parameterName": "resource" + }, + "response": { + "$ref": "Channel" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ], + "supportsSubscription": true + } + } + }, + "projects": { + "resources": { + "hmacKeys": { + "methods": { + "create": { + "description": "Creates a new HMAC key for the specified service account.", + "httpMethod": "POST", + "id": "storage.projects.hmacKeys.create", + "parameterOrder": [ + "projectId", + "serviceAccountEmail" + ], + "parameters": { + "projectId": { + "description": "Project ID owning the service account.", + "location": "path", + "required": true, + "type": "string" + }, + "serviceAccountEmail": { + "description": "Email address of the service account.", + "location": "query", + "required": true, + "type": "string" + } + }, + "path": "projects/{projectId}/hmacKeys", + "response": { + "$ref": "HmacKey" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + }, + "delete": { + "description": "Deletes an HMAC key.", + "httpMethod": "DELETE", + "id": "storage.projects.hmacKeys.delete", + "parameterOrder": [ + "projectId", + "accessId" + ], + "parameters": { + "accessId": { + "description": "Name of the HMAC key to be deleted.", + "location": "path", + "required": true, + "type": "string" + }, + "projectId": { + "description": "Project ID owning the requested key", + "location": "path", + "required": true, + "type": "string" + } + }, + "path": "projects/{projectId}/hmacKeys/{accessId}", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + }, + "get": { + "description": "Retrieves an HMAC key's metadata", + "httpMethod": "GET", + "id": "storage.projects.hmacKeys.get", + "parameterOrder": [ + "projectId", + "accessId" + ], + "parameters": { + "accessId": { + "description": "Name of the HMAC key.", + "location": "path", + "required": true, + "type": "string" + }, + "projectId": { + "description": "Project ID owning the service account of the requested key.", + "location": "path", + "required": true, + "type": "string" + } + }, + "path": "projects/{projectId}/hmacKeys/{accessId}", + "response": { + "$ref": "HmacKeyMetadata" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.read_only" + ] + }, + "list": { + "description": "Retrieves a list of HMAC keys matching the criteria.", + "httpMethod": "GET", + "id": "storage.projects.hmacKeys.list", + "parameterOrder": [ + "projectId" + ], + "parameters": { + "maxResults": { + "default": "1000", + "description": "Maximum number of items plus prefixes to return in a single page of responses. Because duplicate prefixes are omitted, fewer total results may be returned than requested. The service uses this parameter or 1,000 items, whichever is smaller.", + "format": "uint32", + "location": "query", + "minimum": "0", + "type": "integer" + }, + "pageToken": { + "description": "A previously-returned page token representing part of the larger set of results to view.", + "location": "query", + "type": "string" + }, + "projectId": { + "description": "Name of the project in which to look for HMAC keys.", + "location": "path", + "required": true, + "type": "string" + }, + "serviceAccountEmail": { + "description": "If present, only keys for the given service account are returned.", + "location": "query", + "type": "string" + }, + "showDeletedKeys": { + "description": "Whether or not to show keys in the DELETED state.", + "location": "query", + "type": "boolean" + } + }, + "path": "projects/{projectId}/hmacKeys", + "response": { + "$ref": "HmacKeysMetadata" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only" + ] + }, + "update": { + "description": "Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.", + "httpMethod": "PUT", + "id": "storage.projects.hmacKeys.update", + "parameterOrder": [ + "projectId", + "accessId" + ], + "parameters": { + "accessId": { + "description": "Name of the HMAC key being updated.", + "location": "path", + "required": true, + "type": "string" + }, + "projectId": { + "description": "Project ID owning the service account of the updated key.", + "location": "path", + "required": true, + "type": "string" + } + }, + "path": "projects/{projectId}/hmacKeys/{accessId}", + "request": { + "$ref": "HmacKeyMetadata" + }, + "response": { + "$ref": "HmacKeyMetadata" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/devstorage.full_control" + ] + } + } + }, + "serviceAccount": { + "methods": { + "get": { + "description": "Get the email address of this project's Google Cloud Storage service account.", + "httpMethod": "GET", + "id": "storage.projects.serviceAccount.get", + "parameterOrder": [ + "projectId" + ], + "parameters": { + "projectId": { + "description": "Project ID", + "location": "path", + "required": true, + "type": "string" + }, + "userProject": { + "description": "The project to be billed for this request.", + "location": "query", + "type": "string" + } + }, + "path": "projects/{projectId}/serviceAccount", + "response": { + "$ref": "ServiceAccount" + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write" + ] + } + } + } + } + } + }, + "revision": "20190326", + "rootUrl": "https://www.googleapis.com/", + "schemas": { + "Bucket": { + "description": "A bucket.", + "id": "Bucket", + "properties": { + "acl": { + "annotations": { + "required": [ + "storage.buckets.update" + ] + }, + "description": "Access controls on the bucket.", + "items": { + "$ref": "BucketAccessControl" + }, + "type": "array" + }, + "billing": { + "description": "The bucket's billing configuration.", + "properties": { + "requesterPays": { + "description": "When set to true, Requester Pays is enabled for this bucket.", + "type": "boolean" + } + }, + "type": "object" + }, + "cors": { + "description": "The bucket's Cross-Origin Resource Sharing (CORS) configuration.", + "items": { + "properties": { + "maxAgeSeconds": { + "description": "The value, in seconds, to return in the Access-Control-Max-Age header used in preflight responses.", + "format": "int32", + "type": "integer" + }, + "method": { + "description": "The list of HTTP methods on which to include CORS response headers, (GET, OPTIONS, POST, etc) Note: \"*\" is permitted in the list of methods, and means \"any method\".", + "items": { + "type": "string" + }, + "type": "array" + }, + "origin": { + "description": "The list of Origins eligible to receive CORS response headers. Note: \"*\" is permitted in the list of origins, and means \"any Origin\".", + "items": { + "type": "string" + }, + "type": "array" + }, + "responseHeader": { + "description": "The list of HTTP headers other than the simple response headers to give permission for the user-agent to share across domains.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "defaultEventBasedHold": { + "description": "The default value for event-based hold on newly created objects in this bucket. Event-based hold is a way to retain objects indefinitely until an event occurs, signified by the hold's release. After being released, such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here, bucket-level retention is 3 years and the event is loan being paid in full. In this example, these objects will be held intact for any number of years until the event has occurred (event-based hold on the object is released) and then 3 more years after that. That means retention duration of the objects begins from the moment event-based hold transitioned from true to false. Objects under event-based hold cannot be deleted, overwritten or archived until the hold is removed.", + "type": "boolean" + }, + "defaultObjectAcl": { + "description": "Default access controls to apply to new objects when no ACL is provided.", + "items": { + "$ref": "ObjectAccessControl" + }, + "type": "array" + }, + "encryption": { + "description": "Encryption configuration for a bucket.", + "properties": { + "defaultKmsKeyName": { + "description": "A Cloud KMS key that will be used to encrypt objects inserted into this bucket, if no encryption method is specified.", + "type": "string" + } + }, + "type": "object" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the bucket.", + "type": "string" + }, + "iamConfiguration": { + "description": "The bucket's IAM configuration.", + "properties": { + "bucketPolicyOnly": { + "description": "The bucket's Bucket Policy Only configuration.", + "properties": { + "enabled": { + "description": "If set, access checks only use bucket-level IAM policies or above.", + "type": "boolean" + }, + "lockedTime": { + "description": "The deadline time for changing iamConfiguration.bucketPolicyOnly.enabled from true to false in RFC 3339 format. iamConfiguration.bucketPolicyOnly.enabled may be changed from true to false until the locked time, after which the field is immutable.", + "format": "date-time", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "id": { + "description": "The ID of the bucket. For buckets, the id and name properties are the same.", + "type": "string" + }, + "kind": { + "default": "storage#bucket", + "description": "The kind of item this is. For buckets, this is always storage#bucket.", + "type": "string" + }, + "labels": { + "additionalProperties": { + "description": "An individual label entry.", + "type": "string" + }, + "description": "User-provided labels, in key/value pairs.", + "type": "object" + }, + "lifecycle": { + "description": "The bucket's lifecycle configuration. See lifecycle management for more information.", + "properties": { + "rule": { + "description": "A lifecycle management rule, which is made of an action to take and the condition(s) under which the action will be taken.", + "items": { + "properties": { + "action": { + "description": "The action to take.", + "properties": { + "storageClass": { + "description": "Target storage class. Required iff the type of the action is SetStorageClass.", + "type": "string" + }, + "type": { + "description": "Type of the action. Currently, only Delete and SetStorageClass are supported.", + "type": "string" + } + }, + "type": "object" + }, + "condition": { + "description": "The condition(s) under which the action will be taken.", + "properties": { + "age": { + "description": "Age of an object (in days). This condition is satisfied when an object reaches the specified age.", + "format": "int32", + "type": "integer" + }, + "createdBefore": { + "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when an object is created before midnight of the specified date in UTC.", + "format": "date", + "type": "string" + }, + "isLive": { + "description": "Relevant only for versioned objects. If the value is true, this condition matches live objects; if the value is false, it matches archived objects.", + "type": "boolean" + }, + "matchesPattern": { + "description": "A regular expression that satisfies the RE2 syntax. This condition is satisfied when the name of the object matches the RE2 pattern. Note: This feature is currently in the \"Early Access\" launch stage and is only available to a whitelisted set of users; that means that this feature may be changed in backward-incompatible ways and that it is not guaranteed to be released.", + "type": "string" + }, + "matchesStorageClass": { + "description": "Objects having any of the storage classes specified by this condition will be matched. Values include MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, and DURABLE_REDUCED_AVAILABILITY.", + "items": { + "type": "string" + }, + "type": "array" + }, + "numNewerVersions": { + "description": "Relevant only for versioned objects. If the value is N, this condition is satisfied when there are at least N versions (including the live version) newer than this version of the object.", + "format": "int32", + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "location": { + "description": "The location of the bucket. Object data for objects in the bucket resides in physical storage within this region. Defaults to US. See the developer's guide for the authoritative list.", + "type": "string" + }, + "logging": { + "description": "The bucket's logging configuration, which defines the destination bucket and optional name prefix for the current bucket's logs.", + "properties": { + "logBucket": { + "description": "The destination bucket where the current bucket's logs should be placed.", + "type": "string" + }, + "logObjectPrefix": { + "description": "A prefix for log object names.", + "type": "string" + } + }, + "type": "object" + }, + "metageneration": { + "description": "The metadata generation of this bucket.", + "format": "int64", + "type": "string" + }, + "name": { + "annotations": { + "required": [ + "storage.buckets.insert" + ] + }, + "description": "The name of the bucket.", + "type": "string" + }, + "owner": { + "description": "The owner of the bucket. This is always the project team's owner group.", + "properties": { + "entity": { + "description": "The entity, in the form project-owner-projectId.", + "type": "string" + }, + "entityId": { + "description": "The ID for the entity.", + "type": "string" + } + }, + "type": "object" + }, + "projectNumber": { + "description": "The project number of the project the bucket belongs to.", + "format": "uint64", + "type": "string" + }, + "retentionPolicy": { + "description": "The bucket's retention policy. The retention policy enforces a minimum retention time for all objects contained in the bucket, based on their creation time. Any attempt to overwrite or delete objects younger than the retention period will result in a PERMISSION_DENIED error. An unlocked retention policy can be modified or removed from the bucket via a storage.buckets.update operation. A locked retention policy cannot be removed or shortened in duration for the lifetime of the bucket. Attempting to remove or decrease period of a locked retention policy will result in a PERMISSION_DENIED error.", + "properties": { + "effectiveTime": { + "description": "Server-determined value that indicates the time from which policy was enforced and effective. This value is in RFC 3339 format.", + "format": "date-time", + "type": "string" + }, + "isLocked": { + "description": "Once locked, an object retention policy cannot be modified.", + "type": "boolean" + }, + "retentionPeriod": { + "description": "The duration in seconds that objects need to be retained. Retention duration must be greater than zero and less than 100 years. Note that enforcement of retention periods less than a day is not guaranteed. Such periods should only be used for testing purposes.", + "format": "int64", + "type": "string" + } + }, + "type": "object" + }, + "selfLink": { + "description": "The URI of this bucket.", + "type": "string" + }, + "storageClass": { + "description": "The bucket's default storage class, used whenever no storageClass is specified for a newly-created object. This defines how objects in the bucket are stored and determines the SLA and the cost of storage. Values include MULTI_REGIONAL, REGIONAL, STANDARD, NEARLINE, COLDLINE, and DURABLE_REDUCED_AVAILABILITY. If this value is not specified when the bucket is created, it will default to STANDARD. For more information, see storage classes.", + "type": "string" + }, + "timeCreated": { + "description": "The creation time of the bucket in RFC 3339 format.", + "format": "date-time", + "type": "string" + }, + "updated": { + "description": "The modification time of the bucket in RFC 3339 format.", + "format": "date-time", + "type": "string" + }, + "versioning": { + "description": "The bucket's versioning configuration.", + "properties": { + "enabled": { + "description": "While set to true, versioning is fully enabled for this bucket.", + "type": "boolean" + } + }, + "type": "object" + }, + "website": { + "description": "The bucket's website configuration, controlling how the service behaves when accessing bucket contents as a web site. See the Static Website Examples for more information.", + "properties": { + "mainPageSuffix": { + "description": "If the requested object path is missing, the service will ensure the path has a trailing '/', append this suffix, and attempt to retrieve the resulting object. This allows the creation of index.html objects to represent directory pages.", + "type": "string" + }, + "notFoundPage": { + "description": "If the requested object path is missing, and any mainPageSuffix object is missing, if applicable, the service will return the named object from this bucket as the content for a 404 Not Found result.", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "BucketAccessControl": { + "description": "An access-control entry.", + "id": "BucketAccessControl", + "properties": { + "bucket": { + "description": "The name of the bucket.", + "type": "string" + }, + "domain": { + "description": "The domain associated with the entity, if any.", + "type": "string" + }, + "email": { + "description": "The email address associated with the entity, if any.", + "type": "string" + }, + "entity": { + "annotations": { + "required": [ + "storage.bucketAccessControls.insert" + ] + }, + "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", + "type": "string" + }, + "entityId": { + "description": "The ID for the entity, if any.", + "type": "string" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the access-control entry.", + "type": "string" + }, + "id": { + "description": "The ID of the access-control entry.", + "type": "string" + }, + "kind": { + "default": "storage#bucketAccessControl", + "description": "The kind of item this is. For bucket access control entries, this is always storage#bucketAccessControl.", + "type": "string" + }, + "projectTeam": { + "description": "The project team associated with the entity, if any.", + "properties": { + "projectNumber": { + "description": "The project number.", + "type": "string" + }, + "team": { + "description": "The team.", + "type": "string" + } + }, + "type": "object" + }, + "role": { + "annotations": { + "required": [ + "storage.bucketAccessControls.insert" + ] + }, + "description": "The access permission for the entity.", + "type": "string" + }, + "selfLink": { + "description": "The link to this access-control entry.", + "type": "string" + } + }, + "type": "object" + }, + "BucketAccessControls": { + "description": "An access-control list.", + "id": "BucketAccessControls", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "BucketAccessControl" + }, + "type": "array" + }, + "kind": { + "default": "storage#bucketAccessControls", + "description": "The kind of item this is. For lists of bucket access control entries, this is always storage#bucketAccessControls.", + "type": "string" + } + }, + "type": "object" + }, + "Buckets": { + "description": "A list of buckets.", + "id": "Buckets", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "Bucket" + }, + "type": "array" + }, + "kind": { + "default": "storage#buckets", + "description": "The kind of item this is. For lists of buckets, this is always storage#buckets.", + "type": "string" + }, + "nextPageToken": { + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results.", + "type": "string" + } + }, + "type": "object" + }, + "Channel": { + "description": "An notification channel used to watch for resource changes.", + "id": "Channel", + "properties": { + "address": { + "description": "The address where notifications are delivered for this channel.", + "type": "string" + }, + "expiration": { + "description": "Date and time of notification channel expiration, expressed as a Unix timestamp, in milliseconds. Optional.", + "format": "int64", + "type": "string" + }, + "id": { + "description": "A UUID or similar unique string that identifies this channel.", + "type": "string" + }, + "kind": { + "default": "api#channel", + "description": "Identifies this as a notification channel used to watch for changes to a resource. Value: the fixed string \"api#channel\".", + "type": "string" + }, + "params": { + "additionalProperties": { + "description": "Declares a new parameter by name.", + "type": "string" + }, + "description": "Additional parameters controlling delivery channel behavior. Optional.", + "type": "object" + }, + "payload": { + "description": "A Boolean value to indicate whether payload is wanted. Optional.", + "type": "boolean" + }, + "resourceId": { + "description": "An opaque ID that identifies the resource being watched on this channel. Stable across different API versions.", + "type": "string" + }, + "resourceUri": { + "description": "A version-specific identifier for the watched resource.", + "type": "string" + }, + "token": { + "description": "An arbitrary string delivered to the target address with each notification delivered over this channel. Optional.", + "type": "string" + }, + "type": { + "description": "The type of delivery mechanism used for this channel.", + "type": "string" + } + }, + "type": "object" + }, + "ComposeRequest": { + "description": "A Compose request.", + "id": "ComposeRequest", + "properties": { + "destination": { + "$ref": "Object", + "description": "Properties of the resulting object." + }, + "kind": { + "default": "storage#composeRequest", + "description": "The kind of item this is.", + "type": "string" + }, + "sourceObjects": { + "annotations": { + "required": [ + "storage.objects.compose" + ] + }, + "description": "The list of source objects that will be concatenated into a single object.", + "items": { + "properties": { + "generation": { + "description": "The generation of this object to use as the source.", + "format": "int64", + "type": "string" + }, + "name": { + "annotations": { + "required": [ + "storage.objects.compose" + ] + }, + "description": "The source object's name. All source objects must reside in the same bucket.", + "type": "string" + }, + "objectPreconditions": { + "description": "Conditions that must be met for this operation to execute.", + "properties": { + "ifGenerationMatch": { + "description": "Only perform the composition if the generation of the source object that would be used matches this value. If this value and a generation are both specified, they must be the same value or the call will fail.", + "format": "int64", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "Expr": { + "description": "Represents an expression text. Example: title: \"User account presence\" description: \"Determines whether the request has a user account\" expression: \"size(request.user) \u003e 0\"", + "id": "Expr", + "properties": { + "description": { + "description": "An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI.", + "type": "string" + }, + "expression": { + "description": "Textual representation of an expression in Common Expression Language syntax. The application context of the containing message determines which well-known feature set of CEL is supported.", + "type": "string" + }, + "kind": { + "default": "storage#expr", + "description": "The kind of item this is. For storage, this is always storage#expr. This field is ignored on input.", + "type": "string" + }, + "location": { + "description": "An optional string indicating the location of the expression for error reporting, e.g. a file name and a position in the file.", + "type": "string" + }, + "title": { + "description": "An optional title for the expression, i.e. a short string describing its purpose. This can be used e.g. in UIs which allow to enter the expression.", + "type": "string" + } + }, + "type": "object" + }, + "HmacKey": { + "description": "JSON template to produce a JSON-style HMAC Key resource for Create responses.", + "id": "HmacKey", + "properties": { + "kind": { + "default": "storage#hmacKey", + "description": "The kind of item this is. For HMAC keys, this is always storage#hmacKey.", + "type": "string" + }, + "metadata": { + "description": "Key metadata.", + "type": "any" + }, + "secret": { + "description": "HMAC secret key material.", + "type": "string" + } + }, + "type": "object" + }, + "HmacKeyMetadata": { + "description": "JSON template to produce a JSON-style HMAC Key metadata resource.", + "id": "HmacKeyMetadata", + "properties": { + "accessId": { + "description": "The ID of the HMAC Key.", + "type": "string" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the access-control entry.", + "type": "string" + }, + "id": { + "description": "The ID of the HMAC key, including the Project ID and the Access ID.", + "type": "string" + }, + "kind": { + "default": "storage#hmacKeyMetadata", + "description": "The kind of item this is. For HMAC Key metadata, this is always storage#hmacKeyMetadata.", + "type": "string" + }, + "projectId": { + "description": "Project ID owning the service account to which the key authenticates.", + "type": "string" + }, + "selfLink": { + "description": "The link to this resource.", + "type": "string" + }, + "serviceAccountEmail": { + "description": "The email address of the key's associated service account.", + "type": "string" + }, + "state": { + "description": "The state of the key. Can be one of ACTIVE, INACTIVE, or DELETED.", + "type": "string" + }, + "timeCreated": { + "description": "The creation time of the HMAC key in RFC 3339 format.", + "type": "string" + }, + "updated": { + "description": "The last modification time of the HMAC key metadata in RFC 3339 format.", + "type": "string" + } + }, + "type": "object" + }, + "HmacKeysMetadata": { + "description": "A list of hmacKeys.", + "id": "HmacKeysMetadata", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "HmacKeyMetadata" + }, + "type": "array" + }, + "kind": { + "default": "storage#hmacKeysMetadata", + "description": "The kind of item this is. For lists of hmacKeys, this is always storage#hmacKeysMetadata.", + "type": "string" + }, + "nextPageToken": { + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results.", + "type": "string" + } + }, + "type": "object" + }, + "Notification": { + "description": "A subscription to receive Google PubSub notifications.", + "id": "Notification", + "properties": { + "custom_attributes": { + "additionalProperties": { + "type": "string" + }, + "description": "An optional list of additional attributes to attach to each Cloud PubSub message published for this notification subscription.", + "type": "object" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for this subscription notification.", + "type": "string" + }, + "event_types": { + "description": "If present, only send notifications about listed event types. If empty, sent notifications for all event types.", + "items": { + "type": "string" + }, + "type": "array" + }, + "id": { + "description": "The ID of the notification.", + "type": "string" + }, + "kind": { + "default": "storage#notification", + "description": "The kind of item this is. For notifications, this is always storage#notification.", + "type": "string" + }, + "object_name_prefix": { + "description": "If present, only apply this notification configuration to object names that begin with this prefix.", + "type": "string" + }, + "payload_format": { + "annotations": { + "required": [ + "storage.notifications.insert" + ] + }, + "default": "JSON_API_V1", + "description": "The desired content of the Payload.", + "type": "string" + }, + "selfLink": { + "description": "The canonical URL of this notification.", + "type": "string" + }, + "topic": { + "annotations": { + "required": [ + "storage.notifications.insert" + ] + }, + "description": "The Cloud PubSub topic to which this subscription publishes. Formatted as: '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topic}'", + "type": "string" + } + }, + "type": "object" + }, + "Notifications": { + "description": "A list of notification subscriptions.", + "id": "Notifications", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "Notification" + }, + "type": "array" + }, + "kind": { + "default": "storage#notifications", + "description": "The kind of item this is. For lists of notifications, this is always storage#notifications.", + "type": "string" + } + }, + "type": "object" + }, + "Object": { + "description": "An object.", + "id": "Object", + "properties": { + "acl": { + "annotations": { + "required": [ + "storage.objects.update" + ] + }, + "description": "Access controls on the object.", + "items": { + "$ref": "ObjectAccessControl" + }, + "type": "array" + }, + "bucket": { + "description": "The name of the bucket containing this object.", + "type": "string" + }, + "cacheControl": { + "description": "Cache-Control directive for the object data. If omitted, and the object is accessible to all anonymous users, the default will be public, max-age=3600.", + "type": "string" + }, + "componentCount": { + "description": "Number of underlying components that make up this object. Components are accumulated by compose operations.", + "format": "int32", + "type": "integer" + }, + "contentDisposition": { + "description": "Content-Disposition of the object data.", + "type": "string" + }, + "contentEncoding": { + "description": "Content-Encoding of the object data.", + "type": "string" + }, + "contentLanguage": { + "description": "Content-Language of the object data.", + "type": "string" + }, + "contentType": { + "description": "Content-Type of the object data. If an object is stored without a Content-Type, it is served as application/octet-stream.", + "type": "string" + }, + "crc32c": { + "description": "CRC32c checksum, as described in RFC 4960, Appendix B; encoded using base64 in big-endian byte order. For more information about using the CRC32c checksum, see Hashes and ETags: Best Practices.", + "type": "string" + }, + "customerEncryption": { + "description": "Metadata of customer-supplied encryption key, if the object is encrypted by such a key.", + "properties": { + "encryptionAlgorithm": { + "description": "The encryption algorithm.", + "type": "string" + }, + "keySha256": { + "description": "SHA256 hash value of the encryption key.", + "type": "string" + } + }, + "type": "object" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the object.", + "type": "string" + }, + "eventBasedHold": { + "description": "Whether an object is under event-based hold. Event-based hold is a way to retain objects until an event occurs, which is signified by the hold's release (i.e. this value is set to false). After being released (set to false), such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here, bucket-level retention is 3 years and the event is the loan being paid in full. In this example, these objects will be held intact for any number of years until the event has occurred (event-based hold on the object is released) and then 3 more years after that. That means retention duration of the objects begins from the moment event-based hold transitioned from true to false.", + "type": "boolean" + }, + "generation": { + "description": "The content generation of this object. Used for object versioning.", + "format": "int64", + "type": "string" + }, + "id": { + "description": "The ID of the object, including the bucket name, object name, and generation number.", + "type": "string" + }, + "kind": { + "default": "storage#object", + "description": "The kind of item this is. For objects, this is always storage#object.", + "type": "string" + }, + "kmsKeyName": { + "description": "Cloud KMS Key used to encrypt this object, if the object is encrypted by such a key.", + "type": "string" + }, + "md5Hash": { + "description": "MD5 hash of the data; encoded using base64. For more information about using the MD5 hash, see Hashes and ETags: Best Practices.", + "type": "string" + }, + "mediaLink": { + "description": "Media download link.", + "type": "string" + }, + "metadata": { + "additionalProperties": { + "description": "An individual metadata entry.", + "type": "string" + }, + "description": "User-provided metadata, in key/value pairs.", + "type": "object" + }, + "metageneration": { + "description": "The version of the metadata for this object at this generation. Used for preconditions and for detecting changes in metadata. A metageneration number is only meaningful in the context of a particular generation of a particular object.", + "format": "int64", + "type": "string" + }, + "name": { + "description": "The name of the object. Required if not specified by URL parameter.", + "type": "string" + }, + "owner": { + "description": "The owner of the object. This will always be the uploader of the object.", + "properties": { + "entity": { + "description": "The entity, in the form user-userId.", + "type": "string" + }, + "entityId": { + "description": "The ID for the entity.", + "type": "string" + } + }, + "type": "object" + }, + "retentionExpirationTime": { + "description": "A server-determined value that specifies the earliest time that the object's retention period expires. This value is in RFC 3339 format. Note 1: This field is not provided for objects with an active event-based hold, since retention expiration is unknown until the hold is removed. Note 2: This value can be provided even when temporary hold is set (so that the user can reason about policy without having to first unset the temporary hold).", + "format": "date-time", + "type": "string" + }, + "selfLink": { + "description": "The link to this object.", + "type": "string" + }, + "size": { + "description": "Content-Length of the data in bytes.", + "format": "uint64", + "type": "string" + }, + "storageClass": { + "description": "Storage class of the object.", + "type": "string" + }, + "temporaryHold": { + "description": "Whether an object is under temporary hold. While this flag is set to true, the object is protected against deletion and overwrites. A common use case of this flag is regulatory investigations where objects need to be retained while the investigation is ongoing. Note that unlike event-based hold, temporary hold does not impact retention expiration time of an object.", + "type": "boolean" + }, + "timeCreated": { + "description": "The creation time of the object in RFC 3339 format.", + "format": "date-time", + "type": "string" + }, + "timeDeleted": { + "description": "The deletion time of the object in RFC 3339 format. Will be returned if and only if this version of the object has been deleted.", + "format": "date-time", + "type": "string" + }, + "timeStorageClassUpdated": { + "description": "The time at which the object's storage class was last changed. When the object is initially created, it will be set to timeCreated.", + "format": "date-time", + "type": "string" + }, + "updated": { + "description": "The modification time of the object metadata in RFC 3339 format.", + "format": "date-time", + "type": "string" + } + }, + "type": "object" + }, + "ObjectAccessControl": { + "description": "An access-control entry.", + "id": "ObjectAccessControl", + "properties": { + "bucket": { + "description": "The name of the bucket.", + "type": "string" + }, + "domain": { + "description": "The domain associated with the entity, if any.", + "type": "string" + }, + "email": { + "description": "The email address associated with the entity, if any.", + "type": "string" + }, + "entity": { + "annotations": { + "required": [ + "storage.defaultObjectAccessControls.insert", + "storage.objectAccessControls.insert" + ] + }, + "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", + "type": "string" + }, + "entityId": { + "description": "The ID for the entity, if any.", + "type": "string" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the access-control entry.", + "type": "string" + }, + "generation": { + "description": "The content generation of the object, if applied to an object.", + "format": "int64", + "type": "string" + }, + "id": { + "description": "The ID of the access-control entry.", + "type": "string" + }, + "kind": { + "default": "storage#objectAccessControl", + "description": "The kind of item this is. For object access control entries, this is always storage#objectAccessControl.", + "type": "string" + }, + "object": { + "description": "The name of the object, if applied to an object.", + "type": "string" + }, + "projectTeam": { + "description": "The project team associated with the entity, if any.", + "properties": { + "projectNumber": { + "description": "The project number.", + "type": "string" + }, + "team": { + "description": "The team.", + "type": "string" + } + }, + "type": "object" + }, + "role": { + "annotations": { + "required": [ + "storage.defaultObjectAccessControls.insert", + "storage.objectAccessControls.insert" + ] + }, + "description": "The access permission for the entity.", + "type": "string" + }, + "selfLink": { + "description": "The link to this access-control entry.", + "type": "string" + } + }, + "type": "object" + }, + "ObjectAccessControls": { + "description": "An access-control list.", + "id": "ObjectAccessControls", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "ObjectAccessControl" + }, + "type": "array" + }, + "kind": { + "default": "storage#objectAccessControls", + "description": "The kind of item this is. For lists of object access control entries, this is always storage#objectAccessControls.", + "type": "string" + } + }, + "type": "object" + }, + "Objects": { + "description": "A list of objects.", + "id": "Objects", + "properties": { + "items": { + "description": "The list of items.", + "items": { + "$ref": "Object" + }, + "type": "array" + }, + "kind": { + "default": "storage#objects", + "description": "The kind of item this is. For lists of objects, this is always storage#objects.", + "type": "string" + }, + "nextPageToken": { + "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results.", + "type": "string" + }, + "prefixes": { + "description": "The list of prefixes of objects matching-but-not-listed up to and including the requested delimiter.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "Policy": { + "description": "A bucket/object IAM policy.", + "id": "Policy", + "properties": { + "bindings": { + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy" + ] + }, + "description": "An association between a role, which comes with a set of permissions, and members who may assume that role.", + "items": { + "properties": { + "condition": { + "$ref": "Expr", + "description": "The condition that is associated with this binding. NOTE: an unsatisfied condition will not allow user access via current binding. Different bindings, including their conditions, are examined independently." + }, + "members": { + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy" + ] + }, + "description": "A collection of identifiers for members who may assume the provided role. Recognized identifiers are as follows: \n- allUsers — A special identifier that represents anyone on the internet; with or without a Google account. \n- allAuthenticatedUsers — A special identifier that represents anyone who is authenticated with a Google account or a service account. \n- user:emailid — An email address that represents a specific account. For example, user:alice@gmail.com or user:joe@example.com. \n- serviceAccount:emailid — An email address that represents a service account. For example, serviceAccount:my-other-app@appspot.gserviceaccount.com . \n- group:emailid — An email address that represents a Google group. For example, group:admins@example.com. \n- domain:domain — A Google Apps domain name that represents all the users of that domain. For example, domain:google.com or domain:example.com. \n- projectOwner:projectid — Owners of the given project. For example, projectOwner:my-example-project \n- projectEditor:projectid — Editors of the given project. For example, projectEditor:my-example-project \n- projectViewer:projectid — Viewers of the given project. For example, projectViewer:my-example-project", + "items": { + "type": "string" + }, + "type": "array" + }, + "role": { + "annotations": { + "required": [ + "storage.buckets.setIamPolicy", + "storage.objects.setIamPolicy" + ] + }, + "description": "The role to which members belong. Two types of roles are supported: new IAM roles, which grant permissions that do not map directly to those provided by ACLs, and legacy IAM roles, which do map directly to ACL permissions. All roles are of the format roles/storage.specificRole.\nThe new IAM roles are: \n- roles/storage.admin — Full control of Google Cloud Storage resources. \n- roles/storage.objectViewer — Read-Only access to Google Cloud Storage objects. \n- roles/storage.objectCreator — Access to create objects in Google Cloud Storage. \n- roles/storage.objectAdmin — Full control of Google Cloud Storage objects. The legacy IAM roles are: \n- roles/storage.legacyObjectReader — Read-only access to objects without listing. Equivalent to an ACL entry on an object with the READER role. \n- roles/storage.legacyObjectOwner — Read/write access to existing objects without listing. Equivalent to an ACL entry on an object with the OWNER role. \n- roles/storage.legacyBucketReader — Read access to buckets with object listing. Equivalent to an ACL entry on a bucket with the READER role. \n- roles/storage.legacyBucketWriter — Read access to buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the WRITER role. \n- roles/storage.legacyBucketOwner — Read and write access to existing buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the OWNER role.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "etag": { + "description": "HTTP 1.1 Entity tag for the policy.", + "format": "byte", + "type": "string" + }, + "kind": { + "default": "storage#policy", + "description": "The kind of item this is. For policies, this is always storage#policy. This field is ignored on input.", + "type": "string" + }, + "resourceId": { + "description": "The ID of the resource to which this policy belongs. Will be of the form projects/_/buckets/bucket for buckets, and projects/_/buckets/bucket/objects/object for objects. A specific generation may be specified by appending #generationNumber to the end of the object name, e.g. projects/_/buckets/my-bucket/objects/data.txt#17. The current generation can be denoted with #0. This field is ignored on input.", + "type": "string" + } + }, + "type": "object" + }, + "RewriteResponse": { + "description": "A rewrite response.", + "id": "RewriteResponse", + "properties": { + "done": { + "description": "true if the copy is finished; otherwise, false if the copy is in progress. This property is always present in the response.", + "type": "boolean" + }, + "kind": { + "default": "storage#rewriteResponse", + "description": "The kind of item this is.", + "type": "string" + }, + "objectSize": { + "description": "The total size of the object being copied in bytes. This property is always present in the response.", + "format": "int64", + "type": "string" + }, + "resource": { + "$ref": "Object", + "description": "A resource containing the metadata for the copied-to object. This property is present in the response only when copying completes." + }, + "rewriteToken": { + "description": "A token to use in subsequent requests to continue copying data. This token is present in the response only when there is more data to copy.", + "type": "string" + }, + "totalBytesRewritten": { + "description": "The total bytes written so far, which can be used to provide a waiting user with a progress indicator. This property is always present in the response.", + "format": "int64", + "type": "string" + } + }, + "type": "object" + }, + "ServiceAccount": { + "description": "A subscription to receive Google PubSub notifications.", + "id": "ServiceAccount", + "properties": { + "email_address": { + "description": "The ID of the notification.", + "type": "string" + }, + "kind": { + "default": "storage#serviceAccount", + "description": "The kind of item this is. For notifications, this is always storage#notification.", + "type": "string" + } + }, + "type": "object" + }, + "TestIamPermissionsResponse": { + "description": "A storage.(buckets|objects).testIamPermissions response.", + "id": "TestIamPermissionsResponse", + "properties": { + "kind": { + "default": "storage#testIamPermissionsResponse", + "description": "The kind of item this is.", + "type": "string" + }, + "permissions": { + "description": "The permissions held by the caller. Permissions are always of the format storage.resource.capability, where resource is one of buckets or objects. The supported permissions are as follows: \n- storage.buckets.delete — Delete bucket. \n- storage.buckets.get — Read bucket metadata. \n- storage.buckets.getIamPolicy — Read bucket IAM policy. \n- storage.buckets.create — Create bucket. \n- storage.buckets.list — List buckets. \n- storage.buckets.setIamPolicy — Update bucket IAM policy. \n- storage.buckets.update — Update bucket metadata. \n- storage.objects.delete — Delete object. \n- storage.objects.get — Read object data and metadata. \n- storage.objects.getIamPolicy — Read object IAM policy. \n- storage.objects.create — Create object. \n- storage.objects.list — List objects. \n- storage.objects.setIamPolicy — Update object IAM policy. \n- storage.objects.update — Update object metadata.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "servicePath": "storage/v1/", + "title": "Cloud Storage JSON API", + "version": "v1" +} \ No newline at end of file diff --git a/vendor/google.golang.org/api/storage/v1/storage-gen.go b/vendor/google.golang.org/api/storage/v1/storage-gen.go new file mode 100644 index 000000000000..a29fdc1ef167 --- /dev/null +++ b/vendor/google.golang.org/api/storage/v1/storage-gen.go @@ -0,0 +1,12517 @@ +// Copyright 2019 Google LLC. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated file. DO NOT EDIT. + +// Package storage provides access to the Cloud Storage JSON API. +// +// This package is DEPRECATED. Use package cloud.google.com/go/storage instead. +// +// For product documentation, see: https://developers.google.com/storage/docs/json_api/ +// +// Creating a client +// +// Usage example: +// +// import "google.golang.org/api/storage/v1" +// ... +// ctx := context.Background() +// storageService, err := storage.NewService(ctx) +// +// In this example, Google Application Default Credentials are used for authentication. +// +// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials. +// +// Other authentication options +// +// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes: +// +// storageService, err := storage.NewService(ctx, option.WithScopes(storage.DevstorageReadWriteScope)) +// +// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey: +// +// storageService, err := storage.NewService(ctx, option.WithAPIKey("AIza...")) +// +// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource: +// +// config := &oauth2.Config{...} +// // ... +// token, err := config.Exchange(ctx, ...) +// storageService, err := storage.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token))) +// +// See https://godoc.org/google.golang.org/api/option/ for details on options. +package storage // import "google.golang.org/api/storage/v1" + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + + gensupport "google.golang.org/api/gensupport" + googleapi "google.golang.org/api/googleapi" + option "google.golang.org/api/option" + htransport "google.golang.org/api/transport/http" +) + +// Always reference these packages, just in case the auto-generated code +// below doesn't. +var _ = bytes.NewBuffer +var _ = strconv.Itoa +var _ = fmt.Sprintf +var _ = json.NewDecoder +var _ = io.Copy +var _ = url.Parse +var _ = gensupport.MarshalJSON +var _ = googleapi.Version +var _ = errors.New +var _ = strings.Replace +var _ = context.Canceled + +const apiId = "storage:v1" +const apiName = "storage" +const apiVersion = "v1" +const basePath = "https://www.googleapis.com/storage/v1/" + +// OAuth2 scopes used by this API. +const ( + // View and manage your data across Google Cloud Platform services + CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform" + + // View your data across Google Cloud Platform services + CloudPlatformReadOnlyScope = "https://www.googleapis.com/auth/cloud-platform.read-only" + + // Manage your data and permissions in Google Cloud Storage + DevstorageFullControlScope = "https://www.googleapis.com/auth/devstorage.full_control" + + // View your data in Google Cloud Storage + DevstorageReadOnlyScope = "https://www.googleapis.com/auth/devstorage.read_only" + + // Manage your data in Google Cloud Storage + DevstorageReadWriteScope = "https://www.googleapis.com/auth/devstorage.read_write" +) + +// NewService creates a new Service. +func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) { + scopesOption := option.WithScopes( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/devstorage.full_control", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/devstorage.read_write", + ) + // NOTE: prepend, so we don't override user-specified scopes. + opts = append([]option.ClientOption{scopesOption}, opts...) + client, endpoint, err := htransport.NewClient(ctx, opts...) + if err != nil { + return nil, err + } + s, err := New(client) + if err != nil { + return nil, err + } + if endpoint != "" { + s.BasePath = endpoint + } + return s, nil +} + +// New creates a new Service. It uses the provided http.Client for requests. +// +// Deprecated: please use NewService instead. +// To provide a custom HTTP client, use option.WithHTTPClient. +// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead. +func New(client *http.Client) (*Service, error) { + if client == nil { + return nil, errors.New("client is nil") + } + s := &Service{client: client, BasePath: basePath} + s.BucketAccessControls = NewBucketAccessControlsService(s) + s.Buckets = NewBucketsService(s) + s.Channels = NewChannelsService(s) + s.DefaultObjectAccessControls = NewDefaultObjectAccessControlsService(s) + s.Notifications = NewNotificationsService(s) + s.ObjectAccessControls = NewObjectAccessControlsService(s) + s.Objects = NewObjectsService(s) + s.Projects = NewProjectsService(s) + return s, nil +} + +type Service struct { + client *http.Client + BasePath string // API endpoint base URL + UserAgent string // optional additional User-Agent fragment + + BucketAccessControls *BucketAccessControlsService + + Buckets *BucketsService + + Channels *ChannelsService + + DefaultObjectAccessControls *DefaultObjectAccessControlsService + + Notifications *NotificationsService + + ObjectAccessControls *ObjectAccessControlsService + + Objects *ObjectsService + + Projects *ProjectsService +} + +func (s *Service) userAgent() string { + if s.UserAgent == "" { + return googleapi.UserAgent + } + return googleapi.UserAgent + " " + s.UserAgent +} + +func NewBucketAccessControlsService(s *Service) *BucketAccessControlsService { + rs := &BucketAccessControlsService{s: s} + return rs +} + +type BucketAccessControlsService struct { + s *Service +} + +func NewBucketsService(s *Service) *BucketsService { + rs := &BucketsService{s: s} + return rs +} + +type BucketsService struct { + s *Service +} + +func NewChannelsService(s *Service) *ChannelsService { + rs := &ChannelsService{s: s} + return rs +} + +type ChannelsService struct { + s *Service +} + +func NewDefaultObjectAccessControlsService(s *Service) *DefaultObjectAccessControlsService { + rs := &DefaultObjectAccessControlsService{s: s} + return rs +} + +type DefaultObjectAccessControlsService struct { + s *Service +} + +func NewNotificationsService(s *Service) *NotificationsService { + rs := &NotificationsService{s: s} + return rs +} + +type NotificationsService struct { + s *Service +} + +func NewObjectAccessControlsService(s *Service) *ObjectAccessControlsService { + rs := &ObjectAccessControlsService{s: s} + return rs +} + +type ObjectAccessControlsService struct { + s *Service +} + +func NewObjectsService(s *Service) *ObjectsService { + rs := &ObjectsService{s: s} + return rs +} + +type ObjectsService struct { + s *Service +} + +func NewProjectsService(s *Service) *ProjectsService { + rs := &ProjectsService{s: s} + rs.HmacKeys = NewProjectsHmacKeysService(s) + rs.ServiceAccount = NewProjectsServiceAccountService(s) + return rs +} + +type ProjectsService struct { + s *Service + + HmacKeys *ProjectsHmacKeysService + + ServiceAccount *ProjectsServiceAccountService +} + +func NewProjectsHmacKeysService(s *Service) *ProjectsHmacKeysService { + rs := &ProjectsHmacKeysService{s: s} + return rs +} + +type ProjectsHmacKeysService struct { + s *Service +} + +func NewProjectsServiceAccountService(s *Service) *ProjectsServiceAccountService { + rs := &ProjectsServiceAccountService{s: s} + return rs +} + +type ProjectsServiceAccountService struct { + s *Service +} + +// Bucket: A bucket. +type Bucket struct { + // Acl: Access controls on the bucket. + Acl []*BucketAccessControl `json:"acl,omitempty"` + + // Billing: The bucket's billing configuration. + Billing *BucketBilling `json:"billing,omitempty"` + + // Cors: The bucket's Cross-Origin Resource Sharing (CORS) + // configuration. + Cors []*BucketCors `json:"cors,omitempty"` + + // DefaultEventBasedHold: The default value for event-based hold on + // newly created objects in this bucket. Event-based hold is a way to + // retain objects indefinitely until an event occurs, signified by the + // hold's release. After being released, such objects will be subject to + // bucket-level retention (if any). One sample use case of this flag is + // for banks to hold loan documents for at least 3 years after loan is + // paid in full. Here, bucket-level retention is 3 years and the event + // is loan being paid in full. In this example, these objects will be + // held intact for any number of years until the event has occurred + // (event-based hold on the object is released) and then 3 more years + // after that. That means retention duration of the objects begins from + // the moment event-based hold transitioned from true to false. Objects + // under event-based hold cannot be deleted, overwritten or archived + // until the hold is removed. + DefaultEventBasedHold bool `json:"defaultEventBasedHold,omitempty"` + + // DefaultObjectAcl: Default access controls to apply to new objects + // when no ACL is provided. + DefaultObjectAcl []*ObjectAccessControl `json:"defaultObjectAcl,omitempty"` + + // Encryption: Encryption configuration for a bucket. + Encryption *BucketEncryption `json:"encryption,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the bucket. + Etag string `json:"etag,omitempty"` + + // IamConfiguration: The bucket's IAM configuration. + IamConfiguration *BucketIamConfiguration `json:"iamConfiguration,omitempty"` + + // Id: The ID of the bucket. For buckets, the id and name properties are + // the same. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For buckets, this is always + // storage#bucket. + Kind string `json:"kind,omitempty"` + + // Labels: User-provided labels, in key/value pairs. + Labels map[string]string `json:"labels,omitempty"` + + // Lifecycle: The bucket's lifecycle configuration. See lifecycle + // management for more information. + Lifecycle *BucketLifecycle `json:"lifecycle,omitempty"` + + // Location: The location of the bucket. Object data for objects in the + // bucket resides in physical storage within this region. Defaults to + // US. See the developer's guide for the authoritative list. + Location string `json:"location,omitempty"` + + // Logging: The bucket's logging configuration, which defines the + // destination bucket and optional name prefix for the current bucket's + // logs. + Logging *BucketLogging `json:"logging,omitempty"` + + // Metageneration: The metadata generation of this bucket. + Metageneration int64 `json:"metageneration,omitempty,string"` + + // Name: The name of the bucket. + Name string `json:"name,omitempty"` + + // Owner: The owner of the bucket. This is always the project team's + // owner group. + Owner *BucketOwner `json:"owner,omitempty"` + + // ProjectNumber: The project number of the project the bucket belongs + // to. + ProjectNumber uint64 `json:"projectNumber,omitempty,string"` + + // RetentionPolicy: The bucket's retention policy. The retention policy + // enforces a minimum retention time for all objects contained in the + // bucket, based on their creation time. Any attempt to overwrite or + // delete objects younger than the retention period will result in a + // PERMISSION_DENIED error. An unlocked retention policy can be modified + // or removed from the bucket via a storage.buckets.update operation. A + // locked retention policy cannot be removed or shortened in duration + // for the lifetime of the bucket. Attempting to remove or decrease + // period of a locked retention policy will result in a + // PERMISSION_DENIED error. + RetentionPolicy *BucketRetentionPolicy `json:"retentionPolicy,omitempty"` + + // SelfLink: The URI of this bucket. + SelfLink string `json:"selfLink,omitempty"` + + // StorageClass: The bucket's default storage class, used whenever no + // storageClass is specified for a newly-created object. This defines + // how objects in the bucket are stored and determines the SLA and the + // cost of storage. Values include MULTI_REGIONAL, REGIONAL, STANDARD, + // NEARLINE, COLDLINE, and DURABLE_REDUCED_AVAILABILITY. If this value + // is not specified when the bucket is created, it will default to + // STANDARD. For more information, see storage classes. + StorageClass string `json:"storageClass,omitempty"` + + // TimeCreated: The creation time of the bucket in RFC 3339 format. + TimeCreated string `json:"timeCreated,omitempty"` + + // Updated: The modification time of the bucket in RFC 3339 format. + Updated string `json:"updated,omitempty"` + + // Versioning: The bucket's versioning configuration. + Versioning *BucketVersioning `json:"versioning,omitempty"` + + // Website: The bucket's website configuration, controlling how the + // service behaves when accessing bucket contents as a web site. See the + // Static Website Examples for more information. + Website *BucketWebsite `json:"website,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Acl") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Acl") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Bucket) MarshalJSON() ([]byte, error) { + type NoMethod Bucket + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketBilling: The bucket's billing configuration. +type BucketBilling struct { + // RequesterPays: When set to true, Requester Pays is enabled for this + // bucket. + RequesterPays bool `json:"requesterPays,omitempty"` + + // ForceSendFields is a list of field names (e.g. "RequesterPays") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "RequesterPays") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketBilling) MarshalJSON() ([]byte, error) { + type NoMethod BucketBilling + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type BucketCors struct { + // MaxAgeSeconds: The value, in seconds, to return in the + // Access-Control-Max-Age header used in preflight responses. + MaxAgeSeconds int64 `json:"maxAgeSeconds,omitempty"` + + // Method: The list of HTTP methods on which to include CORS response + // headers, (GET, OPTIONS, POST, etc) Note: "*" is permitted in the list + // of methods, and means "any method". + Method []string `json:"method,omitempty"` + + // Origin: The list of Origins eligible to receive CORS response + // headers. Note: "*" is permitted in the list of origins, and means + // "any Origin". + Origin []string `json:"origin,omitempty"` + + // ResponseHeader: The list of HTTP headers other than the simple + // response headers to give permission for the user-agent to share + // across domains. + ResponseHeader []string `json:"responseHeader,omitempty"` + + // ForceSendFields is a list of field names (e.g. "MaxAgeSeconds") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "MaxAgeSeconds") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketCors) MarshalJSON() ([]byte, error) { + type NoMethod BucketCors + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketEncryption: Encryption configuration for a bucket. +type BucketEncryption struct { + // DefaultKmsKeyName: A Cloud KMS key that will be used to encrypt + // objects inserted into this bucket, if no encryption method is + // specified. + DefaultKmsKeyName string `json:"defaultKmsKeyName,omitempty"` + + // ForceSendFields is a list of field names (e.g. "DefaultKmsKeyName") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "DefaultKmsKeyName") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *BucketEncryption) MarshalJSON() ([]byte, error) { + type NoMethod BucketEncryption + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketIamConfiguration: The bucket's IAM configuration. +type BucketIamConfiguration struct { + // BucketPolicyOnly: The bucket's Bucket Policy Only configuration. + BucketPolicyOnly *BucketIamConfigurationBucketPolicyOnly `json:"bucketPolicyOnly,omitempty"` + + // ForceSendFields is a list of field names (e.g. "BucketPolicyOnly") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "BucketPolicyOnly") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *BucketIamConfiguration) MarshalJSON() ([]byte, error) { + type NoMethod BucketIamConfiguration + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketIamConfigurationBucketPolicyOnly: The bucket's Bucket Policy +// Only configuration. +type BucketIamConfigurationBucketPolicyOnly struct { + // Enabled: If set, access checks only use bucket-level IAM policies or + // above. + Enabled bool `json:"enabled,omitempty"` + + // LockedTime: The deadline time for changing + // iamConfiguration.bucketPolicyOnly.enabled from true to false in RFC + // 3339 format. iamConfiguration.bucketPolicyOnly.enabled may be changed + // from true to false until the locked time, after which the field is + // immutable. + LockedTime string `json:"lockedTime,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Enabled") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Enabled") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketIamConfigurationBucketPolicyOnly) MarshalJSON() ([]byte, error) { + type NoMethod BucketIamConfigurationBucketPolicyOnly + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketLifecycle: The bucket's lifecycle configuration. See lifecycle +// management for more information. +type BucketLifecycle struct { + // Rule: A lifecycle management rule, which is made of an action to take + // and the condition(s) under which the action will be taken. + Rule []*BucketLifecycleRule `json:"rule,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Rule") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Rule") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLifecycle) MarshalJSON() ([]byte, error) { + type NoMethod BucketLifecycle + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type BucketLifecycleRule struct { + // Action: The action to take. + Action *BucketLifecycleRuleAction `json:"action,omitempty"` + + // Condition: The condition(s) under which the action will be taken. + Condition *BucketLifecycleRuleCondition `json:"condition,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Action") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Action") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLifecycleRule) MarshalJSON() ([]byte, error) { + type NoMethod BucketLifecycleRule + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketLifecycleRuleAction: The action to take. +type BucketLifecycleRuleAction struct { + // StorageClass: Target storage class. Required iff the type of the + // action is SetStorageClass. + StorageClass string `json:"storageClass,omitempty"` + + // Type: Type of the action. Currently, only Delete and SetStorageClass + // are supported. + Type string `json:"type,omitempty"` + + // ForceSendFields is a list of field names (e.g. "StorageClass") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "StorageClass") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLifecycleRuleAction) MarshalJSON() ([]byte, error) { + type NoMethod BucketLifecycleRuleAction + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketLifecycleRuleCondition: The condition(s) under which the action +// will be taken. +type BucketLifecycleRuleCondition struct { + // Age: Age of an object (in days). This condition is satisfied when an + // object reaches the specified age. + Age int64 `json:"age,omitempty"` + + // CreatedBefore: A date in RFC 3339 format with only the date part (for + // instance, "2013-01-15"). This condition is satisfied when an object + // is created before midnight of the specified date in UTC. + CreatedBefore string `json:"createdBefore,omitempty"` + + // IsLive: Relevant only for versioned objects. If the value is true, + // this condition matches live objects; if the value is false, it + // matches archived objects. + IsLive *bool `json:"isLive,omitempty"` + + // MatchesPattern: A regular expression that satisfies the RE2 syntax. + // This condition is satisfied when the name of the object matches the + // RE2 pattern. Note: This feature is currently in the "Early Access" + // launch stage and is only available to a whitelisted set of users; + // that means that this feature may be changed in backward-incompatible + // ways and that it is not guaranteed to be released. + MatchesPattern string `json:"matchesPattern,omitempty"` + + // MatchesStorageClass: Objects having any of the storage classes + // specified by this condition will be matched. Values include + // MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, and + // DURABLE_REDUCED_AVAILABILITY. + MatchesStorageClass []string `json:"matchesStorageClass,omitempty"` + + // NumNewerVersions: Relevant only for versioned objects. If the value + // is N, this condition is satisfied when there are at least N versions + // (including the live version) newer than this version of the object. + NumNewerVersions int64 `json:"numNewerVersions,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Age") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Age") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLifecycleRuleCondition) MarshalJSON() ([]byte, error) { + type NoMethod BucketLifecycleRuleCondition + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketLogging: The bucket's logging configuration, which defines the +// destination bucket and optional name prefix for the current bucket's +// logs. +type BucketLogging struct { + // LogBucket: The destination bucket where the current bucket's logs + // should be placed. + LogBucket string `json:"logBucket,omitempty"` + + // LogObjectPrefix: A prefix for log object names. + LogObjectPrefix string `json:"logObjectPrefix,omitempty"` + + // ForceSendFields is a list of field names (e.g. "LogBucket") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "LogBucket") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketLogging) MarshalJSON() ([]byte, error) { + type NoMethod BucketLogging + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketOwner: The owner of the bucket. This is always the project +// team's owner group. +type BucketOwner struct { + // Entity: The entity, in the form project-owner-projectId. + Entity string `json:"entity,omitempty"` + + // EntityId: The ID for the entity. + EntityId string `json:"entityId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Entity") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Entity") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketOwner) MarshalJSON() ([]byte, error) { + type NoMethod BucketOwner + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketRetentionPolicy: The bucket's retention policy. The retention +// policy enforces a minimum retention time for all objects contained in +// the bucket, based on their creation time. Any attempt to overwrite or +// delete objects younger than the retention period will result in a +// PERMISSION_DENIED error. An unlocked retention policy can be modified +// or removed from the bucket via a storage.buckets.update operation. A +// locked retention policy cannot be removed or shortened in duration +// for the lifetime of the bucket. Attempting to remove or decrease +// period of a locked retention policy will result in a +// PERMISSION_DENIED error. +type BucketRetentionPolicy struct { + // EffectiveTime: Server-determined value that indicates the time from + // which policy was enforced and effective. This value is in RFC 3339 + // format. + EffectiveTime string `json:"effectiveTime,omitempty"` + + // IsLocked: Once locked, an object retention policy cannot be modified. + IsLocked bool `json:"isLocked,omitempty"` + + // RetentionPeriod: The duration in seconds that objects need to be + // retained. Retention duration must be greater than zero and less than + // 100 years. Note that enforcement of retention periods less than a day + // is not guaranteed. Such periods should only be used for testing + // purposes. + RetentionPeriod int64 `json:"retentionPeriod,omitempty,string"` + + // ForceSendFields is a list of field names (e.g. "EffectiveTime") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "EffectiveTime") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketRetentionPolicy) MarshalJSON() ([]byte, error) { + type NoMethod BucketRetentionPolicy + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketVersioning: The bucket's versioning configuration. +type BucketVersioning struct { + // Enabled: While set to true, versioning is fully enabled for this + // bucket. + Enabled bool `json:"enabled,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Enabled") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Enabled") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketVersioning) MarshalJSON() ([]byte, error) { + type NoMethod BucketVersioning + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketWebsite: The bucket's website configuration, controlling how +// the service behaves when accessing bucket contents as a web site. See +// the Static Website Examples for more information. +type BucketWebsite struct { + // MainPageSuffix: If the requested object path is missing, the service + // will ensure the path has a trailing '/', append this suffix, and + // attempt to retrieve the resulting object. This allows the creation of + // index.html objects to represent directory pages. + MainPageSuffix string `json:"mainPageSuffix,omitempty"` + + // NotFoundPage: If the requested object path is missing, and any + // mainPageSuffix object is missing, if applicable, the service will + // return the named object from this bucket as the content for a 404 Not + // Found result. + NotFoundPage string `json:"notFoundPage,omitempty"` + + // ForceSendFields is a list of field names (e.g. "MainPageSuffix") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "MainPageSuffix") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *BucketWebsite) MarshalJSON() ([]byte, error) { + type NoMethod BucketWebsite + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketAccessControl: An access-control entry. +type BucketAccessControl struct { + // Bucket: The name of the bucket. + Bucket string `json:"bucket,omitempty"` + + // Domain: The domain associated with the entity, if any. + Domain string `json:"domain,omitempty"` + + // Email: The email address associated with the entity, if any. + Email string `json:"email,omitempty"` + + // Entity: The entity holding the permission, in one of the following + // forms: + // - user-userId + // - user-email + // - group-groupId + // - group-email + // - domain-domain + // - project-team-projectId + // - allUsers + // - allAuthenticatedUsers Examples: + // - The user liz@example.com would be user-liz@example.com. + // - The group example@googlegroups.com would be + // group-example@googlegroups.com. + // - To refer to all members of the Google Apps for Business domain + // example.com, the entity would be domain-example.com. + Entity string `json:"entity,omitempty"` + + // EntityId: The ID for the entity, if any. + EntityId string `json:"entityId,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the access-control entry. + Etag string `json:"etag,omitempty"` + + // Id: The ID of the access-control entry. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For bucket access control entries, + // this is always storage#bucketAccessControl. + Kind string `json:"kind,omitempty"` + + // ProjectTeam: The project team associated with the entity, if any. + ProjectTeam *BucketAccessControlProjectTeam `json:"projectTeam,omitempty"` + + // Role: The access permission for the entity. + Role string `json:"role,omitempty"` + + // SelfLink: The link to this access-control entry. + SelfLink string `json:"selfLink,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Bucket") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Bucket") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketAccessControl) MarshalJSON() ([]byte, error) { + type NoMethod BucketAccessControl + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketAccessControlProjectTeam: The project team associated with the +// entity, if any. +type BucketAccessControlProjectTeam struct { + // ProjectNumber: The project number. + ProjectNumber string `json:"projectNumber,omitempty"` + + // Team: The team. + Team string `json:"team,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ProjectNumber") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "ProjectNumber") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketAccessControlProjectTeam) MarshalJSON() ([]byte, error) { + type NoMethod BucketAccessControlProjectTeam + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// BucketAccessControls: An access-control list. +type BucketAccessControls struct { + // Items: The list of items. + Items []*BucketAccessControl `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of bucket access control + // entries, this is always storage#bucketAccessControls. + Kind string `json:"kind,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *BucketAccessControls) MarshalJSON() ([]byte, error) { + type NoMethod BucketAccessControls + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Buckets: A list of buckets. +type Buckets struct { + // Items: The list of items. + Items []*Bucket `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of buckets, this is always + // storage#buckets. + Kind string `json:"kind,omitempty"` + + // NextPageToken: The continuation token, used to page through large + // result sets. Provide this value in a subsequent request to return the + // next page of results. + NextPageToken string `json:"nextPageToken,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Buckets) MarshalJSON() ([]byte, error) { + type NoMethod Buckets + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Channel: An notification channel used to watch for resource changes. +type Channel struct { + // Address: The address where notifications are delivered for this + // channel. + Address string `json:"address,omitempty"` + + // Expiration: Date and time of notification channel expiration, + // expressed as a Unix timestamp, in milliseconds. Optional. + Expiration int64 `json:"expiration,omitempty,string"` + + // Id: A UUID or similar unique string that identifies this channel. + Id string `json:"id,omitempty"` + + // Kind: Identifies this as a notification channel used to watch for + // changes to a resource. Value: the fixed string "api#channel". + Kind string `json:"kind,omitempty"` + + // Params: Additional parameters controlling delivery channel behavior. + // Optional. + Params map[string]string `json:"params,omitempty"` + + // Payload: A Boolean value to indicate whether payload is wanted. + // Optional. + Payload bool `json:"payload,omitempty"` + + // ResourceId: An opaque ID that identifies the resource being watched + // on this channel. Stable across different API versions. + ResourceId string `json:"resourceId,omitempty"` + + // ResourceUri: A version-specific identifier for the watched resource. + ResourceUri string `json:"resourceUri,omitempty"` + + // Token: An arbitrary string delivered to the target address with each + // notification delivered over this channel. Optional. + Token string `json:"token,omitempty"` + + // Type: The type of delivery mechanism used for this channel. + Type string `json:"type,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Address") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Address") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Channel) MarshalJSON() ([]byte, error) { + type NoMethod Channel + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ComposeRequest: A Compose request. +type ComposeRequest struct { + // Destination: Properties of the resulting object. + Destination *Object `json:"destination,omitempty"` + + // Kind: The kind of item this is. + Kind string `json:"kind,omitempty"` + + // SourceObjects: The list of source objects that will be concatenated + // into a single object. + SourceObjects []*ComposeRequestSourceObjects `json:"sourceObjects,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Destination") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Destination") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ComposeRequest) MarshalJSON() ([]byte, error) { + type NoMethod ComposeRequest + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type ComposeRequestSourceObjects struct { + // Generation: The generation of this object to use as the source. + Generation int64 `json:"generation,omitempty,string"` + + // Name: The source object's name. All source objects must reside in the + // same bucket. + Name string `json:"name,omitempty"` + + // ObjectPreconditions: Conditions that must be met for this operation + // to execute. + ObjectPreconditions *ComposeRequestSourceObjectsObjectPreconditions `json:"objectPreconditions,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Generation") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Generation") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ComposeRequestSourceObjects) MarshalJSON() ([]byte, error) { + type NoMethod ComposeRequestSourceObjects + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ComposeRequestSourceObjectsObjectPreconditions: Conditions that must +// be met for this operation to execute. +type ComposeRequestSourceObjectsObjectPreconditions struct { + // IfGenerationMatch: Only perform the composition if the generation of + // the source object that would be used matches this value. If this + // value and a generation are both specified, they must be the same + // value or the call will fail. + IfGenerationMatch int64 `json:"ifGenerationMatch,omitempty,string"` + + // ForceSendFields is a list of field names (e.g. "IfGenerationMatch") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "IfGenerationMatch") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *ComposeRequestSourceObjectsObjectPreconditions) MarshalJSON() ([]byte, error) { + type NoMethod ComposeRequestSourceObjectsObjectPreconditions + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Expr: Represents an expression text. Example: title: "User account +// presence" description: "Determines whether the request has a user +// account" expression: "size(request.user) > 0" +type Expr struct { + // Description: An optional description of the expression. This is a + // longer text which describes the expression, e.g. when hovered over it + // in a UI. + Description string `json:"description,omitempty"` + + // Expression: Textual representation of an expression in Common + // Expression Language syntax. The application context of the containing + // message determines which well-known feature set of CEL is supported. + Expression string `json:"expression,omitempty"` + + // Kind: The kind of item this is. For storage, this is always + // storage#expr. This field is ignored on input. + Kind string `json:"kind,omitempty"` + + // Location: An optional string indicating the location of the + // expression for error reporting, e.g. a file name and a position in + // the file. + Location string `json:"location,omitempty"` + + // Title: An optional title for the expression, i.e. a short string + // describing its purpose. This can be used e.g. in UIs which allow to + // enter the expression. + Title string `json:"title,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Description") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Description") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Expr) MarshalJSON() ([]byte, error) { + type NoMethod Expr + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// HmacKey: JSON template to produce a JSON-style HMAC Key resource for +// Create responses. +type HmacKey struct { + // Kind: The kind of item this is. For HMAC keys, this is always + // storage#hmacKey. + Kind string `json:"kind,omitempty"` + + // Metadata: Key metadata. + Metadata interface{} `json:"metadata,omitempty"` + + // Secret: HMAC secret key material. + Secret string `json:"secret,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Kind") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Kind") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *HmacKey) MarshalJSON() ([]byte, error) { + type NoMethod HmacKey + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// HmacKeyMetadata: JSON template to produce a JSON-style HMAC Key +// metadata resource. +type HmacKeyMetadata struct { + // AccessId: The ID of the HMAC Key. + AccessId string `json:"accessId,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the access-control entry. + Etag string `json:"etag,omitempty"` + + // Id: The ID of the HMAC key, including the Project ID and the Access + // ID. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For HMAC Key metadata, this is always + // storage#hmacKeyMetadata. + Kind string `json:"kind,omitempty"` + + // ProjectId: Project ID owning the service account to which the key + // authenticates. + ProjectId string `json:"projectId,omitempty"` + + // SelfLink: The link to this resource. + SelfLink string `json:"selfLink,omitempty"` + + // ServiceAccountEmail: The email address of the key's associated + // service account. + ServiceAccountEmail string `json:"serviceAccountEmail,omitempty"` + + // State: The state of the key. Can be one of ACTIVE, INACTIVE, or + // DELETED. + State string `json:"state,omitempty"` + + // TimeCreated: The creation time of the HMAC key in RFC 3339 format. + TimeCreated string `json:"timeCreated,omitempty"` + + // Updated: The last modification time of the HMAC key metadata in RFC + // 3339 format. + Updated string `json:"updated,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "AccessId") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "AccessId") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *HmacKeyMetadata) MarshalJSON() ([]byte, error) { + type NoMethod HmacKeyMetadata + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// HmacKeysMetadata: A list of hmacKeys. +type HmacKeysMetadata struct { + // Items: The list of items. + Items []*HmacKeyMetadata `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of hmacKeys, this is always + // storage#hmacKeysMetadata. + Kind string `json:"kind,omitempty"` + + // NextPageToken: The continuation token, used to page through large + // result sets. Provide this value in a subsequent request to return the + // next page of results. + NextPageToken string `json:"nextPageToken,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *HmacKeysMetadata) MarshalJSON() ([]byte, error) { + type NoMethod HmacKeysMetadata + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Notification: A subscription to receive Google PubSub notifications. +type Notification struct { + // CustomAttributes: An optional list of additional attributes to attach + // to each Cloud PubSub message published for this notification + // subscription. + CustomAttributes map[string]string `json:"custom_attributes,omitempty"` + + // Etag: HTTP 1.1 Entity tag for this subscription notification. + Etag string `json:"etag,omitempty"` + + // EventTypes: If present, only send notifications about listed event + // types. If empty, sent notifications for all event types. + EventTypes []string `json:"event_types,omitempty"` + + // Id: The ID of the notification. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For notifications, this is always + // storage#notification. + Kind string `json:"kind,omitempty"` + + // ObjectNamePrefix: If present, only apply this notification + // configuration to object names that begin with this prefix. + ObjectNamePrefix string `json:"object_name_prefix,omitempty"` + + // PayloadFormat: The desired content of the Payload. + PayloadFormat string `json:"payload_format,omitempty"` + + // SelfLink: The canonical URL of this notification. + SelfLink string `json:"selfLink,omitempty"` + + // Topic: The Cloud PubSub topic to which this subscription publishes. + // Formatted as: + // '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topi + // c}' + Topic string `json:"topic,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "CustomAttributes") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "CustomAttributes") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *Notification) MarshalJSON() ([]byte, error) { + type NoMethod Notification + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Notifications: A list of notification subscriptions. +type Notifications struct { + // Items: The list of items. + Items []*Notification `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of notifications, this is + // always storage#notifications. + Kind string `json:"kind,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Notifications) MarshalJSON() ([]byte, error) { + type NoMethod Notifications + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Object: An object. +type Object struct { + // Acl: Access controls on the object. + Acl []*ObjectAccessControl `json:"acl,omitempty"` + + // Bucket: The name of the bucket containing this object. + Bucket string `json:"bucket,omitempty"` + + // CacheControl: Cache-Control directive for the object data. If + // omitted, and the object is accessible to all anonymous users, the + // default will be public, max-age=3600. + CacheControl string `json:"cacheControl,omitempty"` + + // ComponentCount: Number of underlying components that make up this + // object. Components are accumulated by compose operations. + ComponentCount int64 `json:"componentCount,omitempty"` + + // ContentDisposition: Content-Disposition of the object data. + ContentDisposition string `json:"contentDisposition,omitempty"` + + // ContentEncoding: Content-Encoding of the object data. + ContentEncoding string `json:"contentEncoding,omitempty"` + + // ContentLanguage: Content-Language of the object data. + ContentLanguage string `json:"contentLanguage,omitempty"` + + // ContentType: Content-Type of the object data. If an object is stored + // without a Content-Type, it is served as application/octet-stream. + ContentType string `json:"contentType,omitempty"` + + // Crc32c: CRC32c checksum, as described in RFC 4960, Appendix B; + // encoded using base64 in big-endian byte order. For more information + // about using the CRC32c checksum, see Hashes and ETags: Best + // Practices. + Crc32c string `json:"crc32c,omitempty"` + + // CustomerEncryption: Metadata of customer-supplied encryption key, if + // the object is encrypted by such a key. + CustomerEncryption *ObjectCustomerEncryption `json:"customerEncryption,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the object. + Etag string `json:"etag,omitempty"` + + // EventBasedHold: Whether an object is under event-based hold. + // Event-based hold is a way to retain objects until an event occurs, + // which is signified by the hold's release (i.e. this value is set to + // false). After being released (set to false), such objects will be + // subject to bucket-level retention (if any). One sample use case of + // this flag is for banks to hold loan documents for at least 3 years + // after loan is paid in full. Here, bucket-level retention is 3 years + // and the event is the loan being paid in full. In this example, these + // objects will be held intact for any number of years until the event + // has occurred (event-based hold on the object is released) and then 3 + // more years after that. That means retention duration of the objects + // begins from the moment event-based hold transitioned from true to + // false. + EventBasedHold bool `json:"eventBasedHold,omitempty"` + + // Generation: The content generation of this object. Used for object + // versioning. + Generation int64 `json:"generation,omitempty,string"` + + // Id: The ID of the object, including the bucket name, object name, and + // generation number. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For objects, this is always + // storage#object. + Kind string `json:"kind,omitempty"` + + // KmsKeyName: Cloud KMS Key used to encrypt this object, if the object + // is encrypted by such a key. + KmsKeyName string `json:"kmsKeyName,omitempty"` + + // Md5Hash: MD5 hash of the data; encoded using base64. For more + // information about using the MD5 hash, see Hashes and ETags: Best + // Practices. + Md5Hash string `json:"md5Hash,omitempty"` + + // MediaLink: Media download link. + MediaLink string `json:"mediaLink,omitempty"` + + // Metadata: User-provided metadata, in key/value pairs. + Metadata map[string]string `json:"metadata,omitempty"` + + // Metageneration: The version of the metadata for this object at this + // generation. Used for preconditions and for detecting changes in + // metadata. A metageneration number is only meaningful in the context + // of a particular generation of a particular object. + Metageneration int64 `json:"metageneration,omitempty,string"` + + // Name: The name of the object. Required if not specified by URL + // parameter. + Name string `json:"name,omitempty"` + + // Owner: The owner of the object. This will always be the uploader of + // the object. + Owner *ObjectOwner `json:"owner,omitempty"` + + // RetentionExpirationTime: A server-determined value that specifies the + // earliest time that the object's retention period expires. This value + // is in RFC 3339 format. Note 1: This field is not provided for objects + // with an active event-based hold, since retention expiration is + // unknown until the hold is removed. Note 2: This value can be provided + // even when temporary hold is set (so that the user can reason about + // policy without having to first unset the temporary hold). + RetentionExpirationTime string `json:"retentionExpirationTime,omitempty"` + + // SelfLink: The link to this object. + SelfLink string `json:"selfLink,omitempty"` + + // Size: Content-Length of the data in bytes. + Size uint64 `json:"size,omitempty,string"` + + // StorageClass: Storage class of the object. + StorageClass string `json:"storageClass,omitempty"` + + // TemporaryHold: Whether an object is under temporary hold. While this + // flag is set to true, the object is protected against deletion and + // overwrites. A common use case of this flag is regulatory + // investigations where objects need to be retained while the + // investigation is ongoing. Note that unlike event-based hold, + // temporary hold does not impact retention expiration time of an + // object. + TemporaryHold bool `json:"temporaryHold,omitempty"` + + // TimeCreated: The creation time of the object in RFC 3339 format. + TimeCreated string `json:"timeCreated,omitempty"` + + // TimeDeleted: The deletion time of the object in RFC 3339 format. Will + // be returned if and only if this version of the object has been + // deleted. + TimeDeleted string `json:"timeDeleted,omitempty"` + + // TimeStorageClassUpdated: The time at which the object's storage class + // was last changed. When the object is initially created, it will be + // set to timeCreated. + TimeStorageClassUpdated string `json:"timeStorageClassUpdated,omitempty"` + + // Updated: The modification time of the object metadata in RFC 3339 + // format. + Updated string `json:"updated,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Acl") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Acl") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Object) MarshalJSON() ([]byte, error) { + type NoMethod Object + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectCustomerEncryption: Metadata of customer-supplied encryption +// key, if the object is encrypted by such a key. +type ObjectCustomerEncryption struct { + // EncryptionAlgorithm: The encryption algorithm. + EncryptionAlgorithm string `json:"encryptionAlgorithm,omitempty"` + + // KeySha256: SHA256 hash value of the encryption key. + KeySha256 string `json:"keySha256,omitempty"` + + // ForceSendFields is a list of field names (e.g. "EncryptionAlgorithm") + // to unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "EncryptionAlgorithm") to + // include in API requests with the JSON null value. By default, fields + // with empty values are omitted from API requests. However, any field + // with an empty value appearing in NullFields will be sent to the + // server as null. It is an error if a field in this list has a + // non-empty value. This may be used to include null fields in Patch + // requests. + NullFields []string `json:"-"` +} + +func (s *ObjectCustomerEncryption) MarshalJSON() ([]byte, error) { + type NoMethod ObjectCustomerEncryption + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectOwner: The owner of the object. This will always be the +// uploader of the object. +type ObjectOwner struct { + // Entity: The entity, in the form user-userId. + Entity string `json:"entity,omitempty"` + + // EntityId: The ID for the entity. + EntityId string `json:"entityId,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Entity") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Entity") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ObjectOwner) MarshalJSON() ([]byte, error) { + type NoMethod ObjectOwner + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectAccessControl: An access-control entry. +type ObjectAccessControl struct { + // Bucket: The name of the bucket. + Bucket string `json:"bucket,omitempty"` + + // Domain: The domain associated with the entity, if any. + Domain string `json:"domain,omitempty"` + + // Email: The email address associated with the entity, if any. + Email string `json:"email,omitempty"` + + // Entity: The entity holding the permission, in one of the following + // forms: + // - user-userId + // - user-email + // - group-groupId + // - group-email + // - domain-domain + // - project-team-projectId + // - allUsers + // - allAuthenticatedUsers Examples: + // - The user liz@example.com would be user-liz@example.com. + // - The group example@googlegroups.com would be + // group-example@googlegroups.com. + // - To refer to all members of the Google Apps for Business domain + // example.com, the entity would be domain-example.com. + Entity string `json:"entity,omitempty"` + + // EntityId: The ID for the entity, if any. + EntityId string `json:"entityId,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the access-control entry. + Etag string `json:"etag,omitempty"` + + // Generation: The content generation of the object, if applied to an + // object. + Generation int64 `json:"generation,omitempty,string"` + + // Id: The ID of the access-control entry. + Id string `json:"id,omitempty"` + + // Kind: The kind of item this is. For object access control entries, + // this is always storage#objectAccessControl. + Kind string `json:"kind,omitempty"` + + // Object: The name of the object, if applied to an object. + Object string `json:"object,omitempty"` + + // ProjectTeam: The project team associated with the entity, if any. + ProjectTeam *ObjectAccessControlProjectTeam `json:"projectTeam,omitempty"` + + // Role: The access permission for the entity. + Role string `json:"role,omitempty"` + + // SelfLink: The link to this access-control entry. + SelfLink string `json:"selfLink,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Bucket") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Bucket") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ObjectAccessControl) MarshalJSON() ([]byte, error) { + type NoMethod ObjectAccessControl + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectAccessControlProjectTeam: The project team associated with the +// entity, if any. +type ObjectAccessControlProjectTeam struct { + // ProjectNumber: The project number. + ProjectNumber string `json:"projectNumber,omitempty"` + + // Team: The team. + Team string `json:"team,omitempty"` + + // ForceSendFields is a list of field names (e.g. "ProjectNumber") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "ProjectNumber") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ObjectAccessControlProjectTeam) MarshalJSON() ([]byte, error) { + type NoMethod ObjectAccessControlProjectTeam + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ObjectAccessControls: An access-control list. +type ObjectAccessControls struct { + // Items: The list of items. + Items []*ObjectAccessControl `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of object access control + // entries, this is always storage#objectAccessControls. + Kind string `json:"kind,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ObjectAccessControls) MarshalJSON() ([]byte, error) { + type NoMethod ObjectAccessControls + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Objects: A list of objects. +type Objects struct { + // Items: The list of items. + Items []*Object `json:"items,omitempty"` + + // Kind: The kind of item this is. For lists of objects, this is always + // storage#objects. + Kind string `json:"kind,omitempty"` + + // NextPageToken: The continuation token, used to page through large + // result sets. Provide this value in a subsequent request to return the + // next page of results. + NextPageToken string `json:"nextPageToken,omitempty"` + + // Prefixes: The list of prefixes of objects matching-but-not-listed up + // to and including the requested delimiter. + Prefixes []string `json:"prefixes,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Items") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Items") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Objects) MarshalJSON() ([]byte, error) { + type NoMethod Objects + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// Policy: A bucket/object IAM policy. +type Policy struct { + // Bindings: An association between a role, which comes with a set of + // permissions, and members who may assume that role. + Bindings []*PolicyBindings `json:"bindings,omitempty"` + + // Etag: HTTP 1.1 Entity tag for the policy. + Etag string `json:"etag,omitempty"` + + // Kind: The kind of item this is. For policies, this is always + // storage#policy. This field is ignored on input. + Kind string `json:"kind,omitempty"` + + // ResourceId: The ID of the resource to which this policy belongs. Will + // be of the form projects/_/buckets/bucket for buckets, and + // projects/_/buckets/bucket/objects/object for objects. A specific + // generation may be specified by appending #generationNumber to the end + // of the object name, e.g. + // projects/_/buckets/my-bucket/objects/data.txt#17. The current + // generation can be denoted with #0. This field is ignored on input. + ResourceId string `json:"resourceId,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Bindings") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Bindings") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *Policy) MarshalJSON() ([]byte, error) { + type NoMethod Policy + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +type PolicyBindings struct { + // Condition: The condition that is associated with this binding. NOTE: + // an unsatisfied condition will not allow user access via current + // binding. Different bindings, including their conditions, are examined + // independently. + Condition *Expr `json:"condition,omitempty"` + + // Members: A collection of identifiers for members who may assume the + // provided role. Recognized identifiers are as follows: + // - allUsers — A special identifier that represents anyone on the + // internet; with or without a Google account. + // - allAuthenticatedUsers — A special identifier that represents + // anyone who is authenticated with a Google account or a service + // account. + // - user:emailid — An email address that represents a specific + // account. For example, user:alice@gmail.com or user:joe@example.com. + // + // - serviceAccount:emailid — An email address that represents a + // service account. For example, + // serviceAccount:my-other-app@appspot.gserviceaccount.com . + // - group:emailid — An email address that represents a Google group. + // For example, group:admins@example.com. + // - domain:domain — A Google Apps domain name that represents all the + // users of that domain. For example, domain:google.com or + // domain:example.com. + // - projectOwner:projectid — Owners of the given project. For + // example, projectOwner:my-example-project + // - projectEditor:projectid — Editors of the given project. For + // example, projectEditor:my-example-project + // - projectViewer:projectid — Viewers of the given project. For + // example, projectViewer:my-example-project + Members []string `json:"members,omitempty"` + + // Role: The role to which members belong. Two types of roles are + // supported: new IAM roles, which grant permissions that do not map + // directly to those provided by ACLs, and legacy IAM roles, which do + // map directly to ACL permissions. All roles are of the format + // roles/storage.specificRole. + // The new IAM roles are: + // - roles/storage.admin — Full control of Google Cloud Storage + // resources. + // - roles/storage.objectViewer — Read-Only access to Google Cloud + // Storage objects. + // - roles/storage.objectCreator — Access to create objects in Google + // Cloud Storage. + // - roles/storage.objectAdmin — Full control of Google Cloud Storage + // objects. The legacy IAM roles are: + // - roles/storage.legacyObjectReader — Read-only access to objects + // without listing. Equivalent to an ACL entry on an object with the + // READER role. + // - roles/storage.legacyObjectOwner — Read/write access to existing + // objects without listing. Equivalent to an ACL entry on an object with + // the OWNER role. + // - roles/storage.legacyBucketReader — Read access to buckets with + // object listing. Equivalent to an ACL entry on a bucket with the + // READER role. + // - roles/storage.legacyBucketWriter — Read access to buckets with + // object listing/creation/deletion. Equivalent to an ACL entry on a + // bucket with the WRITER role. + // - roles/storage.legacyBucketOwner — Read and write access to + // existing buckets with object listing/creation/deletion. Equivalent to + // an ACL entry on a bucket with the OWNER role. + Role string `json:"role,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Condition") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Condition") to include in + // API requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *PolicyBindings) MarshalJSON() ([]byte, error) { + type NoMethod PolicyBindings + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// RewriteResponse: A rewrite response. +type RewriteResponse struct { + // Done: true if the copy is finished; otherwise, false if the copy is + // in progress. This property is always present in the response. + Done bool `json:"done,omitempty"` + + // Kind: The kind of item this is. + Kind string `json:"kind,omitempty"` + + // ObjectSize: The total size of the object being copied in bytes. This + // property is always present in the response. + ObjectSize int64 `json:"objectSize,omitempty,string"` + + // Resource: A resource containing the metadata for the copied-to + // object. This property is present in the response only when copying + // completes. + Resource *Object `json:"resource,omitempty"` + + // RewriteToken: A token to use in subsequent requests to continue + // copying data. This token is present in the response only when there + // is more data to copy. + RewriteToken string `json:"rewriteToken,omitempty"` + + // TotalBytesRewritten: The total bytes written so far, which can be + // used to provide a waiting user with a progress indicator. This + // property is always present in the response. + TotalBytesRewritten int64 `json:"totalBytesRewritten,omitempty,string"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Done") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Done") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *RewriteResponse) MarshalJSON() ([]byte, error) { + type NoMethod RewriteResponse + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// ServiceAccount: A subscription to receive Google PubSub +// notifications. +type ServiceAccount struct { + // EmailAddress: The ID of the notification. + EmailAddress string `json:"email_address,omitempty"` + + // Kind: The kind of item this is. For notifications, this is always + // storage#notification. + Kind string `json:"kind,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "EmailAddress") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "EmailAddress") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *ServiceAccount) MarshalJSON() ([]byte, error) { + type NoMethod ServiceAccount + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// TestIamPermissionsResponse: A +// storage.(buckets|objects).testIamPermissions response. +type TestIamPermissionsResponse struct { + // Kind: The kind of item this is. + Kind string `json:"kind,omitempty"` + + // Permissions: The permissions held by the caller. Permissions are + // always of the format storage.resource.capability, where resource is + // one of buckets or objects. The supported permissions are as follows: + // + // - storage.buckets.delete — Delete bucket. + // - storage.buckets.get — Read bucket metadata. + // - storage.buckets.getIamPolicy — Read bucket IAM policy. + // - storage.buckets.create — Create bucket. + // - storage.buckets.list — List buckets. + // - storage.buckets.setIamPolicy — Update bucket IAM policy. + // - storage.buckets.update — Update bucket metadata. + // - storage.objects.delete — Delete object. + // - storage.objects.get — Read object data and metadata. + // - storage.objects.getIamPolicy — Read object IAM policy. + // - storage.objects.create — Create object. + // - storage.objects.list — List objects. + // - storage.objects.setIamPolicy — Update object IAM policy. + // - storage.objects.update — Update object metadata. + Permissions []string `json:"permissions,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "Kind") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Kind") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *TestIamPermissionsResponse) MarshalJSON() ([]byte, error) { + type NoMethod TestIamPermissionsResponse + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// method id "storage.bucketAccessControls.delete": + +type BucketAccessControlsDeleteCall struct { + s *Service + bucket string + entity string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes the ACL entry for the specified entity on +// the specified bucket. +func (r *BucketAccessControlsService) Delete(bucket string, entity string) *BucketAccessControlsDeleteCall { + c := &BucketAccessControlsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsDeleteCall) UserProject(userProject string) *BucketAccessControlsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsDeleteCall) Fields(s ...googleapi.Field) *BucketAccessControlsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsDeleteCall) Context(ctx context.Context) *BucketAccessControlsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.delete" call. +func (c *BucketAccessControlsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes the ACL entry for the specified entity on the specified bucket.", + // "httpMethod": "DELETE", + // "id": "storage.bucketAccessControls.delete", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl/{entity}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.get": + +type BucketAccessControlsGetCall struct { + s *Service + bucket string + entity string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Returns the ACL entry for the specified entity on the specified +// bucket. +func (r *BucketAccessControlsService) Get(bucket string, entity string) *BucketAccessControlsGetCall { + c := &BucketAccessControlsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsGetCall) UserProject(userProject string) *BucketAccessControlsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsGetCall) Fields(s ...googleapi.Field) *BucketAccessControlsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketAccessControlsGetCall) IfNoneMatch(entityTag string) *BucketAccessControlsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsGetCall) Context(ctx context.Context) *BucketAccessControlsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.get" call. +// Exactly one of *BucketAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsGetCall) Do(opts ...googleapi.CallOption) (*BucketAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns the ACL entry for the specified entity on the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.bucketAccessControls.get", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl/{entity}", + // "response": { + // "$ref": "BucketAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.insert": + +type BucketAccessControlsInsertCall struct { + s *Service + bucket string + bucketaccesscontrol *BucketAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a new ACL entry on the specified bucket. +func (r *BucketAccessControlsService) Insert(bucket string, bucketaccesscontrol *BucketAccessControl) *BucketAccessControlsInsertCall { + c := &BucketAccessControlsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.bucketaccesscontrol = bucketaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsInsertCall) UserProject(userProject string) *BucketAccessControlsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsInsertCall) Fields(s ...googleapi.Field) *BucketAccessControlsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsInsertCall) Context(ctx context.Context) *BucketAccessControlsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucketaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.insert" call. +// Exactly one of *BucketAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsInsertCall) Do(opts ...googleapi.CallOption) (*BucketAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new ACL entry on the specified bucket.", + // "httpMethod": "POST", + // "id": "storage.bucketAccessControls.insert", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl", + // "request": { + // "$ref": "BucketAccessControl" + // }, + // "response": { + // "$ref": "BucketAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.list": + +type BucketAccessControlsListCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves ACL entries on the specified bucket. +func (r *BucketAccessControlsService) List(bucket string) *BucketAccessControlsListCall { + c := &BucketAccessControlsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsListCall) UserProject(userProject string) *BucketAccessControlsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsListCall) Fields(s ...googleapi.Field) *BucketAccessControlsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketAccessControlsListCall) IfNoneMatch(entityTag string) *BucketAccessControlsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsListCall) Context(ctx context.Context) *BucketAccessControlsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.list" call. +// Exactly one of *BucketAccessControls or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControls.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsListCall) Do(opts ...googleapi.CallOption) (*BucketAccessControls, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControls{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves ACL entries on the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.bucketAccessControls.list", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl", + // "response": { + // "$ref": "BucketAccessControls" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.patch": + +type BucketAccessControlsPatchCall struct { + s *Service + bucket string + entity string + bucketaccesscontrol *BucketAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches an ACL entry on the specified bucket. +func (r *BucketAccessControlsService) Patch(bucket string, entity string, bucketaccesscontrol *BucketAccessControl) *BucketAccessControlsPatchCall { + c := &BucketAccessControlsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + c.bucketaccesscontrol = bucketaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsPatchCall) UserProject(userProject string) *BucketAccessControlsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsPatchCall) Fields(s ...googleapi.Field) *BucketAccessControlsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsPatchCall) Context(ctx context.Context) *BucketAccessControlsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucketaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PATCH", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.patch" call. +// Exactly one of *BucketAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsPatchCall) Do(opts ...googleapi.CallOption) (*BucketAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches an ACL entry on the specified bucket.", + // "httpMethod": "PATCH", + // "id": "storage.bucketAccessControls.patch", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl/{entity}", + // "request": { + // "$ref": "BucketAccessControl" + // }, + // "response": { + // "$ref": "BucketAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.bucketAccessControls.update": + +type BucketAccessControlsUpdateCall struct { + s *Service + bucket string + entity string + bucketaccesscontrol *BucketAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates an ACL entry on the specified bucket. +func (r *BucketAccessControlsService) Update(bucket string, entity string, bucketaccesscontrol *BucketAccessControl) *BucketAccessControlsUpdateCall { + c := &BucketAccessControlsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + c.bucketaccesscontrol = bucketaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketAccessControlsUpdateCall) UserProject(userProject string) *BucketAccessControlsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketAccessControlsUpdateCall) Fields(s ...googleapi.Field) *BucketAccessControlsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketAccessControlsUpdateCall) Context(ctx context.Context) *BucketAccessControlsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketAccessControlsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketAccessControlsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucketaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.bucketAccessControls.update" call. +// Exactly one of *BucketAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *BucketAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketAccessControlsUpdateCall) Do(opts ...googleapi.CallOption) (*BucketAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &BucketAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an ACL entry on the specified bucket.", + // "httpMethod": "PUT", + // "id": "storage.bucketAccessControls.update", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/acl/{entity}", + // "request": { + // "$ref": "BucketAccessControl" + // }, + // "response": { + // "$ref": "BucketAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.buckets.delete": + +type BucketsDeleteCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes an empty bucket. +func (r *BucketsService) Delete(bucket string) *BucketsDeleteCall { + c := &BucketsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": If set, only deletes the bucket if its +// metageneration matches this value. +func (c *BucketsDeleteCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *BucketsDeleteCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": If set, only deletes the bucket if its +// metageneration does not match this value. +func (c *BucketsDeleteCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *BucketsDeleteCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsDeleteCall) UserProject(userProject string) *BucketsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsDeleteCall) Fields(s ...googleapi.Field) *BucketsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsDeleteCall) Context(ctx context.Context) *BucketsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.delete" call. +func (c *BucketsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes an empty bucket.", + // "httpMethod": "DELETE", + // "id": "storage.buckets.delete", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "If set, only deletes the bucket if its metageneration matches this value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "If set, only deletes the bucket if its metageneration does not match this value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.get": + +type BucketsGetCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Returns metadata for the specified bucket. +func (r *BucketsService) Get(bucket string) *BucketsGetCall { + c := &BucketsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration matches +// the given value. +func (c *BucketsGetCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *BucketsGetCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration does not +// match the given value. +func (c *BucketsGetCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *BucketsGetCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsGetCall) Projection(projection string) *BucketsGetCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsGetCall) UserProject(userProject string) *BucketsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsGetCall) Fields(s ...googleapi.Field) *BucketsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketsGetCall) IfNoneMatch(entityTag string) *BucketsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsGetCall) Context(ctx context.Context) *BucketsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.get" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsGetCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns metadata for the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.buckets.get", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}", + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.getIamPolicy": + +type BucketsGetIamPolicyCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// GetIamPolicy: Returns an IAM policy for the specified bucket. +func (r *BucketsService) GetIamPolicy(bucket string) *BucketsGetIamPolicyCall { + c := &BucketsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsGetIamPolicyCall) UserProject(userProject string) *BucketsGetIamPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsGetIamPolicyCall) Fields(s ...googleapi.Field) *BucketsGetIamPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketsGetIamPolicyCall) IfNoneMatch(entityTag string) *BucketsGetIamPolicyCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsGetIamPolicyCall) Context(ctx context.Context) *BucketsGetIamPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsGetIamPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/iam") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.getIamPolicy" call. +// Exactly one of *Policy or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Policy.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Policy{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns an IAM policy for the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.buckets.getIamPolicy", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/iam", + // "response": { + // "$ref": "Policy" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.insert": + +type BucketsInsertCall struct { + s *Service + bucket *Bucket + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a new bucket. +func (r *BucketsService) Insert(projectid string, bucket *Bucket) *BucketsInsertCall { + c := &BucketsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.urlParams_.Set("project", projectid) + c.bucket = bucket + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Project team owners get OWNER access, and +// allAuthenticatedUsers get READER access. +// "private" - Project team owners get OWNER access. +// "projectPrivate" - Project team members get access according to +// their roles. +// "publicRead" - Project team owners get OWNER access, and allUsers +// get READER access. +// "publicReadWrite" - Project team owners get OWNER access, and +// allUsers get WRITER access. +func (c *BucketsInsertCall) PredefinedAcl(predefinedAcl string) *BucketsInsertCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// PredefinedDefaultObjectAcl sets the optional parameter +// "predefinedDefaultObjectAcl": Apply a predefined set of default +// object access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *BucketsInsertCall) PredefinedDefaultObjectAcl(predefinedDefaultObjectAcl string) *BucketsInsertCall { + c.urlParams_.Set("predefinedDefaultObjectAcl", predefinedDefaultObjectAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl, unless the bucket resource +// specifies acl or defaultObjectAcl properties, when it defaults to +// full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsInsertCall) Projection(projection string) *BucketsInsertCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. +func (c *BucketsInsertCall) UserProject(userProject string) *BucketsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsInsertCall) Fields(s ...googleapi.Field) *BucketsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsInsertCall) Context(ctx context.Context) *BucketsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucket) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.insert" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsInsertCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new bucket.", + // "httpMethod": "POST", + // "id": "storage.buckets.insert", + // "parameterOrder": [ + // "project" + // ], + // "parameters": { + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "private", + // "projectPrivate", + // "publicRead", + // "publicReadWrite" + // ], + // "enumDescriptions": [ + // "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + // "Project team owners get OWNER access.", + // "Project team members get access according to their roles.", + // "Project team owners get OWNER access, and allUsers get READER access.", + // "Project team owners get OWNER access, and allUsers get WRITER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "predefinedDefaultObjectAcl": { + // "description": "Apply a predefined set of default object access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "project": { + // "description": "A valid API project identifier.", + // "location": "query", + // "required": true, + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl, unless the bucket resource specifies acl or defaultObjectAcl properties, when it defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b", + // "request": { + // "$ref": "Bucket" + // }, + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.list": + +type BucketsListCall struct { + s *Service + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves a list of buckets for a given project. +func (r *BucketsService) List(projectid string) *BucketsListCall { + c := &BucketsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.urlParams_.Set("project", projectid) + return c +} + +// MaxResults sets the optional parameter "maxResults": Maximum number +// of buckets to return in a single response. The service will use this +// parameter or 1,000 items, whichever is smaller. +func (c *BucketsListCall) MaxResults(maxResults int64) *BucketsListCall { + c.urlParams_.Set("maxResults", fmt.Sprint(maxResults)) + return c +} + +// PageToken sets the optional parameter "pageToken": A +// previously-returned page token representing part of the larger set of +// results to view. +func (c *BucketsListCall) PageToken(pageToken string) *BucketsListCall { + c.urlParams_.Set("pageToken", pageToken) + return c +} + +// Prefix sets the optional parameter "prefix": Filter results to +// buckets whose names begin with this prefix. +func (c *BucketsListCall) Prefix(prefix string) *BucketsListCall { + c.urlParams_.Set("prefix", prefix) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsListCall) Projection(projection string) *BucketsListCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. +func (c *BucketsListCall) UserProject(userProject string) *BucketsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsListCall) Fields(s ...googleapi.Field) *BucketsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketsListCall) IfNoneMatch(entityTag string) *BucketsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsListCall) Context(ctx context.Context) *BucketsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.list" call. +// Exactly one of *Buckets or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Buckets.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsListCall) Do(opts ...googleapi.CallOption) (*Buckets, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Buckets{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves a list of buckets for a given project.", + // "httpMethod": "GET", + // "id": "storage.buckets.list", + // "parameterOrder": [ + // "project" + // ], + // "parameters": { + // "maxResults": { + // "default": "1000", + // "description": "Maximum number of buckets to return in a single response. The service will use this parameter or 1,000 items, whichever is smaller.", + // "format": "uint32", + // "location": "query", + // "minimum": "0", + // "type": "integer" + // }, + // "pageToken": { + // "description": "A previously-returned page token representing part of the larger set of results to view.", + // "location": "query", + // "type": "string" + // }, + // "prefix": { + // "description": "Filter results to buckets whose names begin with this prefix.", + // "location": "query", + // "type": "string" + // }, + // "project": { + // "description": "A valid API project identifier.", + // "location": "query", + // "required": true, + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b", + // "response": { + // "$ref": "Buckets" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// Pages invokes f for each page of results. +// A non-nil error returned from f will halt the iteration. +// The provided context supersedes any context provided to the Context method. +func (c *BucketsListCall) Pages(ctx context.Context, f func(*Buckets) error) error { + c.ctx_ = ctx + defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point + for { + x, err := c.Do() + if err != nil { + return err + } + if err := f(x); err != nil { + return err + } + if x.NextPageToken == "" { + return nil + } + c.PageToken(x.NextPageToken) + } +} + +// method id "storage.buckets.lockRetentionPolicy": + +type BucketsLockRetentionPolicyCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// LockRetentionPolicy: Locks retention policy on a bucket. +func (r *BucketsService) LockRetentionPolicy(bucket string, ifMetagenerationMatch int64) *BucketsLockRetentionPolicyCall { + c := &BucketsLockRetentionPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsLockRetentionPolicyCall) UserProject(userProject string) *BucketsLockRetentionPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsLockRetentionPolicyCall) Fields(s ...googleapi.Field) *BucketsLockRetentionPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsLockRetentionPolicyCall) Context(ctx context.Context) *BucketsLockRetentionPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsLockRetentionPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsLockRetentionPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/lockRetentionPolicy") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.lockRetentionPolicy" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsLockRetentionPolicyCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Locks retention policy on a bucket.", + // "httpMethod": "POST", + // "id": "storage.buckets.lockRetentionPolicy", + // "parameterOrder": [ + // "bucket", + // "ifMetagenerationMatch" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether bucket's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/lockRetentionPolicy", + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.patch": + +type BucketsPatchCall struct { + s *Service + bucket string + bucket2 *Bucket + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches a bucket. Changes to the bucket will be readable +// immediately after writing, but configuration changes may take time to +// propagate. +func (r *BucketsService) Patch(bucket string, bucket2 *Bucket) *BucketsPatchCall { + c := &BucketsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.bucket2 = bucket2 + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration matches +// the given value. +func (c *BucketsPatchCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *BucketsPatchCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration does not +// match the given value. +func (c *BucketsPatchCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *BucketsPatchCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Project team owners get OWNER access, and +// allAuthenticatedUsers get READER access. +// "private" - Project team owners get OWNER access. +// "projectPrivate" - Project team members get access according to +// their roles. +// "publicRead" - Project team owners get OWNER access, and allUsers +// get READER access. +// "publicReadWrite" - Project team owners get OWNER access, and +// allUsers get WRITER access. +func (c *BucketsPatchCall) PredefinedAcl(predefinedAcl string) *BucketsPatchCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// PredefinedDefaultObjectAcl sets the optional parameter +// "predefinedDefaultObjectAcl": Apply a predefined set of default +// object access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *BucketsPatchCall) PredefinedDefaultObjectAcl(predefinedDefaultObjectAcl string) *BucketsPatchCall { + c.urlParams_.Set("predefinedDefaultObjectAcl", predefinedDefaultObjectAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsPatchCall) Projection(projection string) *BucketsPatchCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsPatchCall) UserProject(userProject string) *BucketsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsPatchCall) Fields(s ...googleapi.Field) *BucketsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsPatchCall) Context(ctx context.Context) *BucketsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucket2) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PATCH", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.patch" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsPatchCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", + // "httpMethod": "PATCH", + // "id": "storage.buckets.patch", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "private", + // "projectPrivate", + // "publicRead", + // "publicReadWrite" + // ], + // "enumDescriptions": [ + // "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + // "Project team owners get OWNER access.", + // "Project team members get access according to their roles.", + // "Project team owners get OWNER access, and allUsers get READER access.", + // "Project team owners get OWNER access, and allUsers get WRITER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "predefinedDefaultObjectAcl": { + // "description": "Apply a predefined set of default object access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}", + // "request": { + // "$ref": "Bucket" + // }, + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.buckets.setIamPolicy": + +type BucketsSetIamPolicyCall struct { + s *Service + bucket string + policy *Policy + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// SetIamPolicy: Updates an IAM policy for the specified bucket. +func (r *BucketsService) SetIamPolicy(bucket string, policy *Policy) *BucketsSetIamPolicyCall { + c := &BucketsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.policy = policy + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsSetIamPolicyCall) UserProject(userProject string) *BucketsSetIamPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsSetIamPolicyCall) Fields(s ...googleapi.Field) *BucketsSetIamPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsSetIamPolicyCall) Context(ctx context.Context) *BucketsSetIamPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsSetIamPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.policy) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/iam") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.setIamPolicy" call. +// Exactly one of *Policy or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Policy.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Policy{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an IAM policy for the specified bucket.", + // "httpMethod": "PUT", + // "id": "storage.buckets.setIamPolicy", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/iam", + // "request": { + // "$ref": "Policy" + // }, + // "response": { + // "$ref": "Policy" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.testIamPermissions": + +type BucketsTestIamPermissionsCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// TestIamPermissions: Tests a set of permissions on the given bucket to +// see which, if any, are held by the caller. +func (r *BucketsService) TestIamPermissions(bucket string, permissions []string) *BucketsTestIamPermissionsCall { + c := &BucketsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.urlParams_.SetMulti("permissions", append([]string{}, permissions...)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsTestIamPermissionsCall) UserProject(userProject string) *BucketsTestIamPermissionsCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsTestIamPermissionsCall) Fields(s ...googleapi.Field) *BucketsTestIamPermissionsCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *BucketsTestIamPermissionsCall) IfNoneMatch(entityTag string) *BucketsTestIamPermissionsCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsTestIamPermissionsCall) Context(ctx context.Context) *BucketsTestIamPermissionsCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsTestIamPermissionsCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/iam/testPermissions") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.testIamPermissions" call. +// Exactly one of *TestIamPermissionsResponse or error will be non-nil. +// Any non-2xx status code is an error. Response headers are in either +// *TestIamPermissionsResponse.ServerResponse.Header or (if a response +// was returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *BucketsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &TestIamPermissionsResponse{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Tests a set of permissions on the given bucket to see which, if any, are held by the caller.", + // "httpMethod": "GET", + // "id": "storage.buckets.testIamPermissions", + // "parameterOrder": [ + // "bucket", + // "permissions" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "permissions": { + // "description": "Permissions to test.", + // "location": "query", + // "repeated": true, + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/iam/testPermissions", + // "response": { + // "$ref": "TestIamPermissionsResponse" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.buckets.update": + +type BucketsUpdateCall struct { + s *Service + bucket string + bucket2 *Bucket + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates a bucket. Changes to the bucket will be readable +// immediately after writing, but configuration changes may take time to +// propagate. +func (r *BucketsService) Update(bucket string, bucket2 *Bucket) *BucketsUpdateCall { + c := &BucketsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.bucket2 = bucket2 + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration matches +// the given value. +func (c *BucketsUpdateCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *BucketsUpdateCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the return of the bucket metadata +// conditional on whether the bucket's current metageneration does not +// match the given value. +func (c *BucketsUpdateCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *BucketsUpdateCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Project team owners get OWNER access, and +// allAuthenticatedUsers get READER access. +// "private" - Project team owners get OWNER access. +// "projectPrivate" - Project team members get access according to +// their roles. +// "publicRead" - Project team owners get OWNER access, and allUsers +// get READER access. +// "publicReadWrite" - Project team owners get OWNER access, and +// allUsers get WRITER access. +func (c *BucketsUpdateCall) PredefinedAcl(predefinedAcl string) *BucketsUpdateCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// PredefinedDefaultObjectAcl sets the optional parameter +// "predefinedDefaultObjectAcl": Apply a predefined set of default +// object access controls to this bucket. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *BucketsUpdateCall) PredefinedDefaultObjectAcl(predefinedDefaultObjectAcl string) *BucketsUpdateCall { + c.urlParams_.Set("predefinedDefaultObjectAcl", predefinedDefaultObjectAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit owner, acl and defaultObjectAcl properties. +func (c *BucketsUpdateCall) Projection(projection string) *BucketsUpdateCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *BucketsUpdateCall) UserProject(userProject string) *BucketsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *BucketsUpdateCall) Fields(s ...googleapi.Field) *BucketsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *BucketsUpdateCall) Context(ctx context.Context) *BucketsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *BucketsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *BucketsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.bucket2) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.buckets.update" call. +// Exactly one of *Bucket or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Bucket.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *BucketsUpdateCall) Do(opts ...googleapi.CallOption) (*Bucket, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Bucket{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", + // "httpMethod": "PUT", + // "id": "storage.buckets.update", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "private", + // "projectPrivate", + // "publicRead", + // "publicReadWrite" + // ], + // "enumDescriptions": [ + // "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", + // "Project team owners get OWNER access.", + // "Project team members get access according to their roles.", + // "Project team owners get OWNER access, and allUsers get READER access.", + // "Project team owners get OWNER access, and allUsers get WRITER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "predefinedDefaultObjectAcl": { + // "description": "Apply a predefined set of default object access controls to this bucket.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit owner, acl and defaultObjectAcl properties." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}", + // "request": { + // "$ref": "Bucket" + // }, + // "response": { + // "$ref": "Bucket" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.channels.stop": + +type ChannelsStopCall struct { + s *Service + channel *Channel + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Stop: Stop watching resources through this channel +func (r *ChannelsService) Stop(channel *Channel) *ChannelsStopCall { + c := &ChannelsStopCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.channel = channel + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ChannelsStopCall) Fields(s ...googleapi.Field) *ChannelsStopCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ChannelsStopCall) Context(ctx context.Context) *ChannelsStopCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ChannelsStopCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ChannelsStopCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.channel) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "channels/stop") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.channels.stop" call. +func (c *ChannelsStopCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Stop watching resources through this channel", + // "httpMethod": "POST", + // "id": "storage.channels.stop", + // "path": "channels/stop", + // "request": { + // "$ref": "Channel", + // "parameterName": "resource" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.delete": + +type DefaultObjectAccessControlsDeleteCall struct { + s *Service + bucket string + entity string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes the default object ACL entry for the +// specified entity on the specified bucket. +func (r *DefaultObjectAccessControlsService) Delete(bucket string, entity string) *DefaultObjectAccessControlsDeleteCall { + c := &DefaultObjectAccessControlsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsDeleteCall) UserProject(userProject string) *DefaultObjectAccessControlsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsDeleteCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsDeleteCall) Context(ctx context.Context) *DefaultObjectAccessControlsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.delete" call. +func (c *DefaultObjectAccessControlsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes the default object ACL entry for the specified entity on the specified bucket.", + // "httpMethod": "DELETE", + // "id": "storage.defaultObjectAccessControls.delete", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl/{entity}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.get": + +type DefaultObjectAccessControlsGetCall struct { + s *Service + bucket string + entity string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Returns the default object ACL entry for the specified entity on +// the specified bucket. +func (r *DefaultObjectAccessControlsService) Get(bucket string, entity string) *DefaultObjectAccessControlsGetCall { + c := &DefaultObjectAccessControlsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsGetCall) UserProject(userProject string) *DefaultObjectAccessControlsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsGetCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *DefaultObjectAccessControlsGetCall) IfNoneMatch(entityTag string) *DefaultObjectAccessControlsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsGetCall) Context(ctx context.Context) *DefaultObjectAccessControlsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.get" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsGetCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns the default object ACL entry for the specified entity on the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.defaultObjectAccessControls.get", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl/{entity}", + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.insert": + +type DefaultObjectAccessControlsInsertCall struct { + s *Service + bucket string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a new default object ACL entry on the specified +// bucket. +func (r *DefaultObjectAccessControlsService) Insert(bucket string, objectaccesscontrol *ObjectAccessControl) *DefaultObjectAccessControlsInsertCall { + c := &DefaultObjectAccessControlsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsInsertCall) UserProject(userProject string) *DefaultObjectAccessControlsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsInsertCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsInsertCall) Context(ctx context.Context) *DefaultObjectAccessControlsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.insert" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsInsertCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new default object ACL entry on the specified bucket.", + // "httpMethod": "POST", + // "id": "storage.defaultObjectAccessControls.insert", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.list": + +type DefaultObjectAccessControlsListCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves default object ACL entries on the specified bucket. +func (r *DefaultObjectAccessControlsService) List(bucket string) *DefaultObjectAccessControlsListCall { + c := &DefaultObjectAccessControlsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": If present, only return default ACL listing +// if the bucket's current metageneration matches this value. +func (c *DefaultObjectAccessControlsListCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *DefaultObjectAccessControlsListCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": If present, only return default ACL +// listing if the bucket's current metageneration does not match the +// given value. +func (c *DefaultObjectAccessControlsListCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *DefaultObjectAccessControlsListCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsListCall) UserProject(userProject string) *DefaultObjectAccessControlsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsListCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *DefaultObjectAccessControlsListCall) IfNoneMatch(entityTag string) *DefaultObjectAccessControlsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsListCall) Context(ctx context.Context) *DefaultObjectAccessControlsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.list" call. +// Exactly one of *ObjectAccessControls or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControls.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsListCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControls, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControls{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves default object ACL entries on the specified bucket.", + // "httpMethod": "GET", + // "id": "storage.defaultObjectAccessControls.list", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "If present, only return default ACL listing if the bucket's current metageneration matches this value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "If present, only return default ACL listing if the bucket's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl", + // "response": { + // "$ref": "ObjectAccessControls" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.patch": + +type DefaultObjectAccessControlsPatchCall struct { + s *Service + bucket string + entity string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches a default object ACL entry on the specified bucket. +func (r *DefaultObjectAccessControlsService) Patch(bucket string, entity string, objectaccesscontrol *ObjectAccessControl) *DefaultObjectAccessControlsPatchCall { + c := &DefaultObjectAccessControlsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsPatchCall) UserProject(userProject string) *DefaultObjectAccessControlsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsPatchCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsPatchCall) Context(ctx context.Context) *DefaultObjectAccessControlsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PATCH", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.patch" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsPatchCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches a default object ACL entry on the specified bucket.", + // "httpMethod": "PATCH", + // "id": "storage.defaultObjectAccessControls.patch", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl/{entity}", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.defaultObjectAccessControls.update": + +type DefaultObjectAccessControlsUpdateCall struct { + s *Service + bucket string + entity string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates a default object ACL entry on the specified bucket. +func (r *DefaultObjectAccessControlsService) Update(bucket string, entity string, objectaccesscontrol *ObjectAccessControl) *DefaultObjectAccessControlsUpdateCall { + c := &DefaultObjectAccessControlsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.entity = entity + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *DefaultObjectAccessControlsUpdateCall) UserProject(userProject string) *DefaultObjectAccessControlsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *DefaultObjectAccessControlsUpdateCall) Fields(s ...googleapi.Field) *DefaultObjectAccessControlsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *DefaultObjectAccessControlsUpdateCall) Context(ctx context.Context) *DefaultObjectAccessControlsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *DefaultObjectAccessControlsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *DefaultObjectAccessControlsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/defaultObjectAcl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.defaultObjectAccessControls.update" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *DefaultObjectAccessControlsUpdateCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates a default object ACL entry on the specified bucket.", + // "httpMethod": "PUT", + // "id": "storage.defaultObjectAccessControls.update", + // "parameterOrder": [ + // "bucket", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/defaultObjectAcl/{entity}", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.notifications.delete": + +type NotificationsDeleteCall struct { + s *Service + bucket string + notification string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes a notification subscription. +func (r *NotificationsService) Delete(bucket string, notification string) *NotificationsDeleteCall { + c := &NotificationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.notification = notification + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *NotificationsDeleteCall) UserProject(userProject string) *NotificationsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *NotificationsDeleteCall) Fields(s ...googleapi.Field) *NotificationsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *NotificationsDeleteCall) Context(ctx context.Context) *NotificationsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *NotificationsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *NotificationsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/notificationConfigs/{notification}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "notification": c.notification, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.notifications.delete" call. +func (c *NotificationsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes a notification subscription.", + // "httpMethod": "DELETE", + // "id": "storage.notifications.delete", + // "parameterOrder": [ + // "bucket", + // "notification" + // ], + // "parameters": { + // "bucket": { + // "description": "The parent bucket of the notification.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "notification": { + // "description": "ID of the notification to delete.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/notificationConfigs/{notification}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.notifications.get": + +type NotificationsGetCall struct { + s *Service + bucket string + notification string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: View a notification configuration. +func (r *NotificationsService) Get(bucket string, notification string) *NotificationsGetCall { + c := &NotificationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.notification = notification + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *NotificationsGetCall) UserProject(userProject string) *NotificationsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *NotificationsGetCall) Fields(s ...googleapi.Field) *NotificationsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *NotificationsGetCall) IfNoneMatch(entityTag string) *NotificationsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *NotificationsGetCall) Context(ctx context.Context) *NotificationsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *NotificationsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *NotificationsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/notificationConfigs/{notification}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "notification": c.notification, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.notifications.get" call. +// Exactly one of *Notification or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Notification.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *NotificationsGetCall) Do(opts ...googleapi.CallOption) (*Notification, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Notification{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "View a notification configuration.", + // "httpMethod": "GET", + // "id": "storage.notifications.get", + // "parameterOrder": [ + // "bucket", + // "notification" + // ], + // "parameters": { + // "bucket": { + // "description": "The parent bucket of the notification.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "notification": { + // "description": "Notification ID", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/notificationConfigs/{notification}", + // "response": { + // "$ref": "Notification" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.notifications.insert": + +type NotificationsInsertCall struct { + s *Service + bucket string + notification *Notification + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a notification subscription for a given bucket. +func (r *NotificationsService) Insert(bucket string, notification *Notification) *NotificationsInsertCall { + c := &NotificationsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.notification = notification + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *NotificationsInsertCall) UserProject(userProject string) *NotificationsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *NotificationsInsertCall) Fields(s ...googleapi.Field) *NotificationsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *NotificationsInsertCall) Context(ctx context.Context) *NotificationsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *NotificationsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *NotificationsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.notification) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/notificationConfigs") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.notifications.insert" call. +// Exactly one of *Notification or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Notification.ServerResponse.Header or (if a response was returned at +// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified +// to check whether the returned error was because +// http.StatusNotModified was returned. +func (c *NotificationsInsertCall) Do(opts ...googleapi.CallOption) (*Notification, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Notification{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a notification subscription for a given bucket.", + // "httpMethod": "POST", + // "id": "storage.notifications.insert", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "The parent bucket of the notification.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/notificationConfigs", + // "request": { + // "$ref": "Notification" + // }, + // "response": { + // "$ref": "Notification" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.notifications.list": + +type NotificationsListCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves a list of notification subscriptions for a given +// bucket. +func (r *NotificationsService) List(bucket string) *NotificationsListCall { + c := &NotificationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *NotificationsListCall) UserProject(userProject string) *NotificationsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *NotificationsListCall) Fields(s ...googleapi.Field) *NotificationsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *NotificationsListCall) IfNoneMatch(entityTag string) *NotificationsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *NotificationsListCall) Context(ctx context.Context) *NotificationsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *NotificationsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *NotificationsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/notificationConfigs") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.notifications.list" call. +// Exactly one of *Notifications or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *Notifications.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *NotificationsListCall) Do(opts ...googleapi.CallOption) (*Notifications, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Notifications{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves a list of notification subscriptions for a given bucket.", + // "httpMethod": "GET", + // "id": "storage.notifications.list", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a Google Cloud Storage bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/notificationConfigs", + // "response": { + // "$ref": "Notifications" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objectAccessControls.delete": + +type ObjectAccessControlsDeleteCall struct { + s *Service + bucket string + object string + entity string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Permanently deletes the ACL entry for the specified entity on +// the specified object. +func (r *ObjectAccessControlsService) Delete(bucket string, object string, entity string) *ObjectAccessControlsDeleteCall { + c := &ObjectAccessControlsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.entity = entity + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsDeleteCall) Generation(generation int64) *ObjectAccessControlsDeleteCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsDeleteCall) UserProject(userProject string) *ObjectAccessControlsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsDeleteCall) Fields(s ...googleapi.Field) *ObjectAccessControlsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsDeleteCall) Context(ctx context.Context) *ObjectAccessControlsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.delete" call. +func (c *ObjectAccessControlsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Permanently deletes the ACL entry for the specified entity on the specified object.", + // "httpMethod": "DELETE", + // "id": "storage.objectAccessControls.delete", + // "parameterOrder": [ + // "bucket", + // "object", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl/{entity}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.get": + +type ObjectAccessControlsGetCall struct { + s *Service + bucket string + object string + entity string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Returns the ACL entry for the specified entity on the specified +// object. +func (r *ObjectAccessControlsService) Get(bucket string, object string, entity string) *ObjectAccessControlsGetCall { + c := &ObjectAccessControlsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.entity = entity + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsGetCall) Generation(generation int64) *ObjectAccessControlsGetCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsGetCall) UserProject(userProject string) *ObjectAccessControlsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsGetCall) Fields(s ...googleapi.Field) *ObjectAccessControlsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectAccessControlsGetCall) IfNoneMatch(entityTag string) *ObjectAccessControlsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsGetCall) Context(ctx context.Context) *ObjectAccessControlsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.get" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsGetCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns the ACL entry for the specified entity on the specified object.", + // "httpMethod": "GET", + // "id": "storage.objectAccessControls.get", + // "parameterOrder": [ + // "bucket", + // "object", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl/{entity}", + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.insert": + +type ObjectAccessControlsInsertCall struct { + s *Service + bucket string + object string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Insert: Creates a new ACL entry on the specified object. +func (r *ObjectAccessControlsService) Insert(bucket string, object string, objectaccesscontrol *ObjectAccessControl) *ObjectAccessControlsInsertCall { + c := &ObjectAccessControlsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsInsertCall) Generation(generation int64) *ObjectAccessControlsInsertCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsInsertCall) UserProject(userProject string) *ObjectAccessControlsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsInsertCall) Fields(s ...googleapi.Field) *ObjectAccessControlsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsInsertCall) Context(ctx context.Context) *ObjectAccessControlsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.insert" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsInsertCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new ACL entry on the specified object.", + // "httpMethod": "POST", + // "id": "storage.objectAccessControls.insert", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.list": + +type ObjectAccessControlsListCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves ACL entries on the specified object. +func (r *ObjectAccessControlsService) List(bucket string, object string) *ObjectAccessControlsListCall { + c := &ObjectAccessControlsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsListCall) Generation(generation int64) *ObjectAccessControlsListCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsListCall) UserProject(userProject string) *ObjectAccessControlsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsListCall) Fields(s ...googleapi.Field) *ObjectAccessControlsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectAccessControlsListCall) IfNoneMatch(entityTag string) *ObjectAccessControlsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsListCall) Context(ctx context.Context) *ObjectAccessControlsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.list" call. +// Exactly one of *ObjectAccessControls or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControls.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsListCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControls, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControls{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves ACL entries on the specified object.", + // "httpMethod": "GET", + // "id": "storage.objectAccessControls.list", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl", + // "response": { + // "$ref": "ObjectAccessControls" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.patch": + +type ObjectAccessControlsPatchCall struct { + s *Service + bucket string + object string + entity string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches an ACL entry on the specified object. +func (r *ObjectAccessControlsService) Patch(bucket string, object string, entity string, objectaccesscontrol *ObjectAccessControl) *ObjectAccessControlsPatchCall { + c := &ObjectAccessControlsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.entity = entity + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsPatchCall) Generation(generation int64) *ObjectAccessControlsPatchCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsPatchCall) UserProject(userProject string) *ObjectAccessControlsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsPatchCall) Fields(s ...googleapi.Field) *ObjectAccessControlsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsPatchCall) Context(ctx context.Context) *ObjectAccessControlsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PATCH", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.patch" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsPatchCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches an ACL entry on the specified object.", + // "httpMethod": "PATCH", + // "id": "storage.objectAccessControls.patch", + // "parameterOrder": [ + // "bucket", + // "object", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl/{entity}", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objectAccessControls.update": + +type ObjectAccessControlsUpdateCall struct { + s *Service + bucket string + object string + entity string + objectaccesscontrol *ObjectAccessControl + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates an ACL entry on the specified object. +func (r *ObjectAccessControlsService) Update(bucket string, object string, entity string, objectaccesscontrol *ObjectAccessControl) *ObjectAccessControlsUpdateCall { + c := &ObjectAccessControlsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.entity = entity + c.objectaccesscontrol = objectaccesscontrol + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectAccessControlsUpdateCall) Generation(generation int64) *ObjectAccessControlsUpdateCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectAccessControlsUpdateCall) UserProject(userProject string) *ObjectAccessControlsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectAccessControlsUpdateCall) Fields(s ...googleapi.Field) *ObjectAccessControlsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectAccessControlsUpdateCall) Context(ctx context.Context) *ObjectAccessControlsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectAccessControlsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectAccessControlsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.objectaccesscontrol) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/acl/{entity}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + "entity": c.entity, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objectAccessControls.update" call. +// Exactly one of *ObjectAccessControl or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *ObjectAccessControl.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectAccessControlsUpdateCall) Do(opts ...googleapi.CallOption) (*ObjectAccessControl, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ObjectAccessControl{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an ACL entry on the specified object.", + // "httpMethod": "PUT", + // "id": "storage.objectAccessControls.update", + // "parameterOrder": [ + // "bucket", + // "object", + // "entity" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of a bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "entity": { + // "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/acl/{entity}", + // "request": { + // "$ref": "ObjectAccessControl" + // }, + // "response": { + // "$ref": "ObjectAccessControl" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objects.compose": + +type ObjectsComposeCall struct { + s *Service + destinationBucket string + destinationObject string + composerequest *ComposeRequest + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Compose: Concatenates a list of existing objects into a new object in +// the same bucket. +func (r *ObjectsService) Compose(destinationBucket string, destinationObject string, composerequest *ComposeRequest) *ObjectsComposeCall { + c := &ObjectsComposeCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.destinationBucket = destinationBucket + c.destinationObject = destinationObject + c.composerequest = composerequest + return c +} + +// DestinationPredefinedAcl sets the optional parameter +// "destinationPredefinedAcl": Apply a predefined set of access controls +// to the destination object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsComposeCall) DestinationPredefinedAcl(destinationPredefinedAcl string) *ObjectsComposeCall { + c.urlParams_.Set("destinationPredefinedAcl", destinationPredefinedAcl) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsComposeCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsComposeCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsComposeCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsComposeCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// KmsKeyName sets the optional parameter "kmsKeyName": Resource name of +// the Cloud KMS key, of the form +// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, +// that will be used to encrypt the object. Overrides the object +// metadata's kms_key_name value, if any. +func (c *ObjectsComposeCall) KmsKeyName(kmsKeyName string) *ObjectsComposeCall { + c.urlParams_.Set("kmsKeyName", kmsKeyName) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsComposeCall) UserProject(userProject string) *ObjectsComposeCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsComposeCall) Fields(s ...googleapi.Field) *ObjectsComposeCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsComposeCall) Context(ctx context.Context) *ObjectsComposeCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsComposeCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsComposeCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.composerequest) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{destinationBucket}/o/{destinationObject}/compose") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "destinationBucket": c.destinationBucket, + "destinationObject": c.destinationObject, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.compose" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsComposeCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Concatenates a list of existing objects into a new object in the same bucket.", + // "httpMethod": "POST", + // "id": "storage.objects.compose", + // "parameterOrder": [ + // "destinationBucket", + // "destinationObject" + // ], + // "parameters": { + // "destinationBucket": { + // "description": "Name of the bucket containing the source objects. The destination object is stored in this bucket.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationObject": { + // "description": "Name of the new object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationPredefinedAcl": { + // "description": "Apply a predefined set of access controls to the destination object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "kmsKeyName": { + // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{destinationBucket}/o/{destinationObject}/compose", + // "request": { + // "$ref": "ComposeRequest" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.copy": + +type ObjectsCopyCall struct { + s *Service + sourceBucket string + sourceObject string + destinationBucket string + destinationObject string + object *Object + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Copy: Copies a source object to a destination object. Optionally +// overrides metadata. +func (r *ObjectsService) Copy(sourceBucket string, sourceObject string, destinationBucket string, destinationObject string, object *Object) *ObjectsCopyCall { + c := &ObjectsCopyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.sourceBucket = sourceBucket + c.sourceObject = sourceObject + c.destinationBucket = destinationBucket + c.destinationObject = destinationObject + c.object = object + return c +} + +// DestinationPredefinedAcl sets the optional parameter +// "destinationPredefinedAcl": Apply a predefined set of access controls +// to the destination object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsCopyCall) DestinationPredefinedAcl(destinationPredefinedAcl string) *ObjectsCopyCall { + c.urlParams_.Set("destinationPredefinedAcl", destinationPredefinedAcl) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the destination object's +// current generation matches the given value. Setting to 0 makes the +// operation succeed only if there are no live versions of the object. +func (c *ObjectsCopyCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the destination object's current generation does not match the given +// value. If no live object exists, the precondition fails. Setting to 0 +// makes the operation succeed only if there is a live version of the +// object. +func (c *ObjectsCopyCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the destination object's current metageneration matches the given +// value. +func (c *ObjectsCopyCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the destination object's current metageneration does not +// match the given value. +func (c *ObjectsCopyCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// IfSourceGenerationMatch sets the optional parameter +// "ifSourceGenerationMatch": Makes the operation conditional on whether +// the source object's current generation matches the given value. +func (c *ObjectsCopyCall) IfSourceGenerationMatch(ifSourceGenerationMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifSourceGenerationMatch", fmt.Sprint(ifSourceGenerationMatch)) + return c +} + +// IfSourceGenerationNotMatch sets the optional parameter +// "ifSourceGenerationNotMatch": Makes the operation conditional on +// whether the source object's current generation does not match the +// given value. +func (c *ObjectsCopyCall) IfSourceGenerationNotMatch(ifSourceGenerationNotMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifSourceGenerationNotMatch", fmt.Sprint(ifSourceGenerationNotMatch)) + return c +} + +// IfSourceMetagenerationMatch sets the optional parameter +// "ifSourceMetagenerationMatch": Makes the operation conditional on +// whether the source object's current metageneration matches the given +// value. +func (c *ObjectsCopyCall) IfSourceMetagenerationMatch(ifSourceMetagenerationMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifSourceMetagenerationMatch", fmt.Sprint(ifSourceMetagenerationMatch)) + return c +} + +// IfSourceMetagenerationNotMatch sets the optional parameter +// "ifSourceMetagenerationNotMatch": Makes the operation conditional on +// whether the source object's current metageneration does not match the +// given value. +func (c *ObjectsCopyCall) IfSourceMetagenerationNotMatch(ifSourceMetagenerationNotMatch int64) *ObjectsCopyCall { + c.urlParams_.Set("ifSourceMetagenerationNotMatch", fmt.Sprint(ifSourceMetagenerationNotMatch)) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl, unless the object resource +// specifies the acl property, when it defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsCopyCall) Projection(projection string) *ObjectsCopyCall { + c.urlParams_.Set("projection", projection) + return c +} + +// SourceGeneration sets the optional parameter "sourceGeneration": If +// present, selects a specific revision of the source object (as opposed +// to the latest version, the default). +func (c *ObjectsCopyCall) SourceGeneration(sourceGeneration int64) *ObjectsCopyCall { + c.urlParams_.Set("sourceGeneration", fmt.Sprint(sourceGeneration)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsCopyCall) UserProject(userProject string) *ObjectsCopyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsCopyCall) Fields(s ...googleapi.Field) *ObjectsCopyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsCopyCall) Context(ctx context.Context) *ObjectsCopyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsCopyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsCopyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "sourceBucket": c.sourceBucket, + "sourceObject": c.sourceObject, + "destinationBucket": c.destinationBucket, + "destinationObject": c.destinationObject, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.copy" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsCopyCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Copies a source object to a destination object. Optionally overrides metadata.", + // "httpMethod": "POST", + // "id": "storage.objects.copy", + // "parameterOrder": [ + // "sourceBucket", + // "sourceObject", + // "destinationBucket", + // "destinationObject" + // ], + // "parameters": { + // "destinationBucket": { + // "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationObject": { + // "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationPredefinedAcl": { + // "description": "Apply a predefined set of access controls to the destination object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the destination object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the destination object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceGenerationMatch": { + // "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "sourceBucket": { + // "description": "Name of the bucket in which to find the source object.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "sourceGeneration": { + // "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "sourceObject": { + // "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.delete": + +type ObjectsDeleteCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Deletes an object and its metadata. Deletions are permanent +// if versioning is not enabled for the bucket, or if the generation +// parameter is used. +func (r *ObjectsService) Delete(bucket string, object string) *ObjectsDeleteCall { + c := &ObjectsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// Generation sets the optional parameter "generation": If present, +// permanently deletes a specific revision of this object (as opposed to +// the latest version, the default). +func (c *ObjectsDeleteCall) Generation(generation int64) *ObjectsDeleteCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsDeleteCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsDeleteCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsDeleteCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsDeleteCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsDeleteCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsDeleteCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsDeleteCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsDeleteCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsDeleteCall) UserProject(userProject string) *ObjectsDeleteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsDeleteCall) Fields(s ...googleapi.Field) *ObjectsDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsDeleteCall) Context(ctx context.Context) *ObjectsDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.delete" call. +func (c *ObjectsDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Deletes an object and its metadata. Deletions are permanent if versioning is not enabled for the bucket, or if the generation parameter is used.", + // "httpMethod": "DELETE", + // "id": "storage.objects.delete", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, permanently deletes a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.get": + +type ObjectsGetCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Retrieves an object or its metadata. +func (r *ObjectsService) Get(bucket string, object string) *ObjectsGetCall { + c := &ObjectsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsGetCall) Generation(generation int64) *ObjectsGetCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsGetCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsGetCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsGetCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsGetCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsGetCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsGetCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsGetCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsGetCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsGetCall) Projection(projection string) *ObjectsGetCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsGetCall) UserProject(userProject string) *ObjectsGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsGetCall) Fields(s ...googleapi.Field) *ObjectsGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectsGetCall) IfNoneMatch(entityTag string) *ObjectsGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do and Download +// methods. Any pending HTTP request will be aborted if the provided +// context is canceled. +func (c *ObjectsGetCall) Context(ctx context.Context) *ObjectsGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Download fetches the API endpoint's "media" value, instead of the normal +// API response value. If the returned error is nil, the Response is guaranteed to +// have a 2xx status code. Callers must close the Response.Body as usual. +func (c *ObjectsGetCall) Download(opts ...googleapi.CallOption) (*http.Response, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("media") + if err != nil { + return nil, err + } + if err := googleapi.CheckMediaResponse(res); err != nil { + res.Body.Close() + return nil, err + } + return res, nil +} + +// Do executes the "storage.objects.get" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsGetCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves an object or its metadata.", + // "httpMethod": "GET", + // "id": "storage.objects.get", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}", + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ], + // "supportsMediaDownload": true, + // "useMediaDownloadService": true + // } + +} + +// method id "storage.objects.getIamPolicy": + +type ObjectsGetIamPolicyCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// GetIamPolicy: Returns an IAM policy for the specified object. +func (r *ObjectsService) GetIamPolicy(bucket string, object string) *ObjectsGetIamPolicyCall { + c := &ObjectsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsGetIamPolicyCall) Generation(generation int64) *ObjectsGetIamPolicyCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsGetIamPolicyCall) UserProject(userProject string) *ObjectsGetIamPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsGetIamPolicyCall) Fields(s ...googleapi.Field) *ObjectsGetIamPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectsGetIamPolicyCall) IfNoneMatch(entityTag string) *ObjectsGetIamPolicyCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsGetIamPolicyCall) Context(ctx context.Context) *ObjectsGetIamPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsGetIamPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/iam") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.getIamPolicy" call. +// Exactly one of *Policy or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Policy.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Policy{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Returns an IAM policy for the specified object.", + // "httpMethod": "GET", + // "id": "storage.objects.getIamPolicy", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/iam", + // "response": { + // "$ref": "Policy" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.insert": + +type ObjectsInsertCall struct { + s *Service + bucket string + object *Object + urlParams_ gensupport.URLParams + mediaInfo_ *gensupport.MediaInfo + ctx_ context.Context + header_ http.Header +} + +// Insert: Stores a new object and metadata. +func (r *ObjectsService) Insert(bucket string, object *Object) *ObjectsInsertCall { + c := &ObjectsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + return c +} + +// ContentEncoding sets the optional parameter "contentEncoding": If +// set, sets the contentEncoding property of the final object to this +// value. Setting this parameter is equivalent to setting the +// contentEncoding metadata property. This can be useful when uploading +// an object with uploadType=media to indicate the encoding of the +// content being uploaded. +func (c *ObjectsInsertCall) ContentEncoding(contentEncoding string) *ObjectsInsertCall { + c.urlParams_.Set("contentEncoding", contentEncoding) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsInsertCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsInsertCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsInsertCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsInsertCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsInsertCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsInsertCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsInsertCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsInsertCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// KmsKeyName sets the optional parameter "kmsKeyName": Resource name of +// the Cloud KMS key, of the form +// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, +// that will be used to encrypt the object. Overrides the object +// metadata's kms_key_name value, if any. +func (c *ObjectsInsertCall) KmsKeyName(kmsKeyName string) *ObjectsInsertCall { + c.urlParams_.Set("kmsKeyName", kmsKeyName) + return c +} + +// Name sets the optional parameter "name": Name of the object. Required +// when the object metadata is not otherwise provided. Overrides the +// object metadata's name value, if any. For information about how to +// URL encode object names to be path safe, see Encoding URI Path Parts. +func (c *ObjectsInsertCall) Name(name string) *ObjectsInsertCall { + c.urlParams_.Set("name", name) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsInsertCall) PredefinedAcl(predefinedAcl string) *ObjectsInsertCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl, unless the object resource +// specifies the acl property, when it defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsInsertCall) Projection(projection string) *ObjectsInsertCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsInsertCall) UserProject(userProject string) *ObjectsInsertCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Media specifies the media to upload in one or more chunks. The chunk +// size may be controlled by supplying a MediaOption generated by +// googleapi.ChunkSize. The chunk size defaults to +// googleapi.DefaultUploadChunkSize.The Content-Type header used in the +// upload request will be determined by sniffing the contents of r, +// unless a MediaOption generated by googleapi.ContentType is +// supplied. +// At most one of Media and ResumableMedia may be set. +func (c *ObjectsInsertCall) Media(r io.Reader, options ...googleapi.MediaOption) *ObjectsInsertCall { + if ct := c.object.ContentType; ct != "" { + options = append([]googleapi.MediaOption{googleapi.ContentType(ct)}, options...) + } + c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options) + return c +} + +// ResumableMedia specifies the media to upload in chunks and can be +// canceled with ctx. +// +// Deprecated: use Media instead. +// +// At most one of Media and ResumableMedia may be set. mediaType +// identifies the MIME media type of the upload, such as "image/png". If +// mediaType is "", it will be auto-detected. The provided ctx will +// supersede any context previously provided to the Context method. +func (c *ObjectsInsertCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *ObjectsInsertCall { + c.ctx_ = ctx + c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType) + return c +} + +// ProgressUpdater provides a callback function that will be called +// after every chunk. It should be a low-latency function in order to +// not slow down the upload operation. This should only be called when +// using ResumableMedia (as opposed to Media). +func (c *ObjectsInsertCall) ProgressUpdater(pu googleapi.ProgressUpdater) *ObjectsInsertCall { + c.mediaInfo_.SetProgressUpdater(pu) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsInsertCall) Fields(s ...googleapi.Field) *ObjectsInsertCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +// This context will supersede any context previously provided to the +// ResumableMedia method. +func (c *ObjectsInsertCall) Context(ctx context.Context) *ObjectsInsertCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsInsertCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsInsertCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o") + if c.mediaInfo_ != nil { + urls = strings.Replace(urls, "https://www.googleapis.com/", "https://www.googleapis.com/upload/", 1) + c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType()) + } + if body == nil { + body = new(bytes.Buffer) + reqHeaders.Set("Content-Type", "application/json") + } + body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body) + defer cleanup() + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + req.GetBody = getBody + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.insert" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsInsertCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location")) + if rx != nil { + rx.Client = c.s.client + rx.UserAgent = c.s.userAgent() + ctx := c.ctx_ + if ctx == nil { + ctx = context.TODO() + } + res, err = rx.Upload(ctx) + if err != nil { + return nil, err + } + defer res.Body.Close() + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Stores a new object and metadata.", + // "httpMethod": "POST", + // "id": "storage.objects.insert", + // "mediaUpload": { + // "accept": [ + // "*/*" + // ], + // "protocols": { + // "resumable": { + // "multipart": true, + // "path": "/resumable/upload/storage/v1/b/{bucket}/o" + // }, + // "simple": { + // "multipart": true, + // "path": "/upload/storage/v1/b/{bucket}/o" + // } + // } + // }, + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "contentEncoding": { + // "description": "If set, sets the contentEncoding property of the final object to this value. Setting this parameter is equivalent to setting the contentEncoding metadata property. This can be useful when uploading an object with uploadType=media to indicate the encoding of the content being uploaded.", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "kmsKeyName": { + // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + // "location": "query", + // "type": "string" + // }, + // "name": { + // "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "query", + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ], + // "supportsMediaUpload": true + // } + +} + +// method id "storage.objects.list": + +type ObjectsListCall struct { + s *Service + bucket string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves a list of objects matching the criteria. +func (r *ObjectsService) List(bucket string) *ObjectsListCall { + c := &ObjectsListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + return c +} + +// Delimiter sets the optional parameter "delimiter": Returns results in +// a directory-like mode. items will contain only objects whose names, +// aside from the prefix, do not contain delimiter. Objects whose names, +// aside from the prefix, contain delimiter will have their name, +// truncated after the delimiter, returned in prefixes. Duplicate +// prefixes are omitted. +func (c *ObjectsListCall) Delimiter(delimiter string) *ObjectsListCall { + c.urlParams_.Set("delimiter", delimiter) + return c +} + +// IncludeTrailingDelimiter sets the optional parameter +// "includeTrailingDelimiter": If true, objects that end in exactly one +// instance of delimiter will have their metadata included in items in +// addition to prefixes. +func (c *ObjectsListCall) IncludeTrailingDelimiter(includeTrailingDelimiter bool) *ObjectsListCall { + c.urlParams_.Set("includeTrailingDelimiter", fmt.Sprint(includeTrailingDelimiter)) + return c +} + +// MaxResults sets the optional parameter "maxResults": Maximum number +// of items plus prefixes to return in a single page of responses. As +// duplicate prefixes are omitted, fewer total results may be returned +// than requested. The service will use this parameter or 1,000 items, +// whichever is smaller. +func (c *ObjectsListCall) MaxResults(maxResults int64) *ObjectsListCall { + c.urlParams_.Set("maxResults", fmt.Sprint(maxResults)) + return c +} + +// PageToken sets the optional parameter "pageToken": A +// previously-returned page token representing part of the larger set of +// results to view. +func (c *ObjectsListCall) PageToken(pageToken string) *ObjectsListCall { + c.urlParams_.Set("pageToken", pageToken) + return c +} + +// Prefix sets the optional parameter "prefix": Filter results to +// objects whose names begin with this prefix. +func (c *ObjectsListCall) Prefix(prefix string) *ObjectsListCall { + c.urlParams_.Set("prefix", prefix) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsListCall) Projection(projection string) *ObjectsListCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsListCall) UserProject(userProject string) *ObjectsListCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Versions sets the optional parameter "versions": If true, lists all +// versions of an object as distinct results. The default is false. For +// more information, see Object Versioning. +func (c *ObjectsListCall) Versions(versions bool) *ObjectsListCall { + c.urlParams_.Set("versions", fmt.Sprint(versions)) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsListCall) Fields(s ...googleapi.Field) *ObjectsListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectsListCall) IfNoneMatch(entityTag string) *ObjectsListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsListCall) Context(ctx context.Context) *ObjectsListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.list" call. +// Exactly one of *Objects or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Objects.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsListCall) Do(opts ...googleapi.CallOption) (*Objects, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Objects{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves a list of objects matching the criteria.", + // "httpMethod": "GET", + // "id": "storage.objects.list", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which to look for objects.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "delimiter": { + // "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + // "location": "query", + // "type": "string" + // }, + // "includeTrailingDelimiter": { + // "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", + // "location": "query", + // "type": "boolean" + // }, + // "maxResults": { + // "default": "1000", + // "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + // "format": "uint32", + // "location": "query", + // "minimum": "0", + // "type": "integer" + // }, + // "pageToken": { + // "description": "A previously-returned page token representing part of the larger set of results to view.", + // "location": "query", + // "type": "string" + // }, + // "prefix": { + // "description": "Filter results to objects whose names begin with this prefix.", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // }, + // "versions": { + // "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + // "location": "query", + // "type": "boolean" + // } + // }, + // "path": "b/{bucket}/o", + // "response": { + // "$ref": "Objects" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ], + // "supportsSubscription": true + // } + +} + +// Pages invokes f for each page of results. +// A non-nil error returned from f will halt the iteration. +// The provided context supersedes any context provided to the Context method. +func (c *ObjectsListCall) Pages(ctx context.Context, f func(*Objects) error) error { + c.ctx_ = ctx + defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point + for { + x, err := c.Do() + if err != nil { + return err + } + if err := f(x); err != nil { + return err + } + if x.NextPageToken == "" { + return nil + } + c.PageToken(x.NextPageToken) + } +} + +// method id "storage.objects.patch": + +type ObjectsPatchCall struct { + s *Service + bucket string + object string + object2 *Object + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Patch: Patches an object's metadata. +func (r *ObjectsService) Patch(bucket string, object string, object2 *Object) *ObjectsPatchCall { + c := &ObjectsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.object2 = object2 + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsPatchCall) Generation(generation int64) *ObjectsPatchCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsPatchCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsPatchCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsPatchCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsPatchCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsPatchCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsPatchCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsPatchCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsPatchCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsPatchCall) PredefinedAcl(predefinedAcl string) *ObjectsPatchCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsPatchCall) Projection(projection string) *ObjectsPatchCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request, for Requester Pays buckets. +func (c *ObjectsPatchCall) UserProject(userProject string) *ObjectsPatchCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsPatchCall) Fields(s ...googleapi.Field) *ObjectsPatchCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsPatchCall) Context(ctx context.Context) *ObjectsPatchCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsPatchCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsPatchCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object2) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PATCH", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.patch" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsPatchCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Patches an object's metadata.", + // "httpMethod": "PATCH", + // "id": "storage.objects.patch", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request, for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objects.rewrite": + +type ObjectsRewriteCall struct { + s *Service + sourceBucket string + sourceObject string + destinationBucket string + destinationObject string + object *Object + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Rewrite: Rewrites a source object to a destination object. Optionally +// overrides metadata. +func (r *ObjectsService) Rewrite(sourceBucket string, sourceObject string, destinationBucket string, destinationObject string, object *Object) *ObjectsRewriteCall { + c := &ObjectsRewriteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.sourceBucket = sourceBucket + c.sourceObject = sourceObject + c.destinationBucket = destinationBucket + c.destinationObject = destinationObject + c.object = object + return c +} + +// DestinationKmsKeyName sets the optional parameter +// "destinationKmsKeyName": Resource name of the Cloud KMS key, of the +// form +// projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, +// that will be used to encrypt the object. Overrides the object +// metadata's kms_key_name value, if any. +func (c *ObjectsRewriteCall) DestinationKmsKeyName(destinationKmsKeyName string) *ObjectsRewriteCall { + c.urlParams_.Set("destinationKmsKeyName", destinationKmsKeyName) + return c +} + +// DestinationPredefinedAcl sets the optional parameter +// "destinationPredefinedAcl": Apply a predefined set of access controls +// to the destination object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsRewriteCall) DestinationPredefinedAcl(destinationPredefinedAcl string) *ObjectsRewriteCall { + c.urlParams_.Set("destinationPredefinedAcl", destinationPredefinedAcl) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsRewriteCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsRewriteCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the destination object's current metageneration matches the given +// value. +func (c *ObjectsRewriteCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the destination object's current metageneration does not +// match the given value. +func (c *ObjectsRewriteCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// IfSourceGenerationMatch sets the optional parameter +// "ifSourceGenerationMatch": Makes the operation conditional on whether +// the source object's current generation matches the given value. +func (c *ObjectsRewriteCall) IfSourceGenerationMatch(ifSourceGenerationMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifSourceGenerationMatch", fmt.Sprint(ifSourceGenerationMatch)) + return c +} + +// IfSourceGenerationNotMatch sets the optional parameter +// "ifSourceGenerationNotMatch": Makes the operation conditional on +// whether the source object's current generation does not match the +// given value. +func (c *ObjectsRewriteCall) IfSourceGenerationNotMatch(ifSourceGenerationNotMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifSourceGenerationNotMatch", fmt.Sprint(ifSourceGenerationNotMatch)) + return c +} + +// IfSourceMetagenerationMatch sets the optional parameter +// "ifSourceMetagenerationMatch": Makes the operation conditional on +// whether the source object's current metageneration matches the given +// value. +func (c *ObjectsRewriteCall) IfSourceMetagenerationMatch(ifSourceMetagenerationMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifSourceMetagenerationMatch", fmt.Sprint(ifSourceMetagenerationMatch)) + return c +} + +// IfSourceMetagenerationNotMatch sets the optional parameter +// "ifSourceMetagenerationNotMatch": Makes the operation conditional on +// whether the source object's current metageneration does not match the +// given value. +func (c *ObjectsRewriteCall) IfSourceMetagenerationNotMatch(ifSourceMetagenerationNotMatch int64) *ObjectsRewriteCall { + c.urlParams_.Set("ifSourceMetagenerationNotMatch", fmt.Sprint(ifSourceMetagenerationNotMatch)) + return c +} + +// MaxBytesRewrittenPerCall sets the optional parameter +// "maxBytesRewrittenPerCall": The maximum number of bytes that will be +// rewritten per rewrite request. Most callers shouldn't need to specify +// this parameter - it is primarily in place to support testing. If +// specified the value must be an integral multiple of 1 MiB (1048576). +// Also, this only applies to requests where the source and destination +// span locations and/or storage classes. Finally, this value must not +// change across rewrite calls else you'll get an error that the +// rewriteToken is invalid. +func (c *ObjectsRewriteCall) MaxBytesRewrittenPerCall(maxBytesRewrittenPerCall int64) *ObjectsRewriteCall { + c.urlParams_.Set("maxBytesRewrittenPerCall", fmt.Sprint(maxBytesRewrittenPerCall)) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl, unless the object resource +// specifies the acl property, when it defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsRewriteCall) Projection(projection string) *ObjectsRewriteCall { + c.urlParams_.Set("projection", projection) + return c +} + +// RewriteToken sets the optional parameter "rewriteToken": Include this +// field (from the previous rewrite response) on each rewrite request +// after the first one, until the rewrite response 'done' flag is true. +// Calls that provide a rewriteToken can omit all other request fields, +// but if included those fields must match the values provided in the +// first rewrite request. +func (c *ObjectsRewriteCall) RewriteToken(rewriteToken string) *ObjectsRewriteCall { + c.urlParams_.Set("rewriteToken", rewriteToken) + return c +} + +// SourceGeneration sets the optional parameter "sourceGeneration": If +// present, selects a specific revision of the source object (as opposed +// to the latest version, the default). +func (c *ObjectsRewriteCall) SourceGeneration(sourceGeneration int64) *ObjectsRewriteCall { + c.urlParams_.Set("sourceGeneration", fmt.Sprint(sourceGeneration)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsRewriteCall) UserProject(userProject string) *ObjectsRewriteCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsRewriteCall) Fields(s ...googleapi.Field) *ObjectsRewriteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsRewriteCall) Context(ctx context.Context) *ObjectsRewriteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsRewriteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsRewriteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "sourceBucket": c.sourceBucket, + "sourceObject": c.sourceObject, + "destinationBucket": c.destinationBucket, + "destinationObject": c.destinationObject, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.rewrite" call. +// Exactly one of *RewriteResponse or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *RewriteResponse.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectsRewriteCall) Do(opts ...googleapi.CallOption) (*RewriteResponse, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &RewriteResponse{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Rewrites a source object to a destination object. Optionally overrides metadata.", + // "httpMethod": "POST", + // "id": "storage.objects.rewrite", + // "parameterOrder": [ + // "sourceBucket", + // "sourceObject", + // "destinationBucket", + // "destinationObject" + // ], + // "parameters": { + // "destinationBucket": { + // "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationKmsKeyName": { + // "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", + // "location": "query", + // "type": "string" + // }, + // "destinationObject": { + // "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "destinationPredefinedAcl": { + // "description": "Apply a predefined set of access controls to the destination object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceGenerationMatch": { + // "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifSourceMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "maxBytesRewrittenPerCall": { + // "description": "The maximum number of bytes that will be rewritten per rewrite request. Most callers shouldn't need to specify this parameter - it is primarily in place to support testing. If specified the value must be an integral multiple of 1 MiB (1048576). Also, this only applies to requests where the source and destination span locations and/or storage classes. Finally, this value must not change across rewrite calls else you'll get an error that the rewriteToken is invalid.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "rewriteToken": { + // "description": "Include this field (from the previous rewrite response) on each rewrite request after the first one, until the rewrite response 'done' flag is true. Calls that provide a rewriteToken can omit all other request fields, but if included those fields must match the values provided in the first rewrite request.", + // "location": "query", + // "type": "string" + // }, + // "sourceBucket": { + // "description": "Name of the bucket in which to find the source object.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "sourceGeneration": { + // "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "sourceObject": { + // "description": "Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "RewriteResponse" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.setIamPolicy": + +type ObjectsSetIamPolicyCall struct { + s *Service + bucket string + object string + policy *Policy + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// SetIamPolicy: Updates an IAM policy for the specified object. +func (r *ObjectsService) SetIamPolicy(bucket string, object string, policy *Policy) *ObjectsSetIamPolicyCall { + c := &ObjectsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.policy = policy + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsSetIamPolicyCall) Generation(generation int64) *ObjectsSetIamPolicyCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsSetIamPolicyCall) UserProject(userProject string) *ObjectsSetIamPolicyCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsSetIamPolicyCall) Fields(s ...googleapi.Field) *ObjectsSetIamPolicyCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsSetIamPolicyCall) Context(ctx context.Context) *ObjectsSetIamPolicyCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsSetIamPolicyCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.policy) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/iam") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.setIamPolicy" call. +// Exactly one of *Policy or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Policy.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Policy{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an IAM policy for the specified object.", + // "httpMethod": "PUT", + // "id": "storage.objects.setIamPolicy", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/iam", + // "request": { + // "$ref": "Policy" + // }, + // "response": { + // "$ref": "Policy" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.testIamPermissions": + +type ObjectsTestIamPermissionsCall struct { + s *Service + bucket string + object string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// TestIamPermissions: Tests a set of permissions on the given object to +// see which, if any, are held by the caller. +func (r *ObjectsService) TestIamPermissions(bucket string, object string, permissions []string) *ObjectsTestIamPermissionsCall { + c := &ObjectsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.urlParams_.SetMulti("permissions", append([]string{}, permissions...)) + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsTestIamPermissionsCall) Generation(generation int64) *ObjectsTestIamPermissionsCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsTestIamPermissionsCall) UserProject(userProject string) *ObjectsTestIamPermissionsCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsTestIamPermissionsCall) Fields(s ...googleapi.Field) *ObjectsTestIamPermissionsCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ObjectsTestIamPermissionsCall) IfNoneMatch(entityTag string) *ObjectsTestIamPermissionsCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsTestIamPermissionsCall) Context(ctx context.Context) *ObjectsTestIamPermissionsCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsTestIamPermissionsCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}/iam/testPermissions") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.testIamPermissions" call. +// Exactly one of *TestIamPermissionsResponse or error will be non-nil. +// Any non-2xx status code is an error. Response headers are in either +// *TestIamPermissionsResponse.ServerResponse.Header or (if a response +// was returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ObjectsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &TestIamPermissionsResponse{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Tests a set of permissions on the given object to see which, if any, are held by the caller.", + // "httpMethod": "GET", + // "id": "storage.objects.testIamPermissions", + // "parameterOrder": [ + // "bucket", + // "object", + // "permissions" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "permissions": { + // "description": "Permissions to test.", + // "location": "query", + // "repeated": true, + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}/iam/testPermissions", + // "response": { + // "$ref": "TestIamPermissionsResponse" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.objects.update": + +type ObjectsUpdateCall struct { + s *Service + bucket string + object string + object2 *Object + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates an object's metadata. +func (r *ObjectsService) Update(bucket string, object string, object2 *Object) *ObjectsUpdateCall { + c := &ObjectsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.object = object + c.object2 = object2 + return c +} + +// Generation sets the optional parameter "generation": If present, +// selects a specific revision of this object (as opposed to the latest +// version, the default). +func (c *ObjectsUpdateCall) Generation(generation int64) *ObjectsUpdateCall { + c.urlParams_.Set("generation", fmt.Sprint(generation)) + return c +} + +// IfGenerationMatch sets the optional parameter "ifGenerationMatch": +// Makes the operation conditional on whether the object's current +// generation matches the given value. Setting to 0 makes the operation +// succeed only if there are no live versions of the object. +func (c *ObjectsUpdateCall) IfGenerationMatch(ifGenerationMatch int64) *ObjectsUpdateCall { + c.urlParams_.Set("ifGenerationMatch", fmt.Sprint(ifGenerationMatch)) + return c +} + +// IfGenerationNotMatch sets the optional parameter +// "ifGenerationNotMatch": Makes the operation conditional on whether +// the object's current generation does not match the given value. If no +// live object exists, the precondition fails. Setting to 0 makes the +// operation succeed only if there is a live version of the object. +func (c *ObjectsUpdateCall) IfGenerationNotMatch(ifGenerationNotMatch int64) *ObjectsUpdateCall { + c.urlParams_.Set("ifGenerationNotMatch", fmt.Sprint(ifGenerationNotMatch)) + return c +} + +// IfMetagenerationMatch sets the optional parameter +// "ifMetagenerationMatch": Makes the operation conditional on whether +// the object's current metageneration matches the given value. +func (c *ObjectsUpdateCall) IfMetagenerationMatch(ifMetagenerationMatch int64) *ObjectsUpdateCall { + c.urlParams_.Set("ifMetagenerationMatch", fmt.Sprint(ifMetagenerationMatch)) + return c +} + +// IfMetagenerationNotMatch sets the optional parameter +// "ifMetagenerationNotMatch": Makes the operation conditional on +// whether the object's current metageneration does not match the given +// value. +func (c *ObjectsUpdateCall) IfMetagenerationNotMatch(ifMetagenerationNotMatch int64) *ObjectsUpdateCall { + c.urlParams_.Set("ifMetagenerationNotMatch", fmt.Sprint(ifMetagenerationNotMatch)) + return c +} + +// PredefinedAcl sets the optional parameter "predefinedAcl": Apply a +// predefined set of access controls to this object. +// +// Possible values: +// "authenticatedRead" - Object owner gets OWNER access, and +// allAuthenticatedUsers get READER access. +// "bucketOwnerFullControl" - Object owner gets OWNER access, and +// project team owners get OWNER access. +// "bucketOwnerRead" - Object owner gets OWNER access, and project +// team owners get READER access. +// "private" - Object owner gets OWNER access. +// "projectPrivate" - Object owner gets OWNER access, and project team +// members get access according to their roles. +// "publicRead" - Object owner gets OWNER access, and allUsers get +// READER access. +func (c *ObjectsUpdateCall) PredefinedAcl(predefinedAcl string) *ObjectsUpdateCall { + c.urlParams_.Set("predefinedAcl", predefinedAcl) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to full. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsUpdateCall) Projection(projection string) *ObjectsUpdateCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsUpdateCall) UserProject(userProject string) *ObjectsUpdateCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsUpdateCall) Fields(s ...googleapi.Field) *ObjectsUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsUpdateCall) Context(ctx context.Context) *ObjectsUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.object2) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/{object}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + "object": c.object, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.update" call. +// Exactly one of *Object or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Object.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsUpdateCall) Do(opts ...googleapi.CallOption) (*Object, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Object{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates an object's metadata.", + // "httpMethod": "PUT", + // "id": "storage.objects.update", + // "parameterOrder": [ + // "bucket", + // "object" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which the object resides.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "generation": { + // "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifGenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "ifMetagenerationNotMatch": { + // "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", + // "format": "int64", + // "location": "query", + // "type": "string" + // }, + // "object": { + // "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "predefinedAcl": { + // "description": "Apply a predefined set of access controls to this object.", + // "enum": [ + // "authenticatedRead", + // "bucketOwnerFullControl", + // "bucketOwnerRead", + // "private", + // "projectPrivate", + // "publicRead" + // ], + // "enumDescriptions": [ + // "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", + // "Object owner gets OWNER access, and project team owners get OWNER access.", + // "Object owner gets OWNER access, and project team owners get READER access.", + // "Object owner gets OWNER access.", + // "Object owner gets OWNER access, and project team members get access according to their roles.", + // "Object owner gets OWNER access, and allUsers get READER access." + // ], + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to full.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "b/{bucket}/o/{object}", + // "request": { + // "$ref": "Object" + // }, + // "response": { + // "$ref": "Object" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.objects.watchAll": + +type ObjectsWatchAllCall struct { + s *Service + bucket string + channel *Channel + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// WatchAll: Watch for changes on all objects in a bucket. +func (r *ObjectsService) WatchAll(bucket string, channel *Channel) *ObjectsWatchAllCall { + c := &ObjectsWatchAllCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.bucket = bucket + c.channel = channel + return c +} + +// Delimiter sets the optional parameter "delimiter": Returns results in +// a directory-like mode. items will contain only objects whose names, +// aside from the prefix, do not contain delimiter. Objects whose names, +// aside from the prefix, contain delimiter will have their name, +// truncated after the delimiter, returned in prefixes. Duplicate +// prefixes are omitted. +func (c *ObjectsWatchAllCall) Delimiter(delimiter string) *ObjectsWatchAllCall { + c.urlParams_.Set("delimiter", delimiter) + return c +} + +// IncludeTrailingDelimiter sets the optional parameter +// "includeTrailingDelimiter": If true, objects that end in exactly one +// instance of delimiter will have their metadata included in items in +// addition to prefixes. +func (c *ObjectsWatchAllCall) IncludeTrailingDelimiter(includeTrailingDelimiter bool) *ObjectsWatchAllCall { + c.urlParams_.Set("includeTrailingDelimiter", fmt.Sprint(includeTrailingDelimiter)) + return c +} + +// MaxResults sets the optional parameter "maxResults": Maximum number +// of items plus prefixes to return in a single page of responses. As +// duplicate prefixes are omitted, fewer total results may be returned +// than requested. The service will use this parameter or 1,000 items, +// whichever is smaller. +func (c *ObjectsWatchAllCall) MaxResults(maxResults int64) *ObjectsWatchAllCall { + c.urlParams_.Set("maxResults", fmt.Sprint(maxResults)) + return c +} + +// PageToken sets the optional parameter "pageToken": A +// previously-returned page token representing part of the larger set of +// results to view. +func (c *ObjectsWatchAllCall) PageToken(pageToken string) *ObjectsWatchAllCall { + c.urlParams_.Set("pageToken", pageToken) + return c +} + +// Prefix sets the optional parameter "prefix": Filter results to +// objects whose names begin with this prefix. +func (c *ObjectsWatchAllCall) Prefix(prefix string) *ObjectsWatchAllCall { + c.urlParams_.Set("prefix", prefix) + return c +} + +// Projection sets the optional parameter "projection": Set of +// properties to return. Defaults to noAcl. +// +// Possible values: +// "full" - Include all properties. +// "noAcl" - Omit the owner, acl property. +func (c *ObjectsWatchAllCall) Projection(projection string) *ObjectsWatchAllCall { + c.urlParams_.Set("projection", projection) + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. Required for Requester Pays buckets. +func (c *ObjectsWatchAllCall) UserProject(userProject string) *ObjectsWatchAllCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Versions sets the optional parameter "versions": If true, lists all +// versions of an object as distinct results. The default is false. For +// more information, see Object Versioning. +func (c *ObjectsWatchAllCall) Versions(versions bool) *ObjectsWatchAllCall { + c.urlParams_.Set("versions", fmt.Sprint(versions)) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ObjectsWatchAllCall) Fields(s ...googleapi.Field) *ObjectsWatchAllCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ObjectsWatchAllCall) Context(ctx context.Context) *ObjectsWatchAllCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ObjectsWatchAllCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ObjectsWatchAllCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.channel) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "b/{bucket}/o/watch") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "bucket": c.bucket, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.objects.watchAll" call. +// Exactly one of *Channel or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *Channel.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ObjectsWatchAllCall) Do(opts ...googleapi.CallOption) (*Channel, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &Channel{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Watch for changes on all objects in a bucket.", + // "httpMethod": "POST", + // "id": "storage.objects.watchAll", + // "parameterOrder": [ + // "bucket" + // ], + // "parameters": { + // "bucket": { + // "description": "Name of the bucket in which to look for objects.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "delimiter": { + // "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", + // "location": "query", + // "type": "string" + // }, + // "includeTrailingDelimiter": { + // "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", + // "location": "query", + // "type": "boolean" + // }, + // "maxResults": { + // "default": "1000", + // "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", + // "format": "uint32", + // "location": "query", + // "minimum": "0", + // "type": "integer" + // }, + // "pageToken": { + // "description": "A previously-returned page token representing part of the larger set of results to view.", + // "location": "query", + // "type": "string" + // }, + // "prefix": { + // "description": "Filter results to objects whose names begin with this prefix.", + // "location": "query", + // "type": "string" + // }, + // "projection": { + // "description": "Set of properties to return. Defaults to noAcl.", + // "enum": [ + // "full", + // "noAcl" + // ], + // "enumDescriptions": [ + // "Include all properties.", + // "Omit the owner, acl property." + // ], + // "location": "query", + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request. Required for Requester Pays buckets.", + // "location": "query", + // "type": "string" + // }, + // "versions": { + // "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", + // "location": "query", + // "type": "boolean" + // } + // }, + // "path": "b/{bucket}/o/watch", + // "request": { + // "$ref": "Channel", + // "parameterName": "resource" + // }, + // "response": { + // "$ref": "Channel" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ], + // "supportsSubscription": true + // } + +} + +// method id "storage.projects.hmacKeys.create": + +type ProjectsHmacKeysCreateCall struct { + s *Service + projectId string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Create: Creates a new HMAC key for the specified service account. +func (r *ProjectsHmacKeysService) Create(projectId string, serviceAccountEmail string) *ProjectsHmacKeysCreateCall { + c := &ProjectsHmacKeysCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.projectId = projectId + c.urlParams_.Set("serviceAccountEmail", serviceAccountEmail) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProjectsHmacKeysCreateCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysCreateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ProjectsHmacKeysCreateCall) Context(ctx context.Context) *ProjectsHmacKeysCreateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ProjectsHmacKeysCreateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ProjectsHmacKeysCreateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "projectId": c.projectId, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.projects.hmacKeys.create" call. +// Exactly one of *HmacKey or error will be non-nil. Any non-2xx status +// code is an error. Response headers are in either +// *HmacKey.ServerResponse.Header or (if a response was returned at all) +// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to +// check whether the returned error was because http.StatusNotModified +// was returned. +func (c *ProjectsHmacKeysCreateCall) Do(opts ...googleapi.CallOption) (*HmacKey, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &HmacKey{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Creates a new HMAC key for the specified service account.", + // "httpMethod": "POST", + // "id": "storage.projects.hmacKeys.create", + // "parameterOrder": [ + // "projectId", + // "serviceAccountEmail" + // ], + // "parameters": { + // "projectId": { + // "description": "Project ID owning the service account.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "serviceAccountEmail": { + // "description": "Email address of the service account.", + // "location": "query", + // "required": true, + // "type": "string" + // } + // }, + // "path": "projects/{projectId}/hmacKeys", + // "response": { + // "$ref": "HmacKey" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.projects.hmacKeys.delete": + +type ProjectsHmacKeysDeleteCall struct { + s *Service + projectId string + accessId string + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Delete: Deletes an HMAC key. +func (r *ProjectsHmacKeysService) Delete(projectId string, accessId string) *ProjectsHmacKeysDeleteCall { + c := &ProjectsHmacKeysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.projectId = projectId + c.accessId = accessId + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProjectsHmacKeysDeleteCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysDeleteCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ProjectsHmacKeysDeleteCall) Context(ctx context.Context) *ProjectsHmacKeysDeleteCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ProjectsHmacKeysDeleteCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ProjectsHmacKeysDeleteCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys/{accessId}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("DELETE", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "projectId": c.projectId, + "accessId": c.accessId, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.projects.hmacKeys.delete" call. +func (c *ProjectsHmacKeysDeleteCall) Do(opts ...googleapi.CallOption) error { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if err != nil { + return err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return err + } + return nil + // { + // "description": "Deletes an HMAC key.", + // "httpMethod": "DELETE", + // "id": "storage.projects.hmacKeys.delete", + // "parameterOrder": [ + // "projectId", + // "accessId" + // ], + // "parameters": { + // "accessId": { + // "description": "Name of the HMAC key to be deleted.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "projectId": { + // "description": "Project ID owning the requested key", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "projects/{projectId}/hmacKeys/{accessId}", + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} + +// method id "storage.projects.hmacKeys.get": + +type ProjectsHmacKeysGetCall struct { + s *Service + projectId string + accessId string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Retrieves an HMAC key's metadata +func (r *ProjectsHmacKeysService) Get(projectId string, accessId string) *ProjectsHmacKeysGetCall { + c := &ProjectsHmacKeysGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.projectId = projectId + c.accessId = accessId + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProjectsHmacKeysGetCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ProjectsHmacKeysGetCall) IfNoneMatch(entityTag string) *ProjectsHmacKeysGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ProjectsHmacKeysGetCall) Context(ctx context.Context) *ProjectsHmacKeysGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ProjectsHmacKeysGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ProjectsHmacKeysGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys/{accessId}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "projectId": c.projectId, + "accessId": c.accessId, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.projects.hmacKeys.get" call. +// Exactly one of *HmacKeyMetadata or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *HmacKeyMetadata.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ProjectsHmacKeysGetCall) Do(opts ...googleapi.CallOption) (*HmacKeyMetadata, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &HmacKeyMetadata{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves an HMAC key's metadata", + // "httpMethod": "GET", + // "id": "storage.projects.hmacKeys.get", + // "parameterOrder": [ + // "projectId", + // "accessId" + // ], + // "parameters": { + // "accessId": { + // "description": "Name of the HMAC key.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "projectId": { + // "description": "Project ID owning the service account of the requested key.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "projects/{projectId}/hmacKeys/{accessId}", + // "response": { + // "$ref": "HmacKeyMetadata" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.read_only" + // ] + // } + +} + +// method id "storage.projects.hmacKeys.list": + +type ProjectsHmacKeysListCall struct { + s *Service + projectId string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// List: Retrieves a list of HMAC keys matching the criteria. +func (r *ProjectsHmacKeysService) List(projectId string) *ProjectsHmacKeysListCall { + c := &ProjectsHmacKeysListCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.projectId = projectId + return c +} + +// MaxResults sets the optional parameter "maxResults": Maximum number +// of items plus prefixes to return in a single page of responses. +// Because duplicate prefixes are omitted, fewer total results may be +// returned than requested. The service uses this parameter or 1,000 +// items, whichever is smaller. +func (c *ProjectsHmacKeysListCall) MaxResults(maxResults int64) *ProjectsHmacKeysListCall { + c.urlParams_.Set("maxResults", fmt.Sprint(maxResults)) + return c +} + +// PageToken sets the optional parameter "pageToken": A +// previously-returned page token representing part of the larger set of +// results to view. +func (c *ProjectsHmacKeysListCall) PageToken(pageToken string) *ProjectsHmacKeysListCall { + c.urlParams_.Set("pageToken", pageToken) + return c +} + +// ServiceAccountEmail sets the optional parameter +// "serviceAccountEmail": If present, only keys for the given service +// account are returned. +func (c *ProjectsHmacKeysListCall) ServiceAccountEmail(serviceAccountEmail string) *ProjectsHmacKeysListCall { + c.urlParams_.Set("serviceAccountEmail", serviceAccountEmail) + return c +} + +// ShowDeletedKeys sets the optional parameter "showDeletedKeys": +// Whether or not to show keys in the DELETED state. +func (c *ProjectsHmacKeysListCall) ShowDeletedKeys(showDeletedKeys bool) *ProjectsHmacKeysListCall { + c.urlParams_.Set("showDeletedKeys", fmt.Sprint(showDeletedKeys)) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProjectsHmacKeysListCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysListCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ProjectsHmacKeysListCall) IfNoneMatch(entityTag string) *ProjectsHmacKeysListCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ProjectsHmacKeysListCall) Context(ctx context.Context) *ProjectsHmacKeysListCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ProjectsHmacKeysListCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ProjectsHmacKeysListCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "projectId": c.projectId, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.projects.hmacKeys.list" call. +// Exactly one of *HmacKeysMetadata or error will be non-nil. Any +// non-2xx status code is an error. Response headers are in either +// *HmacKeysMetadata.ServerResponse.Header or (if a response was +// returned at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ProjectsHmacKeysListCall) Do(opts ...googleapi.CallOption) (*HmacKeysMetadata, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &HmacKeysMetadata{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Retrieves a list of HMAC keys matching the criteria.", + // "httpMethod": "GET", + // "id": "storage.projects.hmacKeys.list", + // "parameterOrder": [ + // "projectId" + // ], + // "parameters": { + // "maxResults": { + // "default": "1000", + // "description": "Maximum number of items plus prefixes to return in a single page of responses. Because duplicate prefixes are omitted, fewer total results may be returned than requested. The service uses this parameter or 1,000 items, whichever is smaller.", + // "format": "uint32", + // "location": "query", + // "minimum": "0", + // "type": "integer" + // }, + // "pageToken": { + // "description": "A previously-returned page token representing part of the larger set of results to view.", + // "location": "query", + // "type": "string" + // }, + // "projectId": { + // "description": "Name of the project in which to look for HMAC keys.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "serviceAccountEmail": { + // "description": "If present, only keys for the given service account are returned.", + // "location": "query", + // "type": "string" + // }, + // "showDeletedKeys": { + // "description": "Whether or not to show keys in the DELETED state.", + // "location": "query", + // "type": "boolean" + // } + // }, + // "path": "projects/{projectId}/hmacKeys", + // "response": { + // "$ref": "HmacKeysMetadata" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only" + // ] + // } + +} + +// Pages invokes f for each page of results. +// A non-nil error returned from f will halt the iteration. +// The provided context supersedes any context provided to the Context method. +func (c *ProjectsHmacKeysListCall) Pages(ctx context.Context, f func(*HmacKeysMetadata) error) error { + c.ctx_ = ctx + defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point + for { + x, err := c.Do() + if err != nil { + return err + } + if err := f(x); err != nil { + return err + } + if x.NextPageToken == "" { + return nil + } + c.PageToken(x.NextPageToken) + } +} + +// method id "storage.projects.hmacKeys.update": + +type ProjectsHmacKeysUpdateCall struct { + s *Service + projectId string + accessId string + hmackeymetadata *HmacKeyMetadata + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// Update: Updates the state of an HMAC key. See the HMAC Key resource +// descriptor for valid states. +func (r *ProjectsHmacKeysService) Update(projectId string, accessId string, hmackeymetadata *HmacKeyMetadata) *ProjectsHmacKeysUpdateCall { + c := &ProjectsHmacKeysUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.projectId = projectId + c.accessId = accessId + c.hmackeymetadata = hmackeymetadata + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProjectsHmacKeysUpdateCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysUpdateCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ProjectsHmacKeysUpdateCall) Context(ctx context.Context) *ProjectsHmacKeysUpdateCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ProjectsHmacKeysUpdateCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ProjectsHmacKeysUpdateCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body, err := googleapi.WithoutDataWrapper.JSONReader(c.hmackeymetadata) + if err != nil { + return nil, err + } + reqHeaders.Set("Content-Type", "application/json") + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys/{accessId}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("PUT", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "projectId": c.projectId, + "accessId": c.accessId, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.projects.hmacKeys.update" call. +// Exactly one of *HmacKeyMetadata or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *HmacKeyMetadata.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ProjectsHmacKeysUpdateCall) Do(opts ...googleapi.CallOption) (*HmacKeyMetadata, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &HmacKeyMetadata{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.", + // "httpMethod": "PUT", + // "id": "storage.projects.hmacKeys.update", + // "parameterOrder": [ + // "projectId", + // "accessId" + // ], + // "parameters": { + // "accessId": { + // "description": "Name of the HMAC key being updated.", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "projectId": { + // "description": "Project ID owning the service account of the updated key.", + // "location": "path", + // "required": true, + // "type": "string" + // } + // }, + // "path": "projects/{projectId}/hmacKeys/{accessId}", + // "request": { + // "$ref": "HmacKeyMetadata" + // }, + // "response": { + // "$ref": "HmacKeyMetadata" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/devstorage.full_control" + // ] + // } + +} + +// method id "storage.projects.serviceAccount.get": + +type ProjectsServiceAccountGetCall struct { + s *Service + projectId string + urlParams_ gensupport.URLParams + ifNoneMatch_ string + ctx_ context.Context + header_ http.Header +} + +// Get: Get the email address of this project's Google Cloud Storage +// service account. +func (r *ProjectsServiceAccountService) Get(projectId string) *ProjectsServiceAccountGetCall { + c := &ProjectsServiceAccountGetCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.projectId = projectId + return c +} + +// UserProject sets the optional parameter "userProject": The project to +// be billed for this request. +func (c *ProjectsServiceAccountGetCall) UserProject(userProject string) *ProjectsServiceAccountGetCall { + c.urlParams_.Set("userProject", userProject) + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProjectsServiceAccountGetCall) Fields(s ...googleapi.Field) *ProjectsServiceAccountGetCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// IfNoneMatch sets the optional parameter which makes the operation +// fail if the object's ETag matches the given value. This is useful for +// getting updates only after the object has changed since the last +// request. Use googleapi.IsNotModified to check whether the response +// error from Do is the result of In-None-Match. +func (c *ProjectsServiceAccountGetCall) IfNoneMatch(entityTag string) *ProjectsServiceAccountGetCall { + c.ifNoneMatch_ = entityTag + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ProjectsServiceAccountGetCall) Context(ctx context.Context) *ProjectsServiceAccountGetCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ProjectsServiceAccountGetCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ProjectsServiceAccountGetCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + if c.ifNoneMatch_ != "" { + reqHeaders.Set("If-None-Match", c.ifNoneMatch_) + } + var body io.Reader = nil + c.urlParams_.Set("alt", alt) + c.urlParams_.Set("prettyPrint", "false") + urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/serviceAccount") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("GET", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "projectId": c.projectId, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "storage.projects.serviceAccount.get" call. +// Exactly one of *ServiceAccount or error will be non-nil. Any non-2xx +// status code is an error. Response headers are in either +// *ServiceAccount.ServerResponse.Header or (if a response was returned +// at all) in error.(*googleapi.Error).Header. Use +// googleapi.IsNotModified to check whether the returned error was +// because http.StatusNotModified was returned. +func (c *ProjectsServiceAccountGetCall) Do(opts ...googleapi.CallOption) (*ServiceAccount, error) { + gensupport.SetOptions(c.urlParams_, opts...) + res, err := c.doRequest("json") + if res != nil && res.StatusCode == http.StatusNotModified { + if res.Body != nil { + res.Body.Close() + } + return nil, &googleapi.Error{ + Code: res.StatusCode, + Header: res.Header, + } + } + if err != nil { + return nil, err + } + defer googleapi.CloseBody(res) + if err := googleapi.CheckResponse(res); err != nil { + return nil, err + } + ret := &ServiceAccount{ + ServerResponse: googleapi.ServerResponse{ + Header: res.Header, + HTTPStatusCode: res.StatusCode, + }, + } + target := &ret + if err := gensupport.DecodeResponse(target, res); err != nil { + return nil, err + } + return ret, nil + // { + // "description": "Get the email address of this project's Google Cloud Storage service account.", + // "httpMethod": "GET", + // "id": "storage.projects.serviceAccount.get", + // "parameterOrder": [ + // "projectId" + // ], + // "parameters": { + // "projectId": { + // "description": "Project ID", + // "location": "path", + // "required": true, + // "type": "string" + // }, + // "userProject": { + // "description": "The project to be billed for this request.", + // "location": "query", + // "type": "string" + // } + // }, + // "path": "projects/{projectId}/serviceAccount", + // "response": { + // "$ref": "ServiceAccount" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform", + // "https://www.googleapis.com/auth/cloud-platform.read-only", + // "https://www.googleapis.com/auth/devstorage.full_control", + // "https://www.googleapis.com/auth/devstorage.read_only", + // "https://www.googleapis.com/auth/devstorage.read_write" + // ] + // } + +} diff --git a/vendor/google.golang.org/api/support/bundler/bundler.go b/vendor/google.golang.org/api/support/bundler/bundler.go deleted file mode 100644 index c55327119087..000000000000 --- a/vendor/google.golang.org/api/support/bundler/bundler.go +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright 2016 Google LLC -// -// 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 bundler supports bundling (batching) of items. Bundling amortizes an -// action with fixed costs over multiple items. For example, if an API provides -// an RPC that accepts a list of items as input, but clients would prefer -// adding items one at a time, then a Bundler can accept individual items from -// the client and bundle many of them into a single RPC. -// -// This package is experimental and subject to change without notice. -package bundler - -import ( - "context" - "errors" - "math" - "reflect" - "sync" - "time" - - "golang.org/x/sync/semaphore" -) - -const ( - DefaultDelayThreshold = time.Second - DefaultBundleCountThreshold = 10 - DefaultBundleByteThreshold = 1e6 // 1M - DefaultBufferedByteLimit = 1e9 // 1G -) - -var ( - // ErrOverflow indicates that Bundler's stored bytes exceeds its BufferedByteLimit. - ErrOverflow = errors.New("bundler reached buffered byte limit") - - // ErrOversizedItem indicates that an item's size exceeds the maximum bundle size. - ErrOversizedItem = errors.New("item size exceeds bundle byte limit") -) - -// A Bundler collects items added to it into a bundle until the bundle -// exceeds a given size, then calls a user-provided function to handle the bundle. -type Bundler struct { - // Starting from the time that the first message is added to a bundle, once - // this delay has passed, handle the bundle. The default is DefaultDelayThreshold. - DelayThreshold time.Duration - - // Once a bundle has this many items, handle the bundle. Since only one - // item at a time is added to a bundle, no bundle will exceed this - // threshold, so it also serves as a limit. The default is - // DefaultBundleCountThreshold. - BundleCountThreshold int - - // Once the number of bytes in current bundle reaches this threshold, handle - // the bundle. The default is DefaultBundleByteThreshold. This triggers handling, - // but does not cap the total size of a bundle. - BundleByteThreshold int - - // The maximum size of a bundle, in bytes. Zero means unlimited. - BundleByteLimit int - - // The maximum number of bytes that the Bundler will keep in memory before - // returning ErrOverflow. The default is DefaultBufferedByteLimit. - BufferedByteLimit int - - // The maximum number of handler invocations that can be running at once. - // The default is 1. - HandlerLimit int - - handler func(interface{}) // called to handle a bundle - itemSliceZero reflect.Value // nil (zero value) for slice of items - flushTimer *time.Timer // implements DelayThreshold - - mu sync.Mutex - sem *semaphore.Weighted // enforces BufferedByteLimit - semOnce sync.Once - curBundle bundle // incoming items added to this bundle - - // Each bundle is assigned a unique ticket that determines the order in which the - // handler is called. The ticket is assigned with mu locked, but waiting for tickets - // to be handled is done via mu2 and cond, below. - nextTicket uint64 // next ticket to be assigned - - mu2 sync.Mutex - cond *sync.Cond - nextHandled uint64 // next ticket to be handled - - // In this implementation, active uses space proportional to HandlerLimit, and - // waitUntilAllHandled takes time proportional to HandlerLimit each time an acquire - // or release occurs, so large values of HandlerLimit max may cause performance - // issues. - active map[uint64]bool // tickets of bundles actively being handled -} - -type bundle struct { - items reflect.Value // slice of item type - size int // size in bytes of all items -} - -// NewBundler creates a new Bundler. -// -// itemExample is a value of the type that will be bundled. For example, if you -// want to create bundles of *Entry, you could pass &Entry{} for itemExample. -// -// handler is a function that will be called on each bundle. If itemExample is -// of type T, the argument to handler is of type []T. handler is always called -// sequentially for each bundle, and never in parallel. -// -// Configure the Bundler by setting its thresholds and limits before calling -// any of its methods. -func NewBundler(itemExample interface{}, handler func(interface{})) *Bundler { - b := &Bundler{ - DelayThreshold: DefaultDelayThreshold, - BundleCountThreshold: DefaultBundleCountThreshold, - BundleByteThreshold: DefaultBundleByteThreshold, - BufferedByteLimit: DefaultBufferedByteLimit, - HandlerLimit: 1, - - handler: handler, - itemSliceZero: reflect.Zero(reflect.SliceOf(reflect.TypeOf(itemExample))), - active: map[uint64]bool{}, - } - b.curBundle.items = b.itemSliceZero - b.cond = sync.NewCond(&b.mu2) - return b -} - -func (b *Bundler) initSemaphores() { - // Create the semaphores lazily, because the user may set limits - // after NewBundler. - b.semOnce.Do(func() { - b.sem = semaphore.NewWeighted(int64(b.BufferedByteLimit)) - }) -} - -// Add adds item to the current bundle. It marks the bundle for handling and -// starts a new one if any of the thresholds or limits are exceeded. -// -// If the item's size exceeds the maximum bundle size (Bundler.BundleByteLimit), then -// the item can never be handled. Add returns ErrOversizedItem in this case. -// -// If adding the item would exceed the maximum memory allowed -// (Bundler.BufferedByteLimit) or an AddWait call is blocked waiting for -// memory, Add returns ErrOverflow. -// -// Add never blocks. -func (b *Bundler) Add(item interface{}, size int) error { - // If this item exceeds the maximum size of a bundle, - // we can never send it. - if b.BundleByteLimit > 0 && size > b.BundleByteLimit { - return ErrOversizedItem - } - // If adding this item would exceed our allotted memory - // footprint, we can't accept it. - // (TryAcquire also returns false if anything is waiting on the semaphore, - // so calls to Add and AddWait shouldn't be mixed.) - b.initSemaphores() - if !b.sem.TryAcquire(int64(size)) { - return ErrOverflow - } - b.add(item, size) - return nil -} - -// add adds item to the current bundle. It marks the bundle for handling and -// starts a new one if any of the thresholds or limits are exceeded. -func (b *Bundler) add(item interface{}, size int) { - b.mu.Lock() - defer b.mu.Unlock() - - // If adding this item to the current bundle would cause it to exceed the - // maximum bundle size, close the current bundle and start a new one. - if b.BundleByteLimit > 0 && b.curBundle.size+size > b.BundleByteLimit { - b.startFlushLocked() - } - // Add the item. - b.curBundle.items = reflect.Append(b.curBundle.items, reflect.ValueOf(item)) - b.curBundle.size += size - - // Start a timer to flush the item if one isn't already running. - // startFlushLocked clears the timer and closes the bundle at the same time, - // so we only allocate a new timer for the first item in each bundle. - // (We could try to call Reset on the timer instead, but that would add a lot - // of complexity to the code just to save one small allocation.) - if b.flushTimer == nil { - b.flushTimer = time.AfterFunc(b.DelayThreshold, b.Flush) - } - - // If the current bundle equals the count threshold, close it. - if b.curBundle.items.Len() == b.BundleCountThreshold { - b.startFlushLocked() - } - // If the current bundle equals or exceeds the byte threshold, close it. - if b.curBundle.size >= b.BundleByteThreshold { - b.startFlushLocked() - } -} - -// AddWait adds item to the current bundle. It marks the bundle for handling and -// starts a new one if any of the thresholds or limits are exceeded. -// -// If the item's size exceeds the maximum bundle size (Bundler.BundleByteLimit), then -// the item can never be handled. AddWait returns ErrOversizedItem in this case. -// -// If adding the item would exceed the maximum memory allowed (Bundler.BufferedByteLimit), -// AddWait blocks until space is available or ctx is done. -// -// Calls to Add and AddWait should not be mixed on the same Bundler. -func (b *Bundler) AddWait(ctx context.Context, item interface{}, size int) error { - // If this item exceeds the maximum size of a bundle, - // we can never send it. - if b.BundleByteLimit > 0 && size > b.BundleByteLimit { - return ErrOversizedItem - } - // If adding this item would exceed our allotted memory footprint, block - // until space is available. The semaphore is FIFO, so there will be no - // starvation. - b.initSemaphores() - if err := b.sem.Acquire(ctx, int64(size)); err != nil { - return err - } - // Here, we've reserved space for item. Other goroutines can call AddWait - // and even acquire space, but no one can take away our reservation - // (assuming sem.Release is used correctly). So there is no race condition - // resulting from locking the mutex after sem.Acquire returns. - b.add(item, size) - return nil -} - -// Flush invokes the handler for all remaining items in the Bundler and waits -// for it to return. -func (b *Bundler) Flush() { - b.mu.Lock() - b.startFlushLocked() - // Here, all bundles with tickets < b.nextTicket are - // either finished or active. Those are the ones - // we want to wait for. - t := b.nextTicket - b.mu.Unlock() - b.initSemaphores() - b.waitUntilAllHandled(t) -} - -func (b *Bundler) startFlushLocked() { - if b.flushTimer != nil { - b.flushTimer.Stop() - b.flushTimer = nil - } - if b.curBundle.items.Len() == 0 { - return - } - // Here, both semaphores must have been initialized. - bun := b.curBundle - b.curBundle = bundle{items: b.itemSliceZero} - ticket := b.nextTicket - b.nextTicket++ - go func() { - defer func() { - b.sem.Release(int64(bun.size)) - b.release(ticket) - }() - b.acquire(ticket) - b.handler(bun.items.Interface()) - }() -} - -// acquire blocks until ticket is the next to be served, then returns. In order for N -// acquire calls to return, the tickets must be in the range [0, N). A ticket must -// not be presented to acquire more than once. -func (b *Bundler) acquire(ticket uint64) { - b.mu2.Lock() - defer b.mu2.Unlock() - if ticket < b.nextHandled { - panic("bundler: acquire: arg too small") - } - for !(ticket == b.nextHandled && len(b.active) < b.HandlerLimit) { - b.cond.Wait() - } - // Here, - // ticket == b.nextHandled: the caller is the next one to be handled; - // and len(b.active) < b.HandlerLimit: there is space available. - b.active[ticket] = true - b.nextHandled++ - // Broadcast, not Signal: although at most one acquire waiter can make progress, - // there might be waiters in waitUntilAllHandled. - b.cond.Broadcast() -} - -// If a ticket is used for a call to acquire, it must later be passed to release. A -// ticket must not be presented to release more than once. -func (b *Bundler) release(ticket uint64) { - b.mu2.Lock() - defer b.mu2.Unlock() - if !b.active[ticket] { - panic("bundler: release: not an active ticket") - } - delete(b.active, ticket) - b.cond.Broadcast() -} - -// waitUntilAllHandled blocks until all tickets < n have called release, meaning -// all bundles with tickets < n have been handled. -func (b *Bundler) waitUntilAllHandled(n uint64) { - // Proof of correctness of this function. - // "N is acquired" means acquire(N) has returned. - // "N is released" means release(N) has returned. - // 1. If N is acquired, N-1 is acquired. - // Follows from the loop test in acquire, and the fact - // that nextHandled is incremented by 1. - // 2. If nextHandled >= N, then N-1 is acquired. - // Because we only increment nextHandled to N after N-1 is acquired. - // 3. If nextHandled >= N, then all n < N is acquired. - // Follows from #1 and #2. - // 4. If N is acquired and N is not in active, then N is released. - // Because we put N in active before acquire returns, and only - // remove it when it is released. - // Let min(active) be the smallest member of active, or infinity if active is empty. - // 5. If nextHandled >= N and N <= min(active), then all n < N is released. - // From nextHandled >= N and #3, all n < N is acquired. - // N <= min(active) implies n < min(active) for all n < N. So all n < N is not in active. - // So from #4, all n < N is released. - // The loop test below is the antecedent of #5. - b.mu2.Lock() - defer b.mu2.Unlock() - for !(b.nextHandled >= n && n <= min(b.active)) { - b.cond.Wait() - } -} - -// min returns the minimum value of the set s, or the largest uint64 if -// s is empty. -func min(s map[uint64]bool) uint64 { - var m uint64 = math.MaxUint64 - for n := range s { - if n < m { - m = n - } - } - return m -} diff --git a/vendor/google.golang.org/api/transport/http/dial.go b/vendor/google.golang.org/api/transport/http/dial.go new file mode 100644 index 000000000000..c0d8bf20b022 --- /dev/null +++ b/vendor/google.golang.org/api/transport/http/dial.go @@ -0,0 +1,161 @@ +// Copyright 2015 Google LLC +// +// 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 http supports network connections to HTTP servers. +// This package is not intended for use by end developers. Use the +// google.golang.org/api/option package to configure API clients. +package http + +import ( + "context" + "errors" + "net/http" + + "go.opencensus.io/plugin/ochttp" + "golang.org/x/oauth2" + "google.golang.org/api/googleapi/transport" + "google.golang.org/api/internal" + "google.golang.org/api/option" + "google.golang.org/api/transport/http/internal/propagation" +) + +// NewClient returns an HTTP client for use communicating with a Google cloud +// service, configured with the given ClientOptions. It also returns the endpoint +// for the service as specified in the options. +func NewClient(ctx context.Context, opts ...option.ClientOption) (*http.Client, string, error) { + settings, err := newSettings(opts) + if err != nil { + return nil, "", err + } + // TODO(cbro): consider injecting the User-Agent even if an explicit HTTP client is provided? + if settings.HTTPClient != nil { + return settings.HTTPClient, settings.Endpoint, nil + } + trans, err := newTransport(ctx, defaultBaseTransport(ctx), settings) + if err != nil { + return nil, "", err + } + return &http.Client{Transport: trans}, settings.Endpoint, nil +} + +// NewTransport creates an http.RoundTripper for use communicating with a Google +// cloud service, configured with the given ClientOptions. Its RoundTrip method delegates to base. +func NewTransport(ctx context.Context, base http.RoundTripper, opts ...option.ClientOption) (http.RoundTripper, error) { + settings, err := newSettings(opts) + if err != nil { + return nil, err + } + if settings.HTTPClient != nil { + return nil, errors.New("transport/http: WithHTTPClient passed to NewTransport") + } + return newTransport(ctx, base, settings) +} + +func newTransport(ctx context.Context, base http.RoundTripper, settings *internal.DialSettings) (http.RoundTripper, error) { + trans := base + trans = parameterTransport{ + base: trans, + userAgent: settings.UserAgent, + quotaProject: settings.QuotaProject, + requestReason: settings.RequestReason, + } + trans = addOCTransport(trans) + switch { + case settings.NoAuth: + // Do nothing. + case settings.APIKey != "": + trans = &transport.APIKey{ + Transport: trans, + Key: settings.APIKey, + } + default: + creds, err := internal.Creds(ctx, settings) + if err != nil { + return nil, err + } + trans = &oauth2.Transport{ + Base: trans, + Source: creds.TokenSource, + } + } + return trans, nil +} + +func newSettings(opts []option.ClientOption) (*internal.DialSettings, error) { + var o internal.DialSettings + for _, opt := range opts { + opt.Apply(&o) + } + if err := o.Validate(); err != nil { + return nil, err + } + if o.GRPCConn != nil { + return nil, errors.New("unsupported gRPC connection specified") + } + return &o, nil +} + +type parameterTransport struct { + userAgent string + quotaProject string + requestReason string + + base http.RoundTripper +} + +func (t parameterTransport) RoundTrip(req *http.Request) (*http.Response, error) { + rt := t.base + if rt == nil { + return nil, errors.New("transport: no Transport specified") + } + if t.userAgent == "" { + return rt.RoundTrip(req) + } + newReq := *req + newReq.Header = make(http.Header) + for k, vv := range req.Header { + newReq.Header[k] = vv + } + // TODO(cbro): append to existing User-Agent header? + newReq.Header.Set("User-Agent", t.userAgent) + + // Attach system parameters into the header + if t.quotaProject != "" { + newReq.Header.Set("X-Goog-User-Project", t.quotaProject) + } + if t.requestReason != "" { + newReq.Header.Set("X-Goog-Request-Reason", t.requestReason) + } + + return rt.RoundTrip(&newReq) +} + +// Set at init time by dial_appengine.go. If nil, we're not on App Engine. +var appengineUrlfetchHook func(context.Context) http.RoundTripper + +// defaultBaseTransport returns the base HTTP transport. +// On App Engine, this is urlfetch.Transport, otherwise it's http.DefaultTransport. +func defaultBaseTransport(ctx context.Context) http.RoundTripper { + if appengineUrlfetchHook != nil { + return appengineUrlfetchHook(ctx) + } + return http.DefaultTransport +} + +func addOCTransport(trans http.RoundTripper) http.RoundTripper { + return &ochttp.Transport{ + Base: trans, + Propagation: &propagation.HTTPFormat{}, + } +} diff --git a/vendor/google.golang.org/api/transport/http/dial_appengine.go b/vendor/google.golang.org/api/transport/http/dial_appengine.go new file mode 100644 index 000000000000..04c81413c519 --- /dev/null +++ b/vendor/google.golang.org/api/transport/http/dial_appengine.go @@ -0,0 +1,30 @@ +// Copyright 2016 Google LLC +// +// 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. + +// +build appengine + +package http + +import ( + "context" + "net/http" + + "google.golang.org/appengine/urlfetch" +) + +func init() { + appengineUrlfetchHook = func(ctx context.Context) http.RoundTripper { + return &urlfetch.Transport{Context: ctx} + } +} diff --git a/vendor/google.golang.org/api/transport/http/internal/propagation/http.go b/vendor/google.golang.org/api/transport/http/internal/propagation/http.go new file mode 100644 index 000000000000..24b4f0d29156 --- /dev/null +++ b/vendor/google.golang.org/api/transport/http/internal/propagation/http.go @@ -0,0 +1,96 @@ +// Copyright 2018 Google LLC +// +// 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. + +// +build go1.8 + +// Package propagation implements X-Cloud-Trace-Context header propagation used +// by Google Cloud products. +package propagation + +import ( + "encoding/binary" + "encoding/hex" + "fmt" + "net/http" + "strconv" + "strings" + + "go.opencensus.io/trace" + "go.opencensus.io/trace/propagation" +) + +const ( + httpHeaderMaxSize = 200 + httpHeader = `X-Cloud-Trace-Context` +) + +var _ propagation.HTTPFormat = (*HTTPFormat)(nil) + +// HTTPFormat implements propagation.HTTPFormat to propagate +// traces in HTTP headers for Google Cloud Platform and Stackdriver Trace. +type HTTPFormat struct{} + +// SpanContextFromRequest extracts a Stackdriver Trace span context from incoming requests. +func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) { + h := req.Header.Get(httpHeader) + // See https://cloud.google.com/trace/docs/faq for the header HTTPFormat. + // Return if the header is empty or missing, or if the header is unreasonably + // large, to avoid making unnecessary copies of a large string. + if h == "" || len(h) > httpHeaderMaxSize { + return trace.SpanContext{}, false + } + + // Parse the trace id field. + slash := strings.Index(h, `/`) + if slash == -1 { + return trace.SpanContext{}, false + } + tid, h := h[:slash], h[slash+1:] + + buf, err := hex.DecodeString(tid) + if err != nil { + return trace.SpanContext{}, false + } + copy(sc.TraceID[:], buf) + + // Parse the span id field. + spanstr := h + semicolon := strings.Index(h, `;`) + if semicolon != -1 { + spanstr, h = h[:semicolon], h[semicolon+1:] + } + sid, err := strconv.ParseUint(spanstr, 10, 64) + if err != nil { + return trace.SpanContext{}, false + } + binary.BigEndian.PutUint64(sc.SpanID[:], sid) + + // Parse the options field, options field is optional. + if !strings.HasPrefix(h, "o=") { + return sc, true + } + o, err := strconv.ParseUint(h[2:], 10, 64) + if err != nil { + return trace.SpanContext{}, false + } + sc.TraceOptions = trace.TraceOptions(o) + return sc, true +} + +// SpanContextToRequest modifies the given request to include a Stackdriver Trace header. +func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) { + sid := binary.BigEndian.Uint64(sc.SpanID[:]) + header := fmt.Sprintf("%s/%d;o=%d", hex.EncodeToString(sc.TraceID[:]), sid, int64(sc.TraceOptions)) + req.Header.Set(httpHeader, header) +} diff --git a/vendor/google.golang.org/appengine/.travis.yml b/vendor/google.golang.org/appengine/.travis.yml new file mode 100644 index 000000000000..70ffe89d5e2d --- /dev/null +++ b/vendor/google.golang.org/appengine/.travis.yml @@ -0,0 +1,20 @@ +language: go + +go_import_path: google.golang.org/appengine + +install: + - ./travis_install.sh + +script: + - ./travis_test.sh + +matrix: + include: + - go: 1.8.x + env: GOAPP=true + - go: 1.9.x + env: GOAPP=true + - go: 1.10.x + env: GOAPP=false + - go: 1.11.x + env: GO111MODULE=on diff --git a/vendor/google.golang.org/appengine/CONTRIBUTING.md b/vendor/google.golang.org/appengine/CONTRIBUTING.md new file mode 100644 index 000000000000..ffc298520856 --- /dev/null +++ b/vendor/google.golang.org/appengine/CONTRIBUTING.md @@ -0,0 +1,90 @@ +# Contributing + +1. Sign one of the contributor license agreements below. +1. Get the package: + + `go get -d google.golang.org/appengine` +1. Change into the checked out source: + + `cd $GOPATH/src/google.golang.org/appengine` +1. Fork the repo. +1. Set your fork as a remote: + + `git remote add fork git@github.com:GITHUB_USERNAME/appengine.git` +1. Make changes, commit to your fork. +1. Send a pull request with your changes. + The first line of your commit message is conventionally a one-line summary of the change, prefixed by the primary affected package, and is used as the title of your pull request. + +# Testing + +## Running system tests + +Download and install the [Go App Engine SDK](https://cloud.google.com/appengine/docs/go/download). Make sure the `go_appengine` dir is in your `PATH`. + +Set the `APPENGINE_DEV_APPSERVER` environment variable to `/path/to/go_appengine/dev_appserver.py`. + +Run tests with `goapp test`: + +``` +goapp test -v google.golang.org/appengine/... +``` + +## Contributor License Agreements + +Before we can accept your pull requests you'll need to sign a Contributor +License Agreement (CLA): + +- **If you are an individual writing original source code** and **you own the +intellectual property**, then you'll need to sign an [individual CLA][indvcla]. +- **If you work for a company that wants to allow you to contribute your work**, +then you'll need to sign a [corporate CLA][corpcla]. + +You can sign these electronically (just scroll to the bottom). After that, +we'll be able to accept your pull requests. + +## Contributor Code of Conduct + +As contributors and maintainers of this project, +and in the interest of fostering an open and welcoming community, +we pledge to respect all people who contribute through reporting issues, +posting feature requests, updating documentation, +submitting pull requests or patches, and other activities. + +We are committed to making participation in this project +a harassment-free experience for everyone, +regardless of level of experience, gender, gender identity and expression, +sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, +such as physical or electronic +addresses, without explicit permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct. +By adopting this Code of Conduct, +project maintainers commit themselves to fairly and consistently +applying these principles to every aspect of managing this project. +Project maintainers who do not follow or enforce the Code of Conduct +may be permanently removed from the project team. + +This code of conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior +may be reported by opening an issue +or contacting one or more of the project maintainers. + +This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, +available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) + +[indvcla]: https://developers.google.com/open-source/cla/individual +[corpcla]: https://developers.google.com/open-source/cla/corporate diff --git a/vendor/google.golang.org/appengine/LICENSE b/vendor/google.golang.org/appengine/LICENSE new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/vendor/google.golang.org/appengine/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/google.golang.org/appengine/README.md b/vendor/google.golang.org/appengine/README.md new file mode 100644 index 000000000000..d86768a2c665 --- /dev/null +++ b/vendor/google.golang.org/appengine/README.md @@ -0,0 +1,73 @@ +# Go App Engine packages + +[![Build Status](https://travis-ci.org/golang/appengine.svg)](https://travis-ci.org/golang/appengine) + +This repository supports the Go runtime on *App Engine standard*. +It provides APIs for interacting with App Engine services. +Its canonical import path is `google.golang.org/appengine`. + +See https://cloud.google.com/appengine/docs/go/ +for more information. + +File issue reports and feature requests on the [GitHub's issue +tracker](https://github.com/golang/appengine/issues). + +## Upgrading an App Engine app to the flexible environment + +This package does not work on *App Engine flexible*. + +There are many differences between the App Engine standard environment and +the flexible environment. + +See the [documentation on upgrading to the flexible environment](https://cloud.google.com/appengine/docs/flexible/go/upgrading). + +## Directory structure + +The top level directory of this repository is the `appengine` package. It +contains the +basic APIs (e.g. `appengine.NewContext`) that apply across APIs. Specific API +packages are in subdirectories (e.g. `datastore`). + +There is an `internal` subdirectory that contains service protocol buffers, +plus packages required for connectivity to make API calls. App Engine apps +should not directly import any package under `internal`. + +## Updating from legacy (`import "appengine"`) packages + +If you're currently using the bare `appengine` packages +(that is, not these ones, imported via `google.golang.org/appengine`), +then you can use the `aefix` tool to help automate an upgrade to these packages. + +Run `go get google.golang.org/appengine/cmd/aefix` to install it. + +### 1. Update import paths + +The import paths for App Engine packages are now fully qualified, based at `google.golang.org/appengine`. +You will need to update your code to use import paths starting with that; for instance, +code importing `appengine/datastore` will now need to import `google.golang.org/appengine/datastore`. + +### 2. Update code using deprecated, removed or modified APIs + +Most App Engine services are available with exactly the same API. +A few APIs were cleaned up, and there are some differences: + +* `appengine.Context` has been replaced with the `Context` type from `golang.org/x/net/context`. +* Logging methods that were on `appengine.Context` are now functions in `google.golang.org/appengine/log`. +* `appengine.Timeout` has been removed. Use `context.WithTimeout` instead. +* `appengine.Datacenter` now takes a `context.Context` argument. +* `datastore.PropertyLoadSaver` has been simplified to use slices in place of channels. +* `delay.Call` now returns an error. +* `search.FieldLoadSaver` now handles document metadata. +* `urlfetch.Transport` no longer has a Deadline field; set a deadline on the + `context.Context` instead. +* `aetest` no longer declares its own Context type, and uses the standard one instead. +* `taskqueue.QueueStats` no longer takes a maxTasks argument. That argument has been + deprecated and unused for a long time. +* `appengine.BackendHostname` and `appengine.BackendInstance` were for the deprecated backends feature. + Use `appengine.ModuleHostname`and `appengine.ModuleName` instead. +* Most of `appengine/file` and parts of `appengine/blobstore` are deprecated. + Use [Google Cloud Storage](https://godoc.org/cloud.google.com/go/storage) if the + feature you require is not present in the new + [blobstore package](https://google.golang.org/appengine/blobstore). +* `appengine/socket` is not required on App Engine flexible environment / Managed VMs. + Use the standard `net` package instead. diff --git a/vendor/google.golang.org/appengine/appengine.go b/vendor/google.golang.org/appengine/appengine.go new file mode 100644 index 000000000000..0cca033d37d1 --- /dev/null +++ b/vendor/google.golang.org/appengine/appengine.go @@ -0,0 +1,137 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// Package appengine provides basic functionality for Google App Engine. +// +// For more information on how to write Go apps for Google App Engine, see: +// https://cloud.google.com/appengine/docs/go/ +package appengine // import "google.golang.org/appengine" + +import ( + "net/http" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" +) + +// The gophers party all night; the rabbits provide the beats. + +// Main is the principal entry point for an app running in App Engine. +// +// On App Engine Flexible it installs a trivial health checker if one isn't +// already registered, and starts listening on port 8080 (overridden by the +// $PORT environment variable). +// +// See https://cloud.google.com/appengine/docs/flexible/custom-runtimes#health_check_requests +// for details on how to do your own health checking. +// +// On App Engine Standard it ensures the server has started and is prepared to +// receive requests. +// +// Main never returns. +// +// Main is designed so that the app's main package looks like this: +// +// package main +// +// import ( +// "google.golang.org/appengine" +// +// _ "myapp/package0" +// _ "myapp/package1" +// ) +// +// func main() { +// appengine.Main() +// } +// +// The "myapp/packageX" packages are expected to register HTTP handlers +// in their init functions. +func Main() { + internal.Main() +} + +// IsDevAppServer reports whether the App Engine app is running in the +// development App Server. +func IsDevAppServer() bool { + return internal.IsDevAppServer() +} + +// IsStandard reports whether the App Engine app is running in the standard +// environment. This includes both the first generation runtimes (<= Go 1.9) +// and the second generation runtimes (>= Go 1.11). +func IsStandard() bool { + return internal.IsStandard() +} + +// IsFlex reports whether the App Engine app is running in the flexible environment. +func IsFlex() bool { + return internal.IsFlex() +} + +// IsAppEngine reports whether the App Engine app is running on App Engine, in either +// the standard or flexible environment. +func IsAppEngine() bool { + return internal.IsAppEngine() +} + +// IsSecondGen reports whether the App Engine app is running on the second generation +// runtimes (>= Go 1.11). +func IsSecondGen() bool { + return internal.IsSecondGen() +} + +// NewContext returns a context for an in-flight HTTP request. +// This function is cheap. +func NewContext(req *http.Request) context.Context { + return internal.ReqContext(req) +} + +// WithContext returns a copy of the parent context +// and associates it with an in-flight HTTP request. +// This function is cheap. +func WithContext(parent context.Context, req *http.Request) context.Context { + return internal.WithContext(parent, req) +} + +// TODO(dsymonds): Add a Call function here? Otherwise other packages can't access internal.Call. + +// BlobKey is a key for a blobstore blob. +// +// Conceptually, this type belongs in the blobstore package, but it lives in +// the appengine package to avoid a circular dependency: blobstore depends on +// datastore, and datastore needs to refer to the BlobKey type. +type BlobKey string + +// GeoPoint represents a location as latitude/longitude in degrees. +type GeoPoint struct { + Lat, Lng float64 +} + +// Valid returns whether a GeoPoint is within [-90, 90] latitude and [-180, 180] longitude. +func (g GeoPoint) Valid() bool { + return -90 <= g.Lat && g.Lat <= 90 && -180 <= g.Lng && g.Lng <= 180 +} + +// APICallFunc defines a function type for handling an API call. +// See WithCallOverride. +type APICallFunc func(ctx context.Context, service, method string, in, out proto.Message) error + +// WithAPICallFunc returns a copy of the parent context +// that will cause API calls to invoke f instead of their normal operation. +// +// This is intended for advanced users only. +func WithAPICallFunc(ctx context.Context, f APICallFunc) context.Context { + return internal.WithCallOverride(ctx, internal.CallOverrideFunc(f)) +} + +// APICall performs an API call. +// +// This is not intended for general use; it is exported for use in conjunction +// with WithAPICallFunc. +func APICall(ctx context.Context, service, method string, in, out proto.Message) error { + return internal.Call(ctx, service, method, in, out) +} diff --git a/vendor/google.golang.org/appengine/appengine_vm.go b/vendor/google.golang.org/appengine/appengine_vm.go new file mode 100644 index 000000000000..f4b645aad3be --- /dev/null +++ b/vendor/google.golang.org/appengine/appengine_vm.go @@ -0,0 +1,20 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build !appengine + +package appengine + +import ( + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" +) + +// BackgroundContext returns a context not associated with a request. +// This should only be used when not servicing a request. +// This only works in App Engine "flexible environment". +func BackgroundContext() context.Context { + return internal.BackgroundContext() +} diff --git a/vendor/google.golang.org/appengine/datastore/datastore.go b/vendor/google.golang.org/appengine/datastore/datastore.go new file mode 100644 index 000000000000..576bc50132aa --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/datastore.go @@ -0,0 +1,407 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "errors" + "fmt" + "reflect" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + + "google.golang.org/appengine" + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/datastore" +) + +var ( + // ErrInvalidEntityType is returned when functions like Get or Next are + // passed a dst or src argument of invalid type. + ErrInvalidEntityType = errors.New("datastore: invalid entity type") + // ErrInvalidKey is returned when an invalid key is presented. + ErrInvalidKey = errors.New("datastore: invalid key") + // ErrNoSuchEntity is returned when no entity was found for a given key. + ErrNoSuchEntity = errors.New("datastore: no such entity") +) + +// ErrFieldMismatch is returned when a field is to be loaded into a different +// type than the one it was stored from, or when a field is missing or +// unexported in the destination struct. +// StructType is the type of the struct pointed to by the destination argument +// passed to Get or to Iterator.Next. +type ErrFieldMismatch struct { + StructType reflect.Type + FieldName string + Reason string +} + +func (e *ErrFieldMismatch) Error() string { + return fmt.Sprintf("datastore: cannot load field %q into a %q: %s", + e.FieldName, e.StructType, e.Reason) +} + +// protoToKey converts a Reference proto to a *Key. If the key is invalid, +// protoToKey will return the invalid key along with ErrInvalidKey. +func protoToKey(r *pb.Reference) (k *Key, err error) { + appID := r.GetApp() + namespace := r.GetNameSpace() + for _, e := range r.Path.Element { + k = &Key{ + kind: e.GetType(), + stringID: e.GetName(), + intID: e.GetId(), + parent: k, + appID: appID, + namespace: namespace, + } + if !k.valid() { + return k, ErrInvalidKey + } + } + return +} + +// keyToProto converts a *Key to a Reference proto. +func keyToProto(defaultAppID string, k *Key) *pb.Reference { + appID := k.appID + if appID == "" { + appID = defaultAppID + } + n := 0 + for i := k; i != nil; i = i.parent { + n++ + } + e := make([]*pb.Path_Element, n) + for i := k; i != nil; i = i.parent { + n-- + e[n] = &pb.Path_Element{ + Type: &i.kind, + } + // At most one of {Name,Id} should be set. + // Neither will be set for incomplete keys. + if i.stringID != "" { + e[n].Name = &i.stringID + } else if i.intID != 0 { + e[n].Id = &i.intID + } + } + var namespace *string + if k.namespace != "" { + namespace = proto.String(k.namespace) + } + return &pb.Reference{ + App: proto.String(appID), + NameSpace: namespace, + Path: &pb.Path{ + Element: e, + }, + } +} + +// multiKeyToProto is a batch version of keyToProto. +func multiKeyToProto(appID string, key []*Key) []*pb.Reference { + ret := make([]*pb.Reference, len(key)) + for i, k := range key { + ret[i] = keyToProto(appID, k) + } + return ret +} + +// multiValid is a batch version of Key.valid. It returns an error, not a +// []bool. +func multiValid(key []*Key) error { + invalid := false + for _, k := range key { + if !k.valid() { + invalid = true + break + } + } + if !invalid { + return nil + } + err := make(appengine.MultiError, len(key)) + for i, k := range key { + if !k.valid() { + err[i] = ErrInvalidKey + } + } + return err +} + +// It's unfortunate that the two semantically equivalent concepts pb.Reference +// and pb.PropertyValue_ReferenceValue aren't the same type. For example, the +// two have different protobuf field numbers. + +// referenceValueToKey is the same as protoToKey except the input is a +// PropertyValue_ReferenceValue instead of a Reference. +func referenceValueToKey(r *pb.PropertyValue_ReferenceValue) (k *Key, err error) { + appID := r.GetApp() + namespace := r.GetNameSpace() + for _, e := range r.Pathelement { + k = &Key{ + kind: e.GetType(), + stringID: e.GetName(), + intID: e.GetId(), + parent: k, + appID: appID, + namespace: namespace, + } + if !k.valid() { + return nil, ErrInvalidKey + } + } + return +} + +// keyToReferenceValue is the same as keyToProto except the output is a +// PropertyValue_ReferenceValue instead of a Reference. +func keyToReferenceValue(defaultAppID string, k *Key) *pb.PropertyValue_ReferenceValue { + ref := keyToProto(defaultAppID, k) + pe := make([]*pb.PropertyValue_ReferenceValue_PathElement, len(ref.Path.Element)) + for i, e := range ref.Path.Element { + pe[i] = &pb.PropertyValue_ReferenceValue_PathElement{ + Type: e.Type, + Id: e.Id, + Name: e.Name, + } + } + return &pb.PropertyValue_ReferenceValue{ + App: ref.App, + NameSpace: ref.NameSpace, + Pathelement: pe, + } +} + +type multiArgType int + +const ( + multiArgTypeInvalid multiArgType = iota + multiArgTypePropertyLoadSaver + multiArgTypeStruct + multiArgTypeStructPtr + multiArgTypeInterface +) + +// checkMultiArg checks that v has type []S, []*S, []I, or []P, for some struct +// type S, for some interface type I, or some non-interface non-pointer type P +// such that P or *P implements PropertyLoadSaver. +// +// It returns what category the slice's elements are, and the reflect.Type +// that represents S, I or P. +// +// As a special case, PropertyList is an invalid type for v. +func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) { + if v.Kind() != reflect.Slice { + return multiArgTypeInvalid, nil + } + if v.Type() == typeOfPropertyList { + return multiArgTypeInvalid, nil + } + elemType = v.Type().Elem() + if reflect.PtrTo(elemType).Implements(typeOfPropertyLoadSaver) { + return multiArgTypePropertyLoadSaver, elemType + } + switch elemType.Kind() { + case reflect.Struct: + return multiArgTypeStruct, elemType + case reflect.Interface: + return multiArgTypeInterface, elemType + case reflect.Ptr: + elemType = elemType.Elem() + if elemType.Kind() == reflect.Struct { + return multiArgTypeStructPtr, elemType + } + } + return multiArgTypeInvalid, nil +} + +// Get loads the entity stored for k into dst, which must be a struct pointer +// or implement PropertyLoadSaver. If there is no such entity for the key, Get +// returns ErrNoSuchEntity. +// +// The values of dst's unmatched struct fields are not modified, and matching +// slice-typed fields are not reset before appending to them. In particular, it +// is recommended to pass a pointer to a zero valued struct on each Get call. +// +// ErrFieldMismatch is returned when a field is to be loaded into a different +// type than the one it was stored from, or when a field is missing or +// unexported in the destination struct. ErrFieldMismatch is only returned if +// dst is a struct pointer. +func Get(c context.Context, key *Key, dst interface{}) error { + if dst == nil { // GetMulti catches nil interface; we need to catch nil ptr here + return ErrInvalidEntityType + } + err := GetMulti(c, []*Key{key}, []interface{}{dst}) + if me, ok := err.(appengine.MultiError); ok { + return me[0] + } + return err +} + +// GetMulti is a batch version of Get. +// +// dst must be a []S, []*S, []I or []P, for some struct type S, some interface +// type I, or some non-interface non-pointer type P such that P or *P +// implements PropertyLoadSaver. If an []I, each element must be a valid dst +// for Get: it must be a struct pointer or implement PropertyLoadSaver. +// +// As a special case, PropertyList is an invalid type for dst, even though a +// PropertyList is a slice of structs. It is treated as invalid to avoid being +// mistakenly passed when []PropertyList was intended. +func GetMulti(c context.Context, key []*Key, dst interface{}) error { + v := reflect.ValueOf(dst) + multiArgType, _ := checkMultiArg(v) + if multiArgType == multiArgTypeInvalid { + return errors.New("datastore: dst has invalid type") + } + if len(key) != v.Len() { + return errors.New("datastore: key and dst slices have different length") + } + if len(key) == 0 { + return nil + } + if err := multiValid(key); err != nil { + return err + } + req := &pb.GetRequest{ + Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key), + } + res := &pb.GetResponse{} + if err := internal.Call(c, "datastore_v3", "Get", req, res); err != nil { + return err + } + if len(key) != len(res.Entity) { + return errors.New("datastore: internal error: server returned the wrong number of entities") + } + multiErr, any := make(appengine.MultiError, len(key)), false + for i, e := range res.Entity { + if e.Entity == nil { + multiErr[i] = ErrNoSuchEntity + } else { + elem := v.Index(i) + if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct { + elem = elem.Addr() + } + if multiArgType == multiArgTypeStructPtr && elem.IsNil() { + elem.Set(reflect.New(elem.Type().Elem())) + } + multiErr[i] = loadEntity(elem.Interface(), e.Entity) + } + if multiErr[i] != nil { + any = true + } + } + if any { + return multiErr + } + return nil +} + +// Put saves the entity src into the datastore with key k. src must be a struct +// pointer or implement PropertyLoadSaver; if a struct pointer then any +// unexported fields of that struct will be skipped. If k is an incomplete key, +// the returned key will be a unique key generated by the datastore. +func Put(c context.Context, key *Key, src interface{}) (*Key, error) { + k, err := PutMulti(c, []*Key{key}, []interface{}{src}) + if err != nil { + if me, ok := err.(appengine.MultiError); ok { + return nil, me[0] + } + return nil, err + } + return k[0], nil +} + +// PutMulti is a batch version of Put. +// +// src must satisfy the same conditions as the dst argument to GetMulti. +func PutMulti(c context.Context, key []*Key, src interface{}) ([]*Key, error) { + v := reflect.ValueOf(src) + multiArgType, _ := checkMultiArg(v) + if multiArgType == multiArgTypeInvalid { + return nil, errors.New("datastore: src has invalid type") + } + if len(key) != v.Len() { + return nil, errors.New("datastore: key and src slices have different length") + } + if len(key) == 0 { + return nil, nil + } + appID := internal.FullyQualifiedAppID(c) + if err := multiValid(key); err != nil { + return nil, err + } + req := &pb.PutRequest{} + for i := range key { + elem := v.Index(i) + if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct { + elem = elem.Addr() + } + sProto, err := saveEntity(appID, key[i], elem.Interface()) + if err != nil { + return nil, err + } + req.Entity = append(req.Entity, sProto) + } + res := &pb.PutResponse{} + if err := internal.Call(c, "datastore_v3", "Put", req, res); err != nil { + return nil, err + } + if len(key) != len(res.Key) { + return nil, errors.New("datastore: internal error: server returned the wrong number of keys") + } + ret := make([]*Key, len(key)) + for i := range ret { + var err error + ret[i], err = protoToKey(res.Key[i]) + if err != nil || ret[i].Incomplete() { + return nil, errors.New("datastore: internal error: server returned an invalid key") + } + } + return ret, nil +} + +// Delete deletes the entity for the given key. +func Delete(c context.Context, key *Key) error { + err := DeleteMulti(c, []*Key{key}) + if me, ok := err.(appengine.MultiError); ok { + return me[0] + } + return err +} + +// DeleteMulti is a batch version of Delete. +func DeleteMulti(c context.Context, key []*Key) error { + if len(key) == 0 { + return nil + } + if err := multiValid(key); err != nil { + return err + } + req := &pb.DeleteRequest{ + Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key), + } + res := &pb.DeleteResponse{} + return internal.Call(c, "datastore_v3", "Delete", req, res) +} + +func namespaceMod(m proto.Message, namespace string) { + // pb.Query is the only type that has a name_space field. + // All other namespace support in datastore is in the keys. + switch m := m.(type) { + case *pb.Query: + if m.NameSpace == nil { + m.NameSpace = &namespace + } + } +} + +func init() { + internal.NamespaceMods["datastore_v3"] = namespaceMod + internal.RegisterErrorCodeMap("datastore_v3", pb.Error_ErrorCode_name) + internal.RegisterTimeoutErrorCode("datastore_v3", int32(pb.Error_TIMEOUT)) +} diff --git a/vendor/google.golang.org/appengine/datastore/doc.go b/vendor/google.golang.org/appengine/datastore/doc.go new file mode 100644 index 000000000000..85616cf27410 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/doc.go @@ -0,0 +1,361 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +/* +Package datastore provides a client for App Engine's datastore service. + + +Basic Operations + +Entities are the unit of storage and are associated with a key. A key +consists of an optional parent key, a string application ID, a string kind +(also known as an entity type), and either a StringID or an IntID. A +StringID is also known as an entity name or key name. + +It is valid to create a key with a zero StringID and a zero IntID; this is +called an incomplete key, and does not refer to any saved entity. Putting an +entity into the datastore under an incomplete key will cause a unique key +to be generated for that entity, with a non-zero IntID. + +An entity's contents are a mapping from case-sensitive field names to values. +Valid value types are: + - signed integers (int, int8, int16, int32 and int64), + - bool, + - string, + - float32 and float64, + - []byte (up to 1 megabyte in length), + - any type whose underlying type is one of the above predeclared types, + - ByteString, + - *Key, + - time.Time (stored with microsecond precision), + - appengine.BlobKey, + - appengine.GeoPoint, + - structs whose fields are all valid value types, + - slices of any of the above. + +Slices of structs are valid, as are structs that contain slices. However, if +one struct contains another, then at most one of those can be repeated. This +disqualifies recursively defined struct types: any struct T that (directly or +indirectly) contains a []T. + +The Get and Put functions load and save an entity's contents. An entity's +contents are typically represented by a struct pointer. + +Example code: + + type Entity struct { + Value string + } + + func handle(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + + k := datastore.NewKey(ctx, "Entity", "stringID", 0, nil) + e := new(Entity) + if err := datastore.Get(ctx, k, e); err != nil { + http.Error(w, err.Error(), 500) + return + } + + old := e.Value + e.Value = r.URL.Path + + if _, err := datastore.Put(ctx, k, e); err != nil { + http.Error(w, err.Error(), 500) + return + } + + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + fmt.Fprintf(w, "old=%q\nnew=%q\n", old, e.Value) + } + +GetMulti, PutMulti and DeleteMulti are batch versions of the Get, Put and +Delete functions. They take a []*Key instead of a *Key, and may return an +appengine.MultiError when encountering partial failure. + + +Properties + +An entity's contents can be represented by a variety of types. These are +typically struct pointers, but can also be any type that implements the +PropertyLoadSaver interface. If using a struct pointer, you do not have to +explicitly implement the PropertyLoadSaver interface; the datastore will +automatically convert via reflection. If a struct pointer does implement that +interface then those methods will be used in preference to the default +behavior for struct pointers. Struct pointers are more strongly typed and are +easier to use; PropertyLoadSavers are more flexible. + +The actual types passed do not have to match between Get and Put calls or even +across different calls to datastore. It is valid to put a *PropertyList and +get that same entity as a *myStruct, or put a *myStruct0 and get a *myStruct1. +Conceptually, any entity is saved as a sequence of properties, and is loaded +into the destination value on a property-by-property basis. When loading into +a struct pointer, an entity that cannot be completely represented (such as a +missing field) will result in an ErrFieldMismatch error but it is up to the +caller whether this error is fatal, recoverable or ignorable. + +By default, for struct pointers, all properties are potentially indexed, and +the property name is the same as the field name (and hence must start with an +upper case letter). + +Fields may have a `datastore:"name,options"` tag. The tag name is the +property name, which must be one or more valid Go identifiers joined by ".", +but may start with a lower case letter. An empty tag name means to just use the +field name. A "-" tag name means that the datastore will ignore that field. + +The only valid options are "omitempty" and "noindex". + +If the options include "omitempty" and the value of the field is empty, then the field will be omitted on Save. +The empty values are false, 0, any nil interface value, and any array, slice, map, or string of length zero. +Struct field values will never be empty. + +If options include "noindex" then the field will not be indexed. All fields are indexed +by default. Strings or byte slices longer than 1500 bytes cannot be indexed; +fields used to store long strings and byte slices must be tagged with "noindex" +or they will cause Put operations to fail. + +To use multiple options together, separate them by a comma. +The order does not matter. + +If the options is "" then the comma may be omitted. + +Example code: + + // A and B are renamed to a and b. + // A, C and J are not indexed. + // D's tag is equivalent to having no tag at all (E). + // I is ignored entirely by the datastore. + // J has tag information for both the datastore and json packages. + type TaggedStruct struct { + A int `datastore:"a,noindex"` + B int `datastore:"b"` + C int `datastore:",noindex"` + D int `datastore:""` + E int + I int `datastore:"-"` + J int `datastore:",noindex" json:"j"` + } + + +Structured Properties + +If the struct pointed to contains other structs, then the nested or embedded +structs are flattened. For example, given these definitions: + + type Inner1 struct { + W int32 + X string + } + + type Inner2 struct { + Y float64 + } + + type Inner3 struct { + Z bool + } + + type Outer struct { + A int16 + I []Inner1 + J Inner2 + Inner3 + } + +then an Outer's properties would be equivalent to those of: + + type OuterEquivalent struct { + A int16 + IDotW []int32 `datastore:"I.W"` + IDotX []string `datastore:"I.X"` + JDotY float64 `datastore:"J.Y"` + Z bool + } + +If Outer's embedded Inner3 field was tagged as `datastore:"Foo"` then the +equivalent field would instead be: FooDotZ bool `datastore:"Foo.Z"`. + +If an outer struct is tagged "noindex" then all of its implicit flattened +fields are effectively "noindex". + + +The PropertyLoadSaver Interface + +An entity's contents can also be represented by any type that implements the +PropertyLoadSaver interface. This type may be a struct pointer, but it does +not have to be. The datastore package will call Load when getting the entity's +contents, and Save when putting the entity's contents. +Possible uses include deriving non-stored fields, verifying fields, or indexing +a field only if its value is positive. + +Example code: + + type CustomPropsExample struct { + I, J int + // Sum is not stored, but should always be equal to I + J. + Sum int `datastore:"-"` + } + + func (x *CustomPropsExample) Load(ps []datastore.Property) error { + // Load I and J as usual. + if err := datastore.LoadStruct(x, ps); err != nil { + return err + } + // Derive the Sum field. + x.Sum = x.I + x.J + return nil + } + + func (x *CustomPropsExample) Save() ([]datastore.Property, error) { + // Validate the Sum field. + if x.Sum != x.I + x.J { + return nil, errors.New("CustomPropsExample has inconsistent sum") + } + // Save I and J as usual. The code below is equivalent to calling + // "return datastore.SaveStruct(x)", but is done manually for + // demonstration purposes. + return []datastore.Property{ + { + Name: "I", + Value: int64(x.I), + }, + { + Name: "J", + Value: int64(x.J), + }, + }, nil + } + +The *PropertyList type implements PropertyLoadSaver, and can therefore hold an +arbitrary entity's contents. + + +Queries + +Queries retrieve entities based on their properties or key's ancestry. Running +a query yields an iterator of results: either keys or (key, entity) pairs. +Queries are re-usable and it is safe to call Query.Run from concurrent +goroutines. Iterators are not safe for concurrent use. + +Queries are immutable, and are either created by calling NewQuery, or derived +from an existing query by calling a method like Filter or Order that returns a +new query value. A query is typically constructed by calling NewQuery followed +by a chain of zero or more such methods. These methods are: + - Ancestor and Filter constrain the entities returned by running a query. + - Order affects the order in which they are returned. + - Project constrains the fields returned. + - Distinct de-duplicates projected entities. + - KeysOnly makes the iterator return only keys, not (key, entity) pairs. + - Start, End, Offset and Limit define which sub-sequence of matching entities + to return. Start and End take cursors, Offset and Limit take integers. Start + and Offset affect the first result, End and Limit affect the last result. + If both Start and Offset are set, then the offset is relative to Start. + If both End and Limit are set, then the earliest constraint wins. Limit is + relative to Start+Offset, not relative to End. As a special case, a + negative limit means unlimited. + +Example code: + + type Widget struct { + Description string + Price int + } + + func handle(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + q := datastore.NewQuery("Widget"). + Filter("Price <", 1000). + Order("-Price") + b := new(bytes.Buffer) + for t := q.Run(ctx); ; { + var x Widget + key, err := t.Next(&x) + if err == datastore.Done { + break + } + if err != nil { + serveError(ctx, w, err) + return + } + fmt.Fprintf(b, "Key=%v\nWidget=%#v\n\n", key, x) + } + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + io.Copy(w, b) + } + + +Transactions + +RunInTransaction runs a function in a transaction. + +Example code: + + type Counter struct { + Count int + } + + func inc(ctx context.Context, key *datastore.Key) (int, error) { + var x Counter + if err := datastore.Get(ctx, key, &x); err != nil && err != datastore.ErrNoSuchEntity { + return 0, err + } + x.Count++ + if _, err := datastore.Put(ctx, key, &x); err != nil { + return 0, err + } + return x.Count, nil + } + + func handle(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + var count int + err := datastore.RunInTransaction(ctx, func(ctx context.Context) error { + var err1 error + count, err1 = inc(ctx, datastore.NewKey(ctx, "Counter", "singleton", 0, nil)) + return err1 + }, nil) + if err != nil { + serveError(ctx, w, err) + return + } + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + fmt.Fprintf(w, "Count=%d", count) + } + + +Metadata + +The datastore package provides access to some of App Engine's datastore +metadata. This metadata includes information about the entity groups, +namespaces, entity kinds, and properties in the datastore, as well as the +property representations for each property. + +Example code: + + func handle(w http.ResponseWriter, r *http.Request) { + // Print all the kinds in the datastore, with all the indexed + // properties (and their representations) for each. + ctx := appengine.NewContext(r) + + kinds, err := datastore.Kinds(ctx) + if err != nil { + serveError(ctx, w, err) + return + } + + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + for _, kind := range kinds { + fmt.Fprintf(w, "%s:\n", kind) + props, err := datastore.KindProperties(ctx, kind) + if err != nil { + fmt.Fprintln(w, "\t(unable to retrieve properties)") + continue + } + for p, rep := range props { + fmt.Fprintf(w, "\t-%s (%s)\n", p, strings.Join(rep, ", ")) + } + } + } +*/ +package datastore // import "google.golang.org/appengine/datastore" diff --git a/vendor/google.golang.org/appengine/datastore/key.go b/vendor/google.golang.org/appengine/datastore/key.go new file mode 100644 index 000000000000..6ab83eaf657a --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/key.go @@ -0,0 +1,396 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "bytes" + "encoding/base64" + "encoding/gob" + "errors" + "fmt" + "strconv" + "strings" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/datastore" +) + +type KeyRangeCollisionError struct { + start int64 + end int64 +} + +func (e *KeyRangeCollisionError) Error() string { + return fmt.Sprintf("datastore: Collision when attempting to allocate range [%d, %d]", + e.start, e.end) +} + +type KeyRangeContentionError struct { + start int64 + end int64 +} + +func (e *KeyRangeContentionError) Error() string { + return fmt.Sprintf("datastore: Contention when attempting to allocate range [%d, %d]", + e.start, e.end) +} + +// Key represents the datastore key for a stored entity, and is immutable. +type Key struct { + kind string + stringID string + intID int64 + parent *Key + appID string + namespace string +} + +// Kind returns the key's kind (also known as entity type). +func (k *Key) Kind() string { + return k.kind +} + +// StringID returns the key's string ID (also known as an entity name or key +// name), which may be "". +func (k *Key) StringID() string { + return k.stringID +} + +// IntID returns the key's integer ID, which may be 0. +func (k *Key) IntID() int64 { + return k.intID +} + +// Parent returns the key's parent key, which may be nil. +func (k *Key) Parent() *Key { + return k.parent +} + +// AppID returns the key's application ID. +func (k *Key) AppID() string { + return k.appID +} + +// Namespace returns the key's namespace. +func (k *Key) Namespace() string { + return k.namespace +} + +// Incomplete returns whether the key does not refer to a stored entity. +// In particular, whether the key has a zero StringID and a zero IntID. +func (k *Key) Incomplete() bool { + return k.stringID == "" && k.intID == 0 +} + +// valid returns whether the key is valid. +func (k *Key) valid() bool { + if k == nil { + return false + } + for ; k != nil; k = k.parent { + if k.kind == "" || k.appID == "" { + return false + } + if k.stringID != "" && k.intID != 0 { + return false + } + if k.parent != nil { + if k.parent.Incomplete() { + return false + } + if k.parent.appID != k.appID || k.parent.namespace != k.namespace { + return false + } + } + } + return true +} + +// Equal returns whether two keys are equal. +func (k *Key) Equal(o *Key) bool { + for k != nil && o != nil { + if k.kind != o.kind || k.stringID != o.stringID || k.intID != o.intID || k.appID != o.appID || k.namespace != o.namespace { + return false + } + k, o = k.parent, o.parent + } + return k == o +} + +// root returns the furthest ancestor of a key, which may be itself. +func (k *Key) root() *Key { + for k.parent != nil { + k = k.parent + } + return k +} + +// marshal marshals the key's string representation to the buffer. +func (k *Key) marshal(b *bytes.Buffer) { + if k.parent != nil { + k.parent.marshal(b) + } + b.WriteByte('/') + b.WriteString(k.kind) + b.WriteByte(',') + if k.stringID != "" { + b.WriteString(k.stringID) + } else { + b.WriteString(strconv.FormatInt(k.intID, 10)) + } +} + +// String returns a string representation of the key. +func (k *Key) String() string { + if k == nil { + return "" + } + b := bytes.NewBuffer(make([]byte, 0, 512)) + k.marshal(b) + return b.String() +} + +type gobKey struct { + Kind string + StringID string + IntID int64 + Parent *gobKey + AppID string + Namespace string +} + +func keyToGobKey(k *Key) *gobKey { + if k == nil { + return nil + } + return &gobKey{ + Kind: k.kind, + StringID: k.stringID, + IntID: k.intID, + Parent: keyToGobKey(k.parent), + AppID: k.appID, + Namespace: k.namespace, + } +} + +func gobKeyToKey(gk *gobKey) *Key { + if gk == nil { + return nil + } + return &Key{ + kind: gk.Kind, + stringID: gk.StringID, + intID: gk.IntID, + parent: gobKeyToKey(gk.Parent), + appID: gk.AppID, + namespace: gk.Namespace, + } +} + +func (k *Key) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + if err := gob.NewEncoder(buf).Encode(keyToGobKey(k)); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (k *Key) GobDecode(buf []byte) error { + gk := new(gobKey) + if err := gob.NewDecoder(bytes.NewBuffer(buf)).Decode(gk); err != nil { + return err + } + *k = *gobKeyToKey(gk) + return nil +} + +func (k *Key) MarshalJSON() ([]byte, error) { + return []byte(`"` + k.Encode() + `"`), nil +} + +func (k *Key) UnmarshalJSON(buf []byte) error { + if len(buf) < 2 || buf[0] != '"' || buf[len(buf)-1] != '"' { + return errors.New("datastore: bad JSON key") + } + k2, err := DecodeKey(string(buf[1 : len(buf)-1])) + if err != nil { + return err + } + *k = *k2 + return nil +} + +// Encode returns an opaque representation of the key +// suitable for use in HTML and URLs. +// This is compatible with the Python and Java runtimes. +func (k *Key) Encode() string { + ref := keyToProto("", k) + + b, err := proto.Marshal(ref) + if err != nil { + panic(err) + } + + // Trailing padding is stripped. + return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") +} + +// DecodeKey decodes a key from the opaque representation returned by Encode. +func DecodeKey(encoded string) (*Key, error) { + // Re-add padding. + if m := len(encoded) % 4; m != 0 { + encoded += strings.Repeat("=", 4-m) + } + + b, err := base64.URLEncoding.DecodeString(encoded) + if err != nil { + return nil, err + } + + ref := new(pb.Reference) + if err := proto.Unmarshal(b, ref); err != nil { + return nil, err + } + + return protoToKey(ref) +} + +// NewIncompleteKey creates a new incomplete key. +// kind cannot be empty. +func NewIncompleteKey(c context.Context, kind string, parent *Key) *Key { + return NewKey(c, kind, "", 0, parent) +} + +// NewKey creates a new key. +// kind cannot be empty. +// Either one or both of stringID and intID must be zero. If both are zero, +// the key returned is incomplete. +// parent must either be a complete key or nil. +func NewKey(c context.Context, kind, stringID string, intID int64, parent *Key) *Key { + // If there's a parent key, use its namespace. + // Otherwise, use any namespace attached to the context. + var namespace string + if parent != nil { + namespace = parent.namespace + } else { + namespace = internal.NamespaceFromContext(c) + } + + return &Key{ + kind: kind, + stringID: stringID, + intID: intID, + parent: parent, + appID: internal.FullyQualifiedAppID(c), + namespace: namespace, + } +} + +// AllocateIDs returns a range of n integer IDs with the given kind and parent +// combination. kind cannot be empty; parent may be nil. The IDs in the range +// returned will not be used by the datastore's automatic ID sequence generator +// and may be used with NewKey without conflict. +// +// The range is inclusive at the low end and exclusive at the high end. In +// other words, valid intIDs x satisfy low <= x && x < high. +// +// If no error is returned, low + n == high. +func AllocateIDs(c context.Context, kind string, parent *Key, n int) (low, high int64, err error) { + if kind == "" { + return 0, 0, errors.New("datastore: AllocateIDs given an empty kind") + } + if n < 0 { + return 0, 0, fmt.Errorf("datastore: AllocateIDs given a negative count: %d", n) + } + if n == 0 { + return 0, 0, nil + } + req := &pb.AllocateIdsRequest{ + ModelKey: keyToProto("", NewIncompleteKey(c, kind, parent)), + Size: proto.Int64(int64(n)), + } + res := &pb.AllocateIdsResponse{} + if err := internal.Call(c, "datastore_v3", "AllocateIds", req, res); err != nil { + return 0, 0, err + } + // The protobuf is inclusive at both ends. Idiomatic Go (e.g. slices, for loops) + // is inclusive at the low end and exclusive at the high end, so we add 1. + low = res.GetStart() + high = res.GetEnd() + 1 + if low+int64(n) != high { + return 0, 0, fmt.Errorf("datastore: internal error: could not allocate %d IDs", n) + } + return low, high, nil +} + +// AllocateIDRange allocates a range of IDs with specific endpoints. +// The range is inclusive at both the low and high end. Once these IDs have been +// allocated, you can manually assign them to newly created entities. +// +// The Datastore's automatic ID allocator never assigns a key that has already +// been allocated (either through automatic ID allocation or through an explicit +// AllocateIDs call). As a result, entities written to the given key range will +// never be overwritten. However, writing entities with manually assigned keys in +// this range may overwrite existing entities (or new entities written by a separate +// request), depending on the error returned. +// +// Use this only if you have an existing numeric ID range that you want to reserve +// (for example, bulk loading entities that already have IDs). If you don't care +// about which IDs you receive, use AllocateIDs instead. +// +// AllocateIDRange returns nil if the range is successfully allocated. If one or more +// entities with an ID in the given range already exist, it returns a KeyRangeCollisionError. +// If the Datastore has already cached IDs in this range (e.g. from a previous call to +// AllocateIDRange), it returns a KeyRangeContentionError. Errors of other types indicate +// problems with arguments or an error returned directly from the Datastore. +func AllocateIDRange(c context.Context, kind string, parent *Key, start, end int64) (err error) { + if kind == "" { + return errors.New("datastore: AllocateIDRange given an empty kind") + } + + if start < 1 || end < 1 { + return errors.New("datastore: AllocateIDRange start and end must both be greater than 0") + } + + if start > end { + return errors.New("datastore: AllocateIDRange start must be before end") + } + + req := &pb.AllocateIdsRequest{ + ModelKey: keyToProto("", NewIncompleteKey(c, kind, parent)), + Max: proto.Int64(end), + } + res := &pb.AllocateIdsResponse{} + if err := internal.Call(c, "datastore_v3", "AllocateIds", req, res); err != nil { + return err + } + + // Check for collisions, i.e. existing entities with IDs in this range. + // We could do this before the allocation, but we'd still have to do it + // afterward as well to catch the race condition where an entity is inserted + // after that initial check but before the allocation. Skip the up-front check + // and just do it once. + q := NewQuery(kind).Filter("__key__ >=", NewKey(c, kind, "", start, parent)). + Filter("__key__ <=", NewKey(c, kind, "", end, parent)).KeysOnly().Limit(1) + + keys, err := q.GetAll(c, nil) + if err != nil { + return err + } + if len(keys) != 0 { + return &KeyRangeCollisionError{start: start, end: end} + } + + // Check for a race condition, i.e. cases where the datastore may have + // cached ID batches that contain IDs in this range. + if start < res.GetStart() { + return &KeyRangeContentionError{start: start, end: end} + } + + return nil +} diff --git a/vendor/google.golang.org/appengine/datastore/load.go b/vendor/google.golang.org/appengine/datastore/load.go new file mode 100644 index 000000000000..38a63653979a --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/load.go @@ -0,0 +1,429 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "fmt" + "reflect" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "google.golang.org/appengine" + pb "google.golang.org/appengine/internal/datastore" +) + +var ( + typeOfBlobKey = reflect.TypeOf(appengine.BlobKey("")) + typeOfByteSlice = reflect.TypeOf([]byte(nil)) + typeOfByteString = reflect.TypeOf(ByteString(nil)) + typeOfGeoPoint = reflect.TypeOf(appengine.GeoPoint{}) + typeOfTime = reflect.TypeOf(time.Time{}) + typeOfKeyPtr = reflect.TypeOf(&Key{}) + typeOfEntityPtr = reflect.TypeOf(&Entity{}) +) + +// typeMismatchReason returns a string explaining why the property p could not +// be stored in an entity field of type v.Type(). +func typeMismatchReason(pValue interface{}, v reflect.Value) string { + entityType := "empty" + switch pValue.(type) { + case int64: + entityType = "int" + case bool: + entityType = "bool" + case string: + entityType = "string" + case float64: + entityType = "float" + case *Key: + entityType = "*datastore.Key" + case time.Time: + entityType = "time.Time" + case appengine.BlobKey: + entityType = "appengine.BlobKey" + case appengine.GeoPoint: + entityType = "appengine.GeoPoint" + case ByteString: + entityType = "datastore.ByteString" + case []byte: + entityType = "[]byte" + } + return fmt.Sprintf("type mismatch: %s versus %v", entityType, v.Type()) +} + +type propertyLoader struct { + // m holds the number of times a substruct field like "Foo.Bar.Baz" has + // been seen so far. The map is constructed lazily. + m map[string]int +} + +func (l *propertyLoader) load(codec *structCodec, structValue reflect.Value, p Property, requireSlice bool) string { + var v reflect.Value + var sliceIndex int + + name := p.Name + + // If name ends with a '.', the last field is anonymous. + // In this case, strings.Split will give us "" as the + // last element of our fields slice, which will match the "" + // field name in the substruct codec. + fields := strings.Split(name, ".") + + for len(fields) > 0 { + var decoder fieldCodec + var ok bool + + // Cut off the last field (delimited by ".") and find its parent + // in the codec. + // eg. for name "A.B.C.D", split off "A.B.C" and try to + // find a field in the codec with this name. + // Loop again with "A.B", etc. + for i := len(fields); i > 0; i-- { + parent := strings.Join(fields[:i], ".") + decoder, ok = codec.fields[parent] + if ok { + fields = fields[i:] + break + } + } + + // If we never found a matching field in the codec, return + // error message. + if !ok { + return "no such struct field" + } + + v = initField(structValue, decoder.path) + if !v.IsValid() { + return "no such struct field" + } + if !v.CanSet() { + return "cannot set struct field" + } + + if decoder.structCodec != nil { + codec = decoder.structCodec + structValue = v + } + + if v.Kind() == reflect.Slice && v.Type() != typeOfByteSlice { + if l.m == nil { + l.m = make(map[string]int) + } + sliceIndex = l.m[p.Name] + l.m[p.Name] = sliceIndex + 1 + for v.Len() <= sliceIndex { + v.Set(reflect.Append(v, reflect.New(v.Type().Elem()).Elem())) + } + structValue = v.Index(sliceIndex) + requireSlice = false + } + } + + var slice reflect.Value + if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { + slice = v + v = reflect.New(v.Type().Elem()).Elem() + } else if requireSlice { + return "multiple-valued property requires a slice field type" + } + + // Convert indexValues to a Go value with a meaning derived from the + // destination type. + pValue := p.Value + if iv, ok := pValue.(indexValue); ok { + meaning := pb.Property_NO_MEANING + switch v.Type() { + case typeOfBlobKey: + meaning = pb.Property_BLOBKEY + case typeOfByteSlice: + meaning = pb.Property_BLOB + case typeOfByteString: + meaning = pb.Property_BYTESTRING + case typeOfGeoPoint: + meaning = pb.Property_GEORSS_POINT + case typeOfTime: + meaning = pb.Property_GD_WHEN + case typeOfEntityPtr: + meaning = pb.Property_ENTITY_PROTO + } + var err error + pValue, err = propValue(iv.value, meaning) + if err != nil { + return err.Error() + } + } + + if errReason := setVal(v, pValue); errReason != "" { + // Set the slice back to its zero value. + if slice.IsValid() { + slice.Set(reflect.Zero(slice.Type())) + } + return errReason + } + + if slice.IsValid() { + slice.Index(sliceIndex).Set(v) + } + + return "" +} + +// setVal sets v to the value pValue. +func setVal(v reflect.Value, pValue interface{}) string { + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + x, ok := pValue.(int64) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + if v.OverflowInt(x) { + return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type()) + } + v.SetInt(x) + case reflect.Bool: + x, ok := pValue.(bool) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + v.SetBool(x) + case reflect.String: + switch x := pValue.(type) { + case appengine.BlobKey: + v.SetString(string(x)) + case ByteString: + v.SetString(string(x)) + case string: + v.SetString(x) + default: + if pValue != nil { + return typeMismatchReason(pValue, v) + } + } + case reflect.Float32, reflect.Float64: + x, ok := pValue.(float64) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + if v.OverflowFloat(x) { + return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type()) + } + v.SetFloat(x) + case reflect.Ptr: + x, ok := pValue.(*Key) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + if _, ok := v.Interface().(*Key); !ok { + return typeMismatchReason(pValue, v) + } + v.Set(reflect.ValueOf(x)) + case reflect.Struct: + switch v.Type() { + case typeOfTime: + x, ok := pValue.(time.Time) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + v.Set(reflect.ValueOf(x)) + case typeOfGeoPoint: + x, ok := pValue.(appengine.GeoPoint) + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + v.Set(reflect.ValueOf(x)) + default: + ent, ok := pValue.(*Entity) + if !ok { + return typeMismatchReason(pValue, v) + } + + // Recursively load nested struct + pls, err := newStructPLS(v.Addr().Interface()) + if err != nil { + return err.Error() + } + + // if ent has a Key value and our struct has a Key field, + // load the Entity's Key value into the Key field on the struct. + if ent.Key != nil && pls.codec.keyField != -1 { + + pls.v.Field(pls.codec.keyField).Set(reflect.ValueOf(ent.Key)) + } + + err = pls.Load(ent.Properties) + if err != nil { + return err.Error() + } + } + case reflect.Slice: + x, ok := pValue.([]byte) + if !ok { + if y, yok := pValue.(ByteString); yok { + x, ok = []byte(y), true + } + } + if !ok && pValue != nil { + return typeMismatchReason(pValue, v) + } + if v.Type().Elem().Kind() != reflect.Uint8 { + return typeMismatchReason(pValue, v) + } + v.SetBytes(x) + default: + return typeMismatchReason(pValue, v) + } + return "" +} + +// initField is similar to reflect's Value.FieldByIndex, in that it +// returns the nested struct field corresponding to index, but it +// initialises any nil pointers encountered when traversing the structure. +func initField(val reflect.Value, index []int) reflect.Value { + for _, i := range index[:len(index)-1] { + val = val.Field(i) + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + } + return val.Field(index[len(index)-1]) +} + +// loadEntity loads an EntityProto into PropertyLoadSaver or struct pointer. +func loadEntity(dst interface{}, src *pb.EntityProto) (err error) { + ent, err := protoToEntity(src) + if err != nil { + return err + } + if e, ok := dst.(PropertyLoadSaver); ok { + return e.Load(ent.Properties) + } + return LoadStruct(dst, ent.Properties) +} + +func (s structPLS) Load(props []Property) error { + var fieldName, reason string + var l propertyLoader + for _, p := range props { + if errStr := l.load(s.codec, s.v, p, p.Multiple); errStr != "" { + // We don't return early, as we try to load as many properties as possible. + // It is valid to load an entity into a struct that cannot fully represent it. + // That case returns an error, but the caller is free to ignore it. + fieldName, reason = p.Name, errStr + } + } + if reason != "" { + return &ErrFieldMismatch{ + StructType: s.v.Type(), + FieldName: fieldName, + Reason: reason, + } + } + return nil +} + +func protoToEntity(src *pb.EntityProto) (*Entity, error) { + props, rawProps := src.Property, src.RawProperty + outProps := make([]Property, 0, len(props)+len(rawProps)) + for { + var ( + x *pb.Property + noIndex bool + ) + if len(props) > 0 { + x, props = props[0], props[1:] + } else if len(rawProps) > 0 { + x, rawProps = rawProps[0], rawProps[1:] + noIndex = true + } else { + break + } + + var value interface{} + if x.Meaning != nil && *x.Meaning == pb.Property_INDEX_VALUE { + value = indexValue{x.Value} + } else { + var err error + value, err = propValue(x.Value, x.GetMeaning()) + if err != nil { + return nil, err + } + } + outProps = append(outProps, Property{ + Name: x.GetName(), + Value: value, + NoIndex: noIndex, + Multiple: x.GetMultiple(), + }) + } + + var key *Key + if src.Key != nil { + // Ignore any error, since nested entity values + // are allowed to have an invalid key. + key, _ = protoToKey(src.Key) + } + return &Entity{key, outProps}, nil +} + +// propValue returns a Go value that combines the raw PropertyValue with a +// meaning. For example, an Int64Value with GD_WHEN becomes a time.Time. +func propValue(v *pb.PropertyValue, m pb.Property_Meaning) (interface{}, error) { + switch { + case v.Int64Value != nil: + if m == pb.Property_GD_WHEN { + return fromUnixMicro(*v.Int64Value), nil + } else { + return *v.Int64Value, nil + } + case v.BooleanValue != nil: + return *v.BooleanValue, nil + case v.StringValue != nil: + if m == pb.Property_BLOB { + return []byte(*v.StringValue), nil + } else if m == pb.Property_BLOBKEY { + return appengine.BlobKey(*v.StringValue), nil + } else if m == pb.Property_BYTESTRING { + return ByteString(*v.StringValue), nil + } else if m == pb.Property_ENTITY_PROTO { + var ent pb.EntityProto + err := proto.Unmarshal([]byte(*v.StringValue), &ent) + if err != nil { + return nil, err + } + return protoToEntity(&ent) + } else { + return *v.StringValue, nil + } + case v.DoubleValue != nil: + return *v.DoubleValue, nil + case v.Referencevalue != nil: + key, err := referenceValueToKey(v.Referencevalue) + if err != nil { + return nil, err + } + return key, nil + case v.Pointvalue != nil: + // NOTE: Strangely, latitude maps to X, longitude to Y. + return appengine.GeoPoint{Lat: v.Pointvalue.GetX(), Lng: v.Pointvalue.GetY()}, nil + } + return nil, nil +} + +// indexValue is a Property value that is created when entities are loaded from +// an index, such as from a projection query. +// +// Such Property values do not contain all of the metadata required to be +// faithfully represented as a Go value, and are instead represented as an +// opaque indexValue. Load the properties into a concrete struct type (e.g. by +// passing a struct pointer to Iterator.Next) to reconstruct actual Go values +// of type int, string, time.Time, etc. +type indexValue struct { + value *pb.PropertyValue +} diff --git a/vendor/google.golang.org/appengine/datastore/metadata.go b/vendor/google.golang.org/appengine/datastore/metadata.go new file mode 100644 index 000000000000..6acacc3db9aa --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/metadata.go @@ -0,0 +1,78 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import "golang.org/x/net/context" + +// Datastore kinds for the metadata entities. +const ( + namespaceKind = "__namespace__" + kindKind = "__kind__" + propertyKind = "__property__" +) + +// Namespaces returns all the datastore namespaces. +func Namespaces(ctx context.Context) ([]string, error) { + // TODO(djd): Support range queries. + q := NewQuery(namespaceKind).KeysOnly() + keys, err := q.GetAll(ctx, nil) + if err != nil { + return nil, err + } + // The empty namespace key uses a numeric ID (==1), but luckily + // the string ID defaults to "" for numeric IDs anyway. + return keyNames(keys), nil +} + +// Kinds returns the names of all the kinds in the current namespace. +func Kinds(ctx context.Context) ([]string, error) { + // TODO(djd): Support range queries. + q := NewQuery(kindKind).KeysOnly() + keys, err := q.GetAll(ctx, nil) + if err != nil { + return nil, err + } + return keyNames(keys), nil +} + +// keyNames returns a slice of the provided keys' names (string IDs). +func keyNames(keys []*Key) []string { + n := make([]string, 0, len(keys)) + for _, k := range keys { + n = append(n, k.StringID()) + } + return n +} + +// KindProperties returns all the indexed properties for the given kind. +// The properties are returned as a map of property names to a slice of the +// representation types. The representation types for the supported Go property +// types are: +// "INT64": signed integers and time.Time +// "DOUBLE": float32 and float64 +// "BOOLEAN": bool +// "STRING": string, []byte and ByteString +// "POINT": appengine.GeoPoint +// "REFERENCE": *Key +// "USER": (not used in the Go runtime) +func KindProperties(ctx context.Context, kind string) (map[string][]string, error) { + // TODO(djd): Support range queries. + kindKey := NewKey(ctx, kindKind, kind, 0, nil) + q := NewQuery(propertyKind).Ancestor(kindKey) + + propMap := map[string][]string{} + props := []struct { + Repr []string `datastore:"property_representation"` + }{} + + keys, err := q.GetAll(ctx, &props) + if err != nil { + return nil, err + } + for i, p := range props { + propMap[keys[i].StringID()] = p.Repr + } + return propMap, nil +} diff --git a/vendor/google.golang.org/appengine/datastore/prop.go b/vendor/google.golang.org/appengine/datastore/prop.go new file mode 100644 index 000000000000..5cb2079d8874 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/prop.go @@ -0,0 +1,330 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "fmt" + "reflect" + "strings" + "sync" + "unicode" +) + +// Entities with more than this many indexed properties will not be saved. +const maxIndexedProperties = 20000 + +// []byte fields more than 1 megabyte long will not be loaded or saved. +const maxBlobLen = 1 << 20 + +// Property is a name/value pair plus some metadata. A datastore entity's +// contents are loaded and saved as a sequence of Properties. An entity can +// have multiple Properties with the same name, provided that p.Multiple is +// true on all of that entity's Properties with that name. +type Property struct { + // Name is the property name. + Name string + // Value is the property value. The valid types are: + // - int64 + // - bool + // - string + // - float64 + // - ByteString + // - *Key + // - time.Time + // - appengine.BlobKey + // - appengine.GeoPoint + // - []byte (up to 1 megabyte in length) + // - *Entity (representing a nested struct) + // This set is smaller than the set of valid struct field types that the + // datastore can load and save. A Property Value cannot be a slice (apart + // from []byte); use multiple Properties instead. Also, a Value's type + // must be explicitly on the list above; it is not sufficient for the + // underlying type to be on that list. For example, a Value of "type + // myInt64 int64" is invalid. Smaller-width integers and floats are also + // invalid. Again, this is more restrictive than the set of valid struct + // field types. + // + // A Value will have an opaque type when loading entities from an index, + // such as via a projection query. Load entities into a struct instead + // of a PropertyLoadSaver when using a projection query. + // + // A Value may also be the nil interface value; this is equivalent to + // Python's None but not directly representable by a Go struct. Loading + // a nil-valued property into a struct will set that field to the zero + // value. + Value interface{} + // NoIndex is whether the datastore cannot index this property. + NoIndex bool + // Multiple is whether the entity can have multiple properties with + // the same name. Even if a particular instance only has one property with + // a certain name, Multiple should be true if a struct would best represent + // it as a field of type []T instead of type T. + Multiple bool +} + +// An Entity is the value type for a nested struct. +// This type is only used for a Property's Value. +type Entity struct { + Key *Key + Properties []Property +} + +// ByteString is a short byte slice (up to 1500 bytes) that can be indexed. +type ByteString []byte + +// PropertyLoadSaver can be converted from and to a slice of Properties. +type PropertyLoadSaver interface { + Load([]Property) error + Save() ([]Property, error) +} + +// PropertyList converts a []Property to implement PropertyLoadSaver. +type PropertyList []Property + +var ( + typeOfPropertyLoadSaver = reflect.TypeOf((*PropertyLoadSaver)(nil)).Elem() + typeOfPropertyList = reflect.TypeOf(PropertyList(nil)) +) + +// Load loads all of the provided properties into l. +// It does not first reset *l to an empty slice. +func (l *PropertyList) Load(p []Property) error { + *l = append(*l, p...) + return nil +} + +// Save saves all of l's properties as a slice or Properties. +func (l *PropertyList) Save() ([]Property, error) { + return *l, nil +} + +// validPropertyName returns whether name consists of one or more valid Go +// identifiers joined by ".". +func validPropertyName(name string) bool { + if name == "" { + return false + } + for _, s := range strings.Split(name, ".") { + if s == "" { + return false + } + first := true + for _, c := range s { + if first { + first = false + if c != '_' && !unicode.IsLetter(c) { + return false + } + } else { + if c != '_' && !unicode.IsLetter(c) && !unicode.IsDigit(c) { + return false + } + } + } + } + return true +} + +// structCodec describes how to convert a struct to and from a sequence of +// properties. +type structCodec struct { + // fields gives the field codec for the structTag with the given name. + fields map[string]fieldCodec + // hasSlice is whether a struct or any of its nested or embedded structs + // has a slice-typed field (other than []byte). + hasSlice bool + // keyField is the index of a *Key field with structTag __key__. + // This field is not relevant for the top level struct, only for + // nested structs. + keyField int + // complete is whether the structCodec is complete. An incomplete + // structCodec may be encountered when walking a recursive struct. + complete bool +} + +// fieldCodec is a struct field's index and, if that struct field's type is +// itself a struct, that substruct's structCodec. +type fieldCodec struct { + // path is the index path to the field + path []int + noIndex bool + // omitEmpty indicates that the field should be omitted on save + // if empty. + omitEmpty bool + // structCodec is the codec fot the struct field at index 'path', + // or nil if the field is not a struct. + structCodec *structCodec +} + +// structCodecs collects the structCodecs that have already been calculated. +var ( + structCodecsMutex sync.Mutex + structCodecs = make(map[reflect.Type]*structCodec) +) + +// getStructCodec returns the structCodec for the given struct type. +func getStructCodec(t reflect.Type) (*structCodec, error) { + structCodecsMutex.Lock() + defer structCodecsMutex.Unlock() + return getStructCodecLocked(t) +} + +// getStructCodecLocked implements getStructCodec. The structCodecsMutex must +// be held when calling this function. +func getStructCodecLocked(t reflect.Type) (ret *structCodec, retErr error) { + c, ok := structCodecs[t] + if ok { + return c, nil + } + c = &structCodec{ + fields: make(map[string]fieldCodec), + // We initialize keyField to -1 so that the zero-value is not + // misinterpreted as index 0. + keyField: -1, + } + + // Add c to the structCodecs map before we are sure it is good. If t is + // a recursive type, it needs to find the incomplete entry for itself in + // the map. + structCodecs[t] = c + defer func() { + if retErr != nil { + delete(structCodecs, t) + } + }() + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + // Skip unexported fields. + // Note that if f is an anonymous, unexported struct field, + // we will promote its fields. + if f.PkgPath != "" && !f.Anonymous { + continue + } + + tags := strings.Split(f.Tag.Get("datastore"), ",") + name := tags[0] + opts := make(map[string]bool) + for _, t := range tags[1:] { + opts[t] = true + } + switch { + case name == "": + if !f.Anonymous { + name = f.Name + } + case name == "-": + continue + case name == "__key__": + if f.Type != typeOfKeyPtr { + return nil, fmt.Errorf("datastore: __key__ field on struct %v is not a *datastore.Key", t) + } + c.keyField = i + case !validPropertyName(name): + return nil, fmt.Errorf("datastore: struct tag has invalid property name: %q", name) + } + + substructType, fIsSlice := reflect.Type(nil), false + switch f.Type.Kind() { + case reflect.Struct: + substructType = f.Type + case reflect.Slice: + if f.Type.Elem().Kind() == reflect.Struct { + substructType = f.Type.Elem() + } + fIsSlice = f.Type != typeOfByteSlice + c.hasSlice = c.hasSlice || fIsSlice + } + + var sub *structCodec + if substructType != nil && substructType != typeOfTime && substructType != typeOfGeoPoint { + var err error + sub, err = getStructCodecLocked(substructType) + if err != nil { + return nil, err + } + if !sub.complete { + return nil, fmt.Errorf("datastore: recursive struct: field %q", f.Name) + } + if fIsSlice && sub.hasSlice { + return nil, fmt.Errorf( + "datastore: flattening nested structs leads to a slice of slices: field %q", f.Name) + } + c.hasSlice = c.hasSlice || sub.hasSlice + // If f is an anonymous struct field, we promote the substruct's fields up to this level + // in the linked list of struct codecs. + if f.Anonymous { + for subname, subfield := range sub.fields { + if name != "" { + subname = name + "." + subname + } + if _, ok := c.fields[subname]; ok { + return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", subname) + } + c.fields[subname] = fieldCodec{ + path: append([]int{i}, subfield.path...), + noIndex: subfield.noIndex || opts["noindex"], + omitEmpty: subfield.omitEmpty, + structCodec: subfield.structCodec, + } + } + continue + } + } + + if _, ok := c.fields[name]; ok { + return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", name) + } + c.fields[name] = fieldCodec{ + path: []int{i}, + noIndex: opts["noindex"], + omitEmpty: opts["omitempty"], + structCodec: sub, + } + } + c.complete = true + return c, nil +} + +// structPLS adapts a struct to be a PropertyLoadSaver. +type structPLS struct { + v reflect.Value + codec *structCodec +} + +// newStructPLS returns a structPLS, which implements the +// PropertyLoadSaver interface, for the struct pointer p. +func newStructPLS(p interface{}) (*structPLS, error) { + v := reflect.ValueOf(p) + if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { + return nil, ErrInvalidEntityType + } + v = v.Elem() + codec, err := getStructCodec(v.Type()) + if err != nil { + return nil, err + } + return &structPLS{v, codec}, nil +} + +// LoadStruct loads the properties from p to dst. +// dst must be a struct pointer. +func LoadStruct(dst interface{}, p []Property) error { + x, err := newStructPLS(dst) + if err != nil { + return err + } + return x.Load(p) +} + +// SaveStruct returns the properties from src as a slice of Properties. +// src must be a struct pointer. +func SaveStruct(src interface{}) ([]Property, error) { + x, err := newStructPLS(src) + if err != nil { + return nil, err + } + return x.Save() +} diff --git a/vendor/google.golang.org/appengine/datastore/query.go b/vendor/google.golang.org/appengine/datastore/query.go new file mode 100644 index 000000000000..c1ea4adf6957 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/query.go @@ -0,0 +1,757 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "encoding/base64" + "errors" + "fmt" + "math" + "reflect" + "strings" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/datastore" +) + +type operator int + +const ( + lessThan operator = iota + lessEq + equal + greaterEq + greaterThan +) + +var operatorToProto = map[operator]*pb.Query_Filter_Operator{ + lessThan: pb.Query_Filter_LESS_THAN.Enum(), + lessEq: pb.Query_Filter_LESS_THAN_OR_EQUAL.Enum(), + equal: pb.Query_Filter_EQUAL.Enum(), + greaterEq: pb.Query_Filter_GREATER_THAN_OR_EQUAL.Enum(), + greaterThan: pb.Query_Filter_GREATER_THAN.Enum(), +} + +// filter is a conditional filter on query results. +type filter struct { + FieldName string + Op operator + Value interface{} +} + +type sortDirection int + +const ( + ascending sortDirection = iota + descending +) + +var sortDirectionToProto = map[sortDirection]*pb.Query_Order_Direction{ + ascending: pb.Query_Order_ASCENDING.Enum(), + descending: pb.Query_Order_DESCENDING.Enum(), +} + +// order is a sort order on query results. +type order struct { + FieldName string + Direction sortDirection +} + +// NewQuery creates a new Query for a specific entity kind. +// +// An empty kind means to return all entities, including entities created and +// managed by other App Engine features, and is called a kindless query. +// Kindless queries cannot include filters or sort orders on property values. +func NewQuery(kind string) *Query { + return &Query{ + kind: kind, + limit: -1, + } +} + +// Query represents a datastore query. +type Query struct { + kind string + ancestor *Key + filter []filter + order []order + projection []string + + distinct bool + keysOnly bool + eventual bool + limit int32 + offset int32 + count int32 + start *pb.CompiledCursor + end *pb.CompiledCursor + + err error +} + +func (q *Query) clone() *Query { + x := *q + // Copy the contents of the slice-typed fields to a new backing store. + if len(q.filter) > 0 { + x.filter = make([]filter, len(q.filter)) + copy(x.filter, q.filter) + } + if len(q.order) > 0 { + x.order = make([]order, len(q.order)) + copy(x.order, q.order) + } + return &x +} + +// Ancestor returns a derivative query with an ancestor filter. +// The ancestor should not be nil. +func (q *Query) Ancestor(ancestor *Key) *Query { + q = q.clone() + if ancestor == nil { + q.err = errors.New("datastore: nil query ancestor") + return q + } + q.ancestor = ancestor + return q +} + +// EventualConsistency returns a derivative query that returns eventually +// consistent results. +// It only has an effect on ancestor queries. +func (q *Query) EventualConsistency() *Query { + q = q.clone() + q.eventual = true + return q +} + +// Filter returns a derivative query with a field-based filter. +// The filterStr argument must be a field name followed by optional space, +// followed by an operator, one of ">", "<", ">=", "<=", or "=". +// Fields are compared against the provided value using the operator. +// Multiple filters are AND'ed together. +func (q *Query) Filter(filterStr string, value interface{}) *Query { + q = q.clone() + filterStr = strings.TrimSpace(filterStr) + if len(filterStr) < 1 { + q.err = errors.New("datastore: invalid filter: " + filterStr) + return q + } + f := filter{ + FieldName: strings.TrimRight(filterStr, " ><=!"), + Value: value, + } + switch op := strings.TrimSpace(filterStr[len(f.FieldName):]); op { + case "<=": + f.Op = lessEq + case ">=": + f.Op = greaterEq + case "<": + f.Op = lessThan + case ">": + f.Op = greaterThan + case "=": + f.Op = equal + default: + q.err = fmt.Errorf("datastore: invalid operator %q in filter %q", op, filterStr) + return q + } + q.filter = append(q.filter, f) + return q +} + +// Order returns a derivative query with a field-based sort order. Orders are +// applied in the order they are added. The default order is ascending; to sort +// in descending order prefix the fieldName with a minus sign (-). +func (q *Query) Order(fieldName string) *Query { + q = q.clone() + fieldName = strings.TrimSpace(fieldName) + o := order{ + Direction: ascending, + FieldName: fieldName, + } + if strings.HasPrefix(fieldName, "-") { + o.Direction = descending + o.FieldName = strings.TrimSpace(fieldName[1:]) + } else if strings.HasPrefix(fieldName, "+") { + q.err = fmt.Errorf("datastore: invalid order: %q", fieldName) + return q + } + if len(o.FieldName) == 0 { + q.err = errors.New("datastore: empty order") + return q + } + q.order = append(q.order, o) + return q +} + +// Project returns a derivative query that yields only the given fields. It +// cannot be used with KeysOnly. +func (q *Query) Project(fieldNames ...string) *Query { + q = q.clone() + q.projection = append([]string(nil), fieldNames...) + return q +} + +// Distinct returns a derivative query that yields de-duplicated entities with +// respect to the set of projected fields. It is only used for projection +// queries. +func (q *Query) Distinct() *Query { + q = q.clone() + q.distinct = true + return q +} + +// KeysOnly returns a derivative query that yields only keys, not keys and +// entities. It cannot be used with projection queries. +func (q *Query) KeysOnly() *Query { + q = q.clone() + q.keysOnly = true + return q +} + +// Limit returns a derivative query that has a limit on the number of results +// returned. A negative value means unlimited. +func (q *Query) Limit(limit int) *Query { + q = q.clone() + if limit < math.MinInt32 || limit > math.MaxInt32 { + q.err = errors.New("datastore: query limit overflow") + return q + } + q.limit = int32(limit) + return q +} + +// Offset returns a derivative query that has an offset of how many keys to +// skip over before returning results. A negative value is invalid. +func (q *Query) Offset(offset int) *Query { + q = q.clone() + if offset < 0 { + q.err = errors.New("datastore: negative query offset") + return q + } + if offset > math.MaxInt32 { + q.err = errors.New("datastore: query offset overflow") + return q + } + q.offset = int32(offset) + return q +} + +// BatchSize returns a derivative query to fetch the supplied number of results +// at once. This value should be greater than zero, and equal to or less than +// the Limit. +func (q *Query) BatchSize(size int) *Query { + q = q.clone() + if size <= 0 || size > math.MaxInt32 { + q.err = errors.New("datastore: query batch size overflow") + return q + } + q.count = int32(size) + return q +} + +// Start returns a derivative query with the given start point. +func (q *Query) Start(c Cursor) *Query { + q = q.clone() + if c.cc == nil { + q.err = errors.New("datastore: invalid cursor") + return q + } + q.start = c.cc + return q +} + +// End returns a derivative query with the given end point. +func (q *Query) End(c Cursor) *Query { + q = q.clone() + if c.cc == nil { + q.err = errors.New("datastore: invalid cursor") + return q + } + q.end = c.cc + return q +} + +// toProto converts the query to a protocol buffer. +func (q *Query) toProto(dst *pb.Query, appID string) error { + if len(q.projection) != 0 && q.keysOnly { + return errors.New("datastore: query cannot both project and be keys-only") + } + dst.Reset() + dst.App = proto.String(appID) + if q.kind != "" { + dst.Kind = proto.String(q.kind) + } + if q.ancestor != nil { + dst.Ancestor = keyToProto(appID, q.ancestor) + if q.eventual { + dst.Strong = proto.Bool(false) + } + } + if q.projection != nil { + dst.PropertyName = q.projection + if q.distinct { + dst.GroupByPropertyName = q.projection + } + } + if q.keysOnly { + dst.KeysOnly = proto.Bool(true) + dst.RequirePerfectPlan = proto.Bool(true) + } + for _, qf := range q.filter { + if qf.FieldName == "" { + return errors.New("datastore: empty query filter field name") + } + p, errStr := valueToProto(appID, qf.FieldName, reflect.ValueOf(qf.Value), false) + if errStr != "" { + return errors.New("datastore: bad query filter value type: " + errStr) + } + xf := &pb.Query_Filter{ + Op: operatorToProto[qf.Op], + Property: []*pb.Property{p}, + } + if xf.Op == nil { + return errors.New("datastore: unknown query filter operator") + } + dst.Filter = append(dst.Filter, xf) + } + for _, qo := range q.order { + if qo.FieldName == "" { + return errors.New("datastore: empty query order field name") + } + xo := &pb.Query_Order{ + Property: proto.String(qo.FieldName), + Direction: sortDirectionToProto[qo.Direction], + } + if xo.Direction == nil { + return errors.New("datastore: unknown query order direction") + } + dst.Order = append(dst.Order, xo) + } + if q.limit >= 0 { + dst.Limit = proto.Int32(q.limit) + } + if q.offset != 0 { + dst.Offset = proto.Int32(q.offset) + } + if q.count != 0 { + dst.Count = proto.Int32(q.count) + } + dst.CompiledCursor = q.start + dst.EndCompiledCursor = q.end + dst.Compile = proto.Bool(true) + return nil +} + +// Count returns the number of results for the query. +// +// The running time and number of API calls made by Count scale linearly with +// the sum of the query's offset and limit. Unless the result count is +// expected to be small, it is best to specify a limit; otherwise Count will +// continue until it finishes counting or the provided context expires. +func (q *Query) Count(c context.Context) (int, error) { + // Check that the query is well-formed. + if q.err != nil { + return 0, q.err + } + + // Run a copy of the query, with keysOnly true (if we're not a projection, + // since the two are incompatible), and an adjusted offset. We also set the + // limit to zero, as we don't want any actual entity data, just the number + // of skipped results. + newQ := q.clone() + newQ.keysOnly = len(newQ.projection) == 0 + newQ.limit = 0 + if q.limit < 0 { + // If the original query was unlimited, set the new query's offset to maximum. + newQ.offset = math.MaxInt32 + } else { + newQ.offset = q.offset + q.limit + if newQ.offset < 0 { + // Do the best we can, in the presence of overflow. + newQ.offset = math.MaxInt32 + } + } + req := &pb.Query{} + if err := newQ.toProto(req, internal.FullyQualifiedAppID(c)); err != nil { + return 0, err + } + res := &pb.QueryResult{} + if err := internal.Call(c, "datastore_v3", "RunQuery", req, res); err != nil { + return 0, err + } + + // n is the count we will return. For example, suppose that our original + // query had an offset of 4 and a limit of 2008: the count will be 2008, + // provided that there are at least 2012 matching entities. However, the + // RPCs will only skip 1000 results at a time. The RPC sequence is: + // call RunQuery with (offset, limit) = (2012, 0) // 2012 == newQ.offset + // response has (skippedResults, moreResults) = (1000, true) + // n += 1000 // n == 1000 + // call Next with (offset, limit) = (1012, 0) // 1012 == newQ.offset - n + // response has (skippedResults, moreResults) = (1000, true) + // n += 1000 // n == 2000 + // call Next with (offset, limit) = (12, 0) // 12 == newQ.offset - n + // response has (skippedResults, moreResults) = (12, false) + // n += 12 // n == 2012 + // // exit the loop + // n -= 4 // n == 2008 + var n int32 + for { + // The QueryResult should have no actual entity data, just skipped results. + if len(res.Result) != 0 { + return 0, errors.New("datastore: internal error: Count request returned too much data") + } + n += res.GetSkippedResults() + if !res.GetMoreResults() { + break + } + if err := callNext(c, res, newQ.offset-n, q.count); err != nil { + return 0, err + } + } + n -= q.offset + if n < 0 { + // If the offset was greater than the number of matching entities, + // return 0 instead of negative. + n = 0 + } + return int(n), nil +} + +// callNext issues a datastore_v3/Next RPC to advance a cursor, such as that +// returned by a query with more results. +func callNext(c context.Context, res *pb.QueryResult, offset, count int32) error { + if res.Cursor == nil { + return errors.New("datastore: internal error: server did not return a cursor") + } + req := &pb.NextRequest{ + Cursor: res.Cursor, + } + if count >= 0 { + req.Count = proto.Int32(count) + } + if offset != 0 { + req.Offset = proto.Int32(offset) + } + if res.CompiledCursor != nil { + req.Compile = proto.Bool(true) + } + res.Reset() + return internal.Call(c, "datastore_v3", "Next", req, res) +} + +// GetAll runs the query in the given context and returns all keys that match +// that query, as well as appending the values to dst. +// +// dst must have type *[]S or *[]*S or *[]P, for some struct type S or some non- +// interface, non-pointer type P such that P or *P implements PropertyLoadSaver. +// +// As a special case, *PropertyList is an invalid type for dst, even though a +// PropertyList is a slice of structs. It is treated as invalid to avoid being +// mistakenly passed when *[]PropertyList was intended. +// +// The keys returned by GetAll will be in a 1-1 correspondence with the entities +// added to dst. +// +// If q is a ``keys-only'' query, GetAll ignores dst and only returns the keys. +// +// The running time and number of API calls made by GetAll scale linearly with +// the sum of the query's offset and limit. Unless the result count is +// expected to be small, it is best to specify a limit; otherwise GetAll will +// continue until it finishes collecting results or the provided context +// expires. +func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error) { + var ( + dv reflect.Value + mat multiArgType + elemType reflect.Type + errFieldMismatch error + ) + if !q.keysOnly { + dv = reflect.ValueOf(dst) + if dv.Kind() != reflect.Ptr || dv.IsNil() { + return nil, ErrInvalidEntityType + } + dv = dv.Elem() + mat, elemType = checkMultiArg(dv) + if mat == multiArgTypeInvalid || mat == multiArgTypeInterface { + return nil, ErrInvalidEntityType + } + } + + var keys []*Key + for t := q.Run(c); ; { + k, e, err := t.next() + if err == Done { + break + } + if err != nil { + return keys, err + } + if !q.keysOnly { + ev := reflect.New(elemType) + if elemType.Kind() == reflect.Map { + // This is a special case. The zero values of a map type are + // not immediately useful; they have to be make'd. + // + // Funcs and channels are similar, in that a zero value is not useful, + // but even a freshly make'd channel isn't useful: there's no fixed + // channel buffer size that is always going to be large enough, and + // there's no goroutine to drain the other end. Theoretically, these + // types could be supported, for example by sniffing for a constructor + // method or requiring prior registration, but for now it's not a + // frequent enough concern to be worth it. Programmers can work around + // it by explicitly using Iterator.Next instead of the Query.GetAll + // convenience method. + x := reflect.MakeMap(elemType) + ev.Elem().Set(x) + } + if err = loadEntity(ev.Interface(), e); err != nil { + if _, ok := err.(*ErrFieldMismatch); ok { + // We continue loading entities even in the face of field mismatch errors. + // If we encounter any other error, that other error is returned. Otherwise, + // an ErrFieldMismatch is returned. + errFieldMismatch = err + } else { + return keys, err + } + } + if mat != multiArgTypeStructPtr { + ev = ev.Elem() + } + dv.Set(reflect.Append(dv, ev)) + } + keys = append(keys, k) + } + return keys, errFieldMismatch +} + +// Run runs the query in the given context. +func (q *Query) Run(c context.Context) *Iterator { + if q.err != nil { + return &Iterator{err: q.err} + } + t := &Iterator{ + c: c, + limit: q.limit, + count: q.count, + q: q, + prevCC: q.start, + } + var req pb.Query + if err := q.toProto(&req, internal.FullyQualifiedAppID(c)); err != nil { + t.err = err + return t + } + if err := internal.Call(c, "datastore_v3", "RunQuery", &req, &t.res); err != nil { + t.err = err + return t + } + offset := q.offset - t.res.GetSkippedResults() + var count int32 + if t.count > 0 && (t.limit < 0 || t.count < t.limit) { + count = t.count + } else { + count = t.limit + } + for offset > 0 && t.res.GetMoreResults() { + t.prevCC = t.res.CompiledCursor + if err := callNext(t.c, &t.res, offset, count); err != nil { + t.err = err + break + } + skip := t.res.GetSkippedResults() + if skip < 0 { + t.err = errors.New("datastore: internal error: negative number of skipped_results") + break + } + offset -= skip + } + if offset < 0 { + t.err = errors.New("datastore: internal error: query offset was overshot") + } + return t +} + +// Iterator is the result of running a query. +type Iterator struct { + c context.Context + err error + // res is the result of the most recent RunQuery or Next API call. + res pb.QueryResult + // i is how many elements of res.Result we have iterated over. + i int + // limit is the limit on the number of results this iterator should return. + // A negative value means unlimited. + limit int32 + // count is the number of results this iterator should fetch at once. This + // should be equal to or greater than zero. + count int32 + // q is the original query which yielded this iterator. + q *Query + // prevCC is the compiled cursor that marks the end of the previous batch + // of results. + prevCC *pb.CompiledCursor +} + +// Done is returned when a query iteration has completed. +var Done = errors.New("datastore: query has no more results") + +// Next returns the key of the next result. When there are no more results, +// Done is returned as the error. +// +// If the query is not keys only and dst is non-nil, it also loads the entity +// stored for that key into the struct pointer or PropertyLoadSaver dst, with +// the same semantics and possible errors as for the Get function. +func (t *Iterator) Next(dst interface{}) (*Key, error) { + k, e, err := t.next() + if err != nil { + return nil, err + } + if dst != nil && !t.q.keysOnly { + err = loadEntity(dst, e) + } + return k, err +} + +func (t *Iterator) next() (*Key, *pb.EntityProto, error) { + if t.err != nil { + return nil, nil, t.err + } + + // Issue datastore_v3/Next RPCs as necessary. + for t.i == len(t.res.Result) { + if !t.res.GetMoreResults() { + t.err = Done + return nil, nil, t.err + } + t.prevCC = t.res.CompiledCursor + var count int32 + if t.count > 0 && (t.limit < 0 || t.count < t.limit) { + count = t.count + } else { + count = t.limit + } + if err := callNext(t.c, &t.res, 0, count); err != nil { + t.err = err + return nil, nil, t.err + } + if t.res.GetSkippedResults() != 0 { + t.err = errors.New("datastore: internal error: iterator has skipped results") + return nil, nil, t.err + } + t.i = 0 + if t.limit >= 0 { + t.limit -= int32(len(t.res.Result)) + if t.limit < 0 { + t.err = errors.New("datastore: internal error: query returned more results than the limit") + return nil, nil, t.err + } + } + } + + // Extract the key from the t.i'th element of t.res.Result. + e := t.res.Result[t.i] + t.i++ + if e.Key == nil { + return nil, nil, errors.New("datastore: internal error: server did not return a key") + } + k, err := protoToKey(e.Key) + if err != nil || k.Incomplete() { + return nil, nil, errors.New("datastore: internal error: server returned an invalid key") + } + return k, e, nil +} + +// Cursor returns a cursor for the iterator's current location. +func (t *Iterator) Cursor() (Cursor, error) { + if t.err != nil && t.err != Done { + return Cursor{}, t.err + } + // If we are at either end of the current batch of results, + // return the compiled cursor at that end. + skipped := t.res.GetSkippedResults() + if t.i == 0 && skipped == 0 { + if t.prevCC == nil { + // A nil pointer (of type *pb.CompiledCursor) means no constraint: + // passing it as the end cursor of a new query means unlimited results + // (glossing over the integer limit parameter for now). + // A non-nil pointer to an empty pb.CompiledCursor means the start: + // passing it as the end cursor of a new query means 0 results. + // If prevCC was nil, then the original query had no start cursor, but + // Iterator.Cursor should return "the start" instead of unlimited. + return Cursor{&zeroCC}, nil + } + return Cursor{t.prevCC}, nil + } + if t.i == len(t.res.Result) { + return Cursor{t.res.CompiledCursor}, nil + } + // Otherwise, re-run the query offset to this iterator's position, starting from + // the most recent compiled cursor. This is done on a best-effort basis, as it + // is racy; if a concurrent process has added or removed entities, then the + // cursor returned may be inconsistent. + q := t.q.clone() + q.start = t.prevCC + q.offset = skipped + int32(t.i) + q.limit = 0 + q.keysOnly = len(q.projection) == 0 + t1 := q.Run(t.c) + _, _, err := t1.next() + if err != Done { + if err == nil { + err = fmt.Errorf("datastore: internal error: zero-limit query did not have zero results") + } + return Cursor{}, err + } + return Cursor{t1.res.CompiledCursor}, nil +} + +var zeroCC pb.CompiledCursor + +// Cursor is an iterator's position. It can be converted to and from an opaque +// string. A cursor can be used from different HTTP requests, but only with a +// query with the same kind, ancestor, filter and order constraints. +type Cursor struct { + cc *pb.CompiledCursor +} + +// String returns a base-64 string representation of a cursor. +func (c Cursor) String() string { + if c.cc == nil { + return "" + } + b, err := proto.Marshal(c.cc) + if err != nil { + // The only way to construct a Cursor with a non-nil cc field is to + // unmarshal from the byte representation. We panic if the unmarshal + // succeeds but the marshaling of the unchanged protobuf value fails. + panic(fmt.Sprintf("datastore: internal error: malformed cursor: %v", err)) + } + return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") +} + +// Decode decodes a cursor from its base-64 string representation. +func DecodeCursor(s string) (Cursor, error) { + if s == "" { + return Cursor{&zeroCC}, nil + } + if n := len(s) % 4; n != 0 { + s += strings.Repeat("=", 4-n) + } + b, err := base64.URLEncoding.DecodeString(s) + if err != nil { + return Cursor{}, err + } + cc := &pb.CompiledCursor{} + if err := proto.Unmarshal(b, cc); err != nil { + return Cursor{}, err + } + return Cursor{cc}, nil +} diff --git a/vendor/google.golang.org/appengine/datastore/save.go b/vendor/google.golang.org/appengine/datastore/save.go new file mode 100644 index 000000000000..7b045a595568 --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/save.go @@ -0,0 +1,333 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "errors" + "fmt" + "math" + "reflect" + "time" + + "github.com/golang/protobuf/proto" + + "google.golang.org/appengine" + pb "google.golang.org/appengine/internal/datastore" +) + +func toUnixMicro(t time.Time) int64 { + // We cannot use t.UnixNano() / 1e3 because we want to handle times more than + // 2^63 nanoseconds (which is about 292 years) away from 1970, and those cannot + // be represented in the numerator of a single int64 divide. + return t.Unix()*1e6 + int64(t.Nanosecond()/1e3) +} + +func fromUnixMicro(t int64) time.Time { + return time.Unix(t/1e6, (t%1e6)*1e3).UTC() +} + +var ( + minTime = time.Unix(int64(math.MinInt64)/1e6, (int64(math.MinInt64)%1e6)*1e3) + maxTime = time.Unix(int64(math.MaxInt64)/1e6, (int64(math.MaxInt64)%1e6)*1e3) +) + +// valueToProto converts a named value to a newly allocated Property. +// The returned error string is empty on success. +func valueToProto(defaultAppID, name string, v reflect.Value, multiple bool) (p *pb.Property, errStr string) { + var ( + pv pb.PropertyValue + unsupported bool + ) + switch v.Kind() { + case reflect.Invalid: + // No-op. + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + pv.Int64Value = proto.Int64(v.Int()) + case reflect.Bool: + pv.BooleanValue = proto.Bool(v.Bool()) + case reflect.String: + pv.StringValue = proto.String(v.String()) + case reflect.Float32, reflect.Float64: + pv.DoubleValue = proto.Float64(v.Float()) + case reflect.Ptr: + if k, ok := v.Interface().(*Key); ok { + if k != nil { + pv.Referencevalue = keyToReferenceValue(defaultAppID, k) + } + } else { + unsupported = true + } + case reflect.Struct: + switch t := v.Interface().(type) { + case time.Time: + if t.Before(minTime) || t.After(maxTime) { + return nil, "time value out of range" + } + pv.Int64Value = proto.Int64(toUnixMicro(t)) + case appengine.GeoPoint: + if !t.Valid() { + return nil, "invalid GeoPoint value" + } + // NOTE: Strangely, latitude maps to X, longitude to Y. + pv.Pointvalue = &pb.PropertyValue_PointValue{X: &t.Lat, Y: &t.Lng} + default: + unsupported = true + } + case reflect.Slice: + if b, ok := v.Interface().([]byte); ok { + pv.StringValue = proto.String(string(b)) + } else { + // nvToProto should already catch slice values. + // If we get here, we have a slice of slice values. + unsupported = true + } + default: + unsupported = true + } + if unsupported { + return nil, "unsupported datastore value type: " + v.Type().String() + } + p = &pb.Property{ + Name: proto.String(name), + Value: &pv, + Multiple: proto.Bool(multiple), + } + if v.IsValid() { + switch v.Interface().(type) { + case []byte: + p.Meaning = pb.Property_BLOB.Enum() + case ByteString: + p.Meaning = pb.Property_BYTESTRING.Enum() + case appengine.BlobKey: + p.Meaning = pb.Property_BLOBKEY.Enum() + case time.Time: + p.Meaning = pb.Property_GD_WHEN.Enum() + case appengine.GeoPoint: + p.Meaning = pb.Property_GEORSS_POINT.Enum() + } + } + return p, "" +} + +type saveOpts struct { + noIndex bool + multiple bool + omitEmpty bool +} + +// saveEntity saves an EntityProto into a PropertyLoadSaver or struct pointer. +func saveEntity(defaultAppID string, key *Key, src interface{}) (*pb.EntityProto, error) { + var err error + var props []Property + if e, ok := src.(PropertyLoadSaver); ok { + props, err = e.Save() + } else { + props, err = SaveStruct(src) + } + if err != nil { + return nil, err + } + return propertiesToProto(defaultAppID, key, props) +} + +func saveStructProperty(props *[]Property, name string, opts saveOpts, v reflect.Value) error { + if opts.omitEmpty && isEmptyValue(v) { + return nil + } + p := Property{ + Name: name, + NoIndex: opts.noIndex, + Multiple: opts.multiple, + } + switch x := v.Interface().(type) { + case *Key: + p.Value = x + case time.Time: + p.Value = x + case appengine.BlobKey: + p.Value = x + case appengine.GeoPoint: + p.Value = x + case ByteString: + p.Value = x + default: + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p.Value = v.Int() + case reflect.Bool: + p.Value = v.Bool() + case reflect.String: + p.Value = v.String() + case reflect.Float32, reflect.Float64: + p.Value = v.Float() + case reflect.Slice: + if v.Type().Elem().Kind() == reflect.Uint8 { + p.NoIndex = true + p.Value = v.Bytes() + } + case reflect.Struct: + if !v.CanAddr() { + return fmt.Errorf("datastore: unsupported struct field: value is unaddressable") + } + sub, err := newStructPLS(v.Addr().Interface()) + if err != nil { + return fmt.Errorf("datastore: unsupported struct field: %v", err) + } + return sub.save(props, name+".", opts) + } + } + if p.Value == nil { + return fmt.Errorf("datastore: unsupported struct field type: %v", v.Type()) + } + *props = append(*props, p) + return nil +} + +func (s structPLS) Save() ([]Property, error) { + var props []Property + if err := s.save(&props, "", saveOpts{}); err != nil { + return nil, err + } + return props, nil +} + +func (s structPLS) save(props *[]Property, prefix string, opts saveOpts) error { + for name, f := range s.codec.fields { + name = prefix + name + v := s.v.FieldByIndex(f.path) + if !v.IsValid() || !v.CanSet() { + continue + } + var opts1 saveOpts + opts1.noIndex = opts.noIndex || f.noIndex + opts1.multiple = opts.multiple + opts1.omitEmpty = f.omitEmpty // don't propagate + // For slice fields that aren't []byte, save each element. + if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { + opts1.multiple = true + for j := 0; j < v.Len(); j++ { + if err := saveStructProperty(props, name, opts1, v.Index(j)); err != nil { + return err + } + } + continue + } + // Otherwise, save the field itself. + if err := saveStructProperty(props, name, opts1, v); err != nil { + return err + } + } + return nil +} + +func propertiesToProto(defaultAppID string, key *Key, props []Property) (*pb.EntityProto, error) { + e := &pb.EntityProto{ + Key: keyToProto(defaultAppID, key), + } + if key.parent == nil { + e.EntityGroup = &pb.Path{} + } else { + e.EntityGroup = keyToProto(defaultAppID, key.root()).Path + } + prevMultiple := make(map[string]bool) + + for _, p := range props { + if pm, ok := prevMultiple[p.Name]; ok { + if !pm || !p.Multiple { + return nil, fmt.Errorf("datastore: multiple Properties with Name %q, but Multiple is false", p.Name) + } + } else { + prevMultiple[p.Name] = p.Multiple + } + + x := &pb.Property{ + Name: proto.String(p.Name), + Value: new(pb.PropertyValue), + Multiple: proto.Bool(p.Multiple), + } + switch v := p.Value.(type) { + case int64: + x.Value.Int64Value = proto.Int64(v) + case bool: + x.Value.BooleanValue = proto.Bool(v) + case string: + x.Value.StringValue = proto.String(v) + if p.NoIndex { + x.Meaning = pb.Property_TEXT.Enum() + } + case float64: + x.Value.DoubleValue = proto.Float64(v) + case *Key: + if v != nil { + x.Value.Referencevalue = keyToReferenceValue(defaultAppID, v) + } + case time.Time: + if v.Before(minTime) || v.After(maxTime) { + return nil, fmt.Errorf("datastore: time value out of range") + } + x.Value.Int64Value = proto.Int64(toUnixMicro(v)) + x.Meaning = pb.Property_GD_WHEN.Enum() + case appengine.BlobKey: + x.Value.StringValue = proto.String(string(v)) + x.Meaning = pb.Property_BLOBKEY.Enum() + case appengine.GeoPoint: + if !v.Valid() { + return nil, fmt.Errorf("datastore: invalid GeoPoint value") + } + // NOTE: Strangely, latitude maps to X, longitude to Y. + x.Value.Pointvalue = &pb.PropertyValue_PointValue{X: &v.Lat, Y: &v.Lng} + x.Meaning = pb.Property_GEORSS_POINT.Enum() + case []byte: + x.Value.StringValue = proto.String(string(v)) + x.Meaning = pb.Property_BLOB.Enum() + if !p.NoIndex { + return nil, fmt.Errorf("datastore: cannot index a []byte valued Property with Name %q", p.Name) + } + case ByteString: + x.Value.StringValue = proto.String(string(v)) + x.Meaning = pb.Property_BYTESTRING.Enum() + default: + if p.Value != nil { + return nil, fmt.Errorf("datastore: invalid Value type for a Property with Name %q", p.Name) + } + } + + if p.NoIndex { + e.RawProperty = append(e.RawProperty, x) + } else { + e.Property = append(e.Property, x) + if len(e.Property) > maxIndexedProperties { + return nil, errors.New("datastore: too many indexed properties") + } + } + } + return e, nil +} + +// isEmptyValue is taken from the encoding/json package in the standard library. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + // TODO(perfomance): Only reflect.String needed, other property types are not supported (copy/paste from json package) + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + // TODO(perfomance): Uint* are unsupported property types - should be removed (copy/paste from json package) + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflect.Struct: + switch x := v.Interface().(type) { + case time.Time: + return x.IsZero() + } + } + return false +} diff --git a/vendor/google.golang.org/appengine/datastore/transaction.go b/vendor/google.golang.org/appengine/datastore/transaction.go new file mode 100644 index 000000000000..2ae8428f856a --- /dev/null +++ b/vendor/google.golang.org/appengine/datastore/transaction.go @@ -0,0 +1,96 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package datastore + +import ( + "errors" + + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/datastore" +) + +func init() { + internal.RegisterTransactionSetter(func(x *pb.Query, t *pb.Transaction) { + x.Transaction = t + }) + internal.RegisterTransactionSetter(func(x *pb.GetRequest, t *pb.Transaction) { + x.Transaction = t + }) + internal.RegisterTransactionSetter(func(x *pb.PutRequest, t *pb.Transaction) { + x.Transaction = t + }) + internal.RegisterTransactionSetter(func(x *pb.DeleteRequest, t *pb.Transaction) { + x.Transaction = t + }) +} + +// ErrConcurrentTransaction is returned when a transaction is rolled back due +// to a conflict with a concurrent transaction. +var ErrConcurrentTransaction = errors.New("datastore: concurrent transaction") + +// RunInTransaction runs f in a transaction. It calls f with a transaction +// context tc that f should use for all App Engine operations. +// +// If f returns nil, RunInTransaction attempts to commit the transaction, +// returning nil if it succeeds. If the commit fails due to a conflicting +// transaction, RunInTransaction retries f, each time with a new transaction +// context. It gives up and returns ErrConcurrentTransaction after three +// failed attempts. The number of attempts can be configured by specifying +// TransactionOptions.Attempts. +// +// If f returns non-nil, then any datastore changes will not be applied and +// RunInTransaction returns that same error. The function f is not retried. +// +// Note that when f returns, the transaction is not yet committed. Calling code +// must be careful not to assume that any of f's changes have been committed +// until RunInTransaction returns nil. +// +// Since f may be called multiple times, f should usually be idempotent. +// datastore.Get is not idempotent when unmarshaling slice fields. +// +// Nested transactions are not supported; c may not be a transaction context. +func RunInTransaction(c context.Context, f func(tc context.Context) error, opts *TransactionOptions) error { + xg := false + if opts != nil { + xg = opts.XG + } + readOnly := false + if opts != nil { + readOnly = opts.ReadOnly + } + attempts := 3 + if opts != nil && opts.Attempts > 0 { + attempts = opts.Attempts + } + var t *pb.Transaction + var err error + for i := 0; i < attempts; i++ { + if t, err = internal.RunTransactionOnce(c, f, xg, readOnly, t); err != internal.ErrConcurrentTransaction { + return err + } + } + return ErrConcurrentTransaction +} + +// TransactionOptions are the options for running a transaction. +type TransactionOptions struct { + // XG is whether the transaction can cross multiple entity groups. In + // comparison, a single group transaction is one where all datastore keys + // used have the same root key. Note that cross group transactions do not + // have the same behavior as single group transactions. In particular, it + // is much more likely to see partially applied transactions in different + // entity groups, in global queries. + // It is valid to set XG to true even if the transaction is within a + // single entity group. + XG bool + // Attempts controls the number of retries to perform when commits fail + // due to a conflicting transaction. If omitted, it defaults to 3. + Attempts int + // ReadOnly controls whether the transaction is a read only transaction. + // Read only transactions are potentially more efficient. + ReadOnly bool +} diff --git a/vendor/google.golang.org/appengine/errors.go b/vendor/google.golang.org/appengine/errors.go new file mode 100644 index 000000000000..16d0772e2a46 --- /dev/null +++ b/vendor/google.golang.org/appengine/errors.go @@ -0,0 +1,46 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// This file provides error functions for common API failure modes. + +package appengine + +import ( + "fmt" + + "google.golang.org/appengine/internal" +) + +// IsOverQuota reports whether err represents an API call failure +// due to insufficient available quota. +func IsOverQuota(err error) bool { + callErr, ok := err.(*internal.CallError) + return ok && callErr.Code == 4 +} + +// MultiError is returned by batch operations when there are errors with +// particular elements. Errors will be in a one-to-one correspondence with +// the input elements; successful elements will have a nil entry. +type MultiError []error + +func (m MultiError) Error() string { + s, n := "", 0 + for _, e := range m { + if e != nil { + if n == 0 { + s = e.Error() + } + n++ + } + } + switch n { + case 0: + return "(0 errors)" + case 1: + return s + case 2: + return s + " (and 1 other error)" + } + return fmt.Sprintf("%s (and %d other errors)", s, n-1) +} diff --git a/vendor/google.golang.org/appengine/go.mod b/vendor/google.golang.org/appengine/go.mod new file mode 100644 index 000000000000..f449359d2f85 --- /dev/null +++ b/vendor/google.golang.org/appengine/go.mod @@ -0,0 +1,7 @@ +module google.golang.org/appengine + +require ( + github.com/golang/protobuf v1.2.0 + golang.org/x/net v0.0.0-20180724234803-3673e40ba225 + golang.org/x/text v0.3.0 +) diff --git a/vendor/google.golang.org/appengine/go.sum b/vendor/google.golang.org/appengine/go.sum new file mode 100644 index 000000000000..1a221c0896a5 --- /dev/null +++ b/vendor/google.golang.org/appengine/go.sum @@ -0,0 +1,6 @@ +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225 h1:kNX+jCowfMYzvlSvJu5pQWEmyWFrBXJ3PBy10xKMXK8= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/google.golang.org/appengine/identity.go b/vendor/google.golang.org/appengine/identity.go new file mode 100644 index 000000000000..b8dcf8f36198 --- /dev/null +++ b/vendor/google.golang.org/appengine/identity.go @@ -0,0 +1,142 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package appengine + +import ( + "time" + + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/app_identity" + modpb "google.golang.org/appengine/internal/modules" +) + +// AppID returns the application ID for the current application. +// The string will be a plain application ID (e.g. "appid"), with a +// domain prefix for custom domain deployments (e.g. "example.com:appid"). +func AppID(c context.Context) string { return internal.AppID(c) } + +// DefaultVersionHostname returns the standard hostname of the default version +// of the current application (e.g. "my-app.appspot.com"). This is suitable for +// use in constructing URLs. +func DefaultVersionHostname(c context.Context) string { + return internal.DefaultVersionHostname(c) +} + +// ModuleName returns the module name of the current instance. +func ModuleName(c context.Context) string { + return internal.ModuleName(c) +} + +// ModuleHostname returns a hostname of a module instance. +// If module is the empty string, it refers to the module of the current instance. +// If version is empty, it refers to the version of the current instance if valid, +// or the default version of the module of the current instance. +// If instance is empty, ModuleHostname returns the load-balancing hostname. +func ModuleHostname(c context.Context, module, version, instance string) (string, error) { + req := &modpb.GetHostnameRequest{} + if module != "" { + req.Module = &module + } + if version != "" { + req.Version = &version + } + if instance != "" { + req.Instance = &instance + } + res := &modpb.GetHostnameResponse{} + if err := internal.Call(c, "modules", "GetHostname", req, res); err != nil { + return "", err + } + return *res.Hostname, nil +} + +// VersionID returns the version ID for the current application. +// It will be of the form "X.Y", where X is specified in app.yaml, +// and Y is a number generated when each version of the app is uploaded. +// It does not include a module name. +func VersionID(c context.Context) string { return internal.VersionID(c) } + +// InstanceID returns a mostly-unique identifier for this instance. +func InstanceID() string { return internal.InstanceID() } + +// Datacenter returns an identifier for the datacenter that the instance is running in. +func Datacenter(c context.Context) string { return internal.Datacenter(c) } + +// ServerSoftware returns the App Engine release version. +// In production, it looks like "Google App Engine/X.Y.Z". +// In the development appserver, it looks like "Development/X.Y". +func ServerSoftware() string { return internal.ServerSoftware() } + +// RequestID returns a string that uniquely identifies the request. +func RequestID(c context.Context) string { return internal.RequestID(c) } + +// AccessToken generates an OAuth2 access token for the specified scopes on +// behalf of service account of this application. This token will expire after +// the returned time. +func AccessToken(c context.Context, scopes ...string) (token string, expiry time.Time, err error) { + req := &pb.GetAccessTokenRequest{Scope: scopes} + res := &pb.GetAccessTokenResponse{} + + err = internal.Call(c, "app_identity_service", "GetAccessToken", req, res) + if err != nil { + return "", time.Time{}, err + } + return res.GetAccessToken(), time.Unix(res.GetExpirationTime(), 0), nil +} + +// Certificate represents a public certificate for the app. +type Certificate struct { + KeyName string + Data []byte // PEM-encoded X.509 certificate +} + +// PublicCertificates retrieves the public certificates for the app. +// They can be used to verify a signature returned by SignBytes. +func PublicCertificates(c context.Context) ([]Certificate, error) { + req := &pb.GetPublicCertificateForAppRequest{} + res := &pb.GetPublicCertificateForAppResponse{} + if err := internal.Call(c, "app_identity_service", "GetPublicCertificatesForApp", req, res); err != nil { + return nil, err + } + var cs []Certificate + for _, pc := range res.PublicCertificateList { + cs = append(cs, Certificate{ + KeyName: pc.GetKeyName(), + Data: []byte(pc.GetX509CertificatePem()), + }) + } + return cs, nil +} + +// ServiceAccount returns a string representing the service account name, in +// the form of an email address (typically app_id@appspot.gserviceaccount.com). +func ServiceAccount(c context.Context) (string, error) { + req := &pb.GetServiceAccountNameRequest{} + res := &pb.GetServiceAccountNameResponse{} + + err := internal.Call(c, "app_identity_service", "GetServiceAccountName", req, res) + if err != nil { + return "", err + } + return res.GetServiceAccountName(), err +} + +// SignBytes signs bytes using a private key unique to your application. +func SignBytes(c context.Context, bytes []byte) (keyName string, signature []byte, err error) { + req := &pb.SignForAppRequest{BytesToSign: bytes} + res := &pb.SignForAppResponse{} + + if err := internal.Call(c, "app_identity_service", "SignForApp", req, res); err != nil { + return "", nil, err + } + return res.GetKeyName(), res.GetSignatureBytes(), nil +} + +func init() { + internal.RegisterErrorCodeMap("app_identity_service", pb.AppIdentityServiceError_ErrorCode_name) + internal.RegisterErrorCodeMap("modules", modpb.ModulesServiceError_ErrorCode_name) +} diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go new file mode 100644 index 000000000000..bbc1cb9c3455 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/api.go @@ -0,0 +1,671 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build !appengine + +package internal + +import ( + "bytes" + "errors" + "fmt" + "io/ioutil" + "log" + "net" + "net/http" + "net/url" + "os" + "runtime" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/golang/protobuf/proto" + netcontext "golang.org/x/net/context" + + basepb "google.golang.org/appengine/internal/base" + logpb "google.golang.org/appengine/internal/log" + remotepb "google.golang.org/appengine/internal/remote_api" +) + +const ( + apiPath = "/rpc_http" + defaultTicketSuffix = "/default.20150612t184001.0" +) + +var ( + // Incoming headers. + ticketHeader = http.CanonicalHeaderKey("X-AppEngine-API-Ticket") + dapperHeader = http.CanonicalHeaderKey("X-Google-DapperTraceInfo") + traceHeader = http.CanonicalHeaderKey("X-Cloud-Trace-Context") + curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace") + userIPHeader = http.CanonicalHeaderKey("X-AppEngine-User-IP") + remoteAddrHeader = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr") + + // Outgoing headers. + apiEndpointHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint") + apiEndpointHeaderValue = []string{"app-engine-apis"} + apiMethodHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Method") + apiMethodHeaderValue = []string{"/VMRemoteAPI.CallRemoteAPI"} + apiDeadlineHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Deadline") + apiContentType = http.CanonicalHeaderKey("Content-Type") + apiContentTypeValue = []string{"application/octet-stream"} + logFlushHeader = http.CanonicalHeaderKey("X-AppEngine-Log-Flush-Count") + + apiHTTPClient = &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: limitDial, + }, + } + + defaultTicketOnce sync.Once + defaultTicket string + backgroundContextOnce sync.Once + backgroundContext netcontext.Context +) + +func apiURL() *url.URL { + host, port := "appengine.googleapis.internal", "10001" + if h := os.Getenv("API_HOST"); h != "" { + host = h + } + if p := os.Getenv("API_PORT"); p != "" { + port = p + } + return &url.URL{ + Scheme: "http", + Host: host + ":" + port, + Path: apiPath, + } +} + +func handleHTTP(w http.ResponseWriter, r *http.Request) { + c := &context{ + req: r, + outHeader: w.Header(), + apiURL: apiURL(), + } + r = r.WithContext(withContext(r.Context(), c)) + c.req = r + + stopFlushing := make(chan int) + + // Patch up RemoteAddr so it looks reasonable. + if addr := r.Header.Get(userIPHeader); addr != "" { + r.RemoteAddr = addr + } else if addr = r.Header.Get(remoteAddrHeader); addr != "" { + r.RemoteAddr = addr + } else { + // Should not normally reach here, but pick a sensible default anyway. + r.RemoteAddr = "127.0.0.1" + } + // The address in the headers will most likely be of these forms: + // 123.123.123.123 + // 2001:db8::1 + // net/http.Request.RemoteAddr is specified to be in "IP:port" form. + if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil { + // Assume the remote address is only a host; add a default port. + r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80") + } + + // Start goroutine responsible for flushing app logs. + // This is done after adding c to ctx.m (and stopped before removing it) + // because flushing logs requires making an API call. + go c.logFlusher(stopFlushing) + + executeRequestSafely(c, r) + c.outHeader = nil // make sure header changes aren't respected any more + + stopFlushing <- 1 // any logging beyond this point will be dropped + + // Flush any pending logs asynchronously. + c.pendingLogs.Lock() + flushes := c.pendingLogs.flushes + if len(c.pendingLogs.lines) > 0 { + flushes++ + } + c.pendingLogs.Unlock() + flushed := make(chan struct{}) + go func() { + defer close(flushed) + // Force a log flush, because with very short requests we + // may not ever flush logs. + c.flushLog(true) + }() + w.Header().Set(logFlushHeader, strconv.Itoa(flushes)) + + // Avoid nil Write call if c.Write is never called. + if c.outCode != 0 { + w.WriteHeader(c.outCode) + } + if c.outBody != nil { + w.Write(c.outBody) + } + // Wait for the last flush to complete before returning, + // otherwise the security ticket will not be valid. + <-flushed +} + +func executeRequestSafely(c *context, r *http.Request) { + defer func() { + if x := recover(); x != nil { + logf(c, 4, "%s", renderPanic(x)) // 4 == critical + c.outCode = 500 + } + }() + + http.DefaultServeMux.ServeHTTP(c, r) +} + +func renderPanic(x interface{}) string { + buf := make([]byte, 16<<10) // 16 KB should be plenty + buf = buf[:runtime.Stack(buf, false)] + + // Remove the first few stack frames: + // this func + // the recover closure in the caller + // That will root the stack trace at the site of the panic. + const ( + skipStart = "internal.renderPanic" + skipFrames = 2 + ) + start := bytes.Index(buf, []byte(skipStart)) + p := start + for i := 0; i < skipFrames*2 && p+1 < len(buf); i++ { + p = bytes.IndexByte(buf[p+1:], '\n') + p + 1 + if p < 0 { + break + } + } + if p >= 0 { + // buf[start:p+1] is the block to remove. + // Copy buf[p+1:] over buf[start:] and shrink buf. + copy(buf[start:], buf[p+1:]) + buf = buf[:len(buf)-(p+1-start)] + } + + // Add panic heading. + head := fmt.Sprintf("panic: %v\n\n", x) + if len(head) > len(buf) { + // Extremely unlikely to happen. + return head + } + copy(buf[len(head):], buf) + copy(buf, head) + + return string(buf) +} + +// context represents the context of an in-flight HTTP request. +// It implements the appengine.Context and http.ResponseWriter interfaces. +type context struct { + req *http.Request + + outCode int + outHeader http.Header + outBody []byte + + pendingLogs struct { + sync.Mutex + lines []*logpb.UserAppLogLine + flushes int + } + + apiURL *url.URL +} + +var contextKey = "holds a *context" + +// jointContext joins two contexts in a superficial way. +// It takes values and timeouts from a base context, and only values from another context. +type jointContext struct { + base netcontext.Context + valuesOnly netcontext.Context +} + +func (c jointContext) Deadline() (time.Time, bool) { + return c.base.Deadline() +} + +func (c jointContext) Done() <-chan struct{} { + return c.base.Done() +} + +func (c jointContext) Err() error { + return c.base.Err() +} + +func (c jointContext) Value(key interface{}) interface{} { + if val := c.base.Value(key); val != nil { + return val + } + return c.valuesOnly.Value(key) +} + +// fromContext returns the App Engine context or nil if ctx is not +// derived from an App Engine context. +func fromContext(ctx netcontext.Context) *context { + c, _ := ctx.Value(&contextKey).(*context) + return c +} + +func withContext(parent netcontext.Context, c *context) netcontext.Context { + ctx := netcontext.WithValue(parent, &contextKey, c) + if ns := c.req.Header.Get(curNamespaceHeader); ns != "" { + ctx = withNamespace(ctx, ns) + } + return ctx +} + +func toContext(c *context) netcontext.Context { + return withContext(netcontext.Background(), c) +} + +func IncomingHeaders(ctx netcontext.Context) http.Header { + if c := fromContext(ctx); c != nil { + return c.req.Header + } + return nil +} + +func ReqContext(req *http.Request) netcontext.Context { + return req.Context() +} + +func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context { + return jointContext{ + base: parent, + valuesOnly: req.Context(), + } +} + +// DefaultTicket returns a ticket used for background context or dev_appserver. +func DefaultTicket() string { + defaultTicketOnce.Do(func() { + if IsDevAppServer() { + defaultTicket = "testapp" + defaultTicketSuffix + return + } + appID := partitionlessAppID() + escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1) + majVersion := VersionID(nil) + if i := strings.Index(majVersion, "."); i > 0 { + majVersion = majVersion[:i] + } + defaultTicket = fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID()) + }) + return defaultTicket +} + +func BackgroundContext() netcontext.Context { + backgroundContextOnce.Do(func() { + // Compute background security ticket. + ticket := DefaultTicket() + + c := &context{ + req: &http.Request{ + Header: http.Header{ + ticketHeader: []string{ticket}, + }, + }, + apiURL: apiURL(), + } + backgroundContext = toContext(c) + + // TODO(dsymonds): Wire up the shutdown handler to do a final flush. + go c.logFlusher(make(chan int)) + }) + + return backgroundContext +} + +// RegisterTestRequest registers the HTTP request req for testing, such that +// any API calls are sent to the provided URL. It returns a closure to delete +// the registration. +// It should only be used by aetest package. +func RegisterTestRequest(req *http.Request, apiURL *url.URL, decorate func(netcontext.Context) netcontext.Context) (*http.Request, func()) { + c := &context{ + req: req, + apiURL: apiURL, + } + ctx := withContext(decorate(req.Context()), c) + req = req.WithContext(ctx) + c.req = req + return req, func() {} +} + +var errTimeout = &CallError{ + Detail: "Deadline exceeded", + Code: int32(remotepb.RpcError_CANCELLED), + Timeout: true, +} + +func (c *context) Header() http.Header { return c.outHeader } + +// Copied from $GOROOT/src/pkg/net/http/transfer.go. Some response status +// codes do not permit a response body (nor response entity headers such as +// Content-Length, Content-Type, etc). +func bodyAllowedForStatus(status int) bool { + switch { + case status >= 100 && status <= 199: + return false + case status == 204: + return false + case status == 304: + return false + } + return true +} + +func (c *context) Write(b []byte) (int, error) { + if c.outCode == 0 { + c.WriteHeader(http.StatusOK) + } + if len(b) > 0 && !bodyAllowedForStatus(c.outCode) { + return 0, http.ErrBodyNotAllowed + } + c.outBody = append(c.outBody, b...) + return len(b), nil +} + +func (c *context) WriteHeader(code int) { + if c.outCode != 0 { + logf(c, 3, "WriteHeader called multiple times on request.") // error level + return + } + c.outCode = code +} + +func (c *context) post(body []byte, timeout time.Duration) (b []byte, err error) { + hreq := &http.Request{ + Method: "POST", + URL: c.apiURL, + Header: http.Header{ + apiEndpointHeader: apiEndpointHeaderValue, + apiMethodHeader: apiMethodHeaderValue, + apiContentType: apiContentTypeValue, + apiDeadlineHeader: []string{strconv.FormatFloat(timeout.Seconds(), 'f', -1, 64)}, + }, + Body: ioutil.NopCloser(bytes.NewReader(body)), + ContentLength: int64(len(body)), + Host: c.apiURL.Host, + } + if info := c.req.Header.Get(dapperHeader); info != "" { + hreq.Header.Set(dapperHeader, info) + } + if info := c.req.Header.Get(traceHeader); info != "" { + hreq.Header.Set(traceHeader, info) + } + + tr := apiHTTPClient.Transport.(*http.Transport) + + var timedOut int32 // atomic; set to 1 if timed out + t := time.AfterFunc(timeout, func() { + atomic.StoreInt32(&timedOut, 1) + tr.CancelRequest(hreq) + }) + defer t.Stop() + defer func() { + // Check if timeout was exceeded. + if atomic.LoadInt32(&timedOut) != 0 { + err = errTimeout + } + }() + + hresp, err := apiHTTPClient.Do(hreq) + if err != nil { + return nil, &CallError{ + Detail: fmt.Sprintf("service bridge HTTP failed: %v", err), + Code: int32(remotepb.RpcError_UNKNOWN), + } + } + defer hresp.Body.Close() + hrespBody, err := ioutil.ReadAll(hresp.Body) + if hresp.StatusCode != 200 { + return nil, &CallError{ + Detail: fmt.Sprintf("service bridge returned HTTP %d (%q)", hresp.StatusCode, hrespBody), + Code: int32(remotepb.RpcError_UNKNOWN), + } + } + if err != nil { + return nil, &CallError{ + Detail: fmt.Sprintf("service bridge response bad: %v", err), + Code: int32(remotepb.RpcError_UNKNOWN), + } + } + return hrespBody, nil +} + +func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error { + if ns := NamespaceFromContext(ctx); ns != "" { + if fn, ok := NamespaceMods[service]; ok { + fn(in, ns) + } + } + + if f, ctx, ok := callOverrideFromContext(ctx); ok { + return f(ctx, service, method, in, out) + } + + // Handle already-done contexts quickly. + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + c := fromContext(ctx) + if c == nil { + // Give a good error message rather than a panic lower down. + return errNotAppEngineContext + } + + // Apply transaction modifications if we're in a transaction. + if t := transactionFromContext(ctx); t != nil { + if t.finished { + return errors.New("transaction context has expired") + } + applyTransaction(in, &t.transaction) + } + + // Default RPC timeout is 60s. + timeout := 60 * time.Second + if deadline, ok := ctx.Deadline(); ok { + timeout = deadline.Sub(time.Now()) + } + + data, err := proto.Marshal(in) + if err != nil { + return err + } + + ticket := c.req.Header.Get(ticketHeader) + // Use a test ticket under test environment. + if ticket == "" { + if appid := ctx.Value(&appIDOverrideKey); appid != nil { + ticket = appid.(string) + defaultTicketSuffix + } + } + // Fall back to use background ticket when the request ticket is not available in Flex or dev_appserver. + if ticket == "" { + ticket = DefaultTicket() + } + req := &remotepb.Request{ + ServiceName: &service, + Method: &method, + Request: data, + RequestId: &ticket, + } + hreqBody, err := proto.Marshal(req) + if err != nil { + return err + } + + hrespBody, err := c.post(hreqBody, timeout) + if err != nil { + return err + } + + res := &remotepb.Response{} + if err := proto.Unmarshal(hrespBody, res); err != nil { + return err + } + if res.RpcError != nil { + ce := &CallError{ + Detail: res.RpcError.GetDetail(), + Code: *res.RpcError.Code, + } + switch remotepb.RpcError_ErrorCode(ce.Code) { + case remotepb.RpcError_CANCELLED, remotepb.RpcError_DEADLINE_EXCEEDED: + ce.Timeout = true + } + return ce + } + if res.ApplicationError != nil { + return &APIError{ + Service: *req.ServiceName, + Detail: res.ApplicationError.GetDetail(), + Code: *res.ApplicationError.Code, + } + } + if res.Exception != nil || res.JavaException != nil { + // This shouldn't happen, but let's be defensive. + return &CallError{ + Detail: "service bridge returned exception", + Code: int32(remotepb.RpcError_UNKNOWN), + } + } + return proto.Unmarshal(res.Response, out) +} + +func (c *context) Request() *http.Request { + return c.req +} + +func (c *context) addLogLine(ll *logpb.UserAppLogLine) { + // Truncate long log lines. + // TODO(dsymonds): Check if this is still necessary. + const lim = 8 << 10 + if len(*ll.Message) > lim { + suffix := fmt.Sprintf("...(length %d)", len(*ll.Message)) + ll.Message = proto.String((*ll.Message)[:lim-len(suffix)] + suffix) + } + + c.pendingLogs.Lock() + c.pendingLogs.lines = append(c.pendingLogs.lines, ll) + c.pendingLogs.Unlock() +} + +var logLevelName = map[int64]string{ + 0: "DEBUG", + 1: "INFO", + 2: "WARNING", + 3: "ERROR", + 4: "CRITICAL", +} + +func logf(c *context, level int64, format string, args ...interface{}) { + if c == nil { + panic("not an App Engine context") + } + s := fmt.Sprintf(format, args...) + s = strings.TrimRight(s, "\n") // Remove any trailing newline characters. + c.addLogLine(&logpb.UserAppLogLine{ + TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3), + Level: &level, + Message: &s, + }) + // Only duplicate log to stderr if not running on App Engine second generation + if !IsSecondGen() { + log.Print(logLevelName[level] + ": " + s) + } +} + +// flushLog attempts to flush any pending logs to the appserver. +// It should not be called concurrently. +func (c *context) flushLog(force bool) (flushed bool) { + c.pendingLogs.Lock() + // Grab up to 30 MB. We can get away with up to 32 MB, but let's be cautious. + n, rem := 0, 30<<20 + for ; n < len(c.pendingLogs.lines); n++ { + ll := c.pendingLogs.lines[n] + // Each log line will require about 3 bytes of overhead. + nb := proto.Size(ll) + 3 + if nb > rem { + break + } + rem -= nb + } + lines := c.pendingLogs.lines[:n] + c.pendingLogs.lines = c.pendingLogs.lines[n:] + c.pendingLogs.Unlock() + + if len(lines) == 0 && !force { + // Nothing to flush. + return false + } + + rescueLogs := false + defer func() { + if rescueLogs { + c.pendingLogs.Lock() + c.pendingLogs.lines = append(lines, c.pendingLogs.lines...) + c.pendingLogs.Unlock() + } + }() + + buf, err := proto.Marshal(&logpb.UserAppLogGroup{ + LogLine: lines, + }) + if err != nil { + log.Printf("internal.flushLog: marshaling UserAppLogGroup: %v", err) + rescueLogs = true + return false + } + + req := &logpb.FlushRequest{ + Logs: buf, + } + res := &basepb.VoidProto{} + c.pendingLogs.Lock() + c.pendingLogs.flushes++ + c.pendingLogs.Unlock() + if err := Call(toContext(c), "logservice", "Flush", req, res); err != nil { + log.Printf("internal.flushLog: Flush RPC: %v", err) + rescueLogs = true + return false + } + return true +} + +const ( + // Log flushing parameters. + flushInterval = 1 * time.Second + forceFlushInterval = 60 * time.Second +) + +func (c *context) logFlusher(stop <-chan int) { + lastFlush := time.Now() + tick := time.NewTicker(flushInterval) + for { + select { + case <-stop: + // Request finished. + tick.Stop() + return + case <-tick.C: + force := time.Now().Sub(lastFlush) > forceFlushInterval + if c.flushLog(force) { + lastFlush = time.Now() + } + } + } +} + +func ContextForTesting(req *http.Request) netcontext.Context { + return toContext(&context{req: req}) +} diff --git a/vendor/google.golang.org/appengine/internal/api_classic.go b/vendor/google.golang.org/appengine/internal/api_classic.go new file mode 100644 index 000000000000..f0f40b2e35c2 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/api_classic.go @@ -0,0 +1,169 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build appengine + +package internal + +import ( + "errors" + "fmt" + "net/http" + "time" + + "appengine" + "appengine_internal" + basepb "appengine_internal/base" + + "github.com/golang/protobuf/proto" + netcontext "golang.org/x/net/context" +) + +var contextKey = "holds an appengine.Context" + +// fromContext returns the App Engine context or nil if ctx is not +// derived from an App Engine context. +func fromContext(ctx netcontext.Context) appengine.Context { + c, _ := ctx.Value(&contextKey).(appengine.Context) + return c +} + +// This is only for classic App Engine adapters. +func ClassicContextFromContext(ctx netcontext.Context) (appengine.Context, error) { + c := fromContext(ctx) + if c == nil { + return nil, errNotAppEngineContext + } + return c, nil +} + +func withContext(parent netcontext.Context, c appengine.Context) netcontext.Context { + ctx := netcontext.WithValue(parent, &contextKey, c) + + s := &basepb.StringProto{} + c.Call("__go__", "GetNamespace", &basepb.VoidProto{}, s, nil) + if ns := s.GetValue(); ns != "" { + ctx = NamespacedContext(ctx, ns) + } + + return ctx +} + +func IncomingHeaders(ctx netcontext.Context) http.Header { + if c := fromContext(ctx); c != nil { + if req, ok := c.Request().(*http.Request); ok { + return req.Header + } + } + return nil +} + +func ReqContext(req *http.Request) netcontext.Context { + return WithContext(netcontext.Background(), req) +} + +func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context { + c := appengine.NewContext(req) + return withContext(parent, c) +} + +type testingContext struct { + appengine.Context + + req *http.Request +} + +func (t *testingContext) FullyQualifiedAppID() string { return "dev~testcontext" } +func (t *testingContext) Call(service, method string, _, _ appengine_internal.ProtoMessage, _ *appengine_internal.CallOptions) error { + if service == "__go__" && method == "GetNamespace" { + return nil + } + return fmt.Errorf("testingContext: unsupported Call") +} +func (t *testingContext) Request() interface{} { return t.req } + +func ContextForTesting(req *http.Request) netcontext.Context { + return withContext(netcontext.Background(), &testingContext{req: req}) +} + +func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error { + if ns := NamespaceFromContext(ctx); ns != "" { + if fn, ok := NamespaceMods[service]; ok { + fn(in, ns) + } + } + + if f, ctx, ok := callOverrideFromContext(ctx); ok { + return f(ctx, service, method, in, out) + } + + // Handle already-done contexts quickly. + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + c := fromContext(ctx) + if c == nil { + // Give a good error message rather than a panic lower down. + return errNotAppEngineContext + } + + // Apply transaction modifications if we're in a transaction. + if t := transactionFromContext(ctx); t != nil { + if t.finished { + return errors.New("transaction context has expired") + } + applyTransaction(in, &t.transaction) + } + + var opts *appengine_internal.CallOptions + if d, ok := ctx.Deadline(); ok { + opts = &appengine_internal.CallOptions{ + Timeout: d.Sub(time.Now()), + } + } + + err := c.Call(service, method, in, out, opts) + switch v := err.(type) { + case *appengine_internal.APIError: + return &APIError{ + Service: v.Service, + Detail: v.Detail, + Code: v.Code, + } + case *appengine_internal.CallError: + return &CallError{ + Detail: v.Detail, + Code: v.Code, + Timeout: v.Timeout, + } + } + return err +} + +func handleHTTP(w http.ResponseWriter, r *http.Request) { + panic("handleHTTP called; this should be impossible") +} + +func logf(c appengine.Context, level int64, format string, args ...interface{}) { + var fn func(format string, args ...interface{}) + switch level { + case 0: + fn = c.Debugf + case 1: + fn = c.Infof + case 2: + fn = c.Warningf + case 3: + fn = c.Errorf + case 4: + fn = c.Criticalf + default: + // This shouldn't happen. + fn = c.Criticalf + } + fn(format, args...) +} diff --git a/vendor/google.golang.org/appengine/internal/api_common.go b/vendor/google.golang.org/appengine/internal/api_common.go new file mode 100644 index 000000000000..e0c0b214b724 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/api_common.go @@ -0,0 +1,123 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package internal + +import ( + "errors" + "os" + + "github.com/golang/protobuf/proto" + netcontext "golang.org/x/net/context" +) + +var errNotAppEngineContext = errors.New("not an App Engine context") + +type CallOverrideFunc func(ctx netcontext.Context, service, method string, in, out proto.Message) error + +var callOverrideKey = "holds []CallOverrideFunc" + +func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.Context { + // We avoid appending to any existing call override + // so we don't risk overwriting a popped stack below. + var cofs []CallOverrideFunc + if uf, ok := ctx.Value(&callOverrideKey).([]CallOverrideFunc); ok { + cofs = append(cofs, uf...) + } + cofs = append(cofs, f) + return netcontext.WithValue(ctx, &callOverrideKey, cofs) +} + +func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netcontext.Context, bool) { + cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc) + if len(cofs) == 0 { + return nil, nil, false + } + // We found a list of overrides; grab the last, and reconstitute a + // context that will hide it. + f := cofs[len(cofs)-1] + ctx = netcontext.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1]) + return f, ctx, true +} + +type logOverrideFunc func(level int64, format string, args ...interface{}) + +var logOverrideKey = "holds a logOverrideFunc" + +func WithLogOverride(ctx netcontext.Context, f logOverrideFunc) netcontext.Context { + return netcontext.WithValue(ctx, &logOverrideKey, f) +} + +var appIDOverrideKey = "holds a string, being the full app ID" + +func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context { + return netcontext.WithValue(ctx, &appIDOverrideKey, appID) +} + +var namespaceKey = "holds the namespace string" + +func withNamespace(ctx netcontext.Context, ns string) netcontext.Context { + return netcontext.WithValue(ctx, &namespaceKey, ns) +} + +func NamespaceFromContext(ctx netcontext.Context) string { + // If there's no namespace, return the empty string. + ns, _ := ctx.Value(&namespaceKey).(string) + return ns +} + +// FullyQualifiedAppID returns the fully-qualified application ID. +// This may contain a partition prefix (e.g. "s~" for High Replication apps), +// or a domain prefix (e.g. "example.com:"). +func FullyQualifiedAppID(ctx netcontext.Context) string { + if id, ok := ctx.Value(&appIDOverrideKey).(string); ok { + return id + } + return fullyQualifiedAppID(ctx) +} + +func Logf(ctx netcontext.Context, level int64, format string, args ...interface{}) { + if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok { + f(level, format, args...) + return + } + c := fromContext(ctx) + if c == nil { + panic(errNotAppEngineContext) + } + logf(c, level, format, args...) +} + +// NamespacedContext wraps a Context to support namespaces. +func NamespacedContext(ctx netcontext.Context, namespace string) netcontext.Context { + return withNamespace(ctx, namespace) +} + +// SetTestEnv sets the env variables for testing background ticket in Flex. +func SetTestEnv() func() { + var environ = []struct { + key, value string + }{ + {"GAE_LONG_APP_ID", "my-app-id"}, + {"GAE_MINOR_VERSION", "067924799508853122"}, + {"GAE_MODULE_INSTANCE", "0"}, + {"GAE_MODULE_NAME", "default"}, + {"GAE_MODULE_VERSION", "20150612t184001"}, + } + + for _, v := range environ { + old := os.Getenv(v.key) + os.Setenv(v.key, v.value) + v.value = old + } + return func() { // Restore old environment after the test completes. + for _, v := range environ { + if v.value == "" { + os.Unsetenv(v.key) + continue + } + os.Setenv(v.key, v.value) + } + } +} diff --git a/vendor/google.golang.org/appengine/internal/app_id.go b/vendor/google.golang.org/appengine/internal/app_id.go new file mode 100644 index 000000000000..11df8c07b538 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/app_id.go @@ -0,0 +1,28 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package internal + +import ( + "strings" +) + +func parseFullAppID(appid string) (partition, domain, displayID string) { + if i := strings.Index(appid, "~"); i != -1 { + partition, appid = appid[:i], appid[i+1:] + } + if i := strings.Index(appid, ":"); i != -1 { + domain, appid = appid[:i], appid[i+1:] + } + return partition, domain, appid +} + +// appID returns "appid" or "domain.com:appid". +func appID(fullAppID string) string { + _, dom, dis := parseFullAppID(fullAppID) + if dom != "" { + return dom + ":" + dis + } + return dis +} diff --git a/vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.pb.go b/vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.pb.go new file mode 100644 index 000000000000..9a2ff77ab5d4 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.pb.go @@ -0,0 +1,611 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google.golang.org/appengine/internal/app_identity/app_identity_service.proto + +package app_identity + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type AppIdentityServiceError_ErrorCode int32 + +const ( + AppIdentityServiceError_SUCCESS AppIdentityServiceError_ErrorCode = 0 + AppIdentityServiceError_UNKNOWN_SCOPE AppIdentityServiceError_ErrorCode = 9 + AppIdentityServiceError_BLOB_TOO_LARGE AppIdentityServiceError_ErrorCode = 1000 + AppIdentityServiceError_DEADLINE_EXCEEDED AppIdentityServiceError_ErrorCode = 1001 + AppIdentityServiceError_NOT_A_VALID_APP AppIdentityServiceError_ErrorCode = 1002 + AppIdentityServiceError_UNKNOWN_ERROR AppIdentityServiceError_ErrorCode = 1003 + AppIdentityServiceError_NOT_ALLOWED AppIdentityServiceError_ErrorCode = 1005 + AppIdentityServiceError_NOT_IMPLEMENTED AppIdentityServiceError_ErrorCode = 1006 +) + +var AppIdentityServiceError_ErrorCode_name = map[int32]string{ + 0: "SUCCESS", + 9: "UNKNOWN_SCOPE", + 1000: "BLOB_TOO_LARGE", + 1001: "DEADLINE_EXCEEDED", + 1002: "NOT_A_VALID_APP", + 1003: "UNKNOWN_ERROR", + 1005: "NOT_ALLOWED", + 1006: "NOT_IMPLEMENTED", +} +var AppIdentityServiceError_ErrorCode_value = map[string]int32{ + "SUCCESS": 0, + "UNKNOWN_SCOPE": 9, + "BLOB_TOO_LARGE": 1000, + "DEADLINE_EXCEEDED": 1001, + "NOT_A_VALID_APP": 1002, + "UNKNOWN_ERROR": 1003, + "NOT_ALLOWED": 1005, + "NOT_IMPLEMENTED": 1006, +} + +func (x AppIdentityServiceError_ErrorCode) Enum() *AppIdentityServiceError_ErrorCode { + p := new(AppIdentityServiceError_ErrorCode) + *p = x + return p +} +func (x AppIdentityServiceError_ErrorCode) String() string { + return proto.EnumName(AppIdentityServiceError_ErrorCode_name, int32(x)) +} +func (x *AppIdentityServiceError_ErrorCode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(AppIdentityServiceError_ErrorCode_value, data, "AppIdentityServiceError_ErrorCode") + if err != nil { + return err + } + *x = AppIdentityServiceError_ErrorCode(value) + return nil +} +func (AppIdentityServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{0, 0} +} + +type AppIdentityServiceError struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AppIdentityServiceError) Reset() { *m = AppIdentityServiceError{} } +func (m *AppIdentityServiceError) String() string { return proto.CompactTextString(m) } +func (*AppIdentityServiceError) ProtoMessage() {} +func (*AppIdentityServiceError) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{0} +} +func (m *AppIdentityServiceError) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AppIdentityServiceError.Unmarshal(m, b) +} +func (m *AppIdentityServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AppIdentityServiceError.Marshal(b, m, deterministic) +} +func (dst *AppIdentityServiceError) XXX_Merge(src proto.Message) { + xxx_messageInfo_AppIdentityServiceError.Merge(dst, src) +} +func (m *AppIdentityServiceError) XXX_Size() int { + return xxx_messageInfo_AppIdentityServiceError.Size(m) +} +func (m *AppIdentityServiceError) XXX_DiscardUnknown() { + xxx_messageInfo_AppIdentityServiceError.DiscardUnknown(m) +} + +var xxx_messageInfo_AppIdentityServiceError proto.InternalMessageInfo + +type SignForAppRequest struct { + BytesToSign []byte `protobuf:"bytes,1,opt,name=bytes_to_sign,json=bytesToSign" json:"bytes_to_sign,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SignForAppRequest) Reset() { *m = SignForAppRequest{} } +func (m *SignForAppRequest) String() string { return proto.CompactTextString(m) } +func (*SignForAppRequest) ProtoMessage() {} +func (*SignForAppRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{1} +} +func (m *SignForAppRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SignForAppRequest.Unmarshal(m, b) +} +func (m *SignForAppRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SignForAppRequest.Marshal(b, m, deterministic) +} +func (dst *SignForAppRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignForAppRequest.Merge(dst, src) +} +func (m *SignForAppRequest) XXX_Size() int { + return xxx_messageInfo_SignForAppRequest.Size(m) +} +func (m *SignForAppRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SignForAppRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SignForAppRequest proto.InternalMessageInfo + +func (m *SignForAppRequest) GetBytesToSign() []byte { + if m != nil { + return m.BytesToSign + } + return nil +} + +type SignForAppResponse struct { + KeyName *string `protobuf:"bytes,1,opt,name=key_name,json=keyName" json:"key_name,omitempty"` + SignatureBytes []byte `protobuf:"bytes,2,opt,name=signature_bytes,json=signatureBytes" json:"signature_bytes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SignForAppResponse) Reset() { *m = SignForAppResponse{} } +func (m *SignForAppResponse) String() string { return proto.CompactTextString(m) } +func (*SignForAppResponse) ProtoMessage() {} +func (*SignForAppResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{2} +} +func (m *SignForAppResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SignForAppResponse.Unmarshal(m, b) +} +func (m *SignForAppResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SignForAppResponse.Marshal(b, m, deterministic) +} +func (dst *SignForAppResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignForAppResponse.Merge(dst, src) +} +func (m *SignForAppResponse) XXX_Size() int { + return xxx_messageInfo_SignForAppResponse.Size(m) +} +func (m *SignForAppResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SignForAppResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SignForAppResponse proto.InternalMessageInfo + +func (m *SignForAppResponse) GetKeyName() string { + if m != nil && m.KeyName != nil { + return *m.KeyName + } + return "" +} + +func (m *SignForAppResponse) GetSignatureBytes() []byte { + if m != nil { + return m.SignatureBytes + } + return nil +} + +type GetPublicCertificateForAppRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetPublicCertificateForAppRequest) Reset() { *m = GetPublicCertificateForAppRequest{} } +func (m *GetPublicCertificateForAppRequest) String() string { return proto.CompactTextString(m) } +func (*GetPublicCertificateForAppRequest) ProtoMessage() {} +func (*GetPublicCertificateForAppRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{3} +} +func (m *GetPublicCertificateForAppRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetPublicCertificateForAppRequest.Unmarshal(m, b) +} +func (m *GetPublicCertificateForAppRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetPublicCertificateForAppRequest.Marshal(b, m, deterministic) +} +func (dst *GetPublicCertificateForAppRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetPublicCertificateForAppRequest.Merge(dst, src) +} +func (m *GetPublicCertificateForAppRequest) XXX_Size() int { + return xxx_messageInfo_GetPublicCertificateForAppRequest.Size(m) +} +func (m *GetPublicCertificateForAppRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetPublicCertificateForAppRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetPublicCertificateForAppRequest proto.InternalMessageInfo + +type PublicCertificate struct { + KeyName *string `protobuf:"bytes,1,opt,name=key_name,json=keyName" json:"key_name,omitempty"` + X509CertificatePem *string `protobuf:"bytes,2,opt,name=x509_certificate_pem,json=x509CertificatePem" json:"x509_certificate_pem,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PublicCertificate) Reset() { *m = PublicCertificate{} } +func (m *PublicCertificate) String() string { return proto.CompactTextString(m) } +func (*PublicCertificate) ProtoMessage() {} +func (*PublicCertificate) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{4} +} +func (m *PublicCertificate) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PublicCertificate.Unmarshal(m, b) +} +func (m *PublicCertificate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PublicCertificate.Marshal(b, m, deterministic) +} +func (dst *PublicCertificate) XXX_Merge(src proto.Message) { + xxx_messageInfo_PublicCertificate.Merge(dst, src) +} +func (m *PublicCertificate) XXX_Size() int { + return xxx_messageInfo_PublicCertificate.Size(m) +} +func (m *PublicCertificate) XXX_DiscardUnknown() { + xxx_messageInfo_PublicCertificate.DiscardUnknown(m) +} + +var xxx_messageInfo_PublicCertificate proto.InternalMessageInfo + +func (m *PublicCertificate) GetKeyName() string { + if m != nil && m.KeyName != nil { + return *m.KeyName + } + return "" +} + +func (m *PublicCertificate) GetX509CertificatePem() string { + if m != nil && m.X509CertificatePem != nil { + return *m.X509CertificatePem + } + return "" +} + +type GetPublicCertificateForAppResponse struct { + PublicCertificateList []*PublicCertificate `protobuf:"bytes,1,rep,name=public_certificate_list,json=publicCertificateList" json:"public_certificate_list,omitempty"` + MaxClientCacheTimeInSecond *int64 `protobuf:"varint,2,opt,name=max_client_cache_time_in_second,json=maxClientCacheTimeInSecond" json:"max_client_cache_time_in_second,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetPublicCertificateForAppResponse) Reset() { *m = GetPublicCertificateForAppResponse{} } +func (m *GetPublicCertificateForAppResponse) String() string { return proto.CompactTextString(m) } +func (*GetPublicCertificateForAppResponse) ProtoMessage() {} +func (*GetPublicCertificateForAppResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{5} +} +func (m *GetPublicCertificateForAppResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetPublicCertificateForAppResponse.Unmarshal(m, b) +} +func (m *GetPublicCertificateForAppResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetPublicCertificateForAppResponse.Marshal(b, m, deterministic) +} +func (dst *GetPublicCertificateForAppResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetPublicCertificateForAppResponse.Merge(dst, src) +} +func (m *GetPublicCertificateForAppResponse) XXX_Size() int { + return xxx_messageInfo_GetPublicCertificateForAppResponse.Size(m) +} +func (m *GetPublicCertificateForAppResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetPublicCertificateForAppResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetPublicCertificateForAppResponse proto.InternalMessageInfo + +func (m *GetPublicCertificateForAppResponse) GetPublicCertificateList() []*PublicCertificate { + if m != nil { + return m.PublicCertificateList + } + return nil +} + +func (m *GetPublicCertificateForAppResponse) GetMaxClientCacheTimeInSecond() int64 { + if m != nil && m.MaxClientCacheTimeInSecond != nil { + return *m.MaxClientCacheTimeInSecond + } + return 0 +} + +type GetServiceAccountNameRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetServiceAccountNameRequest) Reset() { *m = GetServiceAccountNameRequest{} } +func (m *GetServiceAccountNameRequest) String() string { return proto.CompactTextString(m) } +func (*GetServiceAccountNameRequest) ProtoMessage() {} +func (*GetServiceAccountNameRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{6} +} +func (m *GetServiceAccountNameRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetServiceAccountNameRequest.Unmarshal(m, b) +} +func (m *GetServiceAccountNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetServiceAccountNameRequest.Marshal(b, m, deterministic) +} +func (dst *GetServiceAccountNameRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetServiceAccountNameRequest.Merge(dst, src) +} +func (m *GetServiceAccountNameRequest) XXX_Size() int { + return xxx_messageInfo_GetServiceAccountNameRequest.Size(m) +} +func (m *GetServiceAccountNameRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetServiceAccountNameRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetServiceAccountNameRequest proto.InternalMessageInfo + +type GetServiceAccountNameResponse struct { + ServiceAccountName *string `protobuf:"bytes,1,opt,name=service_account_name,json=serviceAccountName" json:"service_account_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetServiceAccountNameResponse) Reset() { *m = GetServiceAccountNameResponse{} } +func (m *GetServiceAccountNameResponse) String() string { return proto.CompactTextString(m) } +func (*GetServiceAccountNameResponse) ProtoMessage() {} +func (*GetServiceAccountNameResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{7} +} +func (m *GetServiceAccountNameResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetServiceAccountNameResponse.Unmarshal(m, b) +} +func (m *GetServiceAccountNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetServiceAccountNameResponse.Marshal(b, m, deterministic) +} +func (dst *GetServiceAccountNameResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetServiceAccountNameResponse.Merge(dst, src) +} +func (m *GetServiceAccountNameResponse) XXX_Size() int { + return xxx_messageInfo_GetServiceAccountNameResponse.Size(m) +} +func (m *GetServiceAccountNameResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetServiceAccountNameResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetServiceAccountNameResponse proto.InternalMessageInfo + +func (m *GetServiceAccountNameResponse) GetServiceAccountName() string { + if m != nil && m.ServiceAccountName != nil { + return *m.ServiceAccountName + } + return "" +} + +type GetAccessTokenRequest struct { + Scope []string `protobuf:"bytes,1,rep,name=scope" json:"scope,omitempty"` + ServiceAccountId *int64 `protobuf:"varint,2,opt,name=service_account_id,json=serviceAccountId" json:"service_account_id,omitempty"` + ServiceAccountName *string `protobuf:"bytes,3,opt,name=service_account_name,json=serviceAccountName" json:"service_account_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetAccessTokenRequest) Reset() { *m = GetAccessTokenRequest{} } +func (m *GetAccessTokenRequest) String() string { return proto.CompactTextString(m) } +func (*GetAccessTokenRequest) ProtoMessage() {} +func (*GetAccessTokenRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{8} +} +func (m *GetAccessTokenRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetAccessTokenRequest.Unmarshal(m, b) +} +func (m *GetAccessTokenRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetAccessTokenRequest.Marshal(b, m, deterministic) +} +func (dst *GetAccessTokenRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetAccessTokenRequest.Merge(dst, src) +} +func (m *GetAccessTokenRequest) XXX_Size() int { + return xxx_messageInfo_GetAccessTokenRequest.Size(m) +} +func (m *GetAccessTokenRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetAccessTokenRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetAccessTokenRequest proto.InternalMessageInfo + +func (m *GetAccessTokenRequest) GetScope() []string { + if m != nil { + return m.Scope + } + return nil +} + +func (m *GetAccessTokenRequest) GetServiceAccountId() int64 { + if m != nil && m.ServiceAccountId != nil { + return *m.ServiceAccountId + } + return 0 +} + +func (m *GetAccessTokenRequest) GetServiceAccountName() string { + if m != nil && m.ServiceAccountName != nil { + return *m.ServiceAccountName + } + return "" +} + +type GetAccessTokenResponse struct { + AccessToken *string `protobuf:"bytes,1,opt,name=access_token,json=accessToken" json:"access_token,omitempty"` + ExpirationTime *int64 `protobuf:"varint,2,opt,name=expiration_time,json=expirationTime" json:"expiration_time,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetAccessTokenResponse) Reset() { *m = GetAccessTokenResponse{} } +func (m *GetAccessTokenResponse) String() string { return proto.CompactTextString(m) } +func (*GetAccessTokenResponse) ProtoMessage() {} +func (*GetAccessTokenResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{9} +} +func (m *GetAccessTokenResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetAccessTokenResponse.Unmarshal(m, b) +} +func (m *GetAccessTokenResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetAccessTokenResponse.Marshal(b, m, deterministic) +} +func (dst *GetAccessTokenResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetAccessTokenResponse.Merge(dst, src) +} +func (m *GetAccessTokenResponse) XXX_Size() int { + return xxx_messageInfo_GetAccessTokenResponse.Size(m) +} +func (m *GetAccessTokenResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetAccessTokenResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetAccessTokenResponse proto.InternalMessageInfo + +func (m *GetAccessTokenResponse) GetAccessToken() string { + if m != nil && m.AccessToken != nil { + return *m.AccessToken + } + return "" +} + +func (m *GetAccessTokenResponse) GetExpirationTime() int64 { + if m != nil && m.ExpirationTime != nil { + return *m.ExpirationTime + } + return 0 +} + +type GetDefaultGcsBucketNameRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetDefaultGcsBucketNameRequest) Reset() { *m = GetDefaultGcsBucketNameRequest{} } +func (m *GetDefaultGcsBucketNameRequest) String() string { return proto.CompactTextString(m) } +func (*GetDefaultGcsBucketNameRequest) ProtoMessage() {} +func (*GetDefaultGcsBucketNameRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{10} +} +func (m *GetDefaultGcsBucketNameRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetDefaultGcsBucketNameRequest.Unmarshal(m, b) +} +func (m *GetDefaultGcsBucketNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetDefaultGcsBucketNameRequest.Marshal(b, m, deterministic) +} +func (dst *GetDefaultGcsBucketNameRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetDefaultGcsBucketNameRequest.Merge(dst, src) +} +func (m *GetDefaultGcsBucketNameRequest) XXX_Size() int { + return xxx_messageInfo_GetDefaultGcsBucketNameRequest.Size(m) +} +func (m *GetDefaultGcsBucketNameRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetDefaultGcsBucketNameRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetDefaultGcsBucketNameRequest proto.InternalMessageInfo + +type GetDefaultGcsBucketNameResponse struct { + DefaultGcsBucketName *string `protobuf:"bytes,1,opt,name=default_gcs_bucket_name,json=defaultGcsBucketName" json:"default_gcs_bucket_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetDefaultGcsBucketNameResponse) Reset() { *m = GetDefaultGcsBucketNameResponse{} } +func (m *GetDefaultGcsBucketNameResponse) String() string { return proto.CompactTextString(m) } +func (*GetDefaultGcsBucketNameResponse) ProtoMessage() {} +func (*GetDefaultGcsBucketNameResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{11} +} +func (m *GetDefaultGcsBucketNameResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetDefaultGcsBucketNameResponse.Unmarshal(m, b) +} +func (m *GetDefaultGcsBucketNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetDefaultGcsBucketNameResponse.Marshal(b, m, deterministic) +} +func (dst *GetDefaultGcsBucketNameResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetDefaultGcsBucketNameResponse.Merge(dst, src) +} +func (m *GetDefaultGcsBucketNameResponse) XXX_Size() int { + return xxx_messageInfo_GetDefaultGcsBucketNameResponse.Size(m) +} +func (m *GetDefaultGcsBucketNameResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetDefaultGcsBucketNameResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetDefaultGcsBucketNameResponse proto.InternalMessageInfo + +func (m *GetDefaultGcsBucketNameResponse) GetDefaultGcsBucketName() string { + if m != nil && m.DefaultGcsBucketName != nil { + return *m.DefaultGcsBucketName + } + return "" +} + +func init() { + proto.RegisterType((*AppIdentityServiceError)(nil), "appengine.AppIdentityServiceError") + proto.RegisterType((*SignForAppRequest)(nil), "appengine.SignForAppRequest") + proto.RegisterType((*SignForAppResponse)(nil), "appengine.SignForAppResponse") + proto.RegisterType((*GetPublicCertificateForAppRequest)(nil), "appengine.GetPublicCertificateForAppRequest") + proto.RegisterType((*PublicCertificate)(nil), "appengine.PublicCertificate") + proto.RegisterType((*GetPublicCertificateForAppResponse)(nil), "appengine.GetPublicCertificateForAppResponse") + proto.RegisterType((*GetServiceAccountNameRequest)(nil), "appengine.GetServiceAccountNameRequest") + proto.RegisterType((*GetServiceAccountNameResponse)(nil), "appengine.GetServiceAccountNameResponse") + proto.RegisterType((*GetAccessTokenRequest)(nil), "appengine.GetAccessTokenRequest") + proto.RegisterType((*GetAccessTokenResponse)(nil), "appengine.GetAccessTokenResponse") + proto.RegisterType((*GetDefaultGcsBucketNameRequest)(nil), "appengine.GetDefaultGcsBucketNameRequest") + proto.RegisterType((*GetDefaultGcsBucketNameResponse)(nil), "appengine.GetDefaultGcsBucketNameResponse") +} + +func init() { + proto.RegisterFile("google.golang.org/appengine/internal/app_identity/app_identity_service.proto", fileDescriptor_app_identity_service_08a6e3f74b04cfa4) +} + +var fileDescriptor_app_identity_service_08a6e3f74b04cfa4 = []byte{ + // 676 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xdb, 0x6e, 0xda, 0x58, + 0x14, 0x1d, 0x26, 0x1a, 0x31, 0x6c, 0x12, 0x62, 0xce, 0x90, 0xcb, 0x8c, 0x32, 0xb9, 0x78, 0x1e, + 0x26, 0x0f, 0x15, 0x89, 0x2a, 0x45, 0x55, 0x1f, 0x8d, 0xed, 0x22, 0x54, 0x07, 0x53, 0x43, 0x9a, + 0xa8, 0x2f, 0xa7, 0xce, 0x61, 0xc7, 0x3d, 0x02, 0x9f, 0xe3, 0xda, 0x87, 0x0a, 0x3e, 0xa2, 0x3f, + 0xd2, 0x9f, 0xe8, 0x5b, 0xbf, 0xa5, 0x17, 0xb5, 0xdf, 0x50, 0xd9, 0x38, 0x5c, 0x92, 0x92, 0x37, + 0xbc, 0xf6, 0x5a, 0xcb, 0x6b, 0x2f, 0x6d, 0x0c, 0x4e, 0x20, 0x65, 0x30, 0xc4, 0x7a, 0x20, 0x87, + 0xbe, 0x08, 0xea, 0x32, 0x0e, 0x4e, 0xfc, 0x28, 0x42, 0x11, 0x70, 0x81, 0x27, 0x5c, 0x28, 0x8c, + 0x85, 0x3f, 0x4c, 0x21, 0xca, 0xfb, 0x28, 0x14, 0x57, 0x93, 0xa5, 0x07, 0x9a, 0x60, 0xfc, 0x8e, + 0x33, 0xac, 0x47, 0xb1, 0x54, 0x92, 0x94, 0x66, 0x5a, 0xfd, 0x53, 0x01, 0x76, 0x8c, 0x28, 0x6a, + 0xe5, 0xc4, 0xee, 0x94, 0x67, 0xc7, 0xb1, 0x8c, 0xf5, 0x0f, 0x05, 0x28, 0x65, 0xbf, 0x4c, 0xd9, + 0x47, 0x52, 0x86, 0x62, 0xf7, 0xc2, 0x34, 0xed, 0x6e, 0x57, 0xfb, 0x8d, 0x54, 0x61, 0xe3, 0xa2, + 0xfd, 0xbc, 0xed, 0x5e, 0xb6, 0x69, 0xd7, 0x74, 0x3b, 0xb6, 0x56, 0x22, 0x7f, 0x41, 0xa5, 0xe1, + 0xb8, 0x0d, 0xda, 0x73, 0x5d, 0xea, 0x18, 0x5e, 0xd3, 0xd6, 0x3e, 0x17, 0xc9, 0x36, 0x54, 0x2d, + 0xdb, 0xb0, 0x9c, 0x56, 0xdb, 0xa6, 0xf6, 0x95, 0x69, 0xdb, 0x96, 0x6d, 0x69, 0x5f, 0x8a, 0xa4, + 0x06, 0x9b, 0x6d, 0xb7, 0x47, 0x0d, 0xfa, 0xd2, 0x70, 0x5a, 0x16, 0x35, 0x3a, 0x1d, 0xed, 0x6b, + 0x91, 0x90, 0xb9, 0xab, 0xed, 0x79, 0xae, 0xa7, 0x7d, 0x2b, 0x12, 0x0d, 0xca, 0x19, 0xd3, 0x71, + 0xdc, 0x4b, 0xdb, 0xd2, 0xbe, 0xcf, 0xb4, 0xad, 0xf3, 0x8e, 0x63, 0x9f, 0xdb, 0xed, 0x9e, 0x6d, + 0x69, 0x3f, 0x8a, 0xfa, 0x13, 0xa8, 0x76, 0x79, 0x20, 0x9e, 0xc9, 0xd8, 0x88, 0x22, 0x0f, 0xdf, + 0x8e, 0x30, 0x51, 0x44, 0x87, 0x8d, 0xeb, 0x89, 0xc2, 0x84, 0x2a, 0x49, 0x13, 0x1e, 0x88, 0xdd, + 0xc2, 0x61, 0xe1, 0x78, 0xdd, 0x2b, 0x67, 0x60, 0x4f, 0xa6, 0x02, 0xfd, 0x0a, 0xc8, 0xa2, 0x30, + 0x89, 0xa4, 0x48, 0x90, 0xfc, 0x0d, 0x7f, 0x0e, 0x70, 0x42, 0x85, 0x1f, 0x62, 0x26, 0x2a, 0x79, + 0xc5, 0x01, 0x4e, 0xda, 0x7e, 0x88, 0xe4, 0x7f, 0xd8, 0x4c, 0xbd, 0x7c, 0x35, 0x8a, 0x91, 0x66, + 0x4e, 0xbb, 0xbf, 0x67, 0xb6, 0x95, 0x19, 0xdc, 0x48, 0x51, 0xfd, 0x3f, 0x38, 0x6a, 0xa2, 0xea, + 0x8c, 0xae, 0x87, 0x9c, 0x99, 0x18, 0x2b, 0x7e, 0xc3, 0x99, 0xaf, 0x70, 0x29, 0xa2, 0xfe, 0x1a, + 0xaa, 0xf7, 0x18, 0x0f, 0xbd, 0xfd, 0x14, 0x6a, 0xe3, 0xb3, 0xd3, 0xa7, 0x94, 0xcd, 0xe9, 0x34, + 0xc2, 0x30, 0x8b, 0x50, 0xf2, 0x48, 0x3a, 0x5b, 0x70, 0xea, 0x60, 0xa8, 0x7f, 0x2c, 0x80, 0xfe, + 0x50, 0x8e, 0x7c, 0xe3, 0x1e, 0xec, 0x44, 0x19, 0x65, 0xc9, 0x7a, 0xc8, 0x13, 0xb5, 0x5b, 0x38, + 0x5c, 0x3b, 0x2e, 0x3f, 0xde, 0xab, 0xcf, 0xce, 0xa6, 0x7e, 0xcf, 0xcc, 0xdb, 0x8a, 0xee, 0x42, + 0x0e, 0x4f, 0x14, 0x31, 0xe1, 0x20, 0xf4, 0xc7, 0x94, 0x0d, 0x39, 0x0a, 0x45, 0x99, 0xcf, 0xde, + 0x20, 0x55, 0x3c, 0x44, 0xca, 0x05, 0x4d, 0x90, 0x49, 0xd1, 0xcf, 0x92, 0xaf, 0x79, 0xff, 0x84, + 0xfe, 0xd8, 0xcc, 0x58, 0x66, 0x4a, 0xea, 0xf1, 0x10, 0x5b, 0xa2, 0x9b, 0x31, 0xf4, 0x7d, 0xd8, + 0x6b, 0xa2, 0xca, 0x6f, 0xd3, 0x60, 0x4c, 0x8e, 0x84, 0x4a, 0xcb, 0xb8, 0xed, 0xf0, 0x05, 0xfc, + 0xbb, 0x62, 0x9e, 0xef, 0x76, 0x0a, 0xb5, 0xfc, 0x1f, 0x40, 0xfd, 0xe9, 0x78, 0xb1, 0x5b, 0x92, + 0xdc, 0x53, 0xea, 0xef, 0x0b, 0xb0, 0xd5, 0x44, 0x65, 0x30, 0x86, 0x49, 0xd2, 0x93, 0x03, 0x14, + 0xb7, 0x37, 0x55, 0x83, 0x3f, 0x12, 0x26, 0x23, 0xcc, 0x5a, 0x29, 0x79, 0xd3, 0x07, 0xf2, 0x08, + 0xc8, 0xdd, 0x37, 0xf0, 0xdb, 0xd5, 0xb4, 0x65, 0xff, 0x56, 0x7f, 0x65, 0x9e, 0xb5, 0x95, 0x79, + 0xfa, 0xb0, 0x7d, 0x37, 0x4e, 0xbe, 0xdb, 0x11, 0xac, 0xfb, 0x19, 0x4c, 0x55, 0x8a, 0xe7, 0x3b, + 0x95, 0xfd, 0x39, 0x35, 0xbd, 0x58, 0x1c, 0x47, 0x3c, 0xf6, 0x15, 0x97, 0x22, 0xab, 0x3f, 0x4f, + 0x56, 0x99, 0xc3, 0x69, 0xe1, 0xfa, 0x21, 0xec, 0x37, 0x51, 0x59, 0x78, 0xe3, 0x8f, 0x86, 0xaa, + 0xc9, 0x92, 0xc6, 0x88, 0x0d, 0x70, 0xa9, 0xea, 0x2b, 0x38, 0x58, 0xc9, 0xc8, 0x03, 0x9d, 0xc1, + 0x4e, 0x7f, 0x3a, 0xa7, 0x01, 0x4b, 0xe8, 0x75, 0xc6, 0x58, 0xec, 0xbb, 0xd6, 0xff, 0x85, 0xbc, + 0x51, 0x79, 0xb5, 0xbe, 0xf8, 0xc9, 0xfa, 0x19, 0x00, 0x00, 0xff, 0xff, 0x37, 0x4c, 0x56, 0x38, + 0xf3, 0x04, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.proto b/vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.proto new file mode 100644 index 000000000000..19610ca5b753 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.proto @@ -0,0 +1,64 @@ +syntax = "proto2"; +option go_package = "app_identity"; + +package appengine; + +message AppIdentityServiceError { + enum ErrorCode { + SUCCESS = 0; + UNKNOWN_SCOPE = 9; + BLOB_TOO_LARGE = 1000; + DEADLINE_EXCEEDED = 1001; + NOT_A_VALID_APP = 1002; + UNKNOWN_ERROR = 1003; + NOT_ALLOWED = 1005; + NOT_IMPLEMENTED = 1006; + } +} + +message SignForAppRequest { + optional bytes bytes_to_sign = 1; +} + +message SignForAppResponse { + optional string key_name = 1; + optional bytes signature_bytes = 2; +} + +message GetPublicCertificateForAppRequest { +} + +message PublicCertificate { + optional string key_name = 1; + optional string x509_certificate_pem = 2; +} + +message GetPublicCertificateForAppResponse { + repeated PublicCertificate public_certificate_list = 1; + optional int64 max_client_cache_time_in_second = 2; +} + +message GetServiceAccountNameRequest { +} + +message GetServiceAccountNameResponse { + optional string service_account_name = 1; +} + +message GetAccessTokenRequest { + repeated string scope = 1; + optional int64 service_account_id = 2; + optional string service_account_name = 3; +} + +message GetAccessTokenResponse { + optional string access_token = 1; + optional int64 expiration_time = 2; +} + +message GetDefaultGcsBucketNameRequest { +} + +message GetDefaultGcsBucketNameResponse { + optional string default_gcs_bucket_name = 1; +} diff --git a/vendor/google.golang.org/appengine/internal/base/api_base.pb.go b/vendor/google.golang.org/appengine/internal/base/api_base.pb.go new file mode 100644 index 000000000000..db4777e68e5b --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/base/api_base.pb.go @@ -0,0 +1,308 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google.golang.org/appengine/internal/base/api_base.proto + +package base + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type StringProto struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StringProto) Reset() { *m = StringProto{} } +func (m *StringProto) String() string { return proto.CompactTextString(m) } +func (*StringProto) ProtoMessage() {} +func (*StringProto) Descriptor() ([]byte, []int) { + return fileDescriptor_api_base_9d49f8792e0c1140, []int{0} +} +func (m *StringProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StringProto.Unmarshal(m, b) +} +func (m *StringProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StringProto.Marshal(b, m, deterministic) +} +func (dst *StringProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_StringProto.Merge(dst, src) +} +func (m *StringProto) XXX_Size() int { + return xxx_messageInfo_StringProto.Size(m) +} +func (m *StringProto) XXX_DiscardUnknown() { + xxx_messageInfo_StringProto.DiscardUnknown(m) +} + +var xxx_messageInfo_StringProto proto.InternalMessageInfo + +func (m *StringProto) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +type Integer32Proto struct { + Value *int32 `protobuf:"varint,1,req,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Integer32Proto) Reset() { *m = Integer32Proto{} } +func (m *Integer32Proto) String() string { return proto.CompactTextString(m) } +func (*Integer32Proto) ProtoMessage() {} +func (*Integer32Proto) Descriptor() ([]byte, []int) { + return fileDescriptor_api_base_9d49f8792e0c1140, []int{1} +} +func (m *Integer32Proto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Integer32Proto.Unmarshal(m, b) +} +func (m *Integer32Proto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Integer32Proto.Marshal(b, m, deterministic) +} +func (dst *Integer32Proto) XXX_Merge(src proto.Message) { + xxx_messageInfo_Integer32Proto.Merge(dst, src) +} +func (m *Integer32Proto) XXX_Size() int { + return xxx_messageInfo_Integer32Proto.Size(m) +} +func (m *Integer32Proto) XXX_DiscardUnknown() { + xxx_messageInfo_Integer32Proto.DiscardUnknown(m) +} + +var xxx_messageInfo_Integer32Proto proto.InternalMessageInfo + +func (m *Integer32Proto) GetValue() int32 { + if m != nil && m.Value != nil { + return *m.Value + } + return 0 +} + +type Integer64Proto struct { + Value *int64 `protobuf:"varint,1,req,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Integer64Proto) Reset() { *m = Integer64Proto{} } +func (m *Integer64Proto) String() string { return proto.CompactTextString(m) } +func (*Integer64Proto) ProtoMessage() {} +func (*Integer64Proto) Descriptor() ([]byte, []int) { + return fileDescriptor_api_base_9d49f8792e0c1140, []int{2} +} +func (m *Integer64Proto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Integer64Proto.Unmarshal(m, b) +} +func (m *Integer64Proto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Integer64Proto.Marshal(b, m, deterministic) +} +func (dst *Integer64Proto) XXX_Merge(src proto.Message) { + xxx_messageInfo_Integer64Proto.Merge(dst, src) +} +func (m *Integer64Proto) XXX_Size() int { + return xxx_messageInfo_Integer64Proto.Size(m) +} +func (m *Integer64Proto) XXX_DiscardUnknown() { + xxx_messageInfo_Integer64Proto.DiscardUnknown(m) +} + +var xxx_messageInfo_Integer64Proto proto.InternalMessageInfo + +func (m *Integer64Proto) GetValue() int64 { + if m != nil && m.Value != nil { + return *m.Value + } + return 0 +} + +type BoolProto struct { + Value *bool `protobuf:"varint,1,req,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BoolProto) Reset() { *m = BoolProto{} } +func (m *BoolProto) String() string { return proto.CompactTextString(m) } +func (*BoolProto) ProtoMessage() {} +func (*BoolProto) Descriptor() ([]byte, []int) { + return fileDescriptor_api_base_9d49f8792e0c1140, []int{3} +} +func (m *BoolProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BoolProto.Unmarshal(m, b) +} +func (m *BoolProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BoolProto.Marshal(b, m, deterministic) +} +func (dst *BoolProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_BoolProto.Merge(dst, src) +} +func (m *BoolProto) XXX_Size() int { + return xxx_messageInfo_BoolProto.Size(m) +} +func (m *BoolProto) XXX_DiscardUnknown() { + xxx_messageInfo_BoolProto.DiscardUnknown(m) +} + +var xxx_messageInfo_BoolProto proto.InternalMessageInfo + +func (m *BoolProto) GetValue() bool { + if m != nil && m.Value != nil { + return *m.Value + } + return false +} + +type DoubleProto struct { + Value *float64 `protobuf:"fixed64,1,req,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DoubleProto) Reset() { *m = DoubleProto{} } +func (m *DoubleProto) String() string { return proto.CompactTextString(m) } +func (*DoubleProto) ProtoMessage() {} +func (*DoubleProto) Descriptor() ([]byte, []int) { + return fileDescriptor_api_base_9d49f8792e0c1140, []int{4} +} +func (m *DoubleProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DoubleProto.Unmarshal(m, b) +} +func (m *DoubleProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DoubleProto.Marshal(b, m, deterministic) +} +func (dst *DoubleProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_DoubleProto.Merge(dst, src) +} +func (m *DoubleProto) XXX_Size() int { + return xxx_messageInfo_DoubleProto.Size(m) +} +func (m *DoubleProto) XXX_DiscardUnknown() { + xxx_messageInfo_DoubleProto.DiscardUnknown(m) +} + +var xxx_messageInfo_DoubleProto proto.InternalMessageInfo + +func (m *DoubleProto) GetValue() float64 { + if m != nil && m.Value != nil { + return *m.Value + } + return 0 +} + +type BytesProto struct { + Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BytesProto) Reset() { *m = BytesProto{} } +func (m *BytesProto) String() string { return proto.CompactTextString(m) } +func (*BytesProto) ProtoMessage() {} +func (*BytesProto) Descriptor() ([]byte, []int) { + return fileDescriptor_api_base_9d49f8792e0c1140, []int{5} +} +func (m *BytesProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BytesProto.Unmarshal(m, b) +} +func (m *BytesProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BytesProto.Marshal(b, m, deterministic) +} +func (dst *BytesProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_BytesProto.Merge(dst, src) +} +func (m *BytesProto) XXX_Size() int { + return xxx_messageInfo_BytesProto.Size(m) +} +func (m *BytesProto) XXX_DiscardUnknown() { + xxx_messageInfo_BytesProto.DiscardUnknown(m) +} + +var xxx_messageInfo_BytesProto proto.InternalMessageInfo + +func (m *BytesProto) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type VoidProto struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VoidProto) Reset() { *m = VoidProto{} } +func (m *VoidProto) String() string { return proto.CompactTextString(m) } +func (*VoidProto) ProtoMessage() {} +func (*VoidProto) Descriptor() ([]byte, []int) { + return fileDescriptor_api_base_9d49f8792e0c1140, []int{6} +} +func (m *VoidProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VoidProto.Unmarshal(m, b) +} +func (m *VoidProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VoidProto.Marshal(b, m, deterministic) +} +func (dst *VoidProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_VoidProto.Merge(dst, src) +} +func (m *VoidProto) XXX_Size() int { + return xxx_messageInfo_VoidProto.Size(m) +} +func (m *VoidProto) XXX_DiscardUnknown() { + xxx_messageInfo_VoidProto.DiscardUnknown(m) +} + +var xxx_messageInfo_VoidProto proto.InternalMessageInfo + +func init() { + proto.RegisterType((*StringProto)(nil), "appengine.base.StringProto") + proto.RegisterType((*Integer32Proto)(nil), "appengine.base.Integer32Proto") + proto.RegisterType((*Integer64Proto)(nil), "appengine.base.Integer64Proto") + proto.RegisterType((*BoolProto)(nil), "appengine.base.BoolProto") + proto.RegisterType((*DoubleProto)(nil), "appengine.base.DoubleProto") + proto.RegisterType((*BytesProto)(nil), "appengine.base.BytesProto") + proto.RegisterType((*VoidProto)(nil), "appengine.base.VoidProto") +} + +func init() { + proto.RegisterFile("google.golang.org/appengine/internal/base/api_base.proto", fileDescriptor_api_base_9d49f8792e0c1140) +} + +var fileDescriptor_api_base_9d49f8792e0c1140 = []byte{ + // 199 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0xcf, 0x3f, 0x4b, 0xc6, 0x30, + 0x10, 0x06, 0x70, 0x5a, 0xad, 0xb4, 0x57, 0xe9, 0x20, 0x0e, 0x1d, 0xb5, 0x05, 0x71, 0x4a, 0x40, + 0x45, 0x9c, 0x83, 0x8b, 0x9b, 0x28, 0x38, 0xb8, 0x48, 0x8a, 0xc7, 0x11, 0x08, 0xb9, 0x90, 0xa6, + 0x82, 0xdf, 0x5e, 0xda, 0xd2, 0xfa, 0xc2, 0x9b, 0xed, 0xfe, 0xfc, 0xe0, 0xe1, 0x81, 0x27, 0x62, + 0x26, 0x8b, 0x82, 0xd8, 0x6a, 0x47, 0x82, 0x03, 0x49, 0xed, 0x3d, 0x3a, 0x32, 0x0e, 0xa5, 0x71, + 0x11, 0x83, 0xd3, 0x56, 0x0e, 0x7a, 0x44, 0xa9, 0xbd, 0xf9, 0x9a, 0x07, 0xe1, 0x03, 0x47, 0xbe, + 0x68, 0x76, 0x27, 0xe6, 0x6b, 0xd7, 0x43, 0xfd, 0x1e, 0x83, 0x71, 0xf4, 0xba, 0xbc, 0x2f, 0xa1, + 0xf8, 0xd1, 0x76, 0xc2, 0x36, 0xbb, 0xca, 0x6f, 0xab, 0xb7, 0x75, 0xe9, 0x6e, 0xa0, 0x79, 0x71, + 0x11, 0x09, 0xc3, 0xfd, 0x5d, 0xc2, 0x15, 0xc7, 0xee, 0xf1, 0x21, 0xe1, 0x4e, 0x36, 0x77, 0x0d, + 0x95, 0x62, 0xb6, 0x09, 0x52, 0x6e, 0xa4, 0x87, 0xfa, 0x99, 0xa7, 0xc1, 0x62, 0x02, 0x65, 0xff, + 0x79, 0xa0, 0x7e, 0x23, 0x8e, 0xab, 0x69, 0x0f, 0xcd, 0xb9, 0xca, 0xcb, 0xdd, 0xd5, 0x50, 0x7d, + 0xb0, 0xf9, 0x5e, 0x98, 0x3a, 0xfb, 0x3c, 0x9d, 0x9b, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xba, + 0x37, 0x25, 0xea, 0x44, 0x01, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/appengine/internal/base/api_base.proto b/vendor/google.golang.org/appengine/internal/base/api_base.proto new file mode 100644 index 000000000000..56cd7a3cad05 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/base/api_base.proto @@ -0,0 +1,33 @@ +// Built-in base types for API calls. Primarily useful as return types. + +syntax = "proto2"; +option go_package = "base"; + +package appengine.base; + +message StringProto { + required string value = 1; +} + +message Integer32Proto { + required int32 value = 1; +} + +message Integer64Proto { + required int64 value = 1; +} + +message BoolProto { + required bool value = 1; +} + +message DoubleProto { + required double value = 1; +} + +message BytesProto { + required bytes value = 1 [ctype=CORD]; +} + +message VoidProto { +} diff --git a/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go new file mode 100644 index 000000000000..2fb74828969c --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go @@ -0,0 +1,4367 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google.golang.org/appengine/internal/datastore/datastore_v3.proto + +package datastore + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Property_Meaning int32 + +const ( + Property_NO_MEANING Property_Meaning = 0 + Property_BLOB Property_Meaning = 14 + Property_TEXT Property_Meaning = 15 + Property_BYTESTRING Property_Meaning = 16 + Property_ATOM_CATEGORY Property_Meaning = 1 + Property_ATOM_LINK Property_Meaning = 2 + Property_ATOM_TITLE Property_Meaning = 3 + Property_ATOM_CONTENT Property_Meaning = 4 + Property_ATOM_SUMMARY Property_Meaning = 5 + Property_ATOM_AUTHOR Property_Meaning = 6 + Property_GD_WHEN Property_Meaning = 7 + Property_GD_EMAIL Property_Meaning = 8 + Property_GEORSS_POINT Property_Meaning = 9 + Property_GD_IM Property_Meaning = 10 + Property_GD_PHONENUMBER Property_Meaning = 11 + Property_GD_POSTALADDRESS Property_Meaning = 12 + Property_GD_RATING Property_Meaning = 13 + Property_BLOBKEY Property_Meaning = 17 + Property_ENTITY_PROTO Property_Meaning = 19 + Property_INDEX_VALUE Property_Meaning = 18 +) + +var Property_Meaning_name = map[int32]string{ + 0: "NO_MEANING", + 14: "BLOB", + 15: "TEXT", + 16: "BYTESTRING", + 1: "ATOM_CATEGORY", + 2: "ATOM_LINK", + 3: "ATOM_TITLE", + 4: "ATOM_CONTENT", + 5: "ATOM_SUMMARY", + 6: "ATOM_AUTHOR", + 7: "GD_WHEN", + 8: "GD_EMAIL", + 9: "GEORSS_POINT", + 10: "GD_IM", + 11: "GD_PHONENUMBER", + 12: "GD_POSTALADDRESS", + 13: "GD_RATING", + 17: "BLOBKEY", + 19: "ENTITY_PROTO", + 18: "INDEX_VALUE", +} +var Property_Meaning_value = map[string]int32{ + "NO_MEANING": 0, + "BLOB": 14, + "TEXT": 15, + "BYTESTRING": 16, + "ATOM_CATEGORY": 1, + "ATOM_LINK": 2, + "ATOM_TITLE": 3, + "ATOM_CONTENT": 4, + "ATOM_SUMMARY": 5, + "ATOM_AUTHOR": 6, + "GD_WHEN": 7, + "GD_EMAIL": 8, + "GEORSS_POINT": 9, + "GD_IM": 10, + "GD_PHONENUMBER": 11, + "GD_POSTALADDRESS": 12, + "GD_RATING": 13, + "BLOBKEY": 17, + "ENTITY_PROTO": 19, + "INDEX_VALUE": 18, +} + +func (x Property_Meaning) Enum() *Property_Meaning { + p := new(Property_Meaning) + *p = x + return p +} +func (x Property_Meaning) String() string { + return proto.EnumName(Property_Meaning_name, int32(x)) +} +func (x *Property_Meaning) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Property_Meaning_value, data, "Property_Meaning") + if err != nil { + return err + } + *x = Property_Meaning(value) + return nil +} +func (Property_Meaning) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2, 0} +} + +type Property_FtsTokenizationOption int32 + +const ( + Property_HTML Property_FtsTokenizationOption = 1 + Property_ATOM Property_FtsTokenizationOption = 2 +) + +var Property_FtsTokenizationOption_name = map[int32]string{ + 1: "HTML", + 2: "ATOM", +} +var Property_FtsTokenizationOption_value = map[string]int32{ + "HTML": 1, + "ATOM": 2, +} + +func (x Property_FtsTokenizationOption) Enum() *Property_FtsTokenizationOption { + p := new(Property_FtsTokenizationOption) + *p = x + return p +} +func (x Property_FtsTokenizationOption) String() string { + return proto.EnumName(Property_FtsTokenizationOption_name, int32(x)) +} +func (x *Property_FtsTokenizationOption) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Property_FtsTokenizationOption_value, data, "Property_FtsTokenizationOption") + if err != nil { + return err + } + *x = Property_FtsTokenizationOption(value) + return nil +} +func (Property_FtsTokenizationOption) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2, 1} +} + +type EntityProto_Kind int32 + +const ( + EntityProto_GD_CONTACT EntityProto_Kind = 1 + EntityProto_GD_EVENT EntityProto_Kind = 2 + EntityProto_GD_MESSAGE EntityProto_Kind = 3 +) + +var EntityProto_Kind_name = map[int32]string{ + 1: "GD_CONTACT", + 2: "GD_EVENT", + 3: "GD_MESSAGE", +} +var EntityProto_Kind_value = map[string]int32{ + "GD_CONTACT": 1, + "GD_EVENT": 2, + "GD_MESSAGE": 3, +} + +func (x EntityProto_Kind) Enum() *EntityProto_Kind { + p := new(EntityProto_Kind) + *p = x + return p +} +func (x EntityProto_Kind) String() string { + return proto.EnumName(EntityProto_Kind_name, int32(x)) +} +func (x *EntityProto_Kind) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(EntityProto_Kind_value, data, "EntityProto_Kind") + if err != nil { + return err + } + *x = EntityProto_Kind(value) + return nil +} +func (EntityProto_Kind) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{6, 0} +} + +type Index_Property_Direction int32 + +const ( + Index_Property_ASCENDING Index_Property_Direction = 1 + Index_Property_DESCENDING Index_Property_Direction = 2 +) + +var Index_Property_Direction_name = map[int32]string{ + 1: "ASCENDING", + 2: "DESCENDING", +} +var Index_Property_Direction_value = map[string]int32{ + "ASCENDING": 1, + "DESCENDING": 2, +} + +func (x Index_Property_Direction) Enum() *Index_Property_Direction { + p := new(Index_Property_Direction) + *p = x + return p +} +func (x Index_Property_Direction) String() string { + return proto.EnumName(Index_Property_Direction_name, int32(x)) +} +func (x *Index_Property_Direction) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Index_Property_Direction_value, data, "Index_Property_Direction") + if err != nil { + return err + } + *x = Index_Property_Direction(value) + return nil +} +func (Index_Property_Direction) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8, 0, 0} +} + +type CompositeIndex_State int32 + +const ( + CompositeIndex_WRITE_ONLY CompositeIndex_State = 1 + CompositeIndex_READ_WRITE CompositeIndex_State = 2 + CompositeIndex_DELETED CompositeIndex_State = 3 + CompositeIndex_ERROR CompositeIndex_State = 4 +) + +var CompositeIndex_State_name = map[int32]string{ + 1: "WRITE_ONLY", + 2: "READ_WRITE", + 3: "DELETED", + 4: "ERROR", +} +var CompositeIndex_State_value = map[string]int32{ + "WRITE_ONLY": 1, + "READ_WRITE": 2, + "DELETED": 3, + "ERROR": 4, +} + +func (x CompositeIndex_State) Enum() *CompositeIndex_State { + p := new(CompositeIndex_State) + *p = x + return p +} +func (x CompositeIndex_State) String() string { + return proto.EnumName(CompositeIndex_State_name, int32(x)) +} +func (x *CompositeIndex_State) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(CompositeIndex_State_value, data, "CompositeIndex_State") + if err != nil { + return err + } + *x = CompositeIndex_State(value) + return nil +} +func (CompositeIndex_State) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{9, 0} +} + +type Snapshot_Status int32 + +const ( + Snapshot_INACTIVE Snapshot_Status = 0 + Snapshot_ACTIVE Snapshot_Status = 1 +) + +var Snapshot_Status_name = map[int32]string{ + 0: "INACTIVE", + 1: "ACTIVE", +} +var Snapshot_Status_value = map[string]int32{ + "INACTIVE": 0, + "ACTIVE": 1, +} + +func (x Snapshot_Status) Enum() *Snapshot_Status { + p := new(Snapshot_Status) + *p = x + return p +} +func (x Snapshot_Status) String() string { + return proto.EnumName(Snapshot_Status_name, int32(x)) +} +func (x *Snapshot_Status) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Snapshot_Status_value, data, "Snapshot_Status") + if err != nil { + return err + } + *x = Snapshot_Status(value) + return nil +} +func (Snapshot_Status) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{12, 0} +} + +type Query_Hint int32 + +const ( + Query_ORDER_FIRST Query_Hint = 1 + Query_ANCESTOR_FIRST Query_Hint = 2 + Query_FILTER_FIRST Query_Hint = 3 +) + +var Query_Hint_name = map[int32]string{ + 1: "ORDER_FIRST", + 2: "ANCESTOR_FIRST", + 3: "FILTER_FIRST", +} +var Query_Hint_value = map[string]int32{ + "ORDER_FIRST": 1, + "ANCESTOR_FIRST": 2, + "FILTER_FIRST": 3, +} + +func (x Query_Hint) Enum() *Query_Hint { + p := new(Query_Hint) + *p = x + return p +} +func (x Query_Hint) String() string { + return proto.EnumName(Query_Hint_name, int32(x)) +} +func (x *Query_Hint) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Query_Hint_value, data, "Query_Hint") + if err != nil { + return err + } + *x = Query_Hint(value) + return nil +} +func (Query_Hint) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0} +} + +type Query_Filter_Operator int32 + +const ( + Query_Filter_LESS_THAN Query_Filter_Operator = 1 + Query_Filter_LESS_THAN_OR_EQUAL Query_Filter_Operator = 2 + Query_Filter_GREATER_THAN Query_Filter_Operator = 3 + Query_Filter_GREATER_THAN_OR_EQUAL Query_Filter_Operator = 4 + Query_Filter_EQUAL Query_Filter_Operator = 5 + Query_Filter_IN Query_Filter_Operator = 6 + Query_Filter_EXISTS Query_Filter_Operator = 7 +) + +var Query_Filter_Operator_name = map[int32]string{ + 1: "LESS_THAN", + 2: "LESS_THAN_OR_EQUAL", + 3: "GREATER_THAN", + 4: "GREATER_THAN_OR_EQUAL", + 5: "EQUAL", + 6: "IN", + 7: "EXISTS", +} +var Query_Filter_Operator_value = map[string]int32{ + "LESS_THAN": 1, + "LESS_THAN_OR_EQUAL": 2, + "GREATER_THAN": 3, + "GREATER_THAN_OR_EQUAL": 4, + "EQUAL": 5, + "IN": 6, + "EXISTS": 7, +} + +func (x Query_Filter_Operator) Enum() *Query_Filter_Operator { + p := new(Query_Filter_Operator) + *p = x + return p +} +func (x Query_Filter_Operator) String() string { + return proto.EnumName(Query_Filter_Operator_name, int32(x)) +} +func (x *Query_Filter_Operator) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Query_Filter_Operator_value, data, "Query_Filter_Operator") + if err != nil { + return err + } + *x = Query_Filter_Operator(value) + return nil +} +func (Query_Filter_Operator) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0, 0} +} + +type Query_Order_Direction int32 + +const ( + Query_Order_ASCENDING Query_Order_Direction = 1 + Query_Order_DESCENDING Query_Order_Direction = 2 +) + +var Query_Order_Direction_name = map[int32]string{ + 1: "ASCENDING", + 2: "DESCENDING", +} +var Query_Order_Direction_value = map[string]int32{ + "ASCENDING": 1, + "DESCENDING": 2, +} + +func (x Query_Order_Direction) Enum() *Query_Order_Direction { + p := new(Query_Order_Direction) + *p = x + return p +} +func (x Query_Order_Direction) String() string { + return proto.EnumName(Query_Order_Direction_name, int32(x)) +} +func (x *Query_Order_Direction) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Query_Order_Direction_value, data, "Query_Order_Direction") + if err != nil { + return err + } + *x = Query_Order_Direction(value) + return nil +} +func (Query_Order_Direction) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 1, 0} +} + +type Error_ErrorCode int32 + +const ( + Error_BAD_REQUEST Error_ErrorCode = 1 + Error_CONCURRENT_TRANSACTION Error_ErrorCode = 2 + Error_INTERNAL_ERROR Error_ErrorCode = 3 + Error_NEED_INDEX Error_ErrorCode = 4 + Error_TIMEOUT Error_ErrorCode = 5 + Error_PERMISSION_DENIED Error_ErrorCode = 6 + Error_BIGTABLE_ERROR Error_ErrorCode = 7 + Error_COMMITTED_BUT_STILL_APPLYING Error_ErrorCode = 8 + Error_CAPABILITY_DISABLED Error_ErrorCode = 9 + Error_TRY_ALTERNATE_BACKEND Error_ErrorCode = 10 + Error_SAFE_TIME_TOO_OLD Error_ErrorCode = 11 +) + +var Error_ErrorCode_name = map[int32]string{ + 1: "BAD_REQUEST", + 2: "CONCURRENT_TRANSACTION", + 3: "INTERNAL_ERROR", + 4: "NEED_INDEX", + 5: "TIMEOUT", + 6: "PERMISSION_DENIED", + 7: "BIGTABLE_ERROR", + 8: "COMMITTED_BUT_STILL_APPLYING", + 9: "CAPABILITY_DISABLED", + 10: "TRY_ALTERNATE_BACKEND", + 11: "SAFE_TIME_TOO_OLD", +} +var Error_ErrorCode_value = map[string]int32{ + "BAD_REQUEST": 1, + "CONCURRENT_TRANSACTION": 2, + "INTERNAL_ERROR": 3, + "NEED_INDEX": 4, + "TIMEOUT": 5, + "PERMISSION_DENIED": 6, + "BIGTABLE_ERROR": 7, + "COMMITTED_BUT_STILL_APPLYING": 8, + "CAPABILITY_DISABLED": 9, + "TRY_ALTERNATE_BACKEND": 10, + "SAFE_TIME_TOO_OLD": 11, +} + +func (x Error_ErrorCode) Enum() *Error_ErrorCode { + p := new(Error_ErrorCode) + *p = x + return p +} +func (x Error_ErrorCode) String() string { + return proto.EnumName(Error_ErrorCode_name, int32(x)) +} +func (x *Error_ErrorCode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Error_ErrorCode_value, data, "Error_ErrorCode") + if err != nil { + return err + } + *x = Error_ErrorCode(value) + return nil +} +func (Error_ErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{19, 0} +} + +type PutRequest_AutoIdPolicy int32 + +const ( + PutRequest_CURRENT PutRequest_AutoIdPolicy = 0 + PutRequest_SEQUENTIAL PutRequest_AutoIdPolicy = 1 +) + +var PutRequest_AutoIdPolicy_name = map[int32]string{ + 0: "CURRENT", + 1: "SEQUENTIAL", +} +var PutRequest_AutoIdPolicy_value = map[string]int32{ + "CURRENT": 0, + "SEQUENTIAL": 1, +} + +func (x PutRequest_AutoIdPolicy) Enum() *PutRequest_AutoIdPolicy { + p := new(PutRequest_AutoIdPolicy) + *p = x + return p +} +func (x PutRequest_AutoIdPolicy) String() string { + return proto.EnumName(PutRequest_AutoIdPolicy_name, int32(x)) +} +func (x *PutRequest_AutoIdPolicy) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(PutRequest_AutoIdPolicy_value, data, "PutRequest_AutoIdPolicy") + if err != nil { + return err + } + *x = PutRequest_AutoIdPolicy(value) + return nil +} +func (PutRequest_AutoIdPolicy) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{23, 0} +} + +type BeginTransactionRequest_TransactionMode int32 + +const ( + BeginTransactionRequest_UNKNOWN BeginTransactionRequest_TransactionMode = 0 + BeginTransactionRequest_READ_ONLY BeginTransactionRequest_TransactionMode = 1 + BeginTransactionRequest_READ_WRITE BeginTransactionRequest_TransactionMode = 2 +) + +var BeginTransactionRequest_TransactionMode_name = map[int32]string{ + 0: "UNKNOWN", + 1: "READ_ONLY", + 2: "READ_WRITE", +} +var BeginTransactionRequest_TransactionMode_value = map[string]int32{ + "UNKNOWN": 0, + "READ_ONLY": 1, + "READ_WRITE": 2, +} + +func (x BeginTransactionRequest_TransactionMode) Enum() *BeginTransactionRequest_TransactionMode { + p := new(BeginTransactionRequest_TransactionMode) + *p = x + return p +} +func (x BeginTransactionRequest_TransactionMode) String() string { + return proto.EnumName(BeginTransactionRequest_TransactionMode_name, int32(x)) +} +func (x *BeginTransactionRequest_TransactionMode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(BeginTransactionRequest_TransactionMode_value, data, "BeginTransactionRequest_TransactionMode") + if err != nil { + return err + } + *x = BeginTransactionRequest_TransactionMode(value) + return nil +} +func (BeginTransactionRequest_TransactionMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{36, 0} +} + +type Action struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Action) Reset() { *m = Action{} } +func (m *Action) String() string { return proto.CompactTextString(m) } +func (*Action) ProtoMessage() {} +func (*Action) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{0} +} +func (m *Action) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Action.Unmarshal(m, b) +} +func (m *Action) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Action.Marshal(b, m, deterministic) +} +func (dst *Action) XXX_Merge(src proto.Message) { + xxx_messageInfo_Action.Merge(dst, src) +} +func (m *Action) XXX_Size() int { + return xxx_messageInfo_Action.Size(m) +} +func (m *Action) XXX_DiscardUnknown() { + xxx_messageInfo_Action.DiscardUnknown(m) +} + +var xxx_messageInfo_Action proto.InternalMessageInfo + +type PropertyValue struct { + Int64Value *int64 `protobuf:"varint,1,opt,name=int64Value" json:"int64Value,omitempty"` + BooleanValue *bool `protobuf:"varint,2,opt,name=booleanValue" json:"booleanValue,omitempty"` + StringValue *string `protobuf:"bytes,3,opt,name=stringValue" json:"stringValue,omitempty"` + DoubleValue *float64 `protobuf:"fixed64,4,opt,name=doubleValue" json:"doubleValue,omitempty"` + Pointvalue *PropertyValue_PointValue `protobuf:"group,5,opt,name=PointValue,json=pointvalue" json:"pointvalue,omitempty"` + Uservalue *PropertyValue_UserValue `protobuf:"group,8,opt,name=UserValue,json=uservalue" json:"uservalue,omitempty"` + Referencevalue *PropertyValue_ReferenceValue `protobuf:"group,12,opt,name=ReferenceValue,json=referencevalue" json:"referencevalue,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PropertyValue) Reset() { *m = PropertyValue{} } +func (m *PropertyValue) String() string { return proto.CompactTextString(m) } +func (*PropertyValue) ProtoMessage() {} +func (*PropertyValue) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1} +} +func (m *PropertyValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PropertyValue.Unmarshal(m, b) +} +func (m *PropertyValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PropertyValue.Marshal(b, m, deterministic) +} +func (dst *PropertyValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_PropertyValue.Merge(dst, src) +} +func (m *PropertyValue) XXX_Size() int { + return xxx_messageInfo_PropertyValue.Size(m) +} +func (m *PropertyValue) XXX_DiscardUnknown() { + xxx_messageInfo_PropertyValue.DiscardUnknown(m) +} + +var xxx_messageInfo_PropertyValue proto.InternalMessageInfo + +func (m *PropertyValue) GetInt64Value() int64 { + if m != nil && m.Int64Value != nil { + return *m.Int64Value + } + return 0 +} + +func (m *PropertyValue) GetBooleanValue() bool { + if m != nil && m.BooleanValue != nil { + return *m.BooleanValue + } + return false +} + +func (m *PropertyValue) GetStringValue() string { + if m != nil && m.StringValue != nil { + return *m.StringValue + } + return "" +} + +func (m *PropertyValue) GetDoubleValue() float64 { + if m != nil && m.DoubleValue != nil { + return *m.DoubleValue + } + return 0 +} + +func (m *PropertyValue) GetPointvalue() *PropertyValue_PointValue { + if m != nil { + return m.Pointvalue + } + return nil +} + +func (m *PropertyValue) GetUservalue() *PropertyValue_UserValue { + if m != nil { + return m.Uservalue + } + return nil +} + +func (m *PropertyValue) GetReferencevalue() *PropertyValue_ReferenceValue { + if m != nil { + return m.Referencevalue + } + return nil +} + +type PropertyValue_PointValue struct { + X *float64 `protobuf:"fixed64,6,req,name=x" json:"x,omitempty"` + Y *float64 `protobuf:"fixed64,7,req,name=y" json:"y,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PropertyValue_PointValue) Reset() { *m = PropertyValue_PointValue{} } +func (m *PropertyValue_PointValue) String() string { return proto.CompactTextString(m) } +func (*PropertyValue_PointValue) ProtoMessage() {} +func (*PropertyValue_PointValue) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 0} +} +func (m *PropertyValue_PointValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PropertyValue_PointValue.Unmarshal(m, b) +} +func (m *PropertyValue_PointValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PropertyValue_PointValue.Marshal(b, m, deterministic) +} +func (dst *PropertyValue_PointValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_PropertyValue_PointValue.Merge(dst, src) +} +func (m *PropertyValue_PointValue) XXX_Size() int { + return xxx_messageInfo_PropertyValue_PointValue.Size(m) +} +func (m *PropertyValue_PointValue) XXX_DiscardUnknown() { + xxx_messageInfo_PropertyValue_PointValue.DiscardUnknown(m) +} + +var xxx_messageInfo_PropertyValue_PointValue proto.InternalMessageInfo + +func (m *PropertyValue_PointValue) GetX() float64 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +func (m *PropertyValue_PointValue) GetY() float64 { + if m != nil && m.Y != nil { + return *m.Y + } + return 0 +} + +type PropertyValue_UserValue struct { + Email *string `protobuf:"bytes,9,req,name=email" json:"email,omitempty"` + AuthDomain *string `protobuf:"bytes,10,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"` + Nickname *string `protobuf:"bytes,11,opt,name=nickname" json:"nickname,omitempty"` + FederatedIdentity *string `protobuf:"bytes,21,opt,name=federated_identity,json=federatedIdentity" json:"federated_identity,omitempty"` + FederatedProvider *string `protobuf:"bytes,22,opt,name=federated_provider,json=federatedProvider" json:"federated_provider,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PropertyValue_UserValue) Reset() { *m = PropertyValue_UserValue{} } +func (m *PropertyValue_UserValue) String() string { return proto.CompactTextString(m) } +func (*PropertyValue_UserValue) ProtoMessage() {} +func (*PropertyValue_UserValue) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 1} +} +func (m *PropertyValue_UserValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PropertyValue_UserValue.Unmarshal(m, b) +} +func (m *PropertyValue_UserValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PropertyValue_UserValue.Marshal(b, m, deterministic) +} +func (dst *PropertyValue_UserValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_PropertyValue_UserValue.Merge(dst, src) +} +func (m *PropertyValue_UserValue) XXX_Size() int { + return xxx_messageInfo_PropertyValue_UserValue.Size(m) +} +func (m *PropertyValue_UserValue) XXX_DiscardUnknown() { + xxx_messageInfo_PropertyValue_UserValue.DiscardUnknown(m) +} + +var xxx_messageInfo_PropertyValue_UserValue proto.InternalMessageInfo + +func (m *PropertyValue_UserValue) GetEmail() string { + if m != nil && m.Email != nil { + return *m.Email + } + return "" +} + +func (m *PropertyValue_UserValue) GetAuthDomain() string { + if m != nil && m.AuthDomain != nil { + return *m.AuthDomain + } + return "" +} + +func (m *PropertyValue_UserValue) GetNickname() string { + if m != nil && m.Nickname != nil { + return *m.Nickname + } + return "" +} + +func (m *PropertyValue_UserValue) GetFederatedIdentity() string { + if m != nil && m.FederatedIdentity != nil { + return *m.FederatedIdentity + } + return "" +} + +func (m *PropertyValue_UserValue) GetFederatedProvider() string { + if m != nil && m.FederatedProvider != nil { + return *m.FederatedProvider + } + return "" +} + +type PropertyValue_ReferenceValue struct { + App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"` + NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"` + Pathelement []*PropertyValue_ReferenceValue_PathElement `protobuf:"group,14,rep,name=PathElement,json=pathelement" json:"pathelement,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PropertyValue_ReferenceValue) Reset() { *m = PropertyValue_ReferenceValue{} } +func (m *PropertyValue_ReferenceValue) String() string { return proto.CompactTextString(m) } +func (*PropertyValue_ReferenceValue) ProtoMessage() {} +func (*PropertyValue_ReferenceValue) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 2} +} +func (m *PropertyValue_ReferenceValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PropertyValue_ReferenceValue.Unmarshal(m, b) +} +func (m *PropertyValue_ReferenceValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PropertyValue_ReferenceValue.Marshal(b, m, deterministic) +} +func (dst *PropertyValue_ReferenceValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_PropertyValue_ReferenceValue.Merge(dst, src) +} +func (m *PropertyValue_ReferenceValue) XXX_Size() int { + return xxx_messageInfo_PropertyValue_ReferenceValue.Size(m) +} +func (m *PropertyValue_ReferenceValue) XXX_DiscardUnknown() { + xxx_messageInfo_PropertyValue_ReferenceValue.DiscardUnknown(m) +} + +var xxx_messageInfo_PropertyValue_ReferenceValue proto.InternalMessageInfo + +func (m *PropertyValue_ReferenceValue) GetApp() string { + if m != nil && m.App != nil { + return *m.App + } + return "" +} + +func (m *PropertyValue_ReferenceValue) GetNameSpace() string { + if m != nil && m.NameSpace != nil { + return *m.NameSpace + } + return "" +} + +func (m *PropertyValue_ReferenceValue) GetPathelement() []*PropertyValue_ReferenceValue_PathElement { + if m != nil { + return m.Pathelement + } + return nil +} + +type PropertyValue_ReferenceValue_PathElement struct { + Type *string `protobuf:"bytes,15,req,name=type" json:"type,omitempty"` + Id *int64 `protobuf:"varint,16,opt,name=id" json:"id,omitempty"` + Name *string `protobuf:"bytes,17,opt,name=name" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PropertyValue_ReferenceValue_PathElement) Reset() { + *m = PropertyValue_ReferenceValue_PathElement{} +} +func (m *PropertyValue_ReferenceValue_PathElement) String() string { return proto.CompactTextString(m) } +func (*PropertyValue_ReferenceValue_PathElement) ProtoMessage() {} +func (*PropertyValue_ReferenceValue_PathElement) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 2, 0} +} +func (m *PropertyValue_ReferenceValue_PathElement) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Unmarshal(m, b) +} +func (m *PropertyValue_ReferenceValue_PathElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Marshal(b, m, deterministic) +} +func (dst *PropertyValue_ReferenceValue_PathElement) XXX_Merge(src proto.Message) { + xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Merge(dst, src) +} +func (m *PropertyValue_ReferenceValue_PathElement) XXX_Size() int { + return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Size(m) +} +func (m *PropertyValue_ReferenceValue_PathElement) XXX_DiscardUnknown() { + xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.DiscardUnknown(m) +} + +var xxx_messageInfo_PropertyValue_ReferenceValue_PathElement proto.InternalMessageInfo + +func (m *PropertyValue_ReferenceValue_PathElement) GetType() string { + if m != nil && m.Type != nil { + return *m.Type + } + return "" +} + +func (m *PropertyValue_ReferenceValue_PathElement) GetId() int64 { + if m != nil && m.Id != nil { + return *m.Id + } + return 0 +} + +func (m *PropertyValue_ReferenceValue_PathElement) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +type Property struct { + Meaning *Property_Meaning `protobuf:"varint,1,opt,name=meaning,enum=appengine.Property_Meaning,def=0" json:"meaning,omitempty"` + MeaningUri *string `protobuf:"bytes,2,opt,name=meaning_uri,json=meaningUri" json:"meaning_uri,omitempty"` + Name *string `protobuf:"bytes,3,req,name=name" json:"name,omitempty"` + Value *PropertyValue `protobuf:"bytes,5,req,name=value" json:"value,omitempty"` + Multiple *bool `protobuf:"varint,4,req,name=multiple" json:"multiple,omitempty"` + Searchable *bool `protobuf:"varint,6,opt,name=searchable,def=0" json:"searchable,omitempty"` + FtsTokenizationOption *Property_FtsTokenizationOption `protobuf:"varint,8,opt,name=fts_tokenization_option,json=ftsTokenizationOption,enum=appengine.Property_FtsTokenizationOption" json:"fts_tokenization_option,omitempty"` + Locale *string `protobuf:"bytes,9,opt,name=locale,def=en" json:"locale,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Property) Reset() { *m = Property{} } +func (m *Property) String() string { return proto.CompactTextString(m) } +func (*Property) ProtoMessage() {} +func (*Property) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2} +} +func (m *Property) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Property.Unmarshal(m, b) +} +func (m *Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Property.Marshal(b, m, deterministic) +} +func (dst *Property) XXX_Merge(src proto.Message) { + xxx_messageInfo_Property.Merge(dst, src) +} +func (m *Property) XXX_Size() int { + return xxx_messageInfo_Property.Size(m) +} +func (m *Property) XXX_DiscardUnknown() { + xxx_messageInfo_Property.DiscardUnknown(m) +} + +var xxx_messageInfo_Property proto.InternalMessageInfo + +const Default_Property_Meaning Property_Meaning = Property_NO_MEANING +const Default_Property_Searchable bool = false +const Default_Property_Locale string = "en" + +func (m *Property) GetMeaning() Property_Meaning { + if m != nil && m.Meaning != nil { + return *m.Meaning + } + return Default_Property_Meaning +} + +func (m *Property) GetMeaningUri() string { + if m != nil && m.MeaningUri != nil { + return *m.MeaningUri + } + return "" +} + +func (m *Property) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Property) GetValue() *PropertyValue { + if m != nil { + return m.Value + } + return nil +} + +func (m *Property) GetMultiple() bool { + if m != nil && m.Multiple != nil { + return *m.Multiple + } + return false +} + +func (m *Property) GetSearchable() bool { + if m != nil && m.Searchable != nil { + return *m.Searchable + } + return Default_Property_Searchable +} + +func (m *Property) GetFtsTokenizationOption() Property_FtsTokenizationOption { + if m != nil && m.FtsTokenizationOption != nil { + return *m.FtsTokenizationOption + } + return Property_HTML +} + +func (m *Property) GetLocale() string { + if m != nil && m.Locale != nil { + return *m.Locale + } + return Default_Property_Locale +} + +type Path struct { + Element []*Path_Element `protobuf:"group,1,rep,name=Element,json=element" json:"element,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Path) Reset() { *m = Path{} } +func (m *Path) String() string { return proto.CompactTextString(m) } +func (*Path) ProtoMessage() {} +func (*Path) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3} +} +func (m *Path) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Path.Unmarshal(m, b) +} +func (m *Path) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Path.Marshal(b, m, deterministic) +} +func (dst *Path) XXX_Merge(src proto.Message) { + xxx_messageInfo_Path.Merge(dst, src) +} +func (m *Path) XXX_Size() int { + return xxx_messageInfo_Path.Size(m) +} +func (m *Path) XXX_DiscardUnknown() { + xxx_messageInfo_Path.DiscardUnknown(m) +} + +var xxx_messageInfo_Path proto.InternalMessageInfo + +func (m *Path) GetElement() []*Path_Element { + if m != nil { + return m.Element + } + return nil +} + +type Path_Element struct { + Type *string `protobuf:"bytes,2,req,name=type" json:"type,omitempty"` + Id *int64 `protobuf:"varint,3,opt,name=id" json:"id,omitempty"` + Name *string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Path_Element) Reset() { *m = Path_Element{} } +func (m *Path_Element) String() string { return proto.CompactTextString(m) } +func (*Path_Element) ProtoMessage() {} +func (*Path_Element) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3, 0} +} +func (m *Path_Element) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Path_Element.Unmarshal(m, b) +} +func (m *Path_Element) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Path_Element.Marshal(b, m, deterministic) +} +func (dst *Path_Element) XXX_Merge(src proto.Message) { + xxx_messageInfo_Path_Element.Merge(dst, src) +} +func (m *Path_Element) XXX_Size() int { + return xxx_messageInfo_Path_Element.Size(m) +} +func (m *Path_Element) XXX_DiscardUnknown() { + xxx_messageInfo_Path_Element.DiscardUnknown(m) +} + +var xxx_messageInfo_Path_Element proto.InternalMessageInfo + +func (m *Path_Element) GetType() string { + if m != nil && m.Type != nil { + return *m.Type + } + return "" +} + +func (m *Path_Element) GetId() int64 { + if m != nil && m.Id != nil { + return *m.Id + } + return 0 +} + +func (m *Path_Element) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +type Reference struct { + App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"` + NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"` + Path *Path `protobuf:"bytes,14,req,name=path" json:"path,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Reference) Reset() { *m = Reference{} } +func (m *Reference) String() string { return proto.CompactTextString(m) } +func (*Reference) ProtoMessage() {} +func (*Reference) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{4} +} +func (m *Reference) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Reference.Unmarshal(m, b) +} +func (m *Reference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Reference.Marshal(b, m, deterministic) +} +func (dst *Reference) XXX_Merge(src proto.Message) { + xxx_messageInfo_Reference.Merge(dst, src) +} +func (m *Reference) XXX_Size() int { + return xxx_messageInfo_Reference.Size(m) +} +func (m *Reference) XXX_DiscardUnknown() { + xxx_messageInfo_Reference.DiscardUnknown(m) +} + +var xxx_messageInfo_Reference proto.InternalMessageInfo + +func (m *Reference) GetApp() string { + if m != nil && m.App != nil { + return *m.App + } + return "" +} + +func (m *Reference) GetNameSpace() string { + if m != nil && m.NameSpace != nil { + return *m.NameSpace + } + return "" +} + +func (m *Reference) GetPath() *Path { + if m != nil { + return m.Path + } + return nil +} + +type User struct { + Email *string `protobuf:"bytes,1,req,name=email" json:"email,omitempty"` + AuthDomain *string `protobuf:"bytes,2,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"` + Nickname *string `protobuf:"bytes,3,opt,name=nickname" json:"nickname,omitempty"` + FederatedIdentity *string `protobuf:"bytes,6,opt,name=federated_identity,json=federatedIdentity" json:"federated_identity,omitempty"` + FederatedProvider *string `protobuf:"bytes,7,opt,name=federated_provider,json=federatedProvider" json:"federated_provider,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *User) Reset() { *m = User{} } +func (m *User) String() string { return proto.CompactTextString(m) } +func (*User) ProtoMessage() {} +func (*User) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{5} +} +func (m *User) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_User.Unmarshal(m, b) +} +func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_User.Marshal(b, m, deterministic) +} +func (dst *User) XXX_Merge(src proto.Message) { + xxx_messageInfo_User.Merge(dst, src) +} +func (m *User) XXX_Size() int { + return xxx_messageInfo_User.Size(m) +} +func (m *User) XXX_DiscardUnknown() { + xxx_messageInfo_User.DiscardUnknown(m) +} + +var xxx_messageInfo_User proto.InternalMessageInfo + +func (m *User) GetEmail() string { + if m != nil && m.Email != nil { + return *m.Email + } + return "" +} + +func (m *User) GetAuthDomain() string { + if m != nil && m.AuthDomain != nil { + return *m.AuthDomain + } + return "" +} + +func (m *User) GetNickname() string { + if m != nil && m.Nickname != nil { + return *m.Nickname + } + return "" +} + +func (m *User) GetFederatedIdentity() string { + if m != nil && m.FederatedIdentity != nil { + return *m.FederatedIdentity + } + return "" +} + +func (m *User) GetFederatedProvider() string { + if m != nil && m.FederatedProvider != nil { + return *m.FederatedProvider + } + return "" +} + +type EntityProto struct { + Key *Reference `protobuf:"bytes,13,req,name=key" json:"key,omitempty"` + EntityGroup *Path `protobuf:"bytes,16,req,name=entity_group,json=entityGroup" json:"entity_group,omitempty"` + Owner *User `protobuf:"bytes,17,opt,name=owner" json:"owner,omitempty"` + Kind *EntityProto_Kind `protobuf:"varint,4,opt,name=kind,enum=appengine.EntityProto_Kind" json:"kind,omitempty"` + KindUri *string `protobuf:"bytes,5,opt,name=kind_uri,json=kindUri" json:"kind_uri,omitempty"` + Property []*Property `protobuf:"bytes,14,rep,name=property" json:"property,omitempty"` + RawProperty []*Property `protobuf:"bytes,15,rep,name=raw_property,json=rawProperty" json:"raw_property,omitempty"` + Rank *int32 `protobuf:"varint,18,opt,name=rank" json:"rank,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityProto) Reset() { *m = EntityProto{} } +func (m *EntityProto) String() string { return proto.CompactTextString(m) } +func (*EntityProto) ProtoMessage() {} +func (*EntityProto) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{6} +} +func (m *EntityProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityProto.Unmarshal(m, b) +} +func (m *EntityProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityProto.Marshal(b, m, deterministic) +} +func (dst *EntityProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityProto.Merge(dst, src) +} +func (m *EntityProto) XXX_Size() int { + return xxx_messageInfo_EntityProto.Size(m) +} +func (m *EntityProto) XXX_DiscardUnknown() { + xxx_messageInfo_EntityProto.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityProto proto.InternalMessageInfo + +func (m *EntityProto) GetKey() *Reference { + if m != nil { + return m.Key + } + return nil +} + +func (m *EntityProto) GetEntityGroup() *Path { + if m != nil { + return m.EntityGroup + } + return nil +} + +func (m *EntityProto) GetOwner() *User { + if m != nil { + return m.Owner + } + return nil +} + +func (m *EntityProto) GetKind() EntityProto_Kind { + if m != nil && m.Kind != nil { + return *m.Kind + } + return EntityProto_GD_CONTACT +} + +func (m *EntityProto) GetKindUri() string { + if m != nil && m.KindUri != nil { + return *m.KindUri + } + return "" +} + +func (m *EntityProto) GetProperty() []*Property { + if m != nil { + return m.Property + } + return nil +} + +func (m *EntityProto) GetRawProperty() []*Property { + if m != nil { + return m.RawProperty + } + return nil +} + +func (m *EntityProto) GetRank() int32 { + if m != nil && m.Rank != nil { + return *m.Rank + } + return 0 +} + +type CompositeProperty struct { + IndexId *int64 `protobuf:"varint,1,req,name=index_id,json=indexId" json:"index_id,omitempty"` + Value []string `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompositeProperty) Reset() { *m = CompositeProperty{} } +func (m *CompositeProperty) String() string { return proto.CompactTextString(m) } +func (*CompositeProperty) ProtoMessage() {} +func (*CompositeProperty) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{7} +} +func (m *CompositeProperty) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompositeProperty.Unmarshal(m, b) +} +func (m *CompositeProperty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompositeProperty.Marshal(b, m, deterministic) +} +func (dst *CompositeProperty) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompositeProperty.Merge(dst, src) +} +func (m *CompositeProperty) XXX_Size() int { + return xxx_messageInfo_CompositeProperty.Size(m) +} +func (m *CompositeProperty) XXX_DiscardUnknown() { + xxx_messageInfo_CompositeProperty.DiscardUnknown(m) +} + +var xxx_messageInfo_CompositeProperty proto.InternalMessageInfo + +func (m *CompositeProperty) GetIndexId() int64 { + if m != nil && m.IndexId != nil { + return *m.IndexId + } + return 0 +} + +func (m *CompositeProperty) GetValue() []string { + if m != nil { + return m.Value + } + return nil +} + +type Index struct { + EntityType *string `protobuf:"bytes,1,req,name=entity_type,json=entityType" json:"entity_type,omitempty"` + Ancestor *bool `protobuf:"varint,5,req,name=ancestor" json:"ancestor,omitempty"` + Property []*Index_Property `protobuf:"group,2,rep,name=Property,json=property" json:"property,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Index) Reset() { *m = Index{} } +func (m *Index) String() string { return proto.CompactTextString(m) } +func (*Index) ProtoMessage() {} +func (*Index) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8} +} +func (m *Index) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Index.Unmarshal(m, b) +} +func (m *Index) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Index.Marshal(b, m, deterministic) +} +func (dst *Index) XXX_Merge(src proto.Message) { + xxx_messageInfo_Index.Merge(dst, src) +} +func (m *Index) XXX_Size() int { + return xxx_messageInfo_Index.Size(m) +} +func (m *Index) XXX_DiscardUnknown() { + xxx_messageInfo_Index.DiscardUnknown(m) +} + +var xxx_messageInfo_Index proto.InternalMessageInfo + +func (m *Index) GetEntityType() string { + if m != nil && m.EntityType != nil { + return *m.EntityType + } + return "" +} + +func (m *Index) GetAncestor() bool { + if m != nil && m.Ancestor != nil { + return *m.Ancestor + } + return false +} + +func (m *Index) GetProperty() []*Index_Property { + if m != nil { + return m.Property + } + return nil +} + +type Index_Property struct { + Name *string `protobuf:"bytes,3,req,name=name" json:"name,omitempty"` + Direction *Index_Property_Direction `protobuf:"varint,4,opt,name=direction,enum=appengine.Index_Property_Direction,def=1" json:"direction,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Index_Property) Reset() { *m = Index_Property{} } +func (m *Index_Property) String() string { return proto.CompactTextString(m) } +func (*Index_Property) ProtoMessage() {} +func (*Index_Property) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8, 0} +} +func (m *Index_Property) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Index_Property.Unmarshal(m, b) +} +func (m *Index_Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Index_Property.Marshal(b, m, deterministic) +} +func (dst *Index_Property) XXX_Merge(src proto.Message) { + xxx_messageInfo_Index_Property.Merge(dst, src) +} +func (m *Index_Property) XXX_Size() int { + return xxx_messageInfo_Index_Property.Size(m) +} +func (m *Index_Property) XXX_DiscardUnknown() { + xxx_messageInfo_Index_Property.DiscardUnknown(m) +} + +var xxx_messageInfo_Index_Property proto.InternalMessageInfo + +const Default_Index_Property_Direction Index_Property_Direction = Index_Property_ASCENDING + +func (m *Index_Property) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Index_Property) GetDirection() Index_Property_Direction { + if m != nil && m.Direction != nil { + return *m.Direction + } + return Default_Index_Property_Direction +} + +type CompositeIndex struct { + AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"` + Id *int64 `protobuf:"varint,2,req,name=id" json:"id,omitempty"` + Definition *Index `protobuf:"bytes,3,req,name=definition" json:"definition,omitempty"` + State *CompositeIndex_State `protobuf:"varint,4,req,name=state,enum=appengine.CompositeIndex_State" json:"state,omitempty"` + OnlyUseIfRequired *bool `protobuf:"varint,6,opt,name=only_use_if_required,json=onlyUseIfRequired,def=0" json:"only_use_if_required,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompositeIndex) Reset() { *m = CompositeIndex{} } +func (m *CompositeIndex) String() string { return proto.CompactTextString(m) } +func (*CompositeIndex) ProtoMessage() {} +func (*CompositeIndex) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{9} +} +func (m *CompositeIndex) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompositeIndex.Unmarshal(m, b) +} +func (m *CompositeIndex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompositeIndex.Marshal(b, m, deterministic) +} +func (dst *CompositeIndex) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompositeIndex.Merge(dst, src) +} +func (m *CompositeIndex) XXX_Size() int { + return xxx_messageInfo_CompositeIndex.Size(m) +} +func (m *CompositeIndex) XXX_DiscardUnknown() { + xxx_messageInfo_CompositeIndex.DiscardUnknown(m) +} + +var xxx_messageInfo_CompositeIndex proto.InternalMessageInfo + +const Default_CompositeIndex_OnlyUseIfRequired bool = false + +func (m *CompositeIndex) GetAppId() string { + if m != nil && m.AppId != nil { + return *m.AppId + } + return "" +} + +func (m *CompositeIndex) GetId() int64 { + if m != nil && m.Id != nil { + return *m.Id + } + return 0 +} + +func (m *CompositeIndex) GetDefinition() *Index { + if m != nil { + return m.Definition + } + return nil +} + +func (m *CompositeIndex) GetState() CompositeIndex_State { + if m != nil && m.State != nil { + return *m.State + } + return CompositeIndex_WRITE_ONLY +} + +func (m *CompositeIndex) GetOnlyUseIfRequired() bool { + if m != nil && m.OnlyUseIfRequired != nil { + return *m.OnlyUseIfRequired + } + return Default_CompositeIndex_OnlyUseIfRequired +} + +type IndexPostfix struct { + IndexValue []*IndexPostfix_IndexValue `protobuf:"bytes,1,rep,name=index_value,json=indexValue" json:"index_value,omitempty"` + Key *Reference `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"` + Before *bool `protobuf:"varint,3,opt,name=before,def=1" json:"before,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IndexPostfix) Reset() { *m = IndexPostfix{} } +func (m *IndexPostfix) String() string { return proto.CompactTextString(m) } +func (*IndexPostfix) ProtoMessage() {} +func (*IndexPostfix) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{10} +} +func (m *IndexPostfix) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IndexPostfix.Unmarshal(m, b) +} +func (m *IndexPostfix) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IndexPostfix.Marshal(b, m, deterministic) +} +func (dst *IndexPostfix) XXX_Merge(src proto.Message) { + xxx_messageInfo_IndexPostfix.Merge(dst, src) +} +func (m *IndexPostfix) XXX_Size() int { + return xxx_messageInfo_IndexPostfix.Size(m) +} +func (m *IndexPostfix) XXX_DiscardUnknown() { + xxx_messageInfo_IndexPostfix.DiscardUnknown(m) +} + +var xxx_messageInfo_IndexPostfix proto.InternalMessageInfo + +const Default_IndexPostfix_Before bool = true + +func (m *IndexPostfix) GetIndexValue() []*IndexPostfix_IndexValue { + if m != nil { + return m.IndexValue + } + return nil +} + +func (m *IndexPostfix) GetKey() *Reference { + if m != nil { + return m.Key + } + return nil +} + +func (m *IndexPostfix) GetBefore() bool { + if m != nil && m.Before != nil { + return *m.Before + } + return Default_IndexPostfix_Before +} + +type IndexPostfix_IndexValue struct { + PropertyName *string `protobuf:"bytes,1,req,name=property_name,json=propertyName" json:"property_name,omitempty"` + Value *PropertyValue `protobuf:"bytes,2,req,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IndexPostfix_IndexValue) Reset() { *m = IndexPostfix_IndexValue{} } +func (m *IndexPostfix_IndexValue) String() string { return proto.CompactTextString(m) } +func (*IndexPostfix_IndexValue) ProtoMessage() {} +func (*IndexPostfix_IndexValue) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{10, 0} +} +func (m *IndexPostfix_IndexValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IndexPostfix_IndexValue.Unmarshal(m, b) +} +func (m *IndexPostfix_IndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IndexPostfix_IndexValue.Marshal(b, m, deterministic) +} +func (dst *IndexPostfix_IndexValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_IndexPostfix_IndexValue.Merge(dst, src) +} +func (m *IndexPostfix_IndexValue) XXX_Size() int { + return xxx_messageInfo_IndexPostfix_IndexValue.Size(m) +} +func (m *IndexPostfix_IndexValue) XXX_DiscardUnknown() { + xxx_messageInfo_IndexPostfix_IndexValue.DiscardUnknown(m) +} + +var xxx_messageInfo_IndexPostfix_IndexValue proto.InternalMessageInfo + +func (m *IndexPostfix_IndexValue) GetPropertyName() string { + if m != nil && m.PropertyName != nil { + return *m.PropertyName + } + return "" +} + +func (m *IndexPostfix_IndexValue) GetValue() *PropertyValue { + if m != nil { + return m.Value + } + return nil +} + +type IndexPosition struct { + Key *string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` + Before *bool `protobuf:"varint,2,opt,name=before,def=1" json:"before,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IndexPosition) Reset() { *m = IndexPosition{} } +func (m *IndexPosition) String() string { return proto.CompactTextString(m) } +func (*IndexPosition) ProtoMessage() {} +func (*IndexPosition) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{11} +} +func (m *IndexPosition) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IndexPosition.Unmarshal(m, b) +} +func (m *IndexPosition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IndexPosition.Marshal(b, m, deterministic) +} +func (dst *IndexPosition) XXX_Merge(src proto.Message) { + xxx_messageInfo_IndexPosition.Merge(dst, src) +} +func (m *IndexPosition) XXX_Size() int { + return xxx_messageInfo_IndexPosition.Size(m) +} +func (m *IndexPosition) XXX_DiscardUnknown() { + xxx_messageInfo_IndexPosition.DiscardUnknown(m) +} + +var xxx_messageInfo_IndexPosition proto.InternalMessageInfo + +const Default_IndexPosition_Before bool = true + +func (m *IndexPosition) GetKey() string { + if m != nil && m.Key != nil { + return *m.Key + } + return "" +} + +func (m *IndexPosition) GetBefore() bool { + if m != nil && m.Before != nil { + return *m.Before + } + return Default_IndexPosition_Before +} + +type Snapshot struct { + Ts *int64 `protobuf:"varint,1,req,name=ts" json:"ts,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Snapshot) Reset() { *m = Snapshot{} } +func (m *Snapshot) String() string { return proto.CompactTextString(m) } +func (*Snapshot) ProtoMessage() {} +func (*Snapshot) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{12} +} +func (m *Snapshot) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Snapshot.Unmarshal(m, b) +} +func (m *Snapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Snapshot.Marshal(b, m, deterministic) +} +func (dst *Snapshot) XXX_Merge(src proto.Message) { + xxx_messageInfo_Snapshot.Merge(dst, src) +} +func (m *Snapshot) XXX_Size() int { + return xxx_messageInfo_Snapshot.Size(m) +} +func (m *Snapshot) XXX_DiscardUnknown() { + xxx_messageInfo_Snapshot.DiscardUnknown(m) +} + +var xxx_messageInfo_Snapshot proto.InternalMessageInfo + +func (m *Snapshot) GetTs() int64 { + if m != nil && m.Ts != nil { + return *m.Ts + } + return 0 +} + +type InternalHeader struct { + Qos *string `protobuf:"bytes,1,opt,name=qos" json:"qos,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InternalHeader) Reset() { *m = InternalHeader{} } +func (m *InternalHeader) String() string { return proto.CompactTextString(m) } +func (*InternalHeader) ProtoMessage() {} +func (*InternalHeader) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{13} +} +func (m *InternalHeader) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InternalHeader.Unmarshal(m, b) +} +func (m *InternalHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InternalHeader.Marshal(b, m, deterministic) +} +func (dst *InternalHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_InternalHeader.Merge(dst, src) +} +func (m *InternalHeader) XXX_Size() int { + return xxx_messageInfo_InternalHeader.Size(m) +} +func (m *InternalHeader) XXX_DiscardUnknown() { + xxx_messageInfo_InternalHeader.DiscardUnknown(m) +} + +var xxx_messageInfo_InternalHeader proto.InternalMessageInfo + +func (m *InternalHeader) GetQos() string { + if m != nil && m.Qos != nil { + return *m.Qos + } + return "" +} + +type Transaction struct { + Header *InternalHeader `protobuf:"bytes,4,opt,name=header" json:"header,omitempty"` + Handle *uint64 `protobuf:"fixed64,1,req,name=handle" json:"handle,omitempty"` + App *string `protobuf:"bytes,2,req,name=app" json:"app,omitempty"` + MarkChanges *bool `protobuf:"varint,3,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Transaction) Reset() { *m = Transaction{} } +func (m *Transaction) String() string { return proto.CompactTextString(m) } +func (*Transaction) ProtoMessage() {} +func (*Transaction) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{14} +} +func (m *Transaction) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Transaction.Unmarshal(m, b) +} +func (m *Transaction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Transaction.Marshal(b, m, deterministic) +} +func (dst *Transaction) XXX_Merge(src proto.Message) { + xxx_messageInfo_Transaction.Merge(dst, src) +} +func (m *Transaction) XXX_Size() int { + return xxx_messageInfo_Transaction.Size(m) +} +func (m *Transaction) XXX_DiscardUnknown() { + xxx_messageInfo_Transaction.DiscardUnknown(m) +} + +var xxx_messageInfo_Transaction proto.InternalMessageInfo + +const Default_Transaction_MarkChanges bool = false + +func (m *Transaction) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *Transaction) GetHandle() uint64 { + if m != nil && m.Handle != nil { + return *m.Handle + } + return 0 +} + +func (m *Transaction) GetApp() string { + if m != nil && m.App != nil { + return *m.App + } + return "" +} + +func (m *Transaction) GetMarkChanges() bool { + if m != nil && m.MarkChanges != nil { + return *m.MarkChanges + } + return Default_Transaction_MarkChanges +} + +type Query struct { + Header *InternalHeader `protobuf:"bytes,39,opt,name=header" json:"header,omitempty"` + App *string `protobuf:"bytes,1,req,name=app" json:"app,omitempty"` + NameSpace *string `protobuf:"bytes,29,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"` + Kind *string `protobuf:"bytes,3,opt,name=kind" json:"kind,omitempty"` + Ancestor *Reference `protobuf:"bytes,17,opt,name=ancestor" json:"ancestor,omitempty"` + Filter []*Query_Filter `protobuf:"group,4,rep,name=Filter,json=filter" json:"filter,omitempty"` + SearchQuery *string `protobuf:"bytes,8,opt,name=search_query,json=searchQuery" json:"search_query,omitempty"` + Order []*Query_Order `protobuf:"group,9,rep,name=Order,json=order" json:"order,omitempty"` + Hint *Query_Hint `protobuf:"varint,18,opt,name=hint,enum=appengine.Query_Hint" json:"hint,omitempty"` + Count *int32 `protobuf:"varint,23,opt,name=count" json:"count,omitempty"` + Offset *int32 `protobuf:"varint,12,opt,name=offset,def=0" json:"offset,omitempty"` + Limit *int32 `protobuf:"varint,16,opt,name=limit" json:"limit,omitempty"` + CompiledCursor *CompiledCursor `protobuf:"bytes,30,opt,name=compiled_cursor,json=compiledCursor" json:"compiled_cursor,omitempty"` + EndCompiledCursor *CompiledCursor `protobuf:"bytes,31,opt,name=end_compiled_cursor,json=endCompiledCursor" json:"end_compiled_cursor,omitempty"` + CompositeIndex []*CompositeIndex `protobuf:"bytes,19,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"` + RequirePerfectPlan *bool `protobuf:"varint,20,opt,name=require_perfect_plan,json=requirePerfectPlan,def=0" json:"require_perfect_plan,omitempty"` + KeysOnly *bool `protobuf:"varint,21,opt,name=keys_only,json=keysOnly,def=0" json:"keys_only,omitempty"` + Transaction *Transaction `protobuf:"bytes,22,opt,name=transaction" json:"transaction,omitempty"` + Compile *bool `protobuf:"varint,25,opt,name=compile,def=0" json:"compile,omitempty"` + FailoverMs *int64 `protobuf:"varint,26,opt,name=failover_ms,json=failoverMs" json:"failover_ms,omitempty"` + Strong *bool `protobuf:"varint,32,opt,name=strong" json:"strong,omitempty"` + PropertyName []string `protobuf:"bytes,33,rep,name=property_name,json=propertyName" json:"property_name,omitempty"` + GroupByPropertyName []string `protobuf:"bytes,34,rep,name=group_by_property_name,json=groupByPropertyName" json:"group_by_property_name,omitempty"` + Distinct *bool `protobuf:"varint,24,opt,name=distinct" json:"distinct,omitempty"` + MinSafeTimeSeconds *int64 `protobuf:"varint,35,opt,name=min_safe_time_seconds,json=minSafeTimeSeconds" json:"min_safe_time_seconds,omitempty"` + SafeReplicaName []string `protobuf:"bytes,36,rep,name=safe_replica_name,json=safeReplicaName" json:"safe_replica_name,omitempty"` + PersistOffset *bool `protobuf:"varint,37,opt,name=persist_offset,json=persistOffset,def=0" json:"persist_offset,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Query) Reset() { *m = Query{} } +func (m *Query) String() string { return proto.CompactTextString(m) } +func (*Query) ProtoMessage() {} +func (*Query) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15} +} +func (m *Query) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Query.Unmarshal(m, b) +} +func (m *Query) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Query.Marshal(b, m, deterministic) +} +func (dst *Query) XXX_Merge(src proto.Message) { + xxx_messageInfo_Query.Merge(dst, src) +} +func (m *Query) XXX_Size() int { + return xxx_messageInfo_Query.Size(m) +} +func (m *Query) XXX_DiscardUnknown() { + xxx_messageInfo_Query.DiscardUnknown(m) +} + +var xxx_messageInfo_Query proto.InternalMessageInfo + +const Default_Query_Offset int32 = 0 +const Default_Query_RequirePerfectPlan bool = false +const Default_Query_KeysOnly bool = false +const Default_Query_Compile bool = false +const Default_Query_PersistOffset bool = false + +func (m *Query) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *Query) GetApp() string { + if m != nil && m.App != nil { + return *m.App + } + return "" +} + +func (m *Query) GetNameSpace() string { + if m != nil && m.NameSpace != nil { + return *m.NameSpace + } + return "" +} + +func (m *Query) GetKind() string { + if m != nil && m.Kind != nil { + return *m.Kind + } + return "" +} + +func (m *Query) GetAncestor() *Reference { + if m != nil { + return m.Ancestor + } + return nil +} + +func (m *Query) GetFilter() []*Query_Filter { + if m != nil { + return m.Filter + } + return nil +} + +func (m *Query) GetSearchQuery() string { + if m != nil && m.SearchQuery != nil { + return *m.SearchQuery + } + return "" +} + +func (m *Query) GetOrder() []*Query_Order { + if m != nil { + return m.Order + } + return nil +} + +func (m *Query) GetHint() Query_Hint { + if m != nil && m.Hint != nil { + return *m.Hint + } + return Query_ORDER_FIRST +} + +func (m *Query) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +func (m *Query) GetOffset() int32 { + if m != nil && m.Offset != nil { + return *m.Offset + } + return Default_Query_Offset +} + +func (m *Query) GetLimit() int32 { + if m != nil && m.Limit != nil { + return *m.Limit + } + return 0 +} + +func (m *Query) GetCompiledCursor() *CompiledCursor { + if m != nil { + return m.CompiledCursor + } + return nil +} + +func (m *Query) GetEndCompiledCursor() *CompiledCursor { + if m != nil { + return m.EndCompiledCursor + } + return nil +} + +func (m *Query) GetCompositeIndex() []*CompositeIndex { + if m != nil { + return m.CompositeIndex + } + return nil +} + +func (m *Query) GetRequirePerfectPlan() bool { + if m != nil && m.RequirePerfectPlan != nil { + return *m.RequirePerfectPlan + } + return Default_Query_RequirePerfectPlan +} + +func (m *Query) GetKeysOnly() bool { + if m != nil && m.KeysOnly != nil { + return *m.KeysOnly + } + return Default_Query_KeysOnly +} + +func (m *Query) GetTransaction() *Transaction { + if m != nil { + return m.Transaction + } + return nil +} + +func (m *Query) GetCompile() bool { + if m != nil && m.Compile != nil { + return *m.Compile + } + return Default_Query_Compile +} + +func (m *Query) GetFailoverMs() int64 { + if m != nil && m.FailoverMs != nil { + return *m.FailoverMs + } + return 0 +} + +func (m *Query) GetStrong() bool { + if m != nil && m.Strong != nil { + return *m.Strong + } + return false +} + +func (m *Query) GetPropertyName() []string { + if m != nil { + return m.PropertyName + } + return nil +} + +func (m *Query) GetGroupByPropertyName() []string { + if m != nil { + return m.GroupByPropertyName + } + return nil +} + +func (m *Query) GetDistinct() bool { + if m != nil && m.Distinct != nil { + return *m.Distinct + } + return false +} + +func (m *Query) GetMinSafeTimeSeconds() int64 { + if m != nil && m.MinSafeTimeSeconds != nil { + return *m.MinSafeTimeSeconds + } + return 0 +} + +func (m *Query) GetSafeReplicaName() []string { + if m != nil { + return m.SafeReplicaName + } + return nil +} + +func (m *Query) GetPersistOffset() bool { + if m != nil && m.PersistOffset != nil { + return *m.PersistOffset + } + return Default_Query_PersistOffset +} + +type Query_Filter struct { + Op *Query_Filter_Operator `protobuf:"varint,6,req,name=op,enum=appengine.Query_Filter_Operator" json:"op,omitempty"` + Property []*Property `protobuf:"bytes,14,rep,name=property" json:"property,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Query_Filter) Reset() { *m = Query_Filter{} } +func (m *Query_Filter) String() string { return proto.CompactTextString(m) } +func (*Query_Filter) ProtoMessage() {} +func (*Query_Filter) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0} +} +func (m *Query_Filter) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Query_Filter.Unmarshal(m, b) +} +func (m *Query_Filter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Query_Filter.Marshal(b, m, deterministic) +} +func (dst *Query_Filter) XXX_Merge(src proto.Message) { + xxx_messageInfo_Query_Filter.Merge(dst, src) +} +func (m *Query_Filter) XXX_Size() int { + return xxx_messageInfo_Query_Filter.Size(m) +} +func (m *Query_Filter) XXX_DiscardUnknown() { + xxx_messageInfo_Query_Filter.DiscardUnknown(m) +} + +var xxx_messageInfo_Query_Filter proto.InternalMessageInfo + +func (m *Query_Filter) GetOp() Query_Filter_Operator { + if m != nil && m.Op != nil { + return *m.Op + } + return Query_Filter_LESS_THAN +} + +func (m *Query_Filter) GetProperty() []*Property { + if m != nil { + return m.Property + } + return nil +} + +type Query_Order struct { + Property *string `protobuf:"bytes,10,req,name=property" json:"property,omitempty"` + Direction *Query_Order_Direction `protobuf:"varint,11,opt,name=direction,enum=appengine.Query_Order_Direction,def=1" json:"direction,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Query_Order) Reset() { *m = Query_Order{} } +func (m *Query_Order) String() string { return proto.CompactTextString(m) } +func (*Query_Order) ProtoMessage() {} +func (*Query_Order) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 1} +} +func (m *Query_Order) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Query_Order.Unmarshal(m, b) +} +func (m *Query_Order) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Query_Order.Marshal(b, m, deterministic) +} +func (dst *Query_Order) XXX_Merge(src proto.Message) { + xxx_messageInfo_Query_Order.Merge(dst, src) +} +func (m *Query_Order) XXX_Size() int { + return xxx_messageInfo_Query_Order.Size(m) +} +func (m *Query_Order) XXX_DiscardUnknown() { + xxx_messageInfo_Query_Order.DiscardUnknown(m) +} + +var xxx_messageInfo_Query_Order proto.InternalMessageInfo + +const Default_Query_Order_Direction Query_Order_Direction = Query_Order_ASCENDING + +func (m *Query_Order) GetProperty() string { + if m != nil && m.Property != nil { + return *m.Property + } + return "" +} + +func (m *Query_Order) GetDirection() Query_Order_Direction { + if m != nil && m.Direction != nil { + return *m.Direction + } + return Default_Query_Order_Direction +} + +type CompiledQuery struct { + Primaryscan *CompiledQuery_PrimaryScan `protobuf:"group,1,req,name=PrimaryScan,json=primaryscan" json:"primaryscan,omitempty"` + Mergejoinscan []*CompiledQuery_MergeJoinScan `protobuf:"group,7,rep,name=MergeJoinScan,json=mergejoinscan" json:"mergejoinscan,omitempty"` + IndexDef *Index `protobuf:"bytes,21,opt,name=index_def,json=indexDef" json:"index_def,omitempty"` + Offset *int32 `protobuf:"varint,10,opt,name=offset,def=0" json:"offset,omitempty"` + Limit *int32 `protobuf:"varint,11,opt,name=limit" json:"limit,omitempty"` + KeysOnly *bool `protobuf:"varint,12,req,name=keys_only,json=keysOnly" json:"keys_only,omitempty"` + PropertyName []string `protobuf:"bytes,24,rep,name=property_name,json=propertyName" json:"property_name,omitempty"` + DistinctInfixSize *int32 `protobuf:"varint,25,opt,name=distinct_infix_size,json=distinctInfixSize" json:"distinct_infix_size,omitempty"` + Entityfilter *CompiledQuery_EntityFilter `protobuf:"group,13,opt,name=EntityFilter,json=entityfilter" json:"entityfilter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompiledQuery) Reset() { *m = CompiledQuery{} } +func (m *CompiledQuery) String() string { return proto.CompactTextString(m) } +func (*CompiledQuery) ProtoMessage() {} +func (*CompiledQuery) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16} +} +func (m *CompiledQuery) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompiledQuery.Unmarshal(m, b) +} +func (m *CompiledQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompiledQuery.Marshal(b, m, deterministic) +} +func (dst *CompiledQuery) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompiledQuery.Merge(dst, src) +} +func (m *CompiledQuery) XXX_Size() int { + return xxx_messageInfo_CompiledQuery.Size(m) +} +func (m *CompiledQuery) XXX_DiscardUnknown() { + xxx_messageInfo_CompiledQuery.DiscardUnknown(m) +} + +var xxx_messageInfo_CompiledQuery proto.InternalMessageInfo + +const Default_CompiledQuery_Offset int32 = 0 + +func (m *CompiledQuery) GetPrimaryscan() *CompiledQuery_PrimaryScan { + if m != nil { + return m.Primaryscan + } + return nil +} + +func (m *CompiledQuery) GetMergejoinscan() []*CompiledQuery_MergeJoinScan { + if m != nil { + return m.Mergejoinscan + } + return nil +} + +func (m *CompiledQuery) GetIndexDef() *Index { + if m != nil { + return m.IndexDef + } + return nil +} + +func (m *CompiledQuery) GetOffset() int32 { + if m != nil && m.Offset != nil { + return *m.Offset + } + return Default_CompiledQuery_Offset +} + +func (m *CompiledQuery) GetLimit() int32 { + if m != nil && m.Limit != nil { + return *m.Limit + } + return 0 +} + +func (m *CompiledQuery) GetKeysOnly() bool { + if m != nil && m.KeysOnly != nil { + return *m.KeysOnly + } + return false +} + +func (m *CompiledQuery) GetPropertyName() []string { + if m != nil { + return m.PropertyName + } + return nil +} + +func (m *CompiledQuery) GetDistinctInfixSize() int32 { + if m != nil && m.DistinctInfixSize != nil { + return *m.DistinctInfixSize + } + return 0 +} + +func (m *CompiledQuery) GetEntityfilter() *CompiledQuery_EntityFilter { + if m != nil { + return m.Entityfilter + } + return nil +} + +type CompiledQuery_PrimaryScan struct { + IndexName *string `protobuf:"bytes,2,opt,name=index_name,json=indexName" json:"index_name,omitempty"` + StartKey *string `protobuf:"bytes,3,opt,name=start_key,json=startKey" json:"start_key,omitempty"` + StartInclusive *bool `protobuf:"varint,4,opt,name=start_inclusive,json=startInclusive" json:"start_inclusive,omitempty"` + EndKey *string `protobuf:"bytes,5,opt,name=end_key,json=endKey" json:"end_key,omitempty"` + EndInclusive *bool `protobuf:"varint,6,opt,name=end_inclusive,json=endInclusive" json:"end_inclusive,omitempty"` + StartPostfixValue []string `protobuf:"bytes,22,rep,name=start_postfix_value,json=startPostfixValue" json:"start_postfix_value,omitempty"` + EndPostfixValue []string `protobuf:"bytes,23,rep,name=end_postfix_value,json=endPostfixValue" json:"end_postfix_value,omitempty"` + EndUnappliedLogTimestampUs *int64 `protobuf:"varint,19,opt,name=end_unapplied_log_timestamp_us,json=endUnappliedLogTimestampUs" json:"end_unapplied_log_timestamp_us,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompiledQuery_PrimaryScan) Reset() { *m = CompiledQuery_PrimaryScan{} } +func (m *CompiledQuery_PrimaryScan) String() string { return proto.CompactTextString(m) } +func (*CompiledQuery_PrimaryScan) ProtoMessage() {} +func (*CompiledQuery_PrimaryScan) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 0} +} +func (m *CompiledQuery_PrimaryScan) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompiledQuery_PrimaryScan.Unmarshal(m, b) +} +func (m *CompiledQuery_PrimaryScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompiledQuery_PrimaryScan.Marshal(b, m, deterministic) +} +func (dst *CompiledQuery_PrimaryScan) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompiledQuery_PrimaryScan.Merge(dst, src) +} +func (m *CompiledQuery_PrimaryScan) XXX_Size() int { + return xxx_messageInfo_CompiledQuery_PrimaryScan.Size(m) +} +func (m *CompiledQuery_PrimaryScan) XXX_DiscardUnknown() { + xxx_messageInfo_CompiledQuery_PrimaryScan.DiscardUnknown(m) +} + +var xxx_messageInfo_CompiledQuery_PrimaryScan proto.InternalMessageInfo + +func (m *CompiledQuery_PrimaryScan) GetIndexName() string { + if m != nil && m.IndexName != nil { + return *m.IndexName + } + return "" +} + +func (m *CompiledQuery_PrimaryScan) GetStartKey() string { + if m != nil && m.StartKey != nil { + return *m.StartKey + } + return "" +} + +func (m *CompiledQuery_PrimaryScan) GetStartInclusive() bool { + if m != nil && m.StartInclusive != nil { + return *m.StartInclusive + } + return false +} + +func (m *CompiledQuery_PrimaryScan) GetEndKey() string { + if m != nil && m.EndKey != nil { + return *m.EndKey + } + return "" +} + +func (m *CompiledQuery_PrimaryScan) GetEndInclusive() bool { + if m != nil && m.EndInclusive != nil { + return *m.EndInclusive + } + return false +} + +func (m *CompiledQuery_PrimaryScan) GetStartPostfixValue() []string { + if m != nil { + return m.StartPostfixValue + } + return nil +} + +func (m *CompiledQuery_PrimaryScan) GetEndPostfixValue() []string { + if m != nil { + return m.EndPostfixValue + } + return nil +} + +func (m *CompiledQuery_PrimaryScan) GetEndUnappliedLogTimestampUs() int64 { + if m != nil && m.EndUnappliedLogTimestampUs != nil { + return *m.EndUnappliedLogTimestampUs + } + return 0 +} + +type CompiledQuery_MergeJoinScan struct { + IndexName *string `protobuf:"bytes,8,req,name=index_name,json=indexName" json:"index_name,omitempty"` + PrefixValue []string `protobuf:"bytes,9,rep,name=prefix_value,json=prefixValue" json:"prefix_value,omitempty"` + ValuePrefix *bool `protobuf:"varint,20,opt,name=value_prefix,json=valuePrefix,def=0" json:"value_prefix,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompiledQuery_MergeJoinScan) Reset() { *m = CompiledQuery_MergeJoinScan{} } +func (m *CompiledQuery_MergeJoinScan) String() string { return proto.CompactTextString(m) } +func (*CompiledQuery_MergeJoinScan) ProtoMessage() {} +func (*CompiledQuery_MergeJoinScan) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 1} +} +func (m *CompiledQuery_MergeJoinScan) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompiledQuery_MergeJoinScan.Unmarshal(m, b) +} +func (m *CompiledQuery_MergeJoinScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompiledQuery_MergeJoinScan.Marshal(b, m, deterministic) +} +func (dst *CompiledQuery_MergeJoinScan) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompiledQuery_MergeJoinScan.Merge(dst, src) +} +func (m *CompiledQuery_MergeJoinScan) XXX_Size() int { + return xxx_messageInfo_CompiledQuery_MergeJoinScan.Size(m) +} +func (m *CompiledQuery_MergeJoinScan) XXX_DiscardUnknown() { + xxx_messageInfo_CompiledQuery_MergeJoinScan.DiscardUnknown(m) +} + +var xxx_messageInfo_CompiledQuery_MergeJoinScan proto.InternalMessageInfo + +const Default_CompiledQuery_MergeJoinScan_ValuePrefix bool = false + +func (m *CompiledQuery_MergeJoinScan) GetIndexName() string { + if m != nil && m.IndexName != nil { + return *m.IndexName + } + return "" +} + +func (m *CompiledQuery_MergeJoinScan) GetPrefixValue() []string { + if m != nil { + return m.PrefixValue + } + return nil +} + +func (m *CompiledQuery_MergeJoinScan) GetValuePrefix() bool { + if m != nil && m.ValuePrefix != nil { + return *m.ValuePrefix + } + return Default_CompiledQuery_MergeJoinScan_ValuePrefix +} + +type CompiledQuery_EntityFilter struct { + Distinct *bool `protobuf:"varint,14,opt,name=distinct,def=0" json:"distinct,omitempty"` + Kind *string `protobuf:"bytes,17,opt,name=kind" json:"kind,omitempty"` + Ancestor *Reference `protobuf:"bytes,18,opt,name=ancestor" json:"ancestor,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompiledQuery_EntityFilter) Reset() { *m = CompiledQuery_EntityFilter{} } +func (m *CompiledQuery_EntityFilter) String() string { return proto.CompactTextString(m) } +func (*CompiledQuery_EntityFilter) ProtoMessage() {} +func (*CompiledQuery_EntityFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 2} +} +func (m *CompiledQuery_EntityFilter) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompiledQuery_EntityFilter.Unmarshal(m, b) +} +func (m *CompiledQuery_EntityFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompiledQuery_EntityFilter.Marshal(b, m, deterministic) +} +func (dst *CompiledQuery_EntityFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompiledQuery_EntityFilter.Merge(dst, src) +} +func (m *CompiledQuery_EntityFilter) XXX_Size() int { + return xxx_messageInfo_CompiledQuery_EntityFilter.Size(m) +} +func (m *CompiledQuery_EntityFilter) XXX_DiscardUnknown() { + xxx_messageInfo_CompiledQuery_EntityFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_CompiledQuery_EntityFilter proto.InternalMessageInfo + +const Default_CompiledQuery_EntityFilter_Distinct bool = false + +func (m *CompiledQuery_EntityFilter) GetDistinct() bool { + if m != nil && m.Distinct != nil { + return *m.Distinct + } + return Default_CompiledQuery_EntityFilter_Distinct +} + +func (m *CompiledQuery_EntityFilter) GetKind() string { + if m != nil && m.Kind != nil { + return *m.Kind + } + return "" +} + +func (m *CompiledQuery_EntityFilter) GetAncestor() *Reference { + if m != nil { + return m.Ancestor + } + return nil +} + +type CompiledCursor struct { + Position *CompiledCursor_Position `protobuf:"group,2,opt,name=Position,json=position" json:"position,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompiledCursor) Reset() { *m = CompiledCursor{} } +func (m *CompiledCursor) String() string { return proto.CompactTextString(m) } +func (*CompiledCursor) ProtoMessage() {} +func (*CompiledCursor) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17} +} +func (m *CompiledCursor) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompiledCursor.Unmarshal(m, b) +} +func (m *CompiledCursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompiledCursor.Marshal(b, m, deterministic) +} +func (dst *CompiledCursor) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompiledCursor.Merge(dst, src) +} +func (m *CompiledCursor) XXX_Size() int { + return xxx_messageInfo_CompiledCursor.Size(m) +} +func (m *CompiledCursor) XXX_DiscardUnknown() { + xxx_messageInfo_CompiledCursor.DiscardUnknown(m) +} + +var xxx_messageInfo_CompiledCursor proto.InternalMessageInfo + +func (m *CompiledCursor) GetPosition() *CompiledCursor_Position { + if m != nil { + return m.Position + } + return nil +} + +type CompiledCursor_Position struct { + StartKey *string `protobuf:"bytes,27,opt,name=start_key,json=startKey" json:"start_key,omitempty"` + Indexvalue []*CompiledCursor_Position_IndexValue `protobuf:"group,29,rep,name=IndexValue,json=indexvalue" json:"indexvalue,omitempty"` + Key *Reference `protobuf:"bytes,32,opt,name=key" json:"key,omitempty"` + StartInclusive *bool `protobuf:"varint,28,opt,name=start_inclusive,json=startInclusive,def=1" json:"start_inclusive,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompiledCursor_Position) Reset() { *m = CompiledCursor_Position{} } +func (m *CompiledCursor_Position) String() string { return proto.CompactTextString(m) } +func (*CompiledCursor_Position) ProtoMessage() {} +func (*CompiledCursor_Position) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17, 0} +} +func (m *CompiledCursor_Position) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompiledCursor_Position.Unmarshal(m, b) +} +func (m *CompiledCursor_Position) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompiledCursor_Position.Marshal(b, m, deterministic) +} +func (dst *CompiledCursor_Position) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompiledCursor_Position.Merge(dst, src) +} +func (m *CompiledCursor_Position) XXX_Size() int { + return xxx_messageInfo_CompiledCursor_Position.Size(m) +} +func (m *CompiledCursor_Position) XXX_DiscardUnknown() { + xxx_messageInfo_CompiledCursor_Position.DiscardUnknown(m) +} + +var xxx_messageInfo_CompiledCursor_Position proto.InternalMessageInfo + +const Default_CompiledCursor_Position_StartInclusive bool = true + +func (m *CompiledCursor_Position) GetStartKey() string { + if m != nil && m.StartKey != nil { + return *m.StartKey + } + return "" +} + +func (m *CompiledCursor_Position) GetIndexvalue() []*CompiledCursor_Position_IndexValue { + if m != nil { + return m.Indexvalue + } + return nil +} + +func (m *CompiledCursor_Position) GetKey() *Reference { + if m != nil { + return m.Key + } + return nil +} + +func (m *CompiledCursor_Position) GetStartInclusive() bool { + if m != nil && m.StartInclusive != nil { + return *m.StartInclusive + } + return Default_CompiledCursor_Position_StartInclusive +} + +type CompiledCursor_Position_IndexValue struct { + Property *string `protobuf:"bytes,30,opt,name=property" json:"property,omitempty"` + Value *PropertyValue `protobuf:"bytes,31,req,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompiledCursor_Position_IndexValue) Reset() { *m = CompiledCursor_Position_IndexValue{} } +func (m *CompiledCursor_Position_IndexValue) String() string { return proto.CompactTextString(m) } +func (*CompiledCursor_Position_IndexValue) ProtoMessage() {} +func (*CompiledCursor_Position_IndexValue) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17, 0, 0} +} +func (m *CompiledCursor_Position_IndexValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompiledCursor_Position_IndexValue.Unmarshal(m, b) +} +func (m *CompiledCursor_Position_IndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompiledCursor_Position_IndexValue.Marshal(b, m, deterministic) +} +func (dst *CompiledCursor_Position_IndexValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompiledCursor_Position_IndexValue.Merge(dst, src) +} +func (m *CompiledCursor_Position_IndexValue) XXX_Size() int { + return xxx_messageInfo_CompiledCursor_Position_IndexValue.Size(m) +} +func (m *CompiledCursor_Position_IndexValue) XXX_DiscardUnknown() { + xxx_messageInfo_CompiledCursor_Position_IndexValue.DiscardUnknown(m) +} + +var xxx_messageInfo_CompiledCursor_Position_IndexValue proto.InternalMessageInfo + +func (m *CompiledCursor_Position_IndexValue) GetProperty() string { + if m != nil && m.Property != nil { + return *m.Property + } + return "" +} + +func (m *CompiledCursor_Position_IndexValue) GetValue() *PropertyValue { + if m != nil { + return m.Value + } + return nil +} + +type Cursor struct { + Cursor *uint64 `protobuf:"fixed64,1,req,name=cursor" json:"cursor,omitempty"` + App *string `protobuf:"bytes,2,opt,name=app" json:"app,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Cursor) Reset() { *m = Cursor{} } +func (m *Cursor) String() string { return proto.CompactTextString(m) } +func (*Cursor) ProtoMessage() {} +func (*Cursor) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{18} +} +func (m *Cursor) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Cursor.Unmarshal(m, b) +} +func (m *Cursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Cursor.Marshal(b, m, deterministic) +} +func (dst *Cursor) XXX_Merge(src proto.Message) { + xxx_messageInfo_Cursor.Merge(dst, src) +} +func (m *Cursor) XXX_Size() int { + return xxx_messageInfo_Cursor.Size(m) +} +func (m *Cursor) XXX_DiscardUnknown() { + xxx_messageInfo_Cursor.DiscardUnknown(m) +} + +var xxx_messageInfo_Cursor proto.InternalMessageInfo + +func (m *Cursor) GetCursor() uint64 { + if m != nil && m.Cursor != nil { + return *m.Cursor + } + return 0 +} + +func (m *Cursor) GetApp() string { + if m != nil && m.App != nil { + return *m.App + } + return "" +} + +type Error struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Error) Reset() { *m = Error{} } +func (m *Error) String() string { return proto.CompactTextString(m) } +func (*Error) ProtoMessage() {} +func (*Error) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{19} +} +func (m *Error) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Error.Unmarshal(m, b) +} +func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Error.Marshal(b, m, deterministic) +} +func (dst *Error) XXX_Merge(src proto.Message) { + xxx_messageInfo_Error.Merge(dst, src) +} +func (m *Error) XXX_Size() int { + return xxx_messageInfo_Error.Size(m) +} +func (m *Error) XXX_DiscardUnknown() { + xxx_messageInfo_Error.DiscardUnknown(m) +} + +var xxx_messageInfo_Error proto.InternalMessageInfo + +type Cost struct { + IndexWrites *int32 `protobuf:"varint,1,opt,name=index_writes,json=indexWrites" json:"index_writes,omitempty"` + IndexWriteBytes *int32 `protobuf:"varint,2,opt,name=index_write_bytes,json=indexWriteBytes" json:"index_write_bytes,omitempty"` + EntityWrites *int32 `protobuf:"varint,3,opt,name=entity_writes,json=entityWrites" json:"entity_writes,omitempty"` + EntityWriteBytes *int32 `protobuf:"varint,4,opt,name=entity_write_bytes,json=entityWriteBytes" json:"entity_write_bytes,omitempty"` + Commitcost *Cost_CommitCost `protobuf:"group,5,opt,name=CommitCost,json=commitcost" json:"commitcost,omitempty"` + ApproximateStorageDelta *int32 `protobuf:"varint,8,opt,name=approximate_storage_delta,json=approximateStorageDelta" json:"approximate_storage_delta,omitempty"` + IdSequenceUpdates *int32 `protobuf:"varint,9,opt,name=id_sequence_updates,json=idSequenceUpdates" json:"id_sequence_updates,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Cost) Reset() { *m = Cost{} } +func (m *Cost) String() string { return proto.CompactTextString(m) } +func (*Cost) ProtoMessage() {} +func (*Cost) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{20} +} +func (m *Cost) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Cost.Unmarshal(m, b) +} +func (m *Cost) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Cost.Marshal(b, m, deterministic) +} +func (dst *Cost) XXX_Merge(src proto.Message) { + xxx_messageInfo_Cost.Merge(dst, src) +} +func (m *Cost) XXX_Size() int { + return xxx_messageInfo_Cost.Size(m) +} +func (m *Cost) XXX_DiscardUnknown() { + xxx_messageInfo_Cost.DiscardUnknown(m) +} + +var xxx_messageInfo_Cost proto.InternalMessageInfo + +func (m *Cost) GetIndexWrites() int32 { + if m != nil && m.IndexWrites != nil { + return *m.IndexWrites + } + return 0 +} + +func (m *Cost) GetIndexWriteBytes() int32 { + if m != nil && m.IndexWriteBytes != nil { + return *m.IndexWriteBytes + } + return 0 +} + +func (m *Cost) GetEntityWrites() int32 { + if m != nil && m.EntityWrites != nil { + return *m.EntityWrites + } + return 0 +} + +func (m *Cost) GetEntityWriteBytes() int32 { + if m != nil && m.EntityWriteBytes != nil { + return *m.EntityWriteBytes + } + return 0 +} + +func (m *Cost) GetCommitcost() *Cost_CommitCost { + if m != nil { + return m.Commitcost + } + return nil +} + +func (m *Cost) GetApproximateStorageDelta() int32 { + if m != nil && m.ApproximateStorageDelta != nil { + return *m.ApproximateStorageDelta + } + return 0 +} + +func (m *Cost) GetIdSequenceUpdates() int32 { + if m != nil && m.IdSequenceUpdates != nil { + return *m.IdSequenceUpdates + } + return 0 +} + +type Cost_CommitCost struct { + RequestedEntityPuts *int32 `protobuf:"varint,6,opt,name=requested_entity_puts,json=requestedEntityPuts" json:"requested_entity_puts,omitempty"` + RequestedEntityDeletes *int32 `protobuf:"varint,7,opt,name=requested_entity_deletes,json=requestedEntityDeletes" json:"requested_entity_deletes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Cost_CommitCost) Reset() { *m = Cost_CommitCost{} } +func (m *Cost_CommitCost) String() string { return proto.CompactTextString(m) } +func (*Cost_CommitCost) ProtoMessage() {} +func (*Cost_CommitCost) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{20, 0} +} +func (m *Cost_CommitCost) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Cost_CommitCost.Unmarshal(m, b) +} +func (m *Cost_CommitCost) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Cost_CommitCost.Marshal(b, m, deterministic) +} +func (dst *Cost_CommitCost) XXX_Merge(src proto.Message) { + xxx_messageInfo_Cost_CommitCost.Merge(dst, src) +} +func (m *Cost_CommitCost) XXX_Size() int { + return xxx_messageInfo_Cost_CommitCost.Size(m) +} +func (m *Cost_CommitCost) XXX_DiscardUnknown() { + xxx_messageInfo_Cost_CommitCost.DiscardUnknown(m) +} + +var xxx_messageInfo_Cost_CommitCost proto.InternalMessageInfo + +func (m *Cost_CommitCost) GetRequestedEntityPuts() int32 { + if m != nil && m.RequestedEntityPuts != nil { + return *m.RequestedEntityPuts + } + return 0 +} + +func (m *Cost_CommitCost) GetRequestedEntityDeletes() int32 { + if m != nil && m.RequestedEntityDeletes != nil { + return *m.RequestedEntityDeletes + } + return 0 +} + +type GetRequest struct { + Header *InternalHeader `protobuf:"bytes,6,opt,name=header" json:"header,omitempty"` + Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"` + Transaction *Transaction `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"` + FailoverMs *int64 `protobuf:"varint,3,opt,name=failover_ms,json=failoverMs" json:"failover_ms,omitempty"` + Strong *bool `protobuf:"varint,4,opt,name=strong" json:"strong,omitempty"` + AllowDeferred *bool `protobuf:"varint,5,opt,name=allow_deferred,json=allowDeferred,def=0" json:"allow_deferred,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetRequest) Reset() { *m = GetRequest{} } +func (m *GetRequest) String() string { return proto.CompactTextString(m) } +func (*GetRequest) ProtoMessage() {} +func (*GetRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{21} +} +func (m *GetRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetRequest.Unmarshal(m, b) +} +func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic) +} +func (dst *GetRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetRequest.Merge(dst, src) +} +func (m *GetRequest) XXX_Size() int { + return xxx_messageInfo_GetRequest.Size(m) +} +func (m *GetRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetRequest proto.InternalMessageInfo + +const Default_GetRequest_AllowDeferred bool = false + +func (m *GetRequest) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *GetRequest) GetKey() []*Reference { + if m != nil { + return m.Key + } + return nil +} + +func (m *GetRequest) GetTransaction() *Transaction { + if m != nil { + return m.Transaction + } + return nil +} + +func (m *GetRequest) GetFailoverMs() int64 { + if m != nil && m.FailoverMs != nil { + return *m.FailoverMs + } + return 0 +} + +func (m *GetRequest) GetStrong() bool { + if m != nil && m.Strong != nil { + return *m.Strong + } + return false +} + +func (m *GetRequest) GetAllowDeferred() bool { + if m != nil && m.AllowDeferred != nil { + return *m.AllowDeferred + } + return Default_GetRequest_AllowDeferred +} + +type GetResponse struct { + Entity []*GetResponse_Entity `protobuf:"group,1,rep,name=Entity,json=entity" json:"entity,omitempty"` + Deferred []*Reference `protobuf:"bytes,5,rep,name=deferred" json:"deferred,omitempty"` + InOrder *bool `protobuf:"varint,6,opt,name=in_order,json=inOrder,def=1" json:"in_order,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetResponse) Reset() { *m = GetResponse{} } +func (m *GetResponse) String() string { return proto.CompactTextString(m) } +func (*GetResponse) ProtoMessage() {} +func (*GetResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{22} +} +func (m *GetResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetResponse.Unmarshal(m, b) +} +func (m *GetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetResponse.Marshal(b, m, deterministic) +} +func (dst *GetResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetResponse.Merge(dst, src) +} +func (m *GetResponse) XXX_Size() int { + return xxx_messageInfo_GetResponse.Size(m) +} +func (m *GetResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetResponse proto.InternalMessageInfo + +const Default_GetResponse_InOrder bool = true + +func (m *GetResponse) GetEntity() []*GetResponse_Entity { + if m != nil { + return m.Entity + } + return nil +} + +func (m *GetResponse) GetDeferred() []*Reference { + if m != nil { + return m.Deferred + } + return nil +} + +func (m *GetResponse) GetInOrder() bool { + if m != nil && m.InOrder != nil { + return *m.InOrder + } + return Default_GetResponse_InOrder +} + +type GetResponse_Entity struct { + Entity *EntityProto `protobuf:"bytes,2,opt,name=entity" json:"entity,omitempty"` + Key *Reference `protobuf:"bytes,4,opt,name=key" json:"key,omitempty"` + Version *int64 `protobuf:"varint,3,opt,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetResponse_Entity) Reset() { *m = GetResponse_Entity{} } +func (m *GetResponse_Entity) String() string { return proto.CompactTextString(m) } +func (*GetResponse_Entity) ProtoMessage() {} +func (*GetResponse_Entity) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{22, 0} +} +func (m *GetResponse_Entity) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetResponse_Entity.Unmarshal(m, b) +} +func (m *GetResponse_Entity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetResponse_Entity.Marshal(b, m, deterministic) +} +func (dst *GetResponse_Entity) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetResponse_Entity.Merge(dst, src) +} +func (m *GetResponse_Entity) XXX_Size() int { + return xxx_messageInfo_GetResponse_Entity.Size(m) +} +func (m *GetResponse_Entity) XXX_DiscardUnknown() { + xxx_messageInfo_GetResponse_Entity.DiscardUnknown(m) +} + +var xxx_messageInfo_GetResponse_Entity proto.InternalMessageInfo + +func (m *GetResponse_Entity) GetEntity() *EntityProto { + if m != nil { + return m.Entity + } + return nil +} + +func (m *GetResponse_Entity) GetKey() *Reference { + if m != nil { + return m.Key + } + return nil +} + +func (m *GetResponse_Entity) GetVersion() int64 { + if m != nil && m.Version != nil { + return *m.Version + } + return 0 +} + +type PutRequest struct { + Header *InternalHeader `protobuf:"bytes,11,opt,name=header" json:"header,omitempty"` + Entity []*EntityProto `protobuf:"bytes,1,rep,name=entity" json:"entity,omitempty"` + Transaction *Transaction `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"` + CompositeIndex []*CompositeIndex `protobuf:"bytes,3,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"` + Trusted *bool `protobuf:"varint,4,opt,name=trusted,def=0" json:"trusted,omitempty"` + Force *bool `protobuf:"varint,7,opt,name=force,def=0" json:"force,omitempty"` + MarkChanges *bool `protobuf:"varint,8,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"` + Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"` + AutoIdPolicy *PutRequest_AutoIdPolicy `protobuf:"varint,10,opt,name=auto_id_policy,json=autoIdPolicy,enum=appengine.PutRequest_AutoIdPolicy,def=0" json:"auto_id_policy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PutRequest) Reset() { *m = PutRequest{} } +func (m *PutRequest) String() string { return proto.CompactTextString(m) } +func (*PutRequest) ProtoMessage() {} +func (*PutRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{23} +} +func (m *PutRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PutRequest.Unmarshal(m, b) +} +func (m *PutRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PutRequest.Marshal(b, m, deterministic) +} +func (dst *PutRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PutRequest.Merge(dst, src) +} +func (m *PutRequest) XXX_Size() int { + return xxx_messageInfo_PutRequest.Size(m) +} +func (m *PutRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PutRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PutRequest proto.InternalMessageInfo + +const Default_PutRequest_Trusted bool = false +const Default_PutRequest_Force bool = false +const Default_PutRequest_MarkChanges bool = false +const Default_PutRequest_AutoIdPolicy PutRequest_AutoIdPolicy = PutRequest_CURRENT + +func (m *PutRequest) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *PutRequest) GetEntity() []*EntityProto { + if m != nil { + return m.Entity + } + return nil +} + +func (m *PutRequest) GetTransaction() *Transaction { + if m != nil { + return m.Transaction + } + return nil +} + +func (m *PutRequest) GetCompositeIndex() []*CompositeIndex { + if m != nil { + return m.CompositeIndex + } + return nil +} + +func (m *PutRequest) GetTrusted() bool { + if m != nil && m.Trusted != nil { + return *m.Trusted + } + return Default_PutRequest_Trusted +} + +func (m *PutRequest) GetForce() bool { + if m != nil && m.Force != nil { + return *m.Force + } + return Default_PutRequest_Force +} + +func (m *PutRequest) GetMarkChanges() bool { + if m != nil && m.MarkChanges != nil { + return *m.MarkChanges + } + return Default_PutRequest_MarkChanges +} + +func (m *PutRequest) GetSnapshot() []*Snapshot { + if m != nil { + return m.Snapshot + } + return nil +} + +func (m *PutRequest) GetAutoIdPolicy() PutRequest_AutoIdPolicy { + if m != nil && m.AutoIdPolicy != nil { + return *m.AutoIdPolicy + } + return Default_PutRequest_AutoIdPolicy +} + +type PutResponse struct { + Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"` + Cost *Cost `protobuf:"bytes,2,opt,name=cost" json:"cost,omitempty"` + Version []int64 `protobuf:"varint,3,rep,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PutResponse) Reset() { *m = PutResponse{} } +func (m *PutResponse) String() string { return proto.CompactTextString(m) } +func (*PutResponse) ProtoMessage() {} +func (*PutResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{24} +} +func (m *PutResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PutResponse.Unmarshal(m, b) +} +func (m *PutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PutResponse.Marshal(b, m, deterministic) +} +func (dst *PutResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PutResponse.Merge(dst, src) +} +func (m *PutResponse) XXX_Size() int { + return xxx_messageInfo_PutResponse.Size(m) +} +func (m *PutResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PutResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PutResponse proto.InternalMessageInfo + +func (m *PutResponse) GetKey() []*Reference { + if m != nil { + return m.Key + } + return nil +} + +func (m *PutResponse) GetCost() *Cost { + if m != nil { + return m.Cost + } + return nil +} + +func (m *PutResponse) GetVersion() []int64 { + if m != nil { + return m.Version + } + return nil +} + +type TouchRequest struct { + Header *InternalHeader `protobuf:"bytes,10,opt,name=header" json:"header,omitempty"` + Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"` + CompositeIndex []*CompositeIndex `protobuf:"bytes,2,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"` + Force *bool `protobuf:"varint,3,opt,name=force,def=0" json:"force,omitempty"` + Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TouchRequest) Reset() { *m = TouchRequest{} } +func (m *TouchRequest) String() string { return proto.CompactTextString(m) } +func (*TouchRequest) ProtoMessage() {} +func (*TouchRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{25} +} +func (m *TouchRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TouchRequest.Unmarshal(m, b) +} +func (m *TouchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TouchRequest.Marshal(b, m, deterministic) +} +func (dst *TouchRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TouchRequest.Merge(dst, src) +} +func (m *TouchRequest) XXX_Size() int { + return xxx_messageInfo_TouchRequest.Size(m) +} +func (m *TouchRequest) XXX_DiscardUnknown() { + xxx_messageInfo_TouchRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_TouchRequest proto.InternalMessageInfo + +const Default_TouchRequest_Force bool = false + +func (m *TouchRequest) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *TouchRequest) GetKey() []*Reference { + if m != nil { + return m.Key + } + return nil +} + +func (m *TouchRequest) GetCompositeIndex() []*CompositeIndex { + if m != nil { + return m.CompositeIndex + } + return nil +} + +func (m *TouchRequest) GetForce() bool { + if m != nil && m.Force != nil { + return *m.Force + } + return Default_TouchRequest_Force +} + +func (m *TouchRequest) GetSnapshot() []*Snapshot { + if m != nil { + return m.Snapshot + } + return nil +} + +type TouchResponse struct { + Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TouchResponse) Reset() { *m = TouchResponse{} } +func (m *TouchResponse) String() string { return proto.CompactTextString(m) } +func (*TouchResponse) ProtoMessage() {} +func (*TouchResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{26} +} +func (m *TouchResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TouchResponse.Unmarshal(m, b) +} +func (m *TouchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TouchResponse.Marshal(b, m, deterministic) +} +func (dst *TouchResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TouchResponse.Merge(dst, src) +} +func (m *TouchResponse) XXX_Size() int { + return xxx_messageInfo_TouchResponse.Size(m) +} +func (m *TouchResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TouchResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TouchResponse proto.InternalMessageInfo + +func (m *TouchResponse) GetCost() *Cost { + if m != nil { + return m.Cost + } + return nil +} + +type DeleteRequest struct { + Header *InternalHeader `protobuf:"bytes,10,opt,name=header" json:"header,omitempty"` + Key []*Reference `protobuf:"bytes,6,rep,name=key" json:"key,omitempty"` + Transaction *Transaction `protobuf:"bytes,5,opt,name=transaction" json:"transaction,omitempty"` + Trusted *bool `protobuf:"varint,4,opt,name=trusted,def=0" json:"trusted,omitempty"` + Force *bool `protobuf:"varint,7,opt,name=force,def=0" json:"force,omitempty"` + MarkChanges *bool `protobuf:"varint,8,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"` + Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteRequest) Reset() { *m = DeleteRequest{} } +func (m *DeleteRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteRequest) ProtoMessage() {} +func (*DeleteRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{27} +} +func (m *DeleteRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteRequest.Unmarshal(m, b) +} +func (m *DeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteRequest.Marshal(b, m, deterministic) +} +func (dst *DeleteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteRequest.Merge(dst, src) +} +func (m *DeleteRequest) XXX_Size() int { + return xxx_messageInfo_DeleteRequest.Size(m) +} +func (m *DeleteRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteRequest proto.InternalMessageInfo + +const Default_DeleteRequest_Trusted bool = false +const Default_DeleteRequest_Force bool = false +const Default_DeleteRequest_MarkChanges bool = false + +func (m *DeleteRequest) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *DeleteRequest) GetKey() []*Reference { + if m != nil { + return m.Key + } + return nil +} + +func (m *DeleteRequest) GetTransaction() *Transaction { + if m != nil { + return m.Transaction + } + return nil +} + +func (m *DeleteRequest) GetTrusted() bool { + if m != nil && m.Trusted != nil { + return *m.Trusted + } + return Default_DeleteRequest_Trusted +} + +func (m *DeleteRequest) GetForce() bool { + if m != nil && m.Force != nil { + return *m.Force + } + return Default_DeleteRequest_Force +} + +func (m *DeleteRequest) GetMarkChanges() bool { + if m != nil && m.MarkChanges != nil { + return *m.MarkChanges + } + return Default_DeleteRequest_MarkChanges +} + +func (m *DeleteRequest) GetSnapshot() []*Snapshot { + if m != nil { + return m.Snapshot + } + return nil +} + +type DeleteResponse struct { + Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"` + Version []int64 `protobuf:"varint,3,rep,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteResponse) Reset() { *m = DeleteResponse{} } +func (m *DeleteResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteResponse) ProtoMessage() {} +func (*DeleteResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{28} +} +func (m *DeleteResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteResponse.Unmarshal(m, b) +} +func (m *DeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteResponse.Marshal(b, m, deterministic) +} +func (dst *DeleteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteResponse.Merge(dst, src) +} +func (m *DeleteResponse) XXX_Size() int { + return xxx_messageInfo_DeleteResponse.Size(m) +} +func (m *DeleteResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo + +func (m *DeleteResponse) GetCost() *Cost { + if m != nil { + return m.Cost + } + return nil +} + +func (m *DeleteResponse) GetVersion() []int64 { + if m != nil { + return m.Version + } + return nil +} + +type NextRequest struct { + Header *InternalHeader `protobuf:"bytes,5,opt,name=header" json:"header,omitempty"` + Cursor *Cursor `protobuf:"bytes,1,req,name=cursor" json:"cursor,omitempty"` + Count *int32 `protobuf:"varint,2,opt,name=count" json:"count,omitempty"` + Offset *int32 `protobuf:"varint,4,opt,name=offset,def=0" json:"offset,omitempty"` + Compile *bool `protobuf:"varint,3,opt,name=compile,def=0" json:"compile,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NextRequest) Reset() { *m = NextRequest{} } +func (m *NextRequest) String() string { return proto.CompactTextString(m) } +func (*NextRequest) ProtoMessage() {} +func (*NextRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{29} +} +func (m *NextRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NextRequest.Unmarshal(m, b) +} +func (m *NextRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NextRequest.Marshal(b, m, deterministic) +} +func (dst *NextRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_NextRequest.Merge(dst, src) +} +func (m *NextRequest) XXX_Size() int { + return xxx_messageInfo_NextRequest.Size(m) +} +func (m *NextRequest) XXX_DiscardUnknown() { + xxx_messageInfo_NextRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_NextRequest proto.InternalMessageInfo + +const Default_NextRequest_Offset int32 = 0 +const Default_NextRequest_Compile bool = false + +func (m *NextRequest) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *NextRequest) GetCursor() *Cursor { + if m != nil { + return m.Cursor + } + return nil +} + +func (m *NextRequest) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +func (m *NextRequest) GetOffset() int32 { + if m != nil && m.Offset != nil { + return *m.Offset + } + return Default_NextRequest_Offset +} + +func (m *NextRequest) GetCompile() bool { + if m != nil && m.Compile != nil { + return *m.Compile + } + return Default_NextRequest_Compile +} + +type QueryResult struct { + Cursor *Cursor `protobuf:"bytes,1,opt,name=cursor" json:"cursor,omitempty"` + Result []*EntityProto `protobuf:"bytes,2,rep,name=result" json:"result,omitempty"` + SkippedResults *int32 `protobuf:"varint,7,opt,name=skipped_results,json=skippedResults" json:"skipped_results,omitempty"` + MoreResults *bool `protobuf:"varint,3,req,name=more_results,json=moreResults" json:"more_results,omitempty"` + KeysOnly *bool `protobuf:"varint,4,opt,name=keys_only,json=keysOnly" json:"keys_only,omitempty"` + IndexOnly *bool `protobuf:"varint,9,opt,name=index_only,json=indexOnly" json:"index_only,omitempty"` + SmallOps *bool `protobuf:"varint,10,opt,name=small_ops,json=smallOps" json:"small_ops,omitempty"` + CompiledQuery *CompiledQuery `protobuf:"bytes,5,opt,name=compiled_query,json=compiledQuery" json:"compiled_query,omitempty"` + CompiledCursor *CompiledCursor `protobuf:"bytes,6,opt,name=compiled_cursor,json=compiledCursor" json:"compiled_cursor,omitempty"` + Index []*CompositeIndex `protobuf:"bytes,8,rep,name=index" json:"index,omitempty"` + Version []int64 `protobuf:"varint,11,rep,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *QueryResult) Reset() { *m = QueryResult{} } +func (m *QueryResult) String() string { return proto.CompactTextString(m) } +func (*QueryResult) ProtoMessage() {} +func (*QueryResult) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{30} +} +func (m *QueryResult) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_QueryResult.Unmarshal(m, b) +} +func (m *QueryResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_QueryResult.Marshal(b, m, deterministic) +} +func (dst *QueryResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryResult.Merge(dst, src) +} +func (m *QueryResult) XXX_Size() int { + return xxx_messageInfo_QueryResult.Size(m) +} +func (m *QueryResult) XXX_DiscardUnknown() { + xxx_messageInfo_QueryResult.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryResult proto.InternalMessageInfo + +func (m *QueryResult) GetCursor() *Cursor { + if m != nil { + return m.Cursor + } + return nil +} + +func (m *QueryResult) GetResult() []*EntityProto { + if m != nil { + return m.Result + } + return nil +} + +func (m *QueryResult) GetSkippedResults() int32 { + if m != nil && m.SkippedResults != nil { + return *m.SkippedResults + } + return 0 +} + +func (m *QueryResult) GetMoreResults() bool { + if m != nil && m.MoreResults != nil { + return *m.MoreResults + } + return false +} + +func (m *QueryResult) GetKeysOnly() bool { + if m != nil && m.KeysOnly != nil { + return *m.KeysOnly + } + return false +} + +func (m *QueryResult) GetIndexOnly() bool { + if m != nil && m.IndexOnly != nil { + return *m.IndexOnly + } + return false +} + +func (m *QueryResult) GetSmallOps() bool { + if m != nil && m.SmallOps != nil { + return *m.SmallOps + } + return false +} + +func (m *QueryResult) GetCompiledQuery() *CompiledQuery { + if m != nil { + return m.CompiledQuery + } + return nil +} + +func (m *QueryResult) GetCompiledCursor() *CompiledCursor { + if m != nil { + return m.CompiledCursor + } + return nil +} + +func (m *QueryResult) GetIndex() []*CompositeIndex { + if m != nil { + return m.Index + } + return nil +} + +func (m *QueryResult) GetVersion() []int64 { + if m != nil { + return m.Version + } + return nil +} + +type AllocateIdsRequest struct { + Header *InternalHeader `protobuf:"bytes,4,opt,name=header" json:"header,omitempty"` + ModelKey *Reference `protobuf:"bytes,1,opt,name=model_key,json=modelKey" json:"model_key,omitempty"` + Size *int64 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"` + Max *int64 `protobuf:"varint,3,opt,name=max" json:"max,omitempty"` + Reserve []*Reference `protobuf:"bytes,5,rep,name=reserve" json:"reserve,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AllocateIdsRequest) Reset() { *m = AllocateIdsRequest{} } +func (m *AllocateIdsRequest) String() string { return proto.CompactTextString(m) } +func (*AllocateIdsRequest) ProtoMessage() {} +func (*AllocateIdsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{31} +} +func (m *AllocateIdsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AllocateIdsRequest.Unmarshal(m, b) +} +func (m *AllocateIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AllocateIdsRequest.Marshal(b, m, deterministic) +} +func (dst *AllocateIdsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_AllocateIdsRequest.Merge(dst, src) +} +func (m *AllocateIdsRequest) XXX_Size() int { + return xxx_messageInfo_AllocateIdsRequest.Size(m) +} +func (m *AllocateIdsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_AllocateIdsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_AllocateIdsRequest proto.InternalMessageInfo + +func (m *AllocateIdsRequest) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *AllocateIdsRequest) GetModelKey() *Reference { + if m != nil { + return m.ModelKey + } + return nil +} + +func (m *AllocateIdsRequest) GetSize() int64 { + if m != nil && m.Size != nil { + return *m.Size + } + return 0 +} + +func (m *AllocateIdsRequest) GetMax() int64 { + if m != nil && m.Max != nil { + return *m.Max + } + return 0 +} + +func (m *AllocateIdsRequest) GetReserve() []*Reference { + if m != nil { + return m.Reserve + } + return nil +} + +type AllocateIdsResponse struct { + Start *int64 `protobuf:"varint,1,req,name=start" json:"start,omitempty"` + End *int64 `protobuf:"varint,2,req,name=end" json:"end,omitempty"` + Cost *Cost `protobuf:"bytes,3,opt,name=cost" json:"cost,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AllocateIdsResponse) Reset() { *m = AllocateIdsResponse{} } +func (m *AllocateIdsResponse) String() string { return proto.CompactTextString(m) } +func (*AllocateIdsResponse) ProtoMessage() {} +func (*AllocateIdsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{32} +} +func (m *AllocateIdsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AllocateIdsResponse.Unmarshal(m, b) +} +func (m *AllocateIdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AllocateIdsResponse.Marshal(b, m, deterministic) +} +func (dst *AllocateIdsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_AllocateIdsResponse.Merge(dst, src) +} +func (m *AllocateIdsResponse) XXX_Size() int { + return xxx_messageInfo_AllocateIdsResponse.Size(m) +} +func (m *AllocateIdsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_AllocateIdsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_AllocateIdsResponse proto.InternalMessageInfo + +func (m *AllocateIdsResponse) GetStart() int64 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *AllocateIdsResponse) GetEnd() int64 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +func (m *AllocateIdsResponse) GetCost() *Cost { + if m != nil { + return m.Cost + } + return nil +} + +type CompositeIndices struct { + Index []*CompositeIndex `protobuf:"bytes,1,rep,name=index" json:"index,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompositeIndices) Reset() { *m = CompositeIndices{} } +func (m *CompositeIndices) String() string { return proto.CompactTextString(m) } +func (*CompositeIndices) ProtoMessage() {} +func (*CompositeIndices) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{33} +} +func (m *CompositeIndices) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompositeIndices.Unmarshal(m, b) +} +func (m *CompositeIndices) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompositeIndices.Marshal(b, m, deterministic) +} +func (dst *CompositeIndices) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompositeIndices.Merge(dst, src) +} +func (m *CompositeIndices) XXX_Size() int { + return xxx_messageInfo_CompositeIndices.Size(m) +} +func (m *CompositeIndices) XXX_DiscardUnknown() { + xxx_messageInfo_CompositeIndices.DiscardUnknown(m) +} + +var xxx_messageInfo_CompositeIndices proto.InternalMessageInfo + +func (m *CompositeIndices) GetIndex() []*CompositeIndex { + if m != nil { + return m.Index + } + return nil +} + +type AddActionsRequest struct { + Header *InternalHeader `protobuf:"bytes,3,opt,name=header" json:"header,omitempty"` + Transaction *Transaction `protobuf:"bytes,1,req,name=transaction" json:"transaction,omitempty"` + Action []*Action `protobuf:"bytes,2,rep,name=action" json:"action,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AddActionsRequest) Reset() { *m = AddActionsRequest{} } +func (m *AddActionsRequest) String() string { return proto.CompactTextString(m) } +func (*AddActionsRequest) ProtoMessage() {} +func (*AddActionsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{34} +} +func (m *AddActionsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AddActionsRequest.Unmarshal(m, b) +} +func (m *AddActionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AddActionsRequest.Marshal(b, m, deterministic) +} +func (dst *AddActionsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddActionsRequest.Merge(dst, src) +} +func (m *AddActionsRequest) XXX_Size() int { + return xxx_messageInfo_AddActionsRequest.Size(m) +} +func (m *AddActionsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_AddActionsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_AddActionsRequest proto.InternalMessageInfo + +func (m *AddActionsRequest) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *AddActionsRequest) GetTransaction() *Transaction { + if m != nil { + return m.Transaction + } + return nil +} + +func (m *AddActionsRequest) GetAction() []*Action { + if m != nil { + return m.Action + } + return nil +} + +type AddActionsResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AddActionsResponse) Reset() { *m = AddActionsResponse{} } +func (m *AddActionsResponse) String() string { return proto.CompactTextString(m) } +func (*AddActionsResponse) ProtoMessage() {} +func (*AddActionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{35} +} +func (m *AddActionsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AddActionsResponse.Unmarshal(m, b) +} +func (m *AddActionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AddActionsResponse.Marshal(b, m, deterministic) +} +func (dst *AddActionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddActionsResponse.Merge(dst, src) +} +func (m *AddActionsResponse) XXX_Size() int { + return xxx_messageInfo_AddActionsResponse.Size(m) +} +func (m *AddActionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_AddActionsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_AddActionsResponse proto.InternalMessageInfo + +type BeginTransactionRequest struct { + Header *InternalHeader `protobuf:"bytes,3,opt,name=header" json:"header,omitempty"` + App *string `protobuf:"bytes,1,req,name=app" json:"app,omitempty"` + AllowMultipleEg *bool `protobuf:"varint,2,opt,name=allow_multiple_eg,json=allowMultipleEg,def=0" json:"allow_multiple_eg,omitempty"` + DatabaseId *string `protobuf:"bytes,4,opt,name=database_id,json=databaseId" json:"database_id,omitempty"` + Mode *BeginTransactionRequest_TransactionMode `protobuf:"varint,5,opt,name=mode,enum=appengine.BeginTransactionRequest_TransactionMode,def=0" json:"mode,omitempty"` + PreviousTransaction *Transaction `protobuf:"bytes,7,opt,name=previous_transaction,json=previousTransaction" json:"previous_transaction,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BeginTransactionRequest) Reset() { *m = BeginTransactionRequest{} } +func (m *BeginTransactionRequest) String() string { return proto.CompactTextString(m) } +func (*BeginTransactionRequest) ProtoMessage() {} +func (*BeginTransactionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{36} +} +func (m *BeginTransactionRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BeginTransactionRequest.Unmarshal(m, b) +} +func (m *BeginTransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BeginTransactionRequest.Marshal(b, m, deterministic) +} +func (dst *BeginTransactionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginTransactionRequest.Merge(dst, src) +} +func (m *BeginTransactionRequest) XXX_Size() int { + return xxx_messageInfo_BeginTransactionRequest.Size(m) +} +func (m *BeginTransactionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_BeginTransactionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_BeginTransactionRequest proto.InternalMessageInfo + +const Default_BeginTransactionRequest_AllowMultipleEg bool = false +const Default_BeginTransactionRequest_Mode BeginTransactionRequest_TransactionMode = BeginTransactionRequest_UNKNOWN + +func (m *BeginTransactionRequest) GetHeader() *InternalHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *BeginTransactionRequest) GetApp() string { + if m != nil && m.App != nil { + return *m.App + } + return "" +} + +func (m *BeginTransactionRequest) GetAllowMultipleEg() bool { + if m != nil && m.AllowMultipleEg != nil { + return *m.AllowMultipleEg + } + return Default_BeginTransactionRequest_AllowMultipleEg +} + +func (m *BeginTransactionRequest) GetDatabaseId() string { + if m != nil && m.DatabaseId != nil { + return *m.DatabaseId + } + return "" +} + +func (m *BeginTransactionRequest) GetMode() BeginTransactionRequest_TransactionMode { + if m != nil && m.Mode != nil { + return *m.Mode + } + return Default_BeginTransactionRequest_Mode +} + +func (m *BeginTransactionRequest) GetPreviousTransaction() *Transaction { + if m != nil { + return m.PreviousTransaction + } + return nil +} + +type CommitResponse struct { + Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"` + Version []*CommitResponse_Version `protobuf:"group,3,rep,name=Version,json=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CommitResponse) Reset() { *m = CommitResponse{} } +func (m *CommitResponse) String() string { return proto.CompactTextString(m) } +func (*CommitResponse) ProtoMessage() {} +func (*CommitResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{37} +} +func (m *CommitResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CommitResponse.Unmarshal(m, b) +} +func (m *CommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CommitResponse.Marshal(b, m, deterministic) +} +func (dst *CommitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitResponse.Merge(dst, src) +} +func (m *CommitResponse) XXX_Size() int { + return xxx_messageInfo_CommitResponse.Size(m) +} +func (m *CommitResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CommitResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CommitResponse proto.InternalMessageInfo + +func (m *CommitResponse) GetCost() *Cost { + if m != nil { + return m.Cost + } + return nil +} + +func (m *CommitResponse) GetVersion() []*CommitResponse_Version { + if m != nil { + return m.Version + } + return nil +} + +type CommitResponse_Version struct { + RootEntityKey *Reference `protobuf:"bytes,4,req,name=root_entity_key,json=rootEntityKey" json:"root_entity_key,omitempty"` + Version *int64 `protobuf:"varint,5,req,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CommitResponse_Version) Reset() { *m = CommitResponse_Version{} } +func (m *CommitResponse_Version) String() string { return proto.CompactTextString(m) } +func (*CommitResponse_Version) ProtoMessage() {} +func (*CommitResponse_Version) Descriptor() ([]byte, []int) { + return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{37, 0} +} +func (m *CommitResponse_Version) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CommitResponse_Version.Unmarshal(m, b) +} +func (m *CommitResponse_Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CommitResponse_Version.Marshal(b, m, deterministic) +} +func (dst *CommitResponse_Version) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitResponse_Version.Merge(dst, src) +} +func (m *CommitResponse_Version) XXX_Size() int { + return xxx_messageInfo_CommitResponse_Version.Size(m) +} +func (m *CommitResponse_Version) XXX_DiscardUnknown() { + xxx_messageInfo_CommitResponse_Version.DiscardUnknown(m) +} + +var xxx_messageInfo_CommitResponse_Version proto.InternalMessageInfo + +func (m *CommitResponse_Version) GetRootEntityKey() *Reference { + if m != nil { + return m.RootEntityKey + } + return nil +} + +func (m *CommitResponse_Version) GetVersion() int64 { + if m != nil && m.Version != nil { + return *m.Version + } + return 0 +} + +func init() { + proto.RegisterType((*Action)(nil), "appengine.Action") + proto.RegisterType((*PropertyValue)(nil), "appengine.PropertyValue") + proto.RegisterType((*PropertyValue_PointValue)(nil), "appengine.PropertyValue.PointValue") + proto.RegisterType((*PropertyValue_UserValue)(nil), "appengine.PropertyValue.UserValue") + proto.RegisterType((*PropertyValue_ReferenceValue)(nil), "appengine.PropertyValue.ReferenceValue") + proto.RegisterType((*PropertyValue_ReferenceValue_PathElement)(nil), "appengine.PropertyValue.ReferenceValue.PathElement") + proto.RegisterType((*Property)(nil), "appengine.Property") + proto.RegisterType((*Path)(nil), "appengine.Path") + proto.RegisterType((*Path_Element)(nil), "appengine.Path.Element") + proto.RegisterType((*Reference)(nil), "appengine.Reference") + proto.RegisterType((*User)(nil), "appengine.User") + proto.RegisterType((*EntityProto)(nil), "appengine.EntityProto") + proto.RegisterType((*CompositeProperty)(nil), "appengine.CompositeProperty") + proto.RegisterType((*Index)(nil), "appengine.Index") + proto.RegisterType((*Index_Property)(nil), "appengine.Index.Property") + proto.RegisterType((*CompositeIndex)(nil), "appengine.CompositeIndex") + proto.RegisterType((*IndexPostfix)(nil), "appengine.IndexPostfix") + proto.RegisterType((*IndexPostfix_IndexValue)(nil), "appengine.IndexPostfix.IndexValue") + proto.RegisterType((*IndexPosition)(nil), "appengine.IndexPosition") + proto.RegisterType((*Snapshot)(nil), "appengine.Snapshot") + proto.RegisterType((*InternalHeader)(nil), "appengine.InternalHeader") + proto.RegisterType((*Transaction)(nil), "appengine.Transaction") + proto.RegisterType((*Query)(nil), "appengine.Query") + proto.RegisterType((*Query_Filter)(nil), "appengine.Query.Filter") + proto.RegisterType((*Query_Order)(nil), "appengine.Query.Order") + proto.RegisterType((*CompiledQuery)(nil), "appengine.CompiledQuery") + proto.RegisterType((*CompiledQuery_PrimaryScan)(nil), "appengine.CompiledQuery.PrimaryScan") + proto.RegisterType((*CompiledQuery_MergeJoinScan)(nil), "appengine.CompiledQuery.MergeJoinScan") + proto.RegisterType((*CompiledQuery_EntityFilter)(nil), "appengine.CompiledQuery.EntityFilter") + proto.RegisterType((*CompiledCursor)(nil), "appengine.CompiledCursor") + proto.RegisterType((*CompiledCursor_Position)(nil), "appengine.CompiledCursor.Position") + proto.RegisterType((*CompiledCursor_Position_IndexValue)(nil), "appengine.CompiledCursor.Position.IndexValue") + proto.RegisterType((*Cursor)(nil), "appengine.Cursor") + proto.RegisterType((*Error)(nil), "appengine.Error") + proto.RegisterType((*Cost)(nil), "appengine.Cost") + proto.RegisterType((*Cost_CommitCost)(nil), "appengine.Cost.CommitCost") + proto.RegisterType((*GetRequest)(nil), "appengine.GetRequest") + proto.RegisterType((*GetResponse)(nil), "appengine.GetResponse") + proto.RegisterType((*GetResponse_Entity)(nil), "appengine.GetResponse.Entity") + proto.RegisterType((*PutRequest)(nil), "appengine.PutRequest") + proto.RegisterType((*PutResponse)(nil), "appengine.PutResponse") + proto.RegisterType((*TouchRequest)(nil), "appengine.TouchRequest") + proto.RegisterType((*TouchResponse)(nil), "appengine.TouchResponse") + proto.RegisterType((*DeleteRequest)(nil), "appengine.DeleteRequest") + proto.RegisterType((*DeleteResponse)(nil), "appengine.DeleteResponse") + proto.RegisterType((*NextRequest)(nil), "appengine.NextRequest") + proto.RegisterType((*QueryResult)(nil), "appengine.QueryResult") + proto.RegisterType((*AllocateIdsRequest)(nil), "appengine.AllocateIdsRequest") + proto.RegisterType((*AllocateIdsResponse)(nil), "appengine.AllocateIdsResponse") + proto.RegisterType((*CompositeIndices)(nil), "appengine.CompositeIndices") + proto.RegisterType((*AddActionsRequest)(nil), "appengine.AddActionsRequest") + proto.RegisterType((*AddActionsResponse)(nil), "appengine.AddActionsResponse") + proto.RegisterType((*BeginTransactionRequest)(nil), "appengine.BeginTransactionRequest") + proto.RegisterType((*CommitResponse)(nil), "appengine.CommitResponse") + proto.RegisterType((*CommitResponse_Version)(nil), "appengine.CommitResponse.Version") +} + +func init() { + proto.RegisterFile("google.golang.org/appengine/internal/datastore/datastore_v3.proto", fileDescriptor_datastore_v3_83b17b80c34f6179) +} + +var fileDescriptor_datastore_v3_83b17b80c34f6179 = []byte{ + // 4156 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0xe3, 0x46, + 0x76, 0x37, 0xc1, 0xef, 0x47, 0x89, 0x82, 0x5a, 0xf3, 0xc1, 0xa1, 0x3f, 0x46, 0xc6, 0xac, 0x6d, + 0xd9, 0x6b, 0x73, 0x6c, 0xf9, 0x23, 0x5b, 0x4a, 0x76, 0x1d, 0x4a, 0xc4, 0x68, 0x90, 0xa1, 0x48, + 0xb9, 0x09, 0xd9, 0x9e, 0x5c, 0x50, 0x18, 0xa2, 0x29, 0x21, 0x43, 0x02, 0x30, 0x00, 0x6a, 0x46, + 0x93, 0xe4, 0x90, 0x4b, 0x2a, 0x55, 0x5b, 0xa9, 0x1c, 0x92, 0x4a, 0x25, 0xf9, 0x07, 0x72, 0xc8, + 0x39, 0x95, 0xaa, 0x54, 0xf6, 0x98, 0x5b, 0x0e, 0x7b, 0xc9, 0x31, 0x95, 0x73, 0xf2, 0x27, 0x24, + 0x39, 0xa4, 0xfa, 0x75, 0x03, 0x02, 0x28, 0x4a, 0x23, 0x6d, 0xf6, 0x90, 0x13, 0xd1, 0xef, 0xfd, + 0xba, 0xf1, 0xfa, 0xf5, 0xfb, 0x6c, 0x10, 0xba, 0xc7, 0xbe, 0x7f, 0x3c, 0x65, 0x9d, 0x63, 0x7f, + 0x6a, 0x7b, 0xc7, 0x1d, 0x3f, 0x3c, 0x7e, 0x68, 0x07, 0x01, 0xf3, 0x8e, 0x5d, 0x8f, 0x3d, 0x74, + 0xbd, 0x98, 0x85, 0x9e, 0x3d, 0x7d, 0xe8, 0xd8, 0xb1, 0x1d, 0xc5, 0x7e, 0xc8, 0xce, 0x9f, 0xac, + 0xd3, 0xcf, 0x3b, 0x41, 0xe8, 0xc7, 0x3e, 0xa9, 0xa7, 0x13, 0xb4, 0x1a, 0x54, 0xba, 0xe3, 0xd8, + 0xf5, 0x3d, 0xed, 0x1f, 0x2b, 0xb0, 0x7a, 0x18, 0xfa, 0x01, 0x0b, 0xe3, 0xb3, 0x6f, 0xed, 0xe9, + 0x9c, 0x91, 0x77, 0x00, 0x5c, 0x2f, 0xfe, 0xea, 0x0b, 0x1c, 0xb5, 0x0a, 0x9b, 0x85, 0xad, 0x22, + 0xcd, 0x50, 0x88, 0x06, 0x2b, 0xcf, 0x7c, 0x7f, 0xca, 0x6c, 0x4f, 0x20, 0x94, 0xcd, 0xc2, 0x56, + 0x8d, 0xe6, 0x68, 0x64, 0x13, 0x1a, 0x51, 0x1c, 0xba, 0xde, 0xb1, 0x80, 0x14, 0x37, 0x0b, 0x5b, + 0x75, 0x9a, 0x25, 0x71, 0x84, 0xe3, 0xcf, 0x9f, 0x4d, 0x99, 0x40, 0x94, 0x36, 0x0b, 0x5b, 0x05, + 0x9a, 0x25, 0x91, 0x3d, 0x80, 0xc0, 0x77, 0xbd, 0xf8, 0x14, 0x01, 0xe5, 0xcd, 0xc2, 0x16, 0x6c, + 0x3f, 0xe8, 0xa4, 0x7b, 0xe8, 0xe4, 0xa4, 0xee, 0x1c, 0x72, 0x28, 0x3e, 0xd2, 0xcc, 0x34, 0xf2, + 0xdb, 0x50, 0x9f, 0x47, 0x2c, 0x14, 0x6b, 0xd4, 0x70, 0x0d, 0xed, 0xd2, 0x35, 0x8e, 0x22, 0x16, + 0x8a, 0x25, 0xce, 0x27, 0x91, 0x21, 0x34, 0x43, 0x36, 0x61, 0x21, 0xf3, 0xc6, 0x4c, 0x2c, 0xb3, + 0x82, 0xcb, 0x7c, 0x70, 0xe9, 0x32, 0x34, 0x81, 0x8b, 0xb5, 0x16, 0xa6, 0xb7, 0xb7, 0x00, 0xce, + 0x85, 0x25, 0x2b, 0x50, 0x78, 0xd9, 0xaa, 0x6c, 0x2a, 0x5b, 0x05, 0x5a, 0x78, 0xc9, 0x47, 0x67, + 0xad, 0xaa, 0x18, 0x9d, 0xb5, 0xff, 0xa9, 0x00, 0xf5, 0x54, 0x26, 0x72, 0x0b, 0xca, 0x6c, 0x66, + 0xbb, 0xd3, 0x56, 0x7d, 0x53, 0xd9, 0xaa, 0x53, 0x31, 0x20, 0xf7, 0xa1, 0x61, 0xcf, 0xe3, 0x13, + 0xcb, 0xf1, 0x67, 0xb6, 0xeb, 0xb5, 0x00, 0x79, 0xc0, 0x49, 0x3d, 0xa4, 0x90, 0x36, 0xd4, 0x3c, + 0x77, 0xfc, 0xdc, 0xb3, 0x67, 0xac, 0xd5, 0xc0, 0x73, 0x48, 0xc7, 0xe4, 0x13, 0x20, 0x13, 0xe6, + 0xb0, 0xd0, 0x8e, 0x99, 0x63, 0xb9, 0x0e, 0xf3, 0x62, 0x37, 0x3e, 0x6b, 0xdd, 0x46, 0xd4, 0x7a, + 0xca, 0x31, 0x24, 0x23, 0x0f, 0x0f, 0x42, 0xff, 0xd4, 0x75, 0x58, 0xd8, 0xba, 0xb3, 0x00, 0x3f, + 0x94, 0x8c, 0xf6, 0xbf, 0x17, 0xa0, 0x99, 0xd7, 0x05, 0x51, 0xa1, 0x68, 0x07, 0x41, 0x6b, 0x15, + 0xa5, 0xe4, 0x8f, 0xe4, 0x6d, 0x00, 0x2e, 0x8a, 0x15, 0x05, 0xf6, 0x98, 0xb5, 0x6e, 0xe1, 0x5a, + 0x75, 0x4e, 0x19, 0x71, 0x02, 0x39, 0x82, 0x46, 0x60, 0xc7, 0x27, 0x6c, 0xca, 0x66, 0xcc, 0x8b, + 0x5b, 0xcd, 0xcd, 0xe2, 0x16, 0x6c, 0x7f, 0x7e, 0x4d, 0xd5, 0x77, 0x0e, 0xed, 0xf8, 0x44, 0x17, + 0x53, 0x69, 0x76, 0x9d, 0xb6, 0x0e, 0x8d, 0x0c, 0x8f, 0x10, 0x28, 0xc5, 0x67, 0x01, 0x6b, 0xad, + 0xa1, 0x5c, 0xf8, 0x4c, 0x9a, 0xa0, 0xb8, 0x4e, 0x4b, 0x45, 0xf3, 0x57, 0x5c, 0x87, 0x63, 0x50, + 0x87, 0xeb, 0x28, 0x22, 0x3e, 0x6b, 0xff, 0x51, 0x86, 0x5a, 0x22, 0x00, 0xe9, 0x42, 0x75, 0xc6, + 0x6c, 0xcf, 0xf5, 0x8e, 0xd1, 0x69, 0x9a, 0xdb, 0x6f, 0x2e, 0x11, 0xb3, 0x73, 0x20, 0x20, 0x3b, + 0x30, 0x18, 0x5a, 0x07, 0x7a, 0x77, 0x60, 0x0c, 0xf6, 0x69, 0x32, 0x8f, 0x1f, 0xa6, 0x7c, 0xb4, + 0xe6, 0xa1, 0x8b, 0x9e, 0x55, 0xa7, 0x20, 0x49, 0x47, 0xa1, 0x9b, 0x0a, 0x51, 0x14, 0x82, 0xe2, + 0x21, 0x76, 0xa0, 0x9c, 0xb8, 0x88, 0xb2, 0xd5, 0xd8, 0x6e, 0x5d, 0xa6, 0x1c, 0x2a, 0x60, 0xdc, + 0x20, 0x66, 0xf3, 0x69, 0xec, 0x06, 0x53, 0xee, 0x76, 0xca, 0x56, 0x8d, 0xa6, 0x63, 0xf2, 0x1e, + 0x40, 0xc4, 0xec, 0x70, 0x7c, 0x62, 0x3f, 0x9b, 0xb2, 0x56, 0x85, 0x7b, 0xf6, 0x4e, 0x79, 0x62, + 0x4f, 0x23, 0x46, 0x33, 0x0c, 0x62, 0xc3, 0xdd, 0x49, 0x1c, 0x59, 0xb1, 0xff, 0x9c, 0x79, 0xee, + 0x2b, 0x9b, 0x07, 0x12, 0xcb, 0x0f, 0xf8, 0x0f, 0xfa, 0x58, 0x73, 0xfb, 0xc3, 0x65, 0x5b, 0x7f, + 0x14, 0x47, 0x66, 0x66, 0xc6, 0x10, 0x27, 0xd0, 0xdb, 0x93, 0x65, 0x64, 0xd2, 0x86, 0xca, 0xd4, + 0x1f, 0xdb, 0x53, 0xd6, 0xaa, 0x73, 0x2d, 0xec, 0x28, 0xcc, 0xa3, 0x92, 0xa2, 0xfd, 0xb3, 0x02, + 0x55, 0xa9, 0x47, 0xd2, 0x84, 0x8c, 0x26, 0xd5, 0x37, 0x48, 0x0d, 0x4a, 0xbb, 0xfd, 0xe1, 0xae, + 0xda, 0xe4, 0x4f, 0xa6, 0xfe, 0xbd, 0xa9, 0xae, 0x71, 0xcc, 0xee, 0x53, 0x53, 0x1f, 0x99, 0x94, + 0x63, 0x54, 0xb2, 0x0e, 0xab, 0x5d, 0x73, 0x78, 0x60, 0xed, 0x75, 0x4d, 0x7d, 0x7f, 0x48, 0x9f, + 0xaa, 0x05, 0xb2, 0x0a, 0x75, 0x24, 0xf5, 0x8d, 0xc1, 0x13, 0x55, 0xe1, 0x33, 0x70, 0x68, 0x1a, + 0x66, 0x5f, 0x57, 0x8b, 0x44, 0x85, 0x15, 0x31, 0x63, 0x38, 0x30, 0xf5, 0x81, 0xa9, 0x96, 0x52, + 0xca, 0xe8, 0xe8, 0xe0, 0xa0, 0x4b, 0x9f, 0xaa, 0x65, 0xb2, 0x06, 0x0d, 0xa4, 0x74, 0x8f, 0xcc, + 0xc7, 0x43, 0xaa, 0x56, 0x48, 0x03, 0xaa, 0xfb, 0x3d, 0xeb, 0xbb, 0xc7, 0xfa, 0x40, 0xad, 0x92, + 0x15, 0xa8, 0xed, 0xf7, 0x2c, 0xfd, 0xa0, 0x6b, 0xf4, 0xd5, 0x1a, 0x9f, 0xbd, 0xaf, 0x0f, 0xe9, + 0x68, 0x64, 0x1d, 0x0e, 0x8d, 0x81, 0xa9, 0xd6, 0x49, 0x1d, 0xca, 0xfb, 0x3d, 0xcb, 0x38, 0x50, + 0x81, 0x10, 0x68, 0xee, 0xf7, 0xac, 0xc3, 0xc7, 0xc3, 0x81, 0x3e, 0x38, 0x3a, 0xd8, 0xd5, 0xa9, + 0xda, 0x20, 0xb7, 0x40, 0xe5, 0xb4, 0xe1, 0xc8, 0xec, 0xf6, 0xbb, 0xbd, 0x1e, 0xd5, 0x47, 0x23, + 0x75, 0x85, 0x4b, 0xbd, 0xdf, 0xb3, 0x68, 0xd7, 0xe4, 0xfb, 0x5a, 0xe5, 0x2f, 0xe4, 0x7b, 0x7f, + 0xa2, 0x3f, 0x55, 0xd7, 0xf9, 0x2b, 0xf4, 0x81, 0x69, 0x98, 0x4f, 0xad, 0x43, 0x3a, 0x34, 0x87, + 0xea, 0x06, 0x17, 0xd0, 0x18, 0xf4, 0xf4, 0xef, 0xad, 0x6f, 0xbb, 0xfd, 0x23, 0x5d, 0x25, 0xda, + 0x8f, 0xe1, 0xf6, 0xd2, 0x33, 0xe1, 0xaa, 0x7b, 0x6c, 0x1e, 0xf4, 0xd5, 0x02, 0x7f, 0xe2, 0x9b, + 0x52, 0x15, 0xed, 0x0f, 0xa0, 0xc4, 0x5d, 0x86, 0x7c, 0x06, 0xd5, 0xc4, 0x1b, 0x0b, 0xe8, 0x8d, + 0x77, 0xb3, 0x67, 0x6d, 0xc7, 0x27, 0x9d, 0xc4, 0xe3, 0x12, 0x5c, 0xbb, 0x0b, 0xd5, 0x45, 0x4f, + 0x53, 0x2e, 0x78, 0x5a, 0xf1, 0x82, 0xa7, 0x95, 0x32, 0x9e, 0x66, 0x43, 0x3d, 0xf5, 0xed, 0x9b, + 0x47, 0x91, 0x07, 0x50, 0xe2, 0xde, 0xdf, 0x6a, 0xa2, 0x87, 0xac, 0x2d, 0x08, 0x4c, 0x91, 0xa9, + 0xfd, 0x43, 0x01, 0x4a, 0x3c, 0xda, 0x9e, 0x07, 0xda, 0xc2, 0x15, 0x81, 0x56, 0xb9, 0x32, 0xd0, + 0x16, 0xaf, 0x15, 0x68, 0x2b, 0x37, 0x0b, 0xb4, 0xd5, 0x4b, 0x02, 0xad, 0xf6, 0x67, 0x45, 0x68, + 0xe8, 0x38, 0xf3, 0x10, 0x13, 0xfd, 0xfb, 0x50, 0x7c, 0xce, 0xce, 0x50, 0x3f, 0x8d, 0xed, 0x5b, + 0x99, 0xdd, 0xa6, 0x2a, 0xa4, 0x1c, 0x40, 0xb6, 0x61, 0x45, 0xbc, 0xd0, 0x3a, 0x0e, 0xfd, 0x79, + 0xd0, 0x52, 0x97, 0xab, 0xa7, 0x21, 0x40, 0xfb, 0x1c, 0x43, 0xde, 0x83, 0xb2, 0xff, 0xc2, 0x63, + 0x21, 0xc6, 0xc1, 0x3c, 0x98, 0x2b, 0x8f, 0x0a, 0x2e, 0x79, 0x08, 0xa5, 0xe7, 0xae, 0xe7, 0xe0, + 0x19, 0xe6, 0x23, 0x61, 0x46, 0xd0, 0xce, 0x13, 0xd7, 0x73, 0x28, 0x02, 0xc9, 0x3d, 0xa8, 0xf1, + 0x5f, 0x8c, 0x7b, 0x65, 0xdc, 0x68, 0x95, 0x8f, 0x79, 0xd0, 0x7b, 0x08, 0xb5, 0x40, 0xc6, 0x10, + 0x4c, 0x00, 0x8d, 0xed, 0x8d, 0x25, 0xe1, 0x85, 0xa6, 0x20, 0xf2, 0x15, 0xac, 0x84, 0xf6, 0x0b, + 0x2b, 0x9d, 0xb4, 0x76, 0xf9, 0xa4, 0x46, 0x68, 0xbf, 0x48, 0x23, 0x38, 0x81, 0x52, 0x68, 0x7b, + 0xcf, 0x5b, 0x64, 0xb3, 0xb0, 0x55, 0xa6, 0xf8, 0xac, 0x7d, 0x01, 0x25, 0x2e, 0x25, 0x8f, 0x08, + 0xfb, 0x3d, 0xf4, 0xff, 0xee, 0x9e, 0xa9, 0x16, 0x12, 0x7f, 0xfe, 0x96, 0x47, 0x03, 0x45, 0x72, + 0x0f, 0xf4, 0xd1, 0xa8, 0xbb, 0xaf, 0xab, 0x45, 0xad, 0x07, 0xeb, 0x7b, 0xfe, 0x2c, 0xf0, 0x23, + 0x37, 0x66, 0xe9, 0xf2, 0xf7, 0xa0, 0xe6, 0x7a, 0x0e, 0x7b, 0x69, 0xb9, 0x0e, 0x9a, 0x56, 0x91, + 0x56, 0x71, 0x6c, 0x38, 0xdc, 0xe4, 0x4e, 0x65, 0x31, 0x55, 0xe4, 0x26, 0x87, 0x03, 0xed, 0x2f, + 0x15, 0x28, 0x1b, 0x1c, 0xc1, 0x8d, 0x4f, 0x9e, 0x14, 0x7a, 0x8f, 0x30, 0x4c, 0x10, 0x24, 0x93, + 0xfb, 0x50, 0x1b, 0x6a, 0xb6, 0x37, 0x66, 0xbc, 0xe2, 0xc3, 0x3c, 0x50, 0xa3, 0xe9, 0x98, 0x7c, + 0x99, 0xd1, 0x9f, 0x82, 0x2e, 0x7b, 0x2f, 0xa3, 0x0a, 0x7c, 0xc1, 0x12, 0x2d, 0xb6, 0xff, 0xaa, + 0x90, 0x49, 0x6e, 0xcb, 0x12, 0x4f, 0x1f, 0xea, 0x8e, 0x1b, 0x32, 0xac, 0x23, 0xe5, 0x41, 0x3f, + 0xb8, 0x74, 0xe1, 0x4e, 0x2f, 0x81, 0xee, 0xd4, 0xbb, 0xa3, 0x3d, 0x7d, 0xd0, 0xe3, 0x99, 0xef, + 0x7c, 0x01, 0xed, 0x23, 0xa8, 0xa7, 0x10, 0x0c, 0xc7, 0x09, 0x48, 0x2d, 0x70, 0xf5, 0xf6, 0xf4, + 0x74, 0xac, 0x68, 0x7f, 0xad, 0x40, 0x33, 0xd5, 0xaf, 0xd0, 0xd0, 0x6d, 0xa8, 0xd8, 0x41, 0x90, + 0xa8, 0xb6, 0x4e, 0xcb, 0x76, 0x10, 0x18, 0x8e, 0x8c, 0x2d, 0x0a, 0x6a, 0x9b, 0xc7, 0x96, 0x4f, + 0x01, 0x1c, 0x36, 0x71, 0x3d, 0x17, 0x85, 0x2e, 0xa2, 0xc1, 0xab, 0x8b, 0x42, 0xd3, 0x0c, 0x86, + 0x7c, 0x09, 0xe5, 0x28, 0xb6, 0x63, 0x91, 0x2b, 0x9b, 0xdb, 0xf7, 0x33, 0xe0, 0xbc, 0x08, 0x9d, + 0x11, 0x87, 0x51, 0x81, 0x26, 0x5f, 0xc1, 0x2d, 0xdf, 0x9b, 0x9e, 0x59, 0xf3, 0x88, 0x59, 0xee, + 0xc4, 0x0a, 0xd9, 0x0f, 0x73, 0x37, 0x64, 0x4e, 0x3e, 0xa7, 0xae, 0x73, 0xc8, 0x51, 0xc4, 0x8c, + 0x09, 0x95, 0x7c, 0xed, 0x6b, 0x28, 0xe3, 0x3a, 0x7c, 0xcf, 0xdf, 0x51, 0xc3, 0xd4, 0xad, 0xe1, + 0xa0, 0xff, 0x54, 0xe8, 0x80, 0xea, 0xdd, 0x9e, 0x85, 0x44, 0x55, 0xe1, 0xc1, 0xbe, 0xa7, 0xf7, + 0x75, 0x53, 0xef, 0xa9, 0x45, 0x9e, 0x3d, 0x74, 0x4a, 0x87, 0x54, 0x2d, 0x69, 0xff, 0x53, 0x80, + 0x15, 0x94, 0xe7, 0xd0, 0x8f, 0xe2, 0x89, 0xfb, 0x92, 0xec, 0x41, 0x43, 0x98, 0xdd, 0xa9, 0x2c, + 0xe8, 0xb9, 0x33, 0x68, 0x8b, 0x7b, 0x96, 0x68, 0x31, 0x90, 0x75, 0xb4, 0x9b, 0x3e, 0x27, 0x21, + 0x45, 0x41, 0xa7, 0xbf, 0x22, 0xa4, 0xbc, 0x05, 0x95, 0x67, 0x6c, 0xe2, 0x87, 0x22, 0x04, 0xd6, + 0x76, 0x4a, 0x71, 0x38, 0x67, 0x54, 0xd2, 0xda, 0x36, 0xc0, 0xf9, 0xfa, 0xe4, 0x01, 0xac, 0x26, + 0xc6, 0x66, 0xa1, 0x71, 0x89, 0x93, 0x5b, 0x49, 0x88, 0x83, 0x5c, 0x75, 0xa3, 0x5c, 0xab, 0xba, + 0xd1, 0xbe, 0x86, 0xd5, 0x64, 0x3f, 0xe2, 0xfc, 0x54, 0x21, 0x79, 0x01, 0x63, 0xca, 0x82, 0x8c, + 0xca, 0x45, 0x19, 0xb5, 0x9f, 0x41, 0x6d, 0xe4, 0xd9, 0x41, 0x74, 0xe2, 0xc7, 0xdc, 0x7a, 0xe2, + 0x48, 0xfa, 0xaa, 0x12, 0x47, 0x9a, 0x06, 0x15, 0x7e, 0x38, 0xf3, 0x88, 0xbb, 0xbf, 0x31, 0xe8, + 0xee, 0x99, 0xc6, 0xb7, 0xba, 0xfa, 0x06, 0x01, 0xa8, 0xc8, 0xe7, 0x82, 0xa6, 0x41, 0xd3, 0x90, + 0xed, 0xd8, 0x63, 0x66, 0x3b, 0x2c, 0xe4, 0x12, 0xfc, 0xe0, 0x47, 0x89, 0x04, 0x3f, 0xf8, 0x91, + 0xf6, 0x17, 0x05, 0x68, 0x98, 0xa1, 0xed, 0x45, 0xb6, 0x30, 0xf7, 0xcf, 0xa0, 0x72, 0x82, 0x58, + 0x74, 0xa3, 0xc6, 0x82, 0x7f, 0x66, 0x17, 0xa3, 0x12, 0x48, 0xee, 0x40, 0xe5, 0xc4, 0xf6, 0x9c, + 0xa9, 0xd0, 0x5a, 0x85, 0xca, 0x51, 0x92, 0x1b, 0x95, 0xf3, 0xdc, 0xb8, 0x05, 0x2b, 0x33, 0x3b, + 0x7c, 0x6e, 0x8d, 0x4f, 0x6c, 0xef, 0x98, 0x45, 0xf2, 0x60, 0xa4, 0x05, 0x36, 0x38, 0x6b, 0x4f, + 0x70, 0xb4, 0xbf, 0x5f, 0x81, 0xf2, 0x37, 0x73, 0x16, 0x9e, 0x65, 0x04, 0xfa, 0xe0, 0xba, 0x02, + 0xc9, 0x17, 0x17, 0x2e, 0x4b, 0xca, 0x6f, 0x2f, 0x26, 0x65, 0x22, 0x53, 0x84, 0xc8, 0x95, 0x22, + 0x0b, 0x7c, 0x9a, 0x09, 0x63, 0xeb, 0x57, 0xd8, 0xda, 0x79, 0x70, 0x7b, 0x08, 0x95, 0x89, 0x3b, + 0x8d, 0x51, 0x75, 0x8b, 0xd5, 0x08, 0xee, 0xa5, 0xf3, 0x08, 0xd9, 0x54, 0xc2, 0xc8, 0xbb, 0xb0, + 0x22, 0x2a, 0x59, 0xeb, 0x07, 0xce, 0xc6, 0x82, 0x95, 0xf7, 0xa6, 0x48, 0x13, 0xbb, 0xff, 0x18, + 0xca, 0x7e, 0xc8, 0x37, 0x5f, 0xc7, 0x25, 0xef, 0x5c, 0x58, 0x72, 0xc8, 0xb9, 0x54, 0x80, 0xc8, + 0x87, 0x50, 0x3a, 0x71, 0xbd, 0x18, 0xb3, 0x46, 0x73, 0xfb, 0xf6, 0x05, 0xf0, 0x63, 0xd7, 0x8b, + 0x29, 0x42, 0x78, 0x98, 0x1f, 0xfb, 0x73, 0x2f, 0x6e, 0xdd, 0xc5, 0x0c, 0x23, 0x06, 0xe4, 0x1e, + 0x54, 0xfc, 0xc9, 0x24, 0x62, 0x31, 0x76, 0x96, 0xe5, 0x9d, 0xc2, 0xa7, 0x54, 0x12, 0xf8, 0x84, + 0xa9, 0x3b, 0x73, 0x63, 0xec, 0x43, 0xca, 0x54, 0x0c, 0xc8, 0x2e, 0xac, 0x8d, 0xfd, 0x59, 0xe0, + 0x4e, 0x99, 0x63, 0x8d, 0xe7, 0x61, 0xe4, 0x87, 0xad, 0x77, 0x2e, 0x1c, 0xd3, 0x9e, 0x44, 0xec, + 0x21, 0x80, 0x36, 0xc7, 0xb9, 0x31, 0x31, 0x60, 0x83, 0x79, 0x8e, 0xb5, 0xb8, 0xce, 0xfd, 0xd7, + 0xad, 0xb3, 0xce, 0x3c, 0x27, 0x4f, 0x4a, 0xc4, 0xc1, 0x48, 0x68, 0x61, 0xcc, 0x68, 0x6d, 0x60, + 0x90, 0xb9, 0x77, 0x69, 0xac, 0x14, 0xe2, 0x64, 0xc2, 0xf7, 0x6f, 0xc0, 0x2d, 0x19, 0x22, 0xad, + 0x80, 0x85, 0x13, 0x36, 0x8e, 0xad, 0x60, 0x6a, 0x7b, 0x58, 0xca, 0xa5, 0xc6, 0x4a, 0x24, 0xe4, + 0x50, 0x20, 0x0e, 0xa7, 0xb6, 0x47, 0x34, 0xa8, 0x3f, 0x67, 0x67, 0x91, 0xc5, 0x23, 0x29, 0x76, + 0xae, 0x29, 0xba, 0xc6, 0xe9, 0x43, 0x6f, 0x7a, 0x46, 0x7e, 0x02, 0x8d, 0xf8, 0xdc, 0xdb, 0xb0, + 0x61, 0x6d, 0xe4, 0x4e, 0x35, 0xe3, 0x8b, 0x34, 0x0b, 0x25, 0xf7, 0xa1, 0x2a, 0x35, 0xd4, 0xba, + 0x97, 0x5d, 0x3b, 0xa1, 0xf2, 0xc4, 0x3c, 0xb1, 0xdd, 0xa9, 0x7f, 0xca, 0x42, 0x6b, 0x16, 0xb5, + 0xda, 0xe2, 0xb6, 0x24, 0x21, 0x1d, 0x44, 0xdc, 0x4f, 0xa3, 0x38, 0xf4, 0xbd, 0xe3, 0xd6, 0x26, + 0xde, 0x93, 0xc8, 0xd1, 0xc5, 0xe0, 0xf7, 0x2e, 0x66, 0xfe, 0x7c, 0xf0, 0xfb, 0x1c, 0xee, 0x60, + 0x65, 0x66, 0x3d, 0x3b, 0xb3, 0xf2, 0x68, 0x0d, 0xd1, 0x1b, 0xc8, 0xdd, 0x3d, 0x3b, 0xcc, 0x4e, + 0x6a, 0x43, 0xcd, 0x71, 0xa3, 0xd8, 0xf5, 0xc6, 0x71, 0xab, 0x85, 0xef, 0x4c, 0xc7, 0xe4, 0x33, + 0xb8, 0x3d, 0x73, 0x3d, 0x2b, 0xb2, 0x27, 0xcc, 0x8a, 0x5d, 0xee, 0x9b, 0x6c, 0xec, 0x7b, 0x4e, + 0xd4, 0x7a, 0x80, 0x82, 0x93, 0x99, 0xeb, 0x8d, 0xec, 0x09, 0x33, 0xdd, 0x19, 0x1b, 0x09, 0x0e, + 0xf9, 0x08, 0xd6, 0x11, 0x1e, 0xb2, 0x60, 0xea, 0x8e, 0x6d, 0xf1, 0xfa, 0x1f, 0xe1, 0xeb, 0xd7, + 0x38, 0x83, 0x0a, 0x3a, 0xbe, 0xfa, 0x63, 0x68, 0x06, 0x2c, 0x8c, 0xdc, 0x28, 0xb6, 0xa4, 0x45, + 0xbf, 0x97, 0xd5, 0xda, 0xaa, 0x64, 0x0e, 0x91, 0xd7, 0xfe, 0xcf, 0x02, 0x54, 0x84, 0x73, 0x92, + 0x4f, 0x41, 0xf1, 0x03, 0xbc, 0x06, 0x69, 0x6e, 0x6f, 0x5e, 0xe2, 0xc1, 0x9d, 0x61, 0xc0, 0xeb, + 0x5e, 0x3f, 0xa4, 0x8a, 0x1f, 0xdc, 0xb8, 0x28, 0xd4, 0xfe, 0x10, 0x6a, 0xc9, 0x02, 0xbc, 0xbc, + 0xe8, 0xeb, 0xa3, 0x91, 0x65, 0x3e, 0xee, 0x0e, 0xd4, 0x02, 0xb9, 0x03, 0x24, 0x1d, 0x5a, 0x43, + 0x6a, 0xe9, 0xdf, 0x1c, 0x75, 0xfb, 0xaa, 0x82, 0x5d, 0x1a, 0xd5, 0xbb, 0xa6, 0x4e, 0x05, 0xb2, + 0x48, 0xee, 0xc1, 0xed, 0x2c, 0xe5, 0x1c, 0x5c, 0xc2, 0x14, 0x8c, 0x8f, 0x65, 0x52, 0x01, 0xc5, + 0x18, 0xa8, 0x15, 0x9e, 0x16, 0xf4, 0xef, 0x8d, 0x91, 0x39, 0x52, 0xab, 0xed, 0xbf, 0x29, 0x40, + 0x19, 0xc3, 0x06, 0x3f, 0x9f, 0x54, 0x72, 0x71, 0x5d, 0x73, 0x5e, 0xb9, 0x1a, 0xd9, 0x92, 0xaa, + 0x81, 0x01, 0x65, 0x73, 0x79, 0xf4, 0xf9, 0xb5, 0xd6, 0x53, 0x3f, 0x85, 0x12, 0x8f, 0x52, 0xbc, + 0x43, 0x1c, 0xd2, 0x9e, 0x4e, 0xad, 0x47, 0x06, 0x1d, 0xf1, 0x2a, 0x97, 0x40, 0xb3, 0x3b, 0xd8, + 0xd3, 0x47, 0xe6, 0x30, 0xa1, 0xa1, 0x56, 0x1e, 0x19, 0x7d, 0x33, 0x45, 0x15, 0xb5, 0x9f, 0xd7, + 0x60, 0x35, 0x89, 0x09, 0x22, 0x82, 0x3e, 0x82, 0x46, 0x10, 0xba, 0x33, 0x3b, 0x3c, 0x8b, 0xc6, + 0xb6, 0x87, 0x49, 0x01, 0xb6, 0x7f, 0xb4, 0x24, 0xaa, 0x88, 0x1d, 0x1d, 0x0a, 0xec, 0x68, 0x6c, + 0x7b, 0x34, 0x3b, 0x91, 0xf4, 0x61, 0x75, 0xc6, 0xc2, 0x63, 0xf6, 0x7b, 0xbe, 0xeb, 0xe1, 0x4a, + 0x55, 0x8c, 0xc8, 0xef, 0x5f, 0xba, 0xd2, 0x01, 0x47, 0xff, 0x8e, 0xef, 0x7a, 0xb8, 0x56, 0x7e, + 0x32, 0xf9, 0x04, 0xea, 0xa2, 0x12, 0x72, 0xd8, 0x04, 0x63, 0xc5, 0xb2, 0xda, 0x4f, 0xd4, 0xe8, + 0x3d, 0x36, 0xc9, 0xc4, 0x65, 0xb8, 0x34, 0x2e, 0x37, 0xb2, 0x71, 0xf9, 0xcd, 0x6c, 0x2c, 0x5a, + 0x11, 0x55, 0x78, 0x1a, 0x84, 0x2e, 0x38, 0x7c, 0x6b, 0x89, 0xc3, 0x77, 0x60, 0x23, 0xf1, 0x55, + 0xcb, 0xf5, 0x26, 0xee, 0x4b, 0x2b, 0x72, 0x5f, 0x89, 0xd8, 0x53, 0xa6, 0xeb, 0x09, 0xcb, 0xe0, + 0x9c, 0x91, 0xfb, 0x8a, 0x11, 0x23, 0xe9, 0xe0, 0x64, 0x0e, 0x5c, 0xc5, 0xab, 0xc9, 0xf7, 0x2e, + 0x55, 0x8f, 0x68, 0xbe, 0x64, 0x46, 0xcc, 0x4d, 0x6d, 0xff, 0x52, 0x81, 0x46, 0xe6, 0x1c, 0x78, + 0xf6, 0x16, 0xca, 0x42, 0x61, 0xc5, 0x55, 0x94, 0x50, 0x1f, 0x4a, 0xfa, 0x26, 0xd4, 0xa3, 0xd8, + 0x0e, 0x63, 0x8b, 0x17, 0x57, 0xb2, 0xdd, 0x45, 0xc2, 0x13, 0x76, 0x46, 0x3e, 0x80, 0x35, 0xc1, + 0x74, 0xbd, 0xf1, 0x74, 0x1e, 0xb9, 0xa7, 0xa2, 0x99, 0xaf, 0xd1, 0x26, 0x92, 0x8d, 0x84, 0x4a, + 0xee, 0x42, 0x95, 0x67, 0x21, 0xbe, 0x86, 0x68, 0xfa, 0x2a, 0xcc, 0x73, 0xf8, 0x0a, 0x0f, 0x60, + 0x95, 0x33, 0xce, 0xe7, 0x57, 0xc4, 0x2d, 0x33, 0xf3, 0x9c, 0xf3, 0xd9, 0x1d, 0xd8, 0x10, 0xaf, + 0x09, 0x44, 0xf1, 0x2a, 0x2b, 0xdc, 0x3b, 0xa8, 0xd8, 0x75, 0x64, 0xc9, 0xb2, 0x56, 0x14, 0x9c, + 0x1f, 0x01, 0xcf, 0x5e, 0x0b, 0xe8, 0xbb, 0x22, 0x94, 0x31, 0xcf, 0xc9, 0x61, 0x77, 0xe1, 0x1d, + 0x8e, 0x9d, 0x7b, 0x76, 0x10, 0x4c, 0x5d, 0xe6, 0x58, 0x53, 0xff, 0x18, 0x43, 0x66, 0x14, 0xdb, + 0xb3, 0xc0, 0x9a, 0x47, 0xad, 0x0d, 0x0c, 0x99, 0x6d, 0xe6, 0x39, 0x47, 0x09, 0xa8, 0xef, 0x1f, + 0x9b, 0x09, 0xe4, 0x28, 0x6a, 0xff, 0x3e, 0xac, 0xe6, 0xec, 0x71, 0x41, 0xa7, 0x35, 0x74, 0xfe, + 0x8c, 0x4e, 0xdf, 0x85, 0x95, 0x20, 0x64, 0xe7, 0xa2, 0xd5, 0x51, 0xb4, 0x86, 0xa0, 0x09, 0xb1, + 0xb6, 0x60, 0x05, 0x79, 0x96, 0x20, 0xe6, 0xf3, 0x63, 0x03, 0x59, 0x87, 0xc8, 0x69, 0xbf, 0x80, + 0x95, 0xec, 0x69, 0x93, 0x77, 0x33, 0x69, 0xa1, 0x99, 0xcb, 0x93, 0x69, 0x76, 0x48, 0x2a, 0xb2, + 0xf5, 0x4b, 0x2a, 0x32, 0x72, 0x9d, 0x8a, 0x4c, 0xfb, 0x2f, 0xd9, 0x9c, 0x65, 0x2a, 0x84, 0x9f, + 0x41, 0x2d, 0x90, 0xf5, 0x38, 0x5a, 0x52, 0xfe, 0x12, 0x3e, 0x0f, 0xee, 0x24, 0x95, 0x3b, 0x4d, + 0xe7, 0xb4, 0xff, 0x56, 0x81, 0x5a, 0x5a, 0xd0, 0xe7, 0x2c, 0xef, 0xcd, 0x05, 0xcb, 0x3b, 0x90, + 0x1a, 0x16, 0x0a, 0x7c, 0x1b, 0xa3, 0xc5, 0x27, 0xaf, 0x7f, 0xd7, 0xc5, 0xb6, 0xe7, 0x34, 0xdb, + 0xf6, 0x6c, 0xbe, 0xae, 0xed, 0xf9, 0xe4, 0xa2, 0xc1, 0xbf, 0x95, 0xe9, 0x2d, 0x16, 0xcc, 0xbe, + 0xfd, 0x7d, 0xae, 0x0f, 0xca, 0x26, 0x84, 0x77, 0xc4, 0x7e, 0xd2, 0x84, 0x90, 0xb6, 0x3f, 0xf7, + 0xaf, 0xd7, 0xfe, 0x6c, 0x43, 0x45, 0xea, 0xfc, 0x0e, 0x54, 0x64, 0x4d, 0x27, 0x1b, 0x04, 0x31, + 0x3a, 0x6f, 0x10, 0x0a, 0xb2, 0x4e, 0xd7, 0x7e, 0xae, 0x40, 0x59, 0x0f, 0x43, 0x3f, 0xd4, 0xfe, + 0x48, 0x81, 0x3a, 0x3e, 0xed, 0xf9, 0x0e, 0xe3, 0xd9, 0x60, 0xb7, 0xdb, 0xb3, 0xa8, 0xfe, 0xcd, + 0x91, 0x8e, 0xd9, 0xa0, 0x0d, 0x77, 0xf6, 0x86, 0x83, 0xbd, 0x23, 0x4a, 0xf5, 0x81, 0x69, 0x99, + 0xb4, 0x3b, 0x18, 0xf1, 0xb6, 0x67, 0x38, 0x50, 0x15, 0x9e, 0x29, 0x8c, 0x81, 0xa9, 0xd3, 0x41, + 0xb7, 0x6f, 0x89, 0x56, 0xb4, 0x88, 0x77, 0xb3, 0xba, 0xde, 0xb3, 0xf0, 0xd6, 0x51, 0x2d, 0xf1, + 0x96, 0xd5, 0x34, 0x0e, 0xf4, 0xe1, 0x91, 0xa9, 0x96, 0xc9, 0x6d, 0x58, 0x3f, 0xd4, 0xe9, 0x81, + 0x31, 0x1a, 0x19, 0xc3, 0x81, 0xd5, 0xd3, 0x07, 0x86, 0xde, 0x53, 0x2b, 0x7c, 0x9d, 0x5d, 0x63, + 0xdf, 0xec, 0xee, 0xf6, 0x75, 0xb9, 0x4e, 0x95, 0x6c, 0xc2, 0x5b, 0x7b, 0xc3, 0x83, 0x03, 0xc3, + 0x34, 0xf5, 0x9e, 0xb5, 0x7b, 0x64, 0x5a, 0x23, 0xd3, 0xe8, 0xf7, 0xad, 0xee, 0xe1, 0x61, 0xff, + 0x29, 0x4f, 0x60, 0x35, 0x72, 0x17, 0x36, 0xf6, 0xba, 0x87, 0xdd, 0x5d, 0xa3, 0x6f, 0x98, 0x4f, + 0xad, 0x9e, 0x31, 0xe2, 0xf3, 0x7b, 0x6a, 0x9d, 0x27, 0x6c, 0x93, 0x3e, 0xb5, 0xba, 0x7d, 0x14, + 0xcd, 0xd4, 0xad, 0xdd, 0xee, 0xde, 0x13, 0x7d, 0xd0, 0x53, 0x81, 0x0b, 0x30, 0xea, 0x3e, 0xd2, + 0x2d, 0x2e, 0x92, 0x65, 0x0e, 0x87, 0xd6, 0xb0, 0xdf, 0x53, 0x1b, 0xda, 0xbf, 0x14, 0xa1, 0xb4, + 0xe7, 0x47, 0x31, 0xf7, 0x46, 0xe1, 0xac, 0x2f, 0x42, 0x37, 0x66, 0xa2, 0x7f, 0x2b, 0x53, 0xd1, + 0x4b, 0x7f, 0x87, 0x24, 0x1e, 0x50, 0x32, 0x10, 0xeb, 0xd9, 0x19, 0xc7, 0x29, 0x88, 0x5b, 0x3b, + 0xc7, 0xed, 0x72, 0xb2, 0x88, 0x68, 0x78, 0x85, 0x23, 0xd7, 0x2b, 0x22, 0x4e, 0x06, 0x61, 0xb9, + 0xe0, 0xc7, 0x40, 0xb2, 0x20, 0xb9, 0x62, 0x09, 0x91, 0x6a, 0x06, 0x29, 0x96, 0xdc, 0x01, 0x18, + 0xfb, 0xb3, 0x99, 0x1b, 0x8f, 0xfd, 0x28, 0x96, 0x5f, 0xc8, 0xda, 0x39, 0x63, 0x8f, 0x62, 0x6e, + 0xf1, 0x33, 0x37, 0xe6, 0x8f, 0x34, 0x83, 0x26, 0x3b, 0x70, 0xcf, 0x0e, 0x82, 0xd0, 0x7f, 0xe9, + 0xce, 0xec, 0x98, 0x59, 0xdc, 0x73, 0xed, 0x63, 0x66, 0x39, 0x6c, 0x1a, 0xdb, 0xd8, 0x13, 0x95, + 0xe9, 0xdd, 0x0c, 0x60, 0x24, 0xf8, 0x3d, 0xce, 0xe6, 0x71, 0xd7, 0x75, 0xac, 0x88, 0xfd, 0x30, + 0xe7, 0x1e, 0x60, 0xcd, 0x03, 0xc7, 0xe6, 0x62, 0xd6, 0x45, 0x96, 0x72, 0x9d, 0x91, 0xe4, 0x1c, + 0x09, 0x46, 0xfb, 0x15, 0xc0, 0xb9, 0x14, 0x64, 0x1b, 0x6e, 0xf3, 0x3a, 0x9e, 0x45, 0x31, 0x73, + 0x2c, 0xb9, 0xdb, 0x60, 0x1e, 0x47, 0x18, 0xe2, 0xcb, 0x74, 0x23, 0x65, 0xca, 0x9b, 0xc2, 0x79, + 0x1c, 0x91, 0x9f, 0x40, 0xeb, 0xc2, 0x1c, 0x87, 0x4d, 0x19, 0x7f, 0x6d, 0x15, 0xa7, 0xdd, 0x59, + 0x98, 0xd6, 0x13, 0x5c, 0xed, 0x4f, 0x14, 0x80, 0x7d, 0x16, 0x53, 0xc1, 0xcd, 0x34, 0xb6, 0x95, + 0xeb, 0x36, 0xb6, 0xef, 0x27, 0x17, 0x08, 0xc5, 0xab, 0x63, 0xc0, 0x42, 0x97, 0xa1, 0xdc, 0xa4, + 0xcb, 0xc8, 0x35, 0x11, 0xc5, 0x2b, 0x9a, 0x88, 0x52, 0xae, 0x89, 0xf8, 0x18, 0x9a, 0xf6, 0x74, + 0xea, 0xbf, 0xe0, 0x05, 0x0d, 0x0b, 0x43, 0xe6, 0xa0, 0x11, 0x9c, 0xd7, 0xdb, 0xc8, 0xec, 0x49, + 0x9e, 0xf6, 0xe7, 0x0a, 0x34, 0x50, 0x15, 0x51, 0xe0, 0x7b, 0x11, 0x23, 0x5f, 0x42, 0x45, 0x5e, + 0x44, 0x8b, 0x8b, 0xfc, 0xb7, 0x33, 0xb2, 0x66, 0x70, 0xb2, 0x68, 0xa0, 0x12, 0xcc, 0x33, 0x42, + 0xe6, 0x75, 0x97, 0x2b, 0x25, 0x45, 0x91, 0xfb, 0x50, 0x73, 0x3d, 0x4b, 0xb4, 0xd4, 0x95, 0x4c, + 0x58, 0xac, 0xba, 0x1e, 0xd6, 0xb2, 0xed, 0x57, 0x50, 0x11, 0x2f, 0x21, 0x9d, 0x54, 0xa6, 0x8b, + 0xfa, 0xcb, 0xdc, 0x1c, 0xa7, 0xc2, 0xc8, 0xc3, 0x29, 0xbd, 0x2e, 0x40, 0xb7, 0xa0, 0x7a, 0xca, + 0x9b, 0x0f, 0xbc, 0xf4, 0xe3, 0xea, 0x4d, 0x86, 0xda, 0x1f, 0x97, 0x00, 0x0e, 0xe7, 0x4b, 0x0c, + 0xa4, 0x71, 0x5d, 0x03, 0xe9, 0xe4, 0xf4, 0xf8, 0x7a, 0x99, 0x7f, 0x75, 0x43, 0x59, 0xd2, 0x69, + 0x17, 0x6f, 0xda, 0x69, 0xdf, 0x87, 0x6a, 0x1c, 0xce, 0xb9, 0xa3, 0x08, 0x63, 0x4a, 0x5b, 0x5a, + 0x49, 0x25, 0x6f, 0x42, 0x79, 0xe2, 0x87, 0x63, 0x86, 0x8e, 0x95, 0xb2, 0x05, 0xed, 0xc2, 0x65, + 0x52, 0xed, 0xb2, 0xcb, 0x24, 0xde, 0xa0, 0x45, 0xf2, 0x1e, 0x0d, 0x0b, 0x99, 0x7c, 0x83, 0x96, + 0x5c, 0xb1, 0xd1, 0x14, 0x44, 0xbe, 0x81, 0xa6, 0x3d, 0x8f, 0x7d, 0xcb, 0xe5, 0x15, 0xda, 0xd4, + 0x1d, 0x9f, 0x61, 0xd9, 0xdd, 0xcc, 0x7f, 0xaf, 0x4f, 0x0f, 0xaa, 0xd3, 0x9d, 0xc7, 0xbe, 0xe1, + 0x1c, 0x22, 0x72, 0xa7, 0x2a, 0x93, 0x12, 0x5d, 0xb1, 0x33, 0x64, 0xed, 0xc7, 0xb0, 0x92, 0x85, + 0xf1, 0x04, 0x24, 0x81, 0xea, 0x1b, 0x3c, 0x3b, 0x8d, 0x78, 0x6a, 0x1b, 0x98, 0x46, 0xb7, 0xaf, + 0x16, 0xb4, 0x18, 0x1a, 0xb8, 0xbc, 0xf4, 0x8e, 0xeb, 0xba, 0xfd, 0x03, 0x28, 0x61, 0xf8, 0x55, + 0x2e, 0x7c, 0x0f, 0xc1, 0x98, 0x8b, 0xcc, 0xbc, 0xf9, 0x15, 0xb3, 0xe6, 0xf7, 0xdf, 0x05, 0x58, + 0x31, 0xfd, 0xf9, 0xf8, 0xe4, 0xa2, 0x01, 0xc2, 0xaf, 0x3b, 0x42, 0x2d, 0x31, 0x1f, 0xe5, 0xa6, + 0xe6, 0x93, 0x5a, 0x47, 0x71, 0x89, 0x75, 0xdc, 0xf4, 0xcc, 0xb5, 0x2f, 0x60, 0x55, 0x6e, 0x5e, + 0x6a, 0x3d, 0xd1, 0x66, 0xe1, 0x0a, 0x6d, 0x6a, 0xbf, 0x50, 0x60, 0x55, 0xc4, 0xf7, 0xff, 0xbb, + 0xd2, 0x2a, 0x37, 0x0c, 0xeb, 0xe5, 0x1b, 0x5d, 0x1e, 0xfd, 0xbf, 0xf4, 0x34, 0x6d, 0x08, 0xcd, + 0x44, 0x7d, 0x37, 0x50, 0xfb, 0x15, 0x46, 0xfc, 0x8b, 0x02, 0x34, 0x06, 0xec, 0xe5, 0x92, 0x20, + 0x5a, 0xbe, 0xee, 0x71, 0x7c, 0x98, 0x2b, 0x57, 0x1b, 0xdb, 0xeb, 0x59, 0x19, 0xc4, 0xd5, 0x63, + 0x52, 0xc1, 0xa6, 0xb7, 0xa8, 0xca, 0xf2, 0x5b, 0xd4, 0xd2, 0x62, 0xb7, 0x9e, 0xb9, 0xc5, 0x2b, + 0x2e, 0xbb, 0xc5, 0xd3, 0xfe, 0xad, 0x08, 0x0d, 0x6c, 0x90, 0x29, 0x8b, 0xe6, 0xd3, 0x38, 0x27, + 0x4c, 0xe1, 0x6a, 0x61, 0x3a, 0x50, 0x09, 0x71, 0x92, 0x74, 0xa5, 0x4b, 0x83, 0xbf, 0x40, 0x61, + 0x6b, 0xfc, 0xdc, 0x0d, 0x02, 0xe6, 0x58, 0x82, 0x92, 0x14, 0x30, 0x4d, 0x49, 0x16, 0x22, 0x44, + 0xbc, 0xfc, 0x9c, 0xf9, 0x21, 0x4b, 0x51, 0x45, 0xbc, 0x4f, 0x68, 0x70, 0x5a, 0x02, 0xc9, 0xdd, + 0x37, 0x88, 0xca, 0xe0, 0xfc, 0xbe, 0x21, 0xed, 0x35, 0x91, 0x5b, 0x47, 0xae, 0xe8, 0x35, 0x91, + 0xcd, 0xbb, 0xa8, 0x99, 0x3d, 0x9d, 0x5a, 0x7e, 0x10, 0xa1, 0xd3, 0xd4, 0x68, 0x0d, 0x09, 0xc3, + 0x20, 0x22, 0x5f, 0x43, 0x7a, 0x5d, 0x2c, 0x6f, 0xc9, 0xc5, 0x39, 0xb6, 0x2e, 0xbb, 0x58, 0xa0, + 0xab, 0xe3, 0xdc, 0xfd, 0xcf, 0x92, 0x1b, 0xea, 0xca, 0x4d, 0x6f, 0xa8, 0x1f, 0x42, 0x59, 0xc4, + 0xa8, 0xda, 0xeb, 0x62, 0x94, 0xc0, 0x65, 0xed, 0xb3, 0x91, 0xb7, 0xcf, 0x5f, 0x16, 0x80, 0x74, + 0xa7, 0x53, 0x7f, 0x6c, 0xc7, 0xcc, 0x70, 0xa2, 0x8b, 0x66, 0x7a, 0xed, 0xcf, 0x2e, 0x9f, 0x41, + 0x7d, 0xe6, 0x3b, 0x6c, 0x6a, 0x25, 0xdf, 0x94, 0x2e, 0xad, 0x7e, 0x10, 0xc6, 0x5b, 0x52, 0x02, + 0x25, 0xbc, 0xc4, 0x51, 0xb0, 0xee, 0xc0, 0x67, 0xde, 0x84, 0xcd, 0xec, 0x97, 0xb2, 0x14, 0xe1, + 0x8f, 0xa4, 0x03, 0xd5, 0x90, 0x45, 0x2c, 0x3c, 0x65, 0x57, 0x16, 0x55, 0x09, 0x48, 0x7b, 0x06, + 0x1b, 0xb9, 0x1d, 0x49, 0x47, 0xbe, 0x85, 0x5f, 0x2b, 0xc3, 0x58, 0x7e, 0xb4, 0x12, 0x03, 0xfe, + 0x3a, 0xe6, 0x25, 0x9f, 0x41, 0xf9, 0x63, 0xea, 0xf0, 0xc5, 0xab, 0xe2, 0xec, 0x1e, 0xa8, 0x59, + 0x4d, 0xbb, 0x63, 0x0c, 0x36, 0xf2, 0x54, 0x0a, 0xd7, 0x3b, 0x15, 0xed, 0xef, 0x0a, 0xb0, 0xde, + 0x75, 0x1c, 0xf1, 0x77, 0xc3, 0x25, 0xaa, 0x2f, 0x5e, 0x57, 0xf5, 0x0b, 0x81, 0x58, 0x84, 0x89, + 0x6b, 0x05, 0xe2, 0x0f, 0xa1, 0x92, 0xd6, 0x5a, 0xc5, 0x05, 0x77, 0x16, 0x72, 0x51, 0x09, 0xd0, + 0x6e, 0x01, 0xc9, 0x0a, 0x2b, 0xb4, 0xaa, 0xfd, 0x69, 0x11, 0xee, 0xee, 0xb2, 0x63, 0xd7, 0xcb, + 0xbe, 0xe2, 0x57, 0xdf, 0xc9, 0xc5, 0x4f, 0x65, 0x9f, 0xc1, 0xba, 0x28, 0xe4, 0x93, 0x7f, 0x62, + 0x59, 0xec, 0x58, 0x7e, 0x9d, 0x94, 0xb1, 0x6a, 0x0d, 0xf9, 0x07, 0x92, 0xad, 0xe3, 0x7f, 0xc5, + 0x1c, 0x3b, 0xb6, 0x9f, 0xd9, 0x11, 0xb3, 0x5c, 0x47, 0xfe, 0x59, 0x06, 0x12, 0x92, 0xe1, 0x90, + 0x21, 0x94, 0xb8, 0x0d, 0xa2, 0xeb, 0x36, 0xb7, 0xb7, 0x33, 0x62, 0x5d, 0xb2, 0x95, 0xac, 0x02, + 0x0f, 0x7c, 0x87, 0xed, 0x54, 0x8f, 0x06, 0x4f, 0x06, 0xc3, 0xef, 0x06, 0x14, 0x17, 0x22, 0x06, + 0xdc, 0x0a, 0x42, 0x76, 0xea, 0xfa, 0xf3, 0xc8, 0xca, 0x9e, 0x44, 0xf5, 0xca, 0x94, 0xb8, 0x91, + 0xcc, 0xc9, 0x10, 0xb5, 0x9f, 0xc2, 0xda, 0xc2, 0xcb, 0x78, 0x6d, 0x26, 0x5f, 0xa7, 0xbe, 0x41, + 0x56, 0xa1, 0x8e, 0x1f, 0xbb, 0x97, 0x7f, 0xfb, 0xd6, 0xfe, 0xb5, 0x80, 0x57, 0x4c, 0x33, 0x37, + 0xbe, 0x59, 0x06, 0xfb, 0xcd, 0x7c, 0x06, 0x83, 0xed, 0x77, 0xf3, 0xe6, 0x9b, 0x59, 0xb0, 0xf3, + 0xad, 0x00, 0xa6, 0x41, 0xa4, 0x6d, 0x43, 0x55, 0xd2, 0xc8, 0x6f, 0xc1, 0x5a, 0xe8, 0xfb, 0x71, + 0xd2, 0x89, 0x8a, 0x0e, 0xe4, 0xf2, 0x3f, 0xdb, 0xac, 0x72, 0xb0, 0x48, 0x06, 0x4f, 0xf2, 0xbd, + 0x48, 0x59, 0xfc, 0x0d, 0x44, 0x0e, 0x77, 0x1b, 0xbf, 0x5b, 0x4f, 0xff, 0xb7, 0xfb, 0xbf, 0x01, + 0x00, 0x00, 0xff, 0xff, 0x35, 0x9f, 0x30, 0x98, 0xf2, 0x2b, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto new file mode 100644 index 000000000000..497b4d9a9af5 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto @@ -0,0 +1,551 @@ +syntax = "proto2"; +option go_package = "datastore"; + +package appengine; + +message Action{} + +message PropertyValue { + optional int64 int64Value = 1; + optional bool booleanValue = 2; + optional string stringValue = 3; + optional double doubleValue = 4; + + optional group PointValue = 5 { + required double x = 6; + required double y = 7; + } + + optional group UserValue = 8 { + required string email = 9; + required string auth_domain = 10; + optional string nickname = 11; + optional string federated_identity = 21; + optional string federated_provider = 22; + } + + optional group ReferenceValue = 12 { + required string app = 13; + optional string name_space = 20; + repeated group PathElement = 14 { + required string type = 15; + optional int64 id = 16; + optional string name = 17; + } + } +} + +message Property { + enum Meaning { + NO_MEANING = 0; + BLOB = 14; + TEXT = 15; + BYTESTRING = 16; + + ATOM_CATEGORY = 1; + ATOM_LINK = 2; + ATOM_TITLE = 3; + ATOM_CONTENT = 4; + ATOM_SUMMARY = 5; + ATOM_AUTHOR = 6; + + GD_WHEN = 7; + GD_EMAIL = 8; + GEORSS_POINT = 9; + GD_IM = 10; + + GD_PHONENUMBER = 11; + GD_POSTALADDRESS = 12; + + GD_RATING = 13; + + BLOBKEY = 17; + ENTITY_PROTO = 19; + + INDEX_VALUE = 18; + }; + + optional Meaning meaning = 1 [default = NO_MEANING]; + optional string meaning_uri = 2; + + required string name = 3; + + required PropertyValue value = 5; + + required bool multiple = 4; + + optional bool searchable = 6 [default=false]; + + enum FtsTokenizationOption { + HTML = 1; + ATOM = 2; + } + + optional FtsTokenizationOption fts_tokenization_option = 8; + + optional string locale = 9 [default = "en"]; +} + +message Path { + repeated group Element = 1 { + required string type = 2; + optional int64 id = 3; + optional string name = 4; + } +} + +message Reference { + required string app = 13; + optional string name_space = 20; + required Path path = 14; +} + +message User { + required string email = 1; + required string auth_domain = 2; + optional string nickname = 3; + optional string federated_identity = 6; + optional string federated_provider = 7; +} + +message EntityProto { + required Reference key = 13; + required Path entity_group = 16; + optional User owner = 17; + + enum Kind { + GD_CONTACT = 1; + GD_EVENT = 2; + GD_MESSAGE = 3; + } + optional Kind kind = 4; + optional string kind_uri = 5; + + repeated Property property = 14; + repeated Property raw_property = 15; + + optional int32 rank = 18; +} + +message CompositeProperty { + required int64 index_id = 1; + repeated string value = 2; +} + +message Index { + required string entity_type = 1; + required bool ancestor = 5; + repeated group Property = 2 { + required string name = 3; + enum Direction { + ASCENDING = 1; + DESCENDING = 2; + } + optional Direction direction = 4 [default = ASCENDING]; + } +} + +message CompositeIndex { + required string app_id = 1; + required int64 id = 2; + required Index definition = 3; + + enum State { + WRITE_ONLY = 1; + READ_WRITE = 2; + DELETED = 3; + ERROR = 4; + } + required State state = 4; + + optional bool only_use_if_required = 6 [default = false]; +} + +message IndexPostfix { + message IndexValue { + required string property_name = 1; + required PropertyValue value = 2; + } + + repeated IndexValue index_value = 1; + + optional Reference key = 2; + + optional bool before = 3 [default=true]; +} + +message IndexPosition { + optional string key = 1; + + optional bool before = 2 [default=true]; +} + +message Snapshot { + enum Status { + INACTIVE = 0; + ACTIVE = 1; + } + + required int64 ts = 1; +} + +message InternalHeader { + optional string qos = 1; +} + +message Transaction { + optional InternalHeader header = 4; + required fixed64 handle = 1; + required string app = 2; + optional bool mark_changes = 3 [default = false]; +} + +message Query { + optional InternalHeader header = 39; + + required string app = 1; + optional string name_space = 29; + + optional string kind = 3; + optional Reference ancestor = 17; + + repeated group Filter = 4 { + enum Operator { + LESS_THAN = 1; + LESS_THAN_OR_EQUAL = 2; + GREATER_THAN = 3; + GREATER_THAN_OR_EQUAL = 4; + EQUAL = 5; + IN = 6; + EXISTS = 7; + } + + required Operator op = 6; + repeated Property property = 14; + } + + optional string search_query = 8; + + repeated group Order = 9 { + enum Direction { + ASCENDING = 1; + DESCENDING = 2; + } + + required string property = 10; + optional Direction direction = 11 [default = ASCENDING]; + } + + enum Hint { + ORDER_FIRST = 1; + ANCESTOR_FIRST = 2; + FILTER_FIRST = 3; + } + optional Hint hint = 18; + + optional int32 count = 23; + + optional int32 offset = 12 [default = 0]; + + optional int32 limit = 16; + + optional CompiledCursor compiled_cursor = 30; + optional CompiledCursor end_compiled_cursor = 31; + + repeated CompositeIndex composite_index = 19; + + optional bool require_perfect_plan = 20 [default = false]; + + optional bool keys_only = 21 [default = false]; + + optional Transaction transaction = 22; + + optional bool compile = 25 [default = false]; + + optional int64 failover_ms = 26; + + optional bool strong = 32; + + repeated string property_name = 33; + + repeated string group_by_property_name = 34; + + optional bool distinct = 24; + + optional int64 min_safe_time_seconds = 35; + + repeated string safe_replica_name = 36; + + optional bool persist_offset = 37 [default=false]; +} + +message CompiledQuery { + required group PrimaryScan = 1 { + optional string index_name = 2; + + optional string start_key = 3; + optional bool start_inclusive = 4; + optional string end_key = 5; + optional bool end_inclusive = 6; + + repeated string start_postfix_value = 22; + repeated string end_postfix_value = 23; + + optional int64 end_unapplied_log_timestamp_us = 19; + } + + repeated group MergeJoinScan = 7 { + required string index_name = 8; + + repeated string prefix_value = 9; + + optional bool value_prefix = 20 [default=false]; + } + + optional Index index_def = 21; + + optional int32 offset = 10 [default = 0]; + + optional int32 limit = 11; + + required bool keys_only = 12; + + repeated string property_name = 24; + + optional int32 distinct_infix_size = 25; + + optional group EntityFilter = 13 { + optional bool distinct = 14 [default=false]; + + optional string kind = 17; + optional Reference ancestor = 18; + } +} + +message CompiledCursor { + optional group Position = 2 { + optional string start_key = 27; + + repeated group IndexValue = 29 { + optional string property = 30; + required PropertyValue value = 31; + } + + optional Reference key = 32; + + optional bool start_inclusive = 28 [default=true]; + } +} + +message Cursor { + required fixed64 cursor = 1; + + optional string app = 2; +} + +message Error { + enum ErrorCode { + BAD_REQUEST = 1; + CONCURRENT_TRANSACTION = 2; + INTERNAL_ERROR = 3; + NEED_INDEX = 4; + TIMEOUT = 5; + PERMISSION_DENIED = 6; + BIGTABLE_ERROR = 7; + COMMITTED_BUT_STILL_APPLYING = 8; + CAPABILITY_DISABLED = 9; + TRY_ALTERNATE_BACKEND = 10; + SAFE_TIME_TOO_OLD = 11; + } +} + +message Cost { + optional int32 index_writes = 1; + optional int32 index_write_bytes = 2; + optional int32 entity_writes = 3; + optional int32 entity_write_bytes = 4; + optional group CommitCost = 5 { + optional int32 requested_entity_puts = 6; + optional int32 requested_entity_deletes = 7; + }; + optional int32 approximate_storage_delta = 8; + optional int32 id_sequence_updates = 9; +} + +message GetRequest { + optional InternalHeader header = 6; + + repeated Reference key = 1; + optional Transaction transaction = 2; + + optional int64 failover_ms = 3; + + optional bool strong = 4; + + optional bool allow_deferred = 5 [default=false]; +} + +message GetResponse { + repeated group Entity = 1 { + optional EntityProto entity = 2; + optional Reference key = 4; + + optional int64 version = 3; + } + + repeated Reference deferred = 5; + + optional bool in_order = 6 [default=true]; +} + +message PutRequest { + optional InternalHeader header = 11; + + repeated EntityProto entity = 1; + optional Transaction transaction = 2; + repeated CompositeIndex composite_index = 3; + + optional bool trusted = 4 [default = false]; + + optional bool force = 7 [default = false]; + + optional bool mark_changes = 8 [default = false]; + repeated Snapshot snapshot = 9; + + enum AutoIdPolicy { + CURRENT = 0; + SEQUENTIAL = 1; + } + optional AutoIdPolicy auto_id_policy = 10 [default = CURRENT]; +} + +message PutResponse { + repeated Reference key = 1; + optional Cost cost = 2; + repeated int64 version = 3; +} + +message TouchRequest { + optional InternalHeader header = 10; + + repeated Reference key = 1; + repeated CompositeIndex composite_index = 2; + optional bool force = 3 [default = false]; + repeated Snapshot snapshot = 9; +} + +message TouchResponse { + optional Cost cost = 1; +} + +message DeleteRequest { + optional InternalHeader header = 10; + + repeated Reference key = 6; + optional Transaction transaction = 5; + + optional bool trusted = 4 [default = false]; + + optional bool force = 7 [default = false]; + + optional bool mark_changes = 8 [default = false]; + repeated Snapshot snapshot = 9; +} + +message DeleteResponse { + optional Cost cost = 1; + repeated int64 version = 3; +} + +message NextRequest { + optional InternalHeader header = 5; + + required Cursor cursor = 1; + optional int32 count = 2; + + optional int32 offset = 4 [default = 0]; + + optional bool compile = 3 [default = false]; +} + +message QueryResult { + optional Cursor cursor = 1; + + repeated EntityProto result = 2; + + optional int32 skipped_results = 7; + + required bool more_results = 3; + + optional bool keys_only = 4; + + optional bool index_only = 9; + + optional bool small_ops = 10; + + optional CompiledQuery compiled_query = 5; + + optional CompiledCursor compiled_cursor = 6; + + repeated CompositeIndex index = 8; + + repeated int64 version = 11; +} + +message AllocateIdsRequest { + optional InternalHeader header = 4; + + optional Reference model_key = 1; + + optional int64 size = 2; + + optional int64 max = 3; + + repeated Reference reserve = 5; +} + +message AllocateIdsResponse { + required int64 start = 1; + required int64 end = 2; + optional Cost cost = 3; +} + +message CompositeIndices { + repeated CompositeIndex index = 1; +} + +message AddActionsRequest { + optional InternalHeader header = 3; + + required Transaction transaction = 1; + repeated Action action = 2; +} + +message AddActionsResponse { +} + +message BeginTransactionRequest { + optional InternalHeader header = 3; + + required string app = 1; + optional bool allow_multiple_eg = 2 [default = false]; + optional string database_id = 4; + + enum TransactionMode { + UNKNOWN = 0; + READ_ONLY = 1; + READ_WRITE = 2; + } + optional TransactionMode mode = 5 [default = UNKNOWN]; + + optional Transaction previous_transaction = 7; +} + +message CommitResponse { + optional Cost cost = 1; + + repeated group Version = 3 { + required Reference root_entity_key = 4; + required int64 version = 5; + } +} diff --git a/vendor/google.golang.org/appengine/internal/identity.go b/vendor/google.golang.org/appengine/internal/identity.go new file mode 100644 index 000000000000..9b4134e42573 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/identity.go @@ -0,0 +1,55 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package internal + +import ( + "os" + + netcontext "golang.org/x/net/context" +) + +var ( + // This is set to true in identity_classic.go, which is behind the appengine build tag. + // The appengine build tag is set for the first generation runtimes (<= Go 1.9) but not + // the second generation runtimes (>= Go 1.11), so this indicates whether we're on a + // first-gen runtime. See IsStandard below for the second-gen check. + appengineStandard bool + + // This is set to true in identity_flex.go, which is behind the appenginevm build tag. + appengineFlex bool +) + +// AppID is the implementation of the wrapper function of the same name in +// ../identity.go. See that file for commentary. +func AppID(c netcontext.Context) string { + return appID(FullyQualifiedAppID(c)) +} + +// IsStandard is the implementation of the wrapper function of the same name in +// ../appengine.go. See that file for commentary. +func IsStandard() bool { + // appengineStandard will be true for first-gen runtimes (<= Go 1.9) but not + // second-gen (>= Go 1.11). + return appengineStandard || IsSecondGen() +} + +// IsStandard is the implementation of the wrapper function of the same name in +// ../appengine.go. See that file for commentary. +func IsSecondGen() bool { + // Second-gen runtimes set $GAE_ENV so we use that to check if we're on a second-gen runtime. + return os.Getenv("GAE_ENV") == "standard" +} + +// IsFlex is the implementation of the wrapper function of the same name in +// ../appengine.go. See that file for commentary. +func IsFlex() bool { + return appengineFlex +} + +// IsAppEngine is the implementation of the wrapper function of the same name in +// ../appengine.go. See that file for commentary. +func IsAppEngine() bool { + return IsStandard() || IsFlex() +} diff --git a/vendor/google.golang.org/appengine/internal/identity_classic.go b/vendor/google.golang.org/appengine/internal/identity_classic.go new file mode 100644 index 000000000000..4e979f45e34d --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/identity_classic.go @@ -0,0 +1,61 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build appengine + +package internal + +import ( + "appengine" + + netcontext "golang.org/x/net/context" +) + +func init() { + appengineStandard = true +} + +func DefaultVersionHostname(ctx netcontext.Context) string { + c := fromContext(ctx) + if c == nil { + panic(errNotAppEngineContext) + } + return appengine.DefaultVersionHostname(c) +} + +func Datacenter(_ netcontext.Context) string { return appengine.Datacenter() } +func ServerSoftware() string { return appengine.ServerSoftware() } +func InstanceID() string { return appengine.InstanceID() } +func IsDevAppServer() bool { return appengine.IsDevAppServer() } + +func RequestID(ctx netcontext.Context) string { + c := fromContext(ctx) + if c == nil { + panic(errNotAppEngineContext) + } + return appengine.RequestID(c) +} + +func ModuleName(ctx netcontext.Context) string { + c := fromContext(ctx) + if c == nil { + panic(errNotAppEngineContext) + } + return appengine.ModuleName(c) +} +func VersionID(ctx netcontext.Context) string { + c := fromContext(ctx) + if c == nil { + panic(errNotAppEngineContext) + } + return appengine.VersionID(c) +} + +func fullyQualifiedAppID(ctx netcontext.Context) string { + c := fromContext(ctx) + if c == nil { + panic(errNotAppEngineContext) + } + return c.FullyQualifiedAppID() +} diff --git a/vendor/google.golang.org/appengine/internal/identity_flex.go b/vendor/google.golang.org/appengine/internal/identity_flex.go new file mode 100644 index 000000000000..d5e2e7b5e3f8 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/identity_flex.go @@ -0,0 +1,11 @@ +// Copyright 2018 Google LLC. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build appenginevm + +package internal + +func init() { + appengineFlex = true +} diff --git a/vendor/google.golang.org/appengine/internal/identity_vm.go b/vendor/google.golang.org/appengine/internal/identity_vm.go new file mode 100644 index 000000000000..5d8067263556 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/identity_vm.go @@ -0,0 +1,134 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build !appengine + +package internal + +import ( + "log" + "net/http" + "os" + "strings" + + netcontext "golang.org/x/net/context" +) + +// These functions are implementations of the wrapper functions +// in ../appengine/identity.go. See that file for commentary. + +const ( + hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname" + hRequestLogId = "X-AppEngine-Request-Log-Id" + hDatacenter = "X-AppEngine-Datacenter" +) + +func ctxHeaders(ctx netcontext.Context) http.Header { + c := fromContext(ctx) + if c == nil { + return nil + } + return c.Request().Header +} + +func DefaultVersionHostname(ctx netcontext.Context) string { + return ctxHeaders(ctx).Get(hDefaultVersionHostname) +} + +func RequestID(ctx netcontext.Context) string { + return ctxHeaders(ctx).Get(hRequestLogId) +} + +func Datacenter(ctx netcontext.Context) string { + if dc := ctxHeaders(ctx).Get(hDatacenter); dc != "" { + return dc + } + // If the header isn't set, read zone from the metadata service. + // It has the format projects/[NUMERIC_PROJECT_ID]/zones/[ZONE] + zone, err := getMetadata("instance/zone") + if err != nil { + log.Printf("Datacenter: %v", err) + return "" + } + parts := strings.Split(string(zone), "/") + if len(parts) == 0 { + return "" + } + return parts[len(parts)-1] +} + +func ServerSoftware() string { + // TODO(dsymonds): Remove fallback when we've verified this. + if s := os.Getenv("SERVER_SOFTWARE"); s != "" { + return s + } + if s := os.Getenv("GAE_ENV"); s != "" { + return s + } + return "Google App Engine/1.x.x" +} + +// TODO(dsymonds): Remove the metadata fetches. + +func ModuleName(_ netcontext.Context) string { + if s := os.Getenv("GAE_MODULE_NAME"); s != "" { + return s + } + if s := os.Getenv("GAE_SERVICE"); s != "" { + return s + } + return string(mustGetMetadata("instance/attributes/gae_backend_name")) +} + +func VersionID(_ netcontext.Context) string { + if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" { + return s1 + "." + s2 + } + if s1, s2 := os.Getenv("GAE_VERSION"), os.Getenv("GAE_DEPLOYMENT_ID"); s1 != "" && s2 != "" { + return s1 + "." + s2 + } + return string(mustGetMetadata("instance/attributes/gae_backend_version")) + "." + string(mustGetMetadata("instance/attributes/gae_backend_minor_version")) +} + +func InstanceID() string { + if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" { + return s + } + if s := os.Getenv("GAE_INSTANCE"); s != "" { + return s + } + return string(mustGetMetadata("instance/attributes/gae_backend_instance")) +} + +func partitionlessAppID() string { + // gae_project has everything except the partition prefix. + if appID := os.Getenv("GAE_LONG_APP_ID"); appID != "" { + return appID + } + if project := os.Getenv("GOOGLE_CLOUD_PROJECT"); project != "" { + return project + } + return string(mustGetMetadata("instance/attributes/gae_project")) +} + +func fullyQualifiedAppID(_ netcontext.Context) string { + if s := os.Getenv("GAE_APPLICATION"); s != "" { + return s + } + appID := partitionlessAppID() + + part := os.Getenv("GAE_PARTITION") + if part == "" { + part = string(mustGetMetadata("instance/attributes/gae_partition")) + } + + if part != "" { + appID = part + "~" + appID + } + return appID +} + +func IsDevAppServer() bool { + return os.Getenv("RUN_WITH_DEVAPPSERVER") != "" +} diff --git a/vendor/google.golang.org/appengine/internal/internal.go b/vendor/google.golang.org/appengine/internal/internal.go new file mode 100644 index 000000000000..051ea3980abe --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/internal.go @@ -0,0 +1,110 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// Package internal provides support for package appengine. +// +// Programs should not use this package directly. Its API is not stable. +// Use packages appengine and appengine/* instead. +package internal + +import ( + "fmt" + + "github.com/golang/protobuf/proto" + + remotepb "google.golang.org/appengine/internal/remote_api" +) + +// errorCodeMaps is a map of service name to the error code map for the service. +var errorCodeMaps = make(map[string]map[int32]string) + +// RegisterErrorCodeMap is called from API implementations to register their +// error code map. This should only be called from init functions. +func RegisterErrorCodeMap(service string, m map[int32]string) { + errorCodeMaps[service] = m +} + +type timeoutCodeKey struct { + service string + code int32 +} + +// timeoutCodes is the set of service+code pairs that represent timeouts. +var timeoutCodes = make(map[timeoutCodeKey]bool) + +func RegisterTimeoutErrorCode(service string, code int32) { + timeoutCodes[timeoutCodeKey{service, code}] = true +} + +// APIError is the type returned by appengine.Context's Call method +// when an API call fails in an API-specific way. This may be, for instance, +// a taskqueue API call failing with TaskQueueServiceError::UNKNOWN_QUEUE. +type APIError struct { + Service string + Detail string + Code int32 // API-specific error code +} + +func (e *APIError) Error() string { + if e.Code == 0 { + if e.Detail == "" { + return "APIError <empty>" + } + return e.Detail + } + s := fmt.Sprintf("API error %d", e.Code) + if m, ok := errorCodeMaps[e.Service]; ok { + s += " (" + e.Service + ": " + m[e.Code] + ")" + } else { + // Shouldn't happen, but provide a bit more detail if it does. + s = e.Service + " " + s + } + if e.Detail != "" { + s += ": " + e.Detail + } + return s +} + +func (e *APIError) IsTimeout() bool { + return timeoutCodes[timeoutCodeKey{e.Service, e.Code}] +} + +// CallError is the type returned by appengine.Context's Call method when an +// API call fails in a generic way, such as RpcError::CAPABILITY_DISABLED. +type CallError struct { + Detail string + Code int32 + // TODO: Remove this if we get a distinguishable error code. + Timeout bool +} + +func (e *CallError) Error() string { + var msg string + switch remotepb.RpcError_ErrorCode(e.Code) { + case remotepb.RpcError_UNKNOWN: + return e.Detail + case remotepb.RpcError_OVER_QUOTA: + msg = "Over quota" + case remotepb.RpcError_CAPABILITY_DISABLED: + msg = "Capability disabled" + case remotepb.RpcError_CANCELLED: + msg = "Canceled" + default: + msg = fmt.Sprintf("Call error %d", e.Code) + } + s := msg + ": " + e.Detail + if e.Timeout { + s += " (timeout)" + } + return s +} + +func (e *CallError) IsTimeout() bool { + return e.Timeout +} + +// NamespaceMods is a map from API service to a function that will mutate an RPC request to attach a namespace. +// The function should be prepared to be called on the same message more than once; it should only modify the +// RPC request the first time. +var NamespaceMods = make(map[string]func(m proto.Message, namespace string)) diff --git a/vendor/google.golang.org/appengine/internal/log/log_service.pb.go b/vendor/google.golang.org/appengine/internal/log/log_service.pb.go new file mode 100644 index 000000000000..8545ac4ad6ab --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/log/log_service.pb.go @@ -0,0 +1,1313 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google.golang.org/appengine/internal/log/log_service.proto + +package log + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type LogServiceError_ErrorCode int32 + +const ( + LogServiceError_OK LogServiceError_ErrorCode = 0 + LogServiceError_INVALID_REQUEST LogServiceError_ErrorCode = 1 + LogServiceError_STORAGE_ERROR LogServiceError_ErrorCode = 2 +) + +var LogServiceError_ErrorCode_name = map[int32]string{ + 0: "OK", + 1: "INVALID_REQUEST", + 2: "STORAGE_ERROR", +} +var LogServiceError_ErrorCode_value = map[string]int32{ + "OK": 0, + "INVALID_REQUEST": 1, + "STORAGE_ERROR": 2, +} + +func (x LogServiceError_ErrorCode) Enum() *LogServiceError_ErrorCode { + p := new(LogServiceError_ErrorCode) + *p = x + return p +} +func (x LogServiceError_ErrorCode) String() string { + return proto.EnumName(LogServiceError_ErrorCode_name, int32(x)) +} +func (x *LogServiceError_ErrorCode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(LogServiceError_ErrorCode_value, data, "LogServiceError_ErrorCode") + if err != nil { + return err + } + *x = LogServiceError_ErrorCode(value) + return nil +} +func (LogServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{0, 0} +} + +type LogServiceError struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogServiceError) Reset() { *m = LogServiceError{} } +func (m *LogServiceError) String() string { return proto.CompactTextString(m) } +func (*LogServiceError) ProtoMessage() {} +func (*LogServiceError) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{0} +} +func (m *LogServiceError) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogServiceError.Unmarshal(m, b) +} +func (m *LogServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogServiceError.Marshal(b, m, deterministic) +} +func (dst *LogServiceError) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogServiceError.Merge(dst, src) +} +func (m *LogServiceError) XXX_Size() int { + return xxx_messageInfo_LogServiceError.Size(m) +} +func (m *LogServiceError) XXX_DiscardUnknown() { + xxx_messageInfo_LogServiceError.DiscardUnknown(m) +} + +var xxx_messageInfo_LogServiceError proto.InternalMessageInfo + +type UserAppLogLine struct { + TimestampUsec *int64 `protobuf:"varint,1,req,name=timestamp_usec,json=timestampUsec" json:"timestamp_usec,omitempty"` + Level *int64 `protobuf:"varint,2,req,name=level" json:"level,omitempty"` + Message *string `protobuf:"bytes,3,req,name=message" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UserAppLogLine) Reset() { *m = UserAppLogLine{} } +func (m *UserAppLogLine) String() string { return proto.CompactTextString(m) } +func (*UserAppLogLine) ProtoMessage() {} +func (*UserAppLogLine) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{1} +} +func (m *UserAppLogLine) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UserAppLogLine.Unmarshal(m, b) +} +func (m *UserAppLogLine) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UserAppLogLine.Marshal(b, m, deterministic) +} +func (dst *UserAppLogLine) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserAppLogLine.Merge(dst, src) +} +func (m *UserAppLogLine) XXX_Size() int { + return xxx_messageInfo_UserAppLogLine.Size(m) +} +func (m *UserAppLogLine) XXX_DiscardUnknown() { + xxx_messageInfo_UserAppLogLine.DiscardUnknown(m) +} + +var xxx_messageInfo_UserAppLogLine proto.InternalMessageInfo + +func (m *UserAppLogLine) GetTimestampUsec() int64 { + if m != nil && m.TimestampUsec != nil { + return *m.TimestampUsec + } + return 0 +} + +func (m *UserAppLogLine) GetLevel() int64 { + if m != nil && m.Level != nil { + return *m.Level + } + return 0 +} + +func (m *UserAppLogLine) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +type UserAppLogGroup struct { + LogLine []*UserAppLogLine `protobuf:"bytes,2,rep,name=log_line,json=logLine" json:"log_line,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UserAppLogGroup) Reset() { *m = UserAppLogGroup{} } +func (m *UserAppLogGroup) String() string { return proto.CompactTextString(m) } +func (*UserAppLogGroup) ProtoMessage() {} +func (*UserAppLogGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{2} +} +func (m *UserAppLogGroup) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UserAppLogGroup.Unmarshal(m, b) +} +func (m *UserAppLogGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UserAppLogGroup.Marshal(b, m, deterministic) +} +func (dst *UserAppLogGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserAppLogGroup.Merge(dst, src) +} +func (m *UserAppLogGroup) XXX_Size() int { + return xxx_messageInfo_UserAppLogGroup.Size(m) +} +func (m *UserAppLogGroup) XXX_DiscardUnknown() { + xxx_messageInfo_UserAppLogGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_UserAppLogGroup proto.InternalMessageInfo + +func (m *UserAppLogGroup) GetLogLine() []*UserAppLogLine { + if m != nil { + return m.LogLine + } + return nil +} + +type FlushRequest struct { + Logs []byte `protobuf:"bytes,1,opt,name=logs" json:"logs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FlushRequest) Reset() { *m = FlushRequest{} } +func (m *FlushRequest) String() string { return proto.CompactTextString(m) } +func (*FlushRequest) ProtoMessage() {} +func (*FlushRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{3} +} +func (m *FlushRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FlushRequest.Unmarshal(m, b) +} +func (m *FlushRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FlushRequest.Marshal(b, m, deterministic) +} +func (dst *FlushRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_FlushRequest.Merge(dst, src) +} +func (m *FlushRequest) XXX_Size() int { + return xxx_messageInfo_FlushRequest.Size(m) +} +func (m *FlushRequest) XXX_DiscardUnknown() { + xxx_messageInfo_FlushRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_FlushRequest proto.InternalMessageInfo + +func (m *FlushRequest) GetLogs() []byte { + if m != nil { + return m.Logs + } + return nil +} + +type SetStatusRequest struct { + Status *string `protobuf:"bytes,1,req,name=status" json:"status,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetStatusRequest) Reset() { *m = SetStatusRequest{} } +func (m *SetStatusRequest) String() string { return proto.CompactTextString(m) } +func (*SetStatusRequest) ProtoMessage() {} +func (*SetStatusRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{4} +} +func (m *SetStatusRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetStatusRequest.Unmarshal(m, b) +} +func (m *SetStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetStatusRequest.Marshal(b, m, deterministic) +} +func (dst *SetStatusRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetStatusRequest.Merge(dst, src) +} +func (m *SetStatusRequest) XXX_Size() int { + return xxx_messageInfo_SetStatusRequest.Size(m) +} +func (m *SetStatusRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SetStatusRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SetStatusRequest proto.InternalMessageInfo + +func (m *SetStatusRequest) GetStatus() string { + if m != nil && m.Status != nil { + return *m.Status + } + return "" +} + +type LogOffset struct { + RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId" json:"request_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogOffset) Reset() { *m = LogOffset{} } +func (m *LogOffset) String() string { return proto.CompactTextString(m) } +func (*LogOffset) ProtoMessage() {} +func (*LogOffset) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{5} +} +func (m *LogOffset) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogOffset.Unmarshal(m, b) +} +func (m *LogOffset) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogOffset.Marshal(b, m, deterministic) +} +func (dst *LogOffset) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogOffset.Merge(dst, src) +} +func (m *LogOffset) XXX_Size() int { + return xxx_messageInfo_LogOffset.Size(m) +} +func (m *LogOffset) XXX_DiscardUnknown() { + xxx_messageInfo_LogOffset.DiscardUnknown(m) +} + +var xxx_messageInfo_LogOffset proto.InternalMessageInfo + +func (m *LogOffset) GetRequestId() []byte { + if m != nil { + return m.RequestId + } + return nil +} + +type LogLine struct { + Time *int64 `protobuf:"varint,1,req,name=time" json:"time,omitempty"` + Level *int32 `protobuf:"varint,2,req,name=level" json:"level,omitempty"` + LogMessage *string `protobuf:"bytes,3,req,name=log_message,json=logMessage" json:"log_message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogLine) Reset() { *m = LogLine{} } +func (m *LogLine) String() string { return proto.CompactTextString(m) } +func (*LogLine) ProtoMessage() {} +func (*LogLine) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{6} +} +func (m *LogLine) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogLine.Unmarshal(m, b) +} +func (m *LogLine) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogLine.Marshal(b, m, deterministic) +} +func (dst *LogLine) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogLine.Merge(dst, src) +} +func (m *LogLine) XXX_Size() int { + return xxx_messageInfo_LogLine.Size(m) +} +func (m *LogLine) XXX_DiscardUnknown() { + xxx_messageInfo_LogLine.DiscardUnknown(m) +} + +var xxx_messageInfo_LogLine proto.InternalMessageInfo + +func (m *LogLine) GetTime() int64 { + if m != nil && m.Time != nil { + return *m.Time + } + return 0 +} + +func (m *LogLine) GetLevel() int32 { + if m != nil && m.Level != nil { + return *m.Level + } + return 0 +} + +func (m *LogLine) GetLogMessage() string { + if m != nil && m.LogMessage != nil { + return *m.LogMessage + } + return "" +} + +type RequestLog struct { + AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"` + ModuleId *string `protobuf:"bytes,37,opt,name=module_id,json=moduleId,def=default" json:"module_id,omitempty"` + VersionId *string `protobuf:"bytes,2,req,name=version_id,json=versionId" json:"version_id,omitempty"` + RequestId []byte `protobuf:"bytes,3,req,name=request_id,json=requestId" json:"request_id,omitempty"` + Offset *LogOffset `protobuf:"bytes,35,opt,name=offset" json:"offset,omitempty"` + Ip *string `protobuf:"bytes,4,req,name=ip" json:"ip,omitempty"` + Nickname *string `protobuf:"bytes,5,opt,name=nickname" json:"nickname,omitempty"` + StartTime *int64 `protobuf:"varint,6,req,name=start_time,json=startTime" json:"start_time,omitempty"` + EndTime *int64 `protobuf:"varint,7,req,name=end_time,json=endTime" json:"end_time,omitempty"` + Latency *int64 `protobuf:"varint,8,req,name=latency" json:"latency,omitempty"` + Mcycles *int64 `protobuf:"varint,9,req,name=mcycles" json:"mcycles,omitempty"` + Method *string `protobuf:"bytes,10,req,name=method" json:"method,omitempty"` + Resource *string `protobuf:"bytes,11,req,name=resource" json:"resource,omitempty"` + HttpVersion *string `protobuf:"bytes,12,req,name=http_version,json=httpVersion" json:"http_version,omitempty"` + Status *int32 `protobuf:"varint,13,req,name=status" json:"status,omitempty"` + ResponseSize *int64 `protobuf:"varint,14,req,name=response_size,json=responseSize" json:"response_size,omitempty"` + Referrer *string `protobuf:"bytes,15,opt,name=referrer" json:"referrer,omitempty"` + UserAgent *string `protobuf:"bytes,16,opt,name=user_agent,json=userAgent" json:"user_agent,omitempty"` + UrlMapEntry *string `protobuf:"bytes,17,req,name=url_map_entry,json=urlMapEntry" json:"url_map_entry,omitempty"` + Combined *string `protobuf:"bytes,18,req,name=combined" json:"combined,omitempty"` + ApiMcycles *int64 `protobuf:"varint,19,opt,name=api_mcycles,json=apiMcycles" json:"api_mcycles,omitempty"` + Host *string `protobuf:"bytes,20,opt,name=host" json:"host,omitempty"` + Cost *float64 `protobuf:"fixed64,21,opt,name=cost" json:"cost,omitempty"` + TaskQueueName *string `protobuf:"bytes,22,opt,name=task_queue_name,json=taskQueueName" json:"task_queue_name,omitempty"` + TaskName *string `protobuf:"bytes,23,opt,name=task_name,json=taskName" json:"task_name,omitempty"` + WasLoadingRequest *bool `protobuf:"varint,24,opt,name=was_loading_request,json=wasLoadingRequest" json:"was_loading_request,omitempty"` + PendingTime *int64 `protobuf:"varint,25,opt,name=pending_time,json=pendingTime" json:"pending_time,omitempty"` + ReplicaIndex *int32 `protobuf:"varint,26,opt,name=replica_index,json=replicaIndex,def=-1" json:"replica_index,omitempty"` + Finished *bool `protobuf:"varint,27,opt,name=finished,def=1" json:"finished,omitempty"` + CloneKey []byte `protobuf:"bytes,28,opt,name=clone_key,json=cloneKey" json:"clone_key,omitempty"` + Line []*LogLine `protobuf:"bytes,29,rep,name=line" json:"line,omitempty"` + LinesIncomplete *bool `protobuf:"varint,36,opt,name=lines_incomplete,json=linesIncomplete" json:"lines_incomplete,omitempty"` + AppEngineRelease []byte `protobuf:"bytes,38,opt,name=app_engine_release,json=appEngineRelease" json:"app_engine_release,omitempty"` + ExitReason *int32 `protobuf:"varint,30,opt,name=exit_reason,json=exitReason" json:"exit_reason,omitempty"` + WasThrottledForTime *bool `protobuf:"varint,31,opt,name=was_throttled_for_time,json=wasThrottledForTime" json:"was_throttled_for_time,omitempty"` + WasThrottledForRequests *bool `protobuf:"varint,32,opt,name=was_throttled_for_requests,json=wasThrottledForRequests" json:"was_throttled_for_requests,omitempty"` + ThrottledTime *int64 `protobuf:"varint,33,opt,name=throttled_time,json=throttledTime" json:"throttled_time,omitempty"` + ServerName []byte `protobuf:"bytes,34,opt,name=server_name,json=serverName" json:"server_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RequestLog) Reset() { *m = RequestLog{} } +func (m *RequestLog) String() string { return proto.CompactTextString(m) } +func (*RequestLog) ProtoMessage() {} +func (*RequestLog) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{7} +} +func (m *RequestLog) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RequestLog.Unmarshal(m, b) +} +func (m *RequestLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RequestLog.Marshal(b, m, deterministic) +} +func (dst *RequestLog) XXX_Merge(src proto.Message) { + xxx_messageInfo_RequestLog.Merge(dst, src) +} +func (m *RequestLog) XXX_Size() int { + return xxx_messageInfo_RequestLog.Size(m) +} +func (m *RequestLog) XXX_DiscardUnknown() { + xxx_messageInfo_RequestLog.DiscardUnknown(m) +} + +var xxx_messageInfo_RequestLog proto.InternalMessageInfo + +const Default_RequestLog_ModuleId string = "default" +const Default_RequestLog_ReplicaIndex int32 = -1 +const Default_RequestLog_Finished bool = true + +func (m *RequestLog) GetAppId() string { + if m != nil && m.AppId != nil { + return *m.AppId + } + return "" +} + +func (m *RequestLog) GetModuleId() string { + if m != nil && m.ModuleId != nil { + return *m.ModuleId + } + return Default_RequestLog_ModuleId +} + +func (m *RequestLog) GetVersionId() string { + if m != nil && m.VersionId != nil { + return *m.VersionId + } + return "" +} + +func (m *RequestLog) GetRequestId() []byte { + if m != nil { + return m.RequestId + } + return nil +} + +func (m *RequestLog) GetOffset() *LogOffset { + if m != nil { + return m.Offset + } + return nil +} + +func (m *RequestLog) GetIp() string { + if m != nil && m.Ip != nil { + return *m.Ip + } + return "" +} + +func (m *RequestLog) GetNickname() string { + if m != nil && m.Nickname != nil { + return *m.Nickname + } + return "" +} + +func (m *RequestLog) GetStartTime() int64 { + if m != nil && m.StartTime != nil { + return *m.StartTime + } + return 0 +} + +func (m *RequestLog) GetEndTime() int64 { + if m != nil && m.EndTime != nil { + return *m.EndTime + } + return 0 +} + +func (m *RequestLog) GetLatency() int64 { + if m != nil && m.Latency != nil { + return *m.Latency + } + return 0 +} + +func (m *RequestLog) GetMcycles() int64 { + if m != nil && m.Mcycles != nil { + return *m.Mcycles + } + return 0 +} + +func (m *RequestLog) GetMethod() string { + if m != nil && m.Method != nil { + return *m.Method + } + return "" +} + +func (m *RequestLog) GetResource() string { + if m != nil && m.Resource != nil { + return *m.Resource + } + return "" +} + +func (m *RequestLog) GetHttpVersion() string { + if m != nil && m.HttpVersion != nil { + return *m.HttpVersion + } + return "" +} + +func (m *RequestLog) GetStatus() int32 { + if m != nil && m.Status != nil { + return *m.Status + } + return 0 +} + +func (m *RequestLog) GetResponseSize() int64 { + if m != nil && m.ResponseSize != nil { + return *m.ResponseSize + } + return 0 +} + +func (m *RequestLog) GetReferrer() string { + if m != nil && m.Referrer != nil { + return *m.Referrer + } + return "" +} + +func (m *RequestLog) GetUserAgent() string { + if m != nil && m.UserAgent != nil { + return *m.UserAgent + } + return "" +} + +func (m *RequestLog) GetUrlMapEntry() string { + if m != nil && m.UrlMapEntry != nil { + return *m.UrlMapEntry + } + return "" +} + +func (m *RequestLog) GetCombined() string { + if m != nil && m.Combined != nil { + return *m.Combined + } + return "" +} + +func (m *RequestLog) GetApiMcycles() int64 { + if m != nil && m.ApiMcycles != nil { + return *m.ApiMcycles + } + return 0 +} + +func (m *RequestLog) GetHost() string { + if m != nil && m.Host != nil { + return *m.Host + } + return "" +} + +func (m *RequestLog) GetCost() float64 { + if m != nil && m.Cost != nil { + return *m.Cost + } + return 0 +} + +func (m *RequestLog) GetTaskQueueName() string { + if m != nil && m.TaskQueueName != nil { + return *m.TaskQueueName + } + return "" +} + +func (m *RequestLog) GetTaskName() string { + if m != nil && m.TaskName != nil { + return *m.TaskName + } + return "" +} + +func (m *RequestLog) GetWasLoadingRequest() bool { + if m != nil && m.WasLoadingRequest != nil { + return *m.WasLoadingRequest + } + return false +} + +func (m *RequestLog) GetPendingTime() int64 { + if m != nil && m.PendingTime != nil { + return *m.PendingTime + } + return 0 +} + +func (m *RequestLog) GetReplicaIndex() int32 { + if m != nil && m.ReplicaIndex != nil { + return *m.ReplicaIndex + } + return Default_RequestLog_ReplicaIndex +} + +func (m *RequestLog) GetFinished() bool { + if m != nil && m.Finished != nil { + return *m.Finished + } + return Default_RequestLog_Finished +} + +func (m *RequestLog) GetCloneKey() []byte { + if m != nil { + return m.CloneKey + } + return nil +} + +func (m *RequestLog) GetLine() []*LogLine { + if m != nil { + return m.Line + } + return nil +} + +func (m *RequestLog) GetLinesIncomplete() bool { + if m != nil && m.LinesIncomplete != nil { + return *m.LinesIncomplete + } + return false +} + +func (m *RequestLog) GetAppEngineRelease() []byte { + if m != nil { + return m.AppEngineRelease + } + return nil +} + +func (m *RequestLog) GetExitReason() int32 { + if m != nil && m.ExitReason != nil { + return *m.ExitReason + } + return 0 +} + +func (m *RequestLog) GetWasThrottledForTime() bool { + if m != nil && m.WasThrottledForTime != nil { + return *m.WasThrottledForTime + } + return false +} + +func (m *RequestLog) GetWasThrottledForRequests() bool { + if m != nil && m.WasThrottledForRequests != nil { + return *m.WasThrottledForRequests + } + return false +} + +func (m *RequestLog) GetThrottledTime() int64 { + if m != nil && m.ThrottledTime != nil { + return *m.ThrottledTime + } + return 0 +} + +func (m *RequestLog) GetServerName() []byte { + if m != nil { + return m.ServerName + } + return nil +} + +type LogModuleVersion struct { + ModuleId *string `protobuf:"bytes,1,opt,name=module_id,json=moduleId,def=default" json:"module_id,omitempty"` + VersionId *string `protobuf:"bytes,2,opt,name=version_id,json=versionId" json:"version_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogModuleVersion) Reset() { *m = LogModuleVersion{} } +func (m *LogModuleVersion) String() string { return proto.CompactTextString(m) } +func (*LogModuleVersion) ProtoMessage() {} +func (*LogModuleVersion) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{8} +} +func (m *LogModuleVersion) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogModuleVersion.Unmarshal(m, b) +} +func (m *LogModuleVersion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogModuleVersion.Marshal(b, m, deterministic) +} +func (dst *LogModuleVersion) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogModuleVersion.Merge(dst, src) +} +func (m *LogModuleVersion) XXX_Size() int { + return xxx_messageInfo_LogModuleVersion.Size(m) +} +func (m *LogModuleVersion) XXX_DiscardUnknown() { + xxx_messageInfo_LogModuleVersion.DiscardUnknown(m) +} + +var xxx_messageInfo_LogModuleVersion proto.InternalMessageInfo + +const Default_LogModuleVersion_ModuleId string = "default" + +func (m *LogModuleVersion) GetModuleId() string { + if m != nil && m.ModuleId != nil { + return *m.ModuleId + } + return Default_LogModuleVersion_ModuleId +} + +func (m *LogModuleVersion) GetVersionId() string { + if m != nil && m.VersionId != nil { + return *m.VersionId + } + return "" +} + +type LogReadRequest struct { + AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"` + VersionId []string `protobuf:"bytes,2,rep,name=version_id,json=versionId" json:"version_id,omitempty"` + ModuleVersion []*LogModuleVersion `protobuf:"bytes,19,rep,name=module_version,json=moduleVersion" json:"module_version,omitempty"` + StartTime *int64 `protobuf:"varint,3,opt,name=start_time,json=startTime" json:"start_time,omitempty"` + EndTime *int64 `protobuf:"varint,4,opt,name=end_time,json=endTime" json:"end_time,omitempty"` + Offset *LogOffset `protobuf:"bytes,5,opt,name=offset" json:"offset,omitempty"` + RequestId [][]byte `protobuf:"bytes,6,rep,name=request_id,json=requestId" json:"request_id,omitempty"` + MinimumLogLevel *int32 `protobuf:"varint,7,opt,name=minimum_log_level,json=minimumLogLevel" json:"minimum_log_level,omitempty"` + IncludeIncomplete *bool `protobuf:"varint,8,opt,name=include_incomplete,json=includeIncomplete" json:"include_incomplete,omitempty"` + Count *int64 `protobuf:"varint,9,opt,name=count" json:"count,omitempty"` + CombinedLogRegex *string `protobuf:"bytes,14,opt,name=combined_log_regex,json=combinedLogRegex" json:"combined_log_regex,omitempty"` + HostRegex *string `protobuf:"bytes,15,opt,name=host_regex,json=hostRegex" json:"host_regex,omitempty"` + ReplicaIndex *int32 `protobuf:"varint,16,opt,name=replica_index,json=replicaIndex" json:"replica_index,omitempty"` + IncludeAppLogs *bool `protobuf:"varint,10,opt,name=include_app_logs,json=includeAppLogs" json:"include_app_logs,omitempty"` + AppLogsPerRequest *int32 `protobuf:"varint,17,opt,name=app_logs_per_request,json=appLogsPerRequest" json:"app_logs_per_request,omitempty"` + IncludeHost *bool `protobuf:"varint,11,opt,name=include_host,json=includeHost" json:"include_host,omitempty"` + IncludeAll *bool `protobuf:"varint,12,opt,name=include_all,json=includeAll" json:"include_all,omitempty"` + CacheIterator *bool `protobuf:"varint,13,opt,name=cache_iterator,json=cacheIterator" json:"cache_iterator,omitempty"` + NumShards *int32 `protobuf:"varint,18,opt,name=num_shards,json=numShards" json:"num_shards,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogReadRequest) Reset() { *m = LogReadRequest{} } +func (m *LogReadRequest) String() string { return proto.CompactTextString(m) } +func (*LogReadRequest) ProtoMessage() {} +func (*LogReadRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{9} +} +func (m *LogReadRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogReadRequest.Unmarshal(m, b) +} +func (m *LogReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogReadRequest.Marshal(b, m, deterministic) +} +func (dst *LogReadRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogReadRequest.Merge(dst, src) +} +func (m *LogReadRequest) XXX_Size() int { + return xxx_messageInfo_LogReadRequest.Size(m) +} +func (m *LogReadRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LogReadRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LogReadRequest proto.InternalMessageInfo + +func (m *LogReadRequest) GetAppId() string { + if m != nil && m.AppId != nil { + return *m.AppId + } + return "" +} + +func (m *LogReadRequest) GetVersionId() []string { + if m != nil { + return m.VersionId + } + return nil +} + +func (m *LogReadRequest) GetModuleVersion() []*LogModuleVersion { + if m != nil { + return m.ModuleVersion + } + return nil +} + +func (m *LogReadRequest) GetStartTime() int64 { + if m != nil && m.StartTime != nil { + return *m.StartTime + } + return 0 +} + +func (m *LogReadRequest) GetEndTime() int64 { + if m != nil && m.EndTime != nil { + return *m.EndTime + } + return 0 +} + +func (m *LogReadRequest) GetOffset() *LogOffset { + if m != nil { + return m.Offset + } + return nil +} + +func (m *LogReadRequest) GetRequestId() [][]byte { + if m != nil { + return m.RequestId + } + return nil +} + +func (m *LogReadRequest) GetMinimumLogLevel() int32 { + if m != nil && m.MinimumLogLevel != nil { + return *m.MinimumLogLevel + } + return 0 +} + +func (m *LogReadRequest) GetIncludeIncomplete() bool { + if m != nil && m.IncludeIncomplete != nil { + return *m.IncludeIncomplete + } + return false +} + +func (m *LogReadRequest) GetCount() int64 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +func (m *LogReadRequest) GetCombinedLogRegex() string { + if m != nil && m.CombinedLogRegex != nil { + return *m.CombinedLogRegex + } + return "" +} + +func (m *LogReadRequest) GetHostRegex() string { + if m != nil && m.HostRegex != nil { + return *m.HostRegex + } + return "" +} + +func (m *LogReadRequest) GetReplicaIndex() int32 { + if m != nil && m.ReplicaIndex != nil { + return *m.ReplicaIndex + } + return 0 +} + +func (m *LogReadRequest) GetIncludeAppLogs() bool { + if m != nil && m.IncludeAppLogs != nil { + return *m.IncludeAppLogs + } + return false +} + +func (m *LogReadRequest) GetAppLogsPerRequest() int32 { + if m != nil && m.AppLogsPerRequest != nil { + return *m.AppLogsPerRequest + } + return 0 +} + +func (m *LogReadRequest) GetIncludeHost() bool { + if m != nil && m.IncludeHost != nil { + return *m.IncludeHost + } + return false +} + +func (m *LogReadRequest) GetIncludeAll() bool { + if m != nil && m.IncludeAll != nil { + return *m.IncludeAll + } + return false +} + +func (m *LogReadRequest) GetCacheIterator() bool { + if m != nil && m.CacheIterator != nil { + return *m.CacheIterator + } + return false +} + +func (m *LogReadRequest) GetNumShards() int32 { + if m != nil && m.NumShards != nil { + return *m.NumShards + } + return 0 +} + +type LogReadResponse struct { + Log []*RequestLog `protobuf:"bytes,1,rep,name=log" json:"log,omitempty"` + Offset *LogOffset `protobuf:"bytes,2,opt,name=offset" json:"offset,omitempty"` + LastEndTime *int64 `protobuf:"varint,3,opt,name=last_end_time,json=lastEndTime" json:"last_end_time,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogReadResponse) Reset() { *m = LogReadResponse{} } +func (m *LogReadResponse) String() string { return proto.CompactTextString(m) } +func (*LogReadResponse) ProtoMessage() {} +func (*LogReadResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{10} +} +func (m *LogReadResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogReadResponse.Unmarshal(m, b) +} +func (m *LogReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogReadResponse.Marshal(b, m, deterministic) +} +func (dst *LogReadResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogReadResponse.Merge(dst, src) +} +func (m *LogReadResponse) XXX_Size() int { + return xxx_messageInfo_LogReadResponse.Size(m) +} +func (m *LogReadResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LogReadResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LogReadResponse proto.InternalMessageInfo + +func (m *LogReadResponse) GetLog() []*RequestLog { + if m != nil { + return m.Log + } + return nil +} + +func (m *LogReadResponse) GetOffset() *LogOffset { + if m != nil { + return m.Offset + } + return nil +} + +func (m *LogReadResponse) GetLastEndTime() int64 { + if m != nil && m.LastEndTime != nil { + return *m.LastEndTime + } + return 0 +} + +type LogUsageRecord struct { + VersionId *string `protobuf:"bytes,1,opt,name=version_id,json=versionId" json:"version_id,omitempty"` + StartTime *int32 `protobuf:"varint,2,opt,name=start_time,json=startTime" json:"start_time,omitempty"` + EndTime *int32 `protobuf:"varint,3,opt,name=end_time,json=endTime" json:"end_time,omitempty"` + Count *int64 `protobuf:"varint,4,opt,name=count" json:"count,omitempty"` + TotalSize *int64 `protobuf:"varint,5,opt,name=total_size,json=totalSize" json:"total_size,omitempty"` + Records *int32 `protobuf:"varint,6,opt,name=records" json:"records,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogUsageRecord) Reset() { *m = LogUsageRecord{} } +func (m *LogUsageRecord) String() string { return proto.CompactTextString(m) } +func (*LogUsageRecord) ProtoMessage() {} +func (*LogUsageRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{11} +} +func (m *LogUsageRecord) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogUsageRecord.Unmarshal(m, b) +} +func (m *LogUsageRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogUsageRecord.Marshal(b, m, deterministic) +} +func (dst *LogUsageRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogUsageRecord.Merge(dst, src) +} +func (m *LogUsageRecord) XXX_Size() int { + return xxx_messageInfo_LogUsageRecord.Size(m) +} +func (m *LogUsageRecord) XXX_DiscardUnknown() { + xxx_messageInfo_LogUsageRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_LogUsageRecord proto.InternalMessageInfo + +func (m *LogUsageRecord) GetVersionId() string { + if m != nil && m.VersionId != nil { + return *m.VersionId + } + return "" +} + +func (m *LogUsageRecord) GetStartTime() int32 { + if m != nil && m.StartTime != nil { + return *m.StartTime + } + return 0 +} + +func (m *LogUsageRecord) GetEndTime() int32 { + if m != nil && m.EndTime != nil { + return *m.EndTime + } + return 0 +} + +func (m *LogUsageRecord) GetCount() int64 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +func (m *LogUsageRecord) GetTotalSize() int64 { + if m != nil && m.TotalSize != nil { + return *m.TotalSize + } + return 0 +} + +func (m *LogUsageRecord) GetRecords() int32 { + if m != nil && m.Records != nil { + return *m.Records + } + return 0 +} + +type LogUsageRequest struct { + AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"` + VersionId []string `protobuf:"bytes,2,rep,name=version_id,json=versionId" json:"version_id,omitempty"` + StartTime *int32 `protobuf:"varint,3,opt,name=start_time,json=startTime" json:"start_time,omitempty"` + EndTime *int32 `protobuf:"varint,4,opt,name=end_time,json=endTime" json:"end_time,omitempty"` + ResolutionHours *uint32 `protobuf:"varint,5,opt,name=resolution_hours,json=resolutionHours,def=1" json:"resolution_hours,omitempty"` + CombineVersions *bool `protobuf:"varint,6,opt,name=combine_versions,json=combineVersions" json:"combine_versions,omitempty"` + UsageVersion *int32 `protobuf:"varint,7,opt,name=usage_version,json=usageVersion" json:"usage_version,omitempty"` + VersionsOnly *bool `protobuf:"varint,8,opt,name=versions_only,json=versionsOnly" json:"versions_only,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogUsageRequest) Reset() { *m = LogUsageRequest{} } +func (m *LogUsageRequest) String() string { return proto.CompactTextString(m) } +func (*LogUsageRequest) ProtoMessage() {} +func (*LogUsageRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{12} +} +func (m *LogUsageRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogUsageRequest.Unmarshal(m, b) +} +func (m *LogUsageRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogUsageRequest.Marshal(b, m, deterministic) +} +func (dst *LogUsageRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogUsageRequest.Merge(dst, src) +} +func (m *LogUsageRequest) XXX_Size() int { + return xxx_messageInfo_LogUsageRequest.Size(m) +} +func (m *LogUsageRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LogUsageRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LogUsageRequest proto.InternalMessageInfo + +const Default_LogUsageRequest_ResolutionHours uint32 = 1 + +func (m *LogUsageRequest) GetAppId() string { + if m != nil && m.AppId != nil { + return *m.AppId + } + return "" +} + +func (m *LogUsageRequest) GetVersionId() []string { + if m != nil { + return m.VersionId + } + return nil +} + +func (m *LogUsageRequest) GetStartTime() int32 { + if m != nil && m.StartTime != nil { + return *m.StartTime + } + return 0 +} + +func (m *LogUsageRequest) GetEndTime() int32 { + if m != nil && m.EndTime != nil { + return *m.EndTime + } + return 0 +} + +func (m *LogUsageRequest) GetResolutionHours() uint32 { + if m != nil && m.ResolutionHours != nil { + return *m.ResolutionHours + } + return Default_LogUsageRequest_ResolutionHours +} + +func (m *LogUsageRequest) GetCombineVersions() bool { + if m != nil && m.CombineVersions != nil { + return *m.CombineVersions + } + return false +} + +func (m *LogUsageRequest) GetUsageVersion() int32 { + if m != nil && m.UsageVersion != nil { + return *m.UsageVersion + } + return 0 +} + +func (m *LogUsageRequest) GetVersionsOnly() bool { + if m != nil && m.VersionsOnly != nil { + return *m.VersionsOnly + } + return false +} + +type LogUsageResponse struct { + Usage []*LogUsageRecord `protobuf:"bytes,1,rep,name=usage" json:"usage,omitempty"` + Summary *LogUsageRecord `protobuf:"bytes,2,opt,name=summary" json:"summary,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogUsageResponse) Reset() { *m = LogUsageResponse{} } +func (m *LogUsageResponse) String() string { return proto.CompactTextString(m) } +func (*LogUsageResponse) ProtoMessage() {} +func (*LogUsageResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_log_service_f054fd4b5012319d, []int{13} +} +func (m *LogUsageResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogUsageResponse.Unmarshal(m, b) +} +func (m *LogUsageResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogUsageResponse.Marshal(b, m, deterministic) +} +func (dst *LogUsageResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogUsageResponse.Merge(dst, src) +} +func (m *LogUsageResponse) XXX_Size() int { + return xxx_messageInfo_LogUsageResponse.Size(m) +} +func (m *LogUsageResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LogUsageResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LogUsageResponse proto.InternalMessageInfo + +func (m *LogUsageResponse) GetUsage() []*LogUsageRecord { + if m != nil { + return m.Usage + } + return nil +} + +func (m *LogUsageResponse) GetSummary() *LogUsageRecord { + if m != nil { + return m.Summary + } + return nil +} + +func init() { + proto.RegisterType((*LogServiceError)(nil), "appengine.LogServiceError") + proto.RegisterType((*UserAppLogLine)(nil), "appengine.UserAppLogLine") + proto.RegisterType((*UserAppLogGroup)(nil), "appengine.UserAppLogGroup") + proto.RegisterType((*FlushRequest)(nil), "appengine.FlushRequest") + proto.RegisterType((*SetStatusRequest)(nil), "appengine.SetStatusRequest") + proto.RegisterType((*LogOffset)(nil), "appengine.LogOffset") + proto.RegisterType((*LogLine)(nil), "appengine.LogLine") + proto.RegisterType((*RequestLog)(nil), "appengine.RequestLog") + proto.RegisterType((*LogModuleVersion)(nil), "appengine.LogModuleVersion") + proto.RegisterType((*LogReadRequest)(nil), "appengine.LogReadRequest") + proto.RegisterType((*LogReadResponse)(nil), "appengine.LogReadResponse") + proto.RegisterType((*LogUsageRecord)(nil), "appengine.LogUsageRecord") + proto.RegisterType((*LogUsageRequest)(nil), "appengine.LogUsageRequest") + proto.RegisterType((*LogUsageResponse)(nil), "appengine.LogUsageResponse") +} + +func init() { + proto.RegisterFile("google.golang.org/appengine/internal/log/log_service.proto", fileDescriptor_log_service_f054fd4b5012319d) +} + +var fileDescriptor_log_service_f054fd4b5012319d = []byte{ + // 1553 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xdd, 0x72, 0xdb, 0xc6, + 0x15, 0x2e, 0x48, 0x51, 0x24, 0x0f, 0x49, 0x91, 0x5a, 0xcb, 0xce, 0xda, 0xae, 0x6b, 0x1a, 0x4e, + 0x1c, 0xd6, 0x93, 0x48, 0x93, 0xa4, 0x57, 0xca, 0x95, 0xd3, 0x2a, 0x8e, 0x26, 0xb4, 0xd5, 0x40, + 0x72, 0x3a, 0xd3, 0x1b, 0x0c, 0x0a, 0x1c, 0x81, 0x18, 0x2f, 0xb1, 0xc8, 0xee, 0xc2, 0x91, 0x72, + 0xdb, 0xdb, 0x3e, 0x46, 0x1f, 0xa2, 0xaf, 0xd2, 0xb7, 0xe9, 0xec, 0xd9, 0x05, 0x44, 0x2a, 0x4d, + 0xc6, 0x33, 0xb9, 0xe0, 0x10, 0xfb, 0x9d, 0x83, 0xdd, 0xf3, 0xf3, 0x9d, 0x6f, 0x01, 0xc7, 0xb9, + 0x94, 0xb9, 0xc0, 0xc3, 0x5c, 0x8a, 0xa4, 0xcc, 0x0f, 0xa5, 0xca, 0x8f, 0x92, 0xaa, 0xc2, 0x32, + 0x2f, 0x4a, 0x3c, 0x2a, 0x4a, 0x83, 0xaa, 0x4c, 0xc4, 0x91, 0x90, 0xb9, 0xfd, 0xc5, 0x1a, 0xd5, + 0xbb, 0x22, 0xc5, 0xc3, 0x4a, 0x49, 0x23, 0xd9, 0xb0, 0xf5, 0x0c, 0x5f, 0xc3, 0x74, 0x29, 0xf3, + 0x73, 0x67, 0x3e, 0x51, 0x4a, 0xaa, 0xf0, 0x4b, 0x18, 0xd2, 0xc3, 0x9f, 0x65, 0x86, 0x6c, 0x17, + 0x3a, 0x67, 0xdf, 0xce, 0x7e, 0xc7, 0xee, 0xc0, 0xf4, 0xf4, 0xf5, 0xf7, 0x2f, 0x96, 0xa7, 0x7f, + 0x89, 0xa3, 0x93, 0xef, 0xde, 0x9c, 0x9c, 0x5f, 0xcc, 0x02, 0xb6, 0x0f, 0x93, 0xf3, 0x8b, 0xb3, + 0xe8, 0xc5, 0xcb, 0x93, 0xf8, 0x24, 0x8a, 0xce, 0xa2, 0x59, 0x27, 0xcc, 0x61, 0xef, 0x8d, 0x46, + 0xf5, 0xa2, 0xaa, 0x96, 0x32, 0x5f, 0x16, 0x25, 0xb2, 0x8f, 0x60, 0xcf, 0x14, 0x6b, 0xd4, 0x26, + 0x59, 0x57, 0x71, 0xad, 0x31, 0xe5, 0xc1, 0xbc, 0xb3, 0xe8, 0x46, 0x93, 0x16, 0x7d, 0xa3, 0x31, + 0x65, 0x07, 0xd0, 0x13, 0xf8, 0x0e, 0x05, 0xef, 0x90, 0xd5, 0x2d, 0x18, 0x87, 0xfe, 0x1a, 0xb5, + 0x4e, 0x72, 0xe4, 0xdd, 0x79, 0x67, 0x31, 0x8c, 0x9a, 0x65, 0xf8, 0x12, 0xa6, 0x37, 0x07, 0xbd, + 0x54, 0xb2, 0xae, 0xd8, 0x9f, 0x60, 0x60, 0x73, 0x15, 0x45, 0x89, 0xbc, 0x33, 0xef, 0x2e, 0x46, + 0x9f, 0xdf, 0x3f, 0x6c, 0x33, 0x3d, 0xdc, 0x0e, 0x2b, 0xea, 0x0b, 0xf7, 0x10, 0x86, 0x30, 0xfe, + 0x5a, 0xd4, 0x7a, 0x15, 0xe1, 0x0f, 0x35, 0x6a, 0xc3, 0x18, 0xec, 0x08, 0x99, 0x6b, 0x1e, 0xcc, + 0x83, 0xc5, 0x38, 0xa2, 0xe7, 0xf0, 0x39, 0xcc, 0xce, 0xd1, 0x9c, 0x9b, 0xc4, 0xd4, 0xba, 0xf1, + 0xbb, 0x07, 0xbb, 0x9a, 0x00, 0xca, 0x67, 0x18, 0xf9, 0x55, 0xf8, 0x1c, 0x86, 0x4b, 0x99, 0x9f, + 0x5d, 0x5e, 0x6a, 0x34, 0xec, 0x11, 0x80, 0x72, 0xfe, 0x71, 0x91, 0xf9, 0x2d, 0x87, 0x1e, 0x39, + 0xcd, 0xc2, 0x0b, 0xe8, 0x37, 0x65, 0x62, 0xb0, 0x63, 0x0b, 0xe2, 0x8b, 0x43, 0xcf, 0xdb, 0x35, + 0xe9, 0x35, 0x35, 0x79, 0x0c, 0x23, 0x9b, 0xe6, 0x76, 0x5d, 0x40, 0xc8, 0xfc, 0x95, 0x2f, 0xcd, + 0x3f, 0x01, 0xc0, 0x47, 0xb9, 0x94, 0x39, 0xbb, 0x0b, 0xbb, 0x49, 0x55, 0xb9, 0xf3, 0xad, 0x6b, + 0x2f, 0xa9, 0xaa, 0xd3, 0x8c, 0x7d, 0x08, 0xc3, 0xb5, 0xcc, 0x6a, 0x81, 0xd6, 0xf2, 0xd1, 0x3c, + 0x58, 0x0c, 0x8f, 0xfb, 0x19, 0x5e, 0x26, 0xb5, 0x30, 0xd1, 0xc0, 0x59, 0x4e, 0x33, 0x9b, 0xc0, + 0x3b, 0x54, 0xba, 0x90, 0xa5, 0x75, 0xeb, 0xd0, 0x06, 0x43, 0x8f, 0x38, 0xf3, 0x46, 0x7e, 0x36, + 0x94, 0xcd, 0xfc, 0xd8, 0x27, 0xb0, 0x2b, 0xa9, 0x10, 0xfc, 0xe9, 0x3c, 0x58, 0x8c, 0x3e, 0x3f, + 0xd8, 0xe8, 0x47, 0x5b, 0xa4, 0xc8, 0xfb, 0xb0, 0x3d, 0xe8, 0x14, 0x15, 0xdf, 0xa1, 0x33, 0x3a, + 0x45, 0xc5, 0x1e, 0xc0, 0xa0, 0x2c, 0xd2, 0xb7, 0x65, 0xb2, 0x46, 0xde, 0xb3, 0x01, 0x46, 0xed, + 0xda, 0x1e, 0xac, 0x4d, 0xa2, 0x4c, 0x4c, 0x45, 0xdb, 0xa5, 0xa2, 0x0d, 0x09, 0xb9, 0xb0, 0x95, + 0xbb, 0x0f, 0x03, 0x2c, 0x33, 0x67, 0xec, 0x93, 0xb1, 0x8f, 0x65, 0x46, 0x26, 0x0e, 0x7d, 0x91, + 0x18, 0x2c, 0xd3, 0x6b, 0x3e, 0x70, 0x16, 0xbf, 0x24, 0xb2, 0xa5, 0xd7, 0xa9, 0x40, 0xcd, 0x87, + 0xce, 0xe2, 0x97, 0xb6, 0xd7, 0x6b, 0x34, 0x2b, 0x99, 0x71, 0x70, 0xbd, 0x76, 0x2b, 0x1b, 0xa1, + 0x42, 0x2d, 0x6b, 0x95, 0x22, 0x1f, 0x91, 0xa5, 0x5d, 0xb3, 0x27, 0x30, 0x5e, 0x19, 0x53, 0xc5, + 0xbe, 0x58, 0x7c, 0x4c, 0xf6, 0x91, 0xc5, 0xbe, 0x77, 0xd0, 0x06, 0x85, 0x26, 0xd4, 0x60, 0xbf, + 0x62, 0x4f, 0x61, 0xa2, 0x50, 0x57, 0xb2, 0xd4, 0x18, 0xeb, 0xe2, 0x27, 0xe4, 0x7b, 0x14, 0xce, + 0xb8, 0x01, 0xcf, 0x8b, 0x9f, 0xd0, 0x9d, 0x7d, 0x89, 0x4a, 0xa1, 0xe2, 0x53, 0x57, 0x9d, 0x66, + 0x6d, 0xab, 0x53, 0x6b, 0x54, 0x71, 0x92, 0x63, 0x69, 0xf8, 0x8c, 0xac, 0x43, 0x8b, 0xbc, 0xb0, + 0x00, 0x0b, 0x61, 0x52, 0x2b, 0x11, 0xaf, 0x93, 0x2a, 0xc6, 0xd2, 0xa8, 0x6b, 0xbe, 0xef, 0x62, + 0xab, 0x95, 0x78, 0x95, 0x54, 0x27, 0x16, 0xb2, 0xdb, 0xa7, 0x72, 0xfd, 0x8f, 0xa2, 0xc4, 0x8c, + 0x33, 0x97, 0x5a, 0xb3, 0xb6, 0x0c, 0x4c, 0xaa, 0x22, 0x6e, 0x8a, 0x75, 0x67, 0x1e, 0x2c, 0xba, + 0x11, 0x24, 0x55, 0xf1, 0xca, 0xd7, 0x8b, 0xc1, 0xce, 0x4a, 0x6a, 0xc3, 0x0f, 0xe8, 0x64, 0x7a, + 0xb6, 0x58, 0x6a, 0xb1, 0xbb, 0xf3, 0x60, 0x11, 0x44, 0xf4, 0xcc, 0x9e, 0xc1, 0xd4, 0x24, 0xfa, + 0x6d, 0xfc, 0x43, 0x8d, 0x35, 0xc6, 0xd4, 0xe8, 0x7b, 0xf4, 0xca, 0xc4, 0xc2, 0xdf, 0x59, 0xf4, + 0xb5, 0xed, 0xf6, 0x43, 0x18, 0x92, 0x1f, 0x79, 0x7c, 0xe0, 0x92, 0xb5, 0x00, 0x19, 0x0f, 0xe1, + 0xce, 0x8f, 0x89, 0x8e, 0x85, 0x4c, 0xb2, 0xa2, 0xcc, 0x63, 0xcf, 0x3e, 0xce, 0xe7, 0xc1, 0x62, + 0x10, 0xed, 0xff, 0x98, 0xe8, 0xa5, 0xb3, 0x34, 0x83, 0xfb, 0x04, 0xc6, 0x15, 0x96, 0xe4, 0x4b, + 0xfc, 0xb8, 0x4f, 0xe1, 0x8f, 0x3c, 0x46, 0x1c, 0xf9, 0xd8, 0x36, 0xa0, 0x12, 0x45, 0x9a, 0xc4, + 0x45, 0x99, 0xe1, 0x15, 0x7f, 0x30, 0x0f, 0x16, 0xbd, 0xe3, 0xce, 0xa7, 0x9f, 0xd9, 0x26, 0x90, + 0xe1, 0xd4, 0xe2, 0x6c, 0x0e, 0x83, 0xcb, 0xa2, 0x2c, 0xf4, 0x0a, 0x33, 0xfe, 0xd0, 0x1e, 0x78, + 0xbc, 0x63, 0x54, 0x8d, 0x51, 0x8b, 0xda, 0xd0, 0x53, 0x21, 0x4b, 0x8c, 0xdf, 0xe2, 0x35, 0xff, + 0x3d, 0x09, 0xc0, 0x80, 0x80, 0x6f, 0xf1, 0x9a, 0x3d, 0x83, 0x1d, 0x52, 0xab, 0x47, 0xa4, 0x56, + 0x6c, 0x7b, 0x3a, 0x48, 0xa6, 0xc8, 0xce, 0xfe, 0x08, 0x33, 0xfb, 0xaf, 0xe3, 0xa2, 0x4c, 0xe5, + 0xba, 0x12, 0x68, 0x90, 0x7f, 0x48, 0xf9, 0x4d, 0x09, 0x3f, 0x6d, 0x61, 0xf6, 0x09, 0x30, 0x3b, + 0xed, 0x6e, 0x9b, 0x58, 0xa1, 0xc0, 0x44, 0x23, 0x7f, 0x46, 0x07, 0xcf, 0x92, 0xaa, 0x3a, 0x21, + 0x43, 0xe4, 0x70, 0xdb, 0x49, 0xbc, 0x2a, 0x4c, 0xac, 0x30, 0xd1, 0xb2, 0xe4, 0x7f, 0xb0, 0x69, + 0x46, 0x60, 0xa1, 0x88, 0x10, 0xf6, 0x05, 0xdc, 0xb3, 0xc5, 0x35, 0x2b, 0x25, 0x8d, 0x11, 0x98, + 0xc5, 0x97, 0x52, 0xb9, 0xb2, 0x3d, 0xa6, 0xf3, 0x6d, 0xe9, 0x2f, 0x1a, 0xe3, 0xd7, 0x52, 0x51, + 0xf9, 0xbe, 0x84, 0x07, 0x3f, 0x7f, 0xc9, 0xf7, 0x45, 0xf3, 0x39, 0xbd, 0xf8, 0xc1, 0xad, 0x17, + 0x7d, 0x77, 0x34, 0xdd, 0x17, 0xed, 0x8b, 0x74, 0xd2, 0x13, 0x6a, 0xd0, 0xa4, 0x45, 0xe9, 0x8c, + 0xc7, 0x30, 0xb2, 0x97, 0x1a, 0x2a, 0x47, 0x8a, 0x90, 0x12, 0x04, 0x07, 0x59, 0x5a, 0x84, 0x7f, + 0x83, 0xd9, 0x52, 0xe6, 0xaf, 0x48, 0xc8, 0x9a, 0x81, 0xdb, 0xd2, 0xbc, 0xe0, 0x7d, 0x35, 0x2f, + 0xd8, 0xd2, 0xbc, 0xf0, 0xbf, 0x3d, 0xd8, 0x5b, 0xca, 0x3c, 0xc2, 0x24, 0x6b, 0x28, 0xf5, 0x0b, + 0x12, 0x7b, 0x7b, 0xa3, 0xee, 0xb6, 0x78, 0x7e, 0x05, 0x7b, 0x3e, 0x9a, 0x46, 0x23, 0xee, 0x10, + 0x0f, 0x1e, 0x6e, 0xf3, 0x60, 0x2b, 0x85, 0x68, 0xb2, 0xde, 0xca, 0x68, 0x5b, 0x07, 0xbb, 0x54, + 0xa9, 0x5f, 0xd0, 0xc1, 0x1d, 0x32, 0xb6, 0x3a, 0x78, 0xa3, 0xcd, 0xbd, 0xf7, 0xd0, 0xe6, 0x6d, + 0xa1, 0xdf, 0x9d, 0x77, 0xb7, 0x85, 0xfe, 0x39, 0xec, 0xaf, 0x8b, 0xb2, 0x58, 0xd7, 0xeb, 0x98, + 0xae, 0x60, 0xba, 0xb5, 0xfa, 0xc4, 0xa6, 0xa9, 0x37, 0x58, 0x46, 0xd3, 0xfd, 0xf5, 0x29, 0xb0, + 0xa2, 0x4c, 0x45, 0x9d, 0xe1, 0x26, 0x9d, 0x07, 0x6e, 0x5c, 0xbd, 0x65, 0x83, 0xd0, 0x07, 0xd0, + 0x4b, 0x65, 0x5d, 0x1a, 0x3e, 0xa4, 0xf8, 0xdd, 0xc2, 0xd2, 0xbc, 0x91, 0x23, 0x3a, 0x51, 0x61, + 0x8e, 0x57, 0x7c, 0x8f, 0x7a, 0x35, 0x6b, 0x2c, 0xd4, 0xa5, 0x1c, 0xaf, 0x6c, 0xf4, 0x56, 0x83, + 0xbc, 0x97, 0x53, 0xcb, 0xa1, 0x45, 0x9c, 0xf9, 0xe9, 0xed, 0x71, 0x9f, 0x51, 0xe4, 0xdb, 0xa3, + 0xbe, 0x80, 0x59, 0x13, 0xb6, 0xed, 0x35, 0x7d, 0x23, 0x00, 0x05, 0xbd, 0xe7, 0x71, 0xf7, 0x75, + 0xa1, 0xd9, 0x11, 0x1c, 0x34, 0x1e, 0x71, 0x85, 0x2d, 0xf3, 0xf9, 0x3e, 0xed, 0xba, 0x9f, 0x38, + 0xb7, 0xbf, 0xa2, 0xda, 0x50, 0xa4, 0x66, 0x6b, 0x92, 0xcd, 0x11, 0x6d, 0x3b, 0xf2, 0xd8, 0x37, + 0x56, 0x29, 0x1f, 0xc3, 0xa8, 0x3d, 0x5d, 0x08, 0x3e, 0x26, 0x0f, 0x68, 0x0e, 0x16, 0xc2, 0x8e, + 0x4d, 0x9a, 0xa4, 0x2b, 0x8c, 0x0b, 0x83, 0x2a, 0x31, 0x52, 0xf1, 0x09, 0xf9, 0x4c, 0x08, 0x3d, + 0xf5, 0xa0, 0xad, 0x44, 0x59, 0xaf, 0x63, 0xbd, 0x4a, 0x54, 0xa6, 0x39, 0xa3, 0x88, 0x86, 0x65, + 0xbd, 0x3e, 0x27, 0x20, 0xfc, 0x57, 0x40, 0xdf, 0x83, 0x8e, 0xdb, 0xee, 0xb2, 0x61, 0x1f, 0x43, + 0x57, 0xc8, 0x9c, 0x07, 0xc4, 0xcd, 0xbb, 0x1b, 0x2c, 0xb9, 0xf9, 0xc6, 0x88, 0xac, 0xc7, 0x06, + 0xa3, 0x3a, 0xef, 0xc1, 0xa8, 0x10, 0x26, 0x22, 0xd1, 0x26, 0x6e, 0xf9, 0xe9, 0xc8, 0x3b, 0xb2, + 0xe0, 0x89, 0xe3, 0x68, 0xf8, 0x9f, 0x80, 0x46, 0xed, 0x8d, 0xfd, 0xac, 0x89, 0x30, 0x95, 0xea, + 0xf6, 0x4c, 0x05, 0xb7, 0x86, 0xf3, 0xd6, 0x3c, 0x74, 0x5c, 0x7e, 0xff, 0x7f, 0x1e, 0xba, 0x64, + 0x6c, 0xe7, 0xa1, 0xe5, 0xd9, 0xce, 0x26, 0xcf, 0x1e, 0x01, 0x18, 0x69, 0x12, 0xe1, 0xee, 0xe1, + 0x9e, 0x9b, 0x2f, 0x42, 0xe8, 0x12, 0xe6, 0xd0, 0x57, 0x14, 0x97, 0xe6, 0xbb, 0x6e, 0x3b, 0xbf, + 0x0c, 0xff, 0xdd, 0xa1, 0x4a, 0xfa, 0xd0, 0x7f, 0x8b, 0x4c, 0xfc, 0x7c, 0xc4, 0x7b, 0xbf, 0x36, + 0xe2, 0xbd, 0xcd, 0x11, 0x9f, 0xd9, 0xcf, 0x11, 0x51, 0x1b, 0xbb, 0xf7, 0x4a, 0xd6, 0x4a, 0x53, + 0x0a, 0x93, 0xe3, 0xe0, 0xb3, 0x68, 0x7a, 0x63, 0xfa, 0xc6, 0x5a, 0xec, 0x25, 0xe3, 0x07, 0xa7, + 0xd1, 0x23, 0x97, 0xd4, 0x20, 0x9a, 0x7a, 0xdc, 0x8b, 0x0e, 0x7d, 0xa0, 0xd4, 0x36, 0xb1, 0x56, + 0xb8, 0xdc, 0xa8, 0x8f, 0x09, 0x6c, 0xa4, 0xe9, 0x29, 0x4c, 0x9a, 0x7d, 0x62, 0x59, 0x8a, 0x6b, + 0x3f, 0xe2, 0xe3, 0x06, 0x3c, 0x2b, 0xc5, 0x75, 0x78, 0x45, 0x2a, 0xed, 0xab, 0xe4, 0x09, 0x77, + 0x04, 0x3d, 0xda, 0xc8, 0x53, 0xee, 0xfe, 0x36, 0x8d, 0x36, 0xc8, 0x10, 0x39, 0x3f, 0xf6, 0x05, + 0xf4, 0x75, 0xbd, 0x5e, 0x27, 0xea, 0xda, 0x33, 0xef, 0x57, 0x5e, 0x69, 0x3c, 0xbf, 0xea, 0xfd, + 0xdd, 0x92, 0xf6, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x70, 0xd9, 0xa0, 0xf8, 0x48, 0x0d, 0x00, + 0x00, +} diff --git a/vendor/google.golang.org/appengine/internal/log/log_service.proto b/vendor/google.golang.org/appengine/internal/log/log_service.proto new file mode 100644 index 000000000000..8981dc47577c --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/log/log_service.proto @@ -0,0 +1,150 @@ +syntax = "proto2"; +option go_package = "log"; + +package appengine; + +message LogServiceError { + enum ErrorCode { + OK = 0; + INVALID_REQUEST = 1; + STORAGE_ERROR = 2; + } +} + +message UserAppLogLine { + required int64 timestamp_usec = 1; + required int64 level = 2; + required string message = 3; +} + +message UserAppLogGroup { + repeated UserAppLogLine log_line = 2; +} + +message FlushRequest { + optional bytes logs = 1; +} + +message SetStatusRequest { + required string status = 1; +} + + +message LogOffset { + optional bytes request_id = 1; +} + +message LogLine { + required int64 time = 1; + required int32 level = 2; + required string log_message = 3; +} + +message RequestLog { + required string app_id = 1; + optional string module_id = 37 [default="default"]; + required string version_id = 2; + required bytes request_id = 3; + optional LogOffset offset = 35; + required string ip = 4; + optional string nickname = 5; + required int64 start_time = 6; + required int64 end_time = 7; + required int64 latency = 8; + required int64 mcycles = 9; + required string method = 10; + required string resource = 11; + required string http_version = 12; + required int32 status = 13; + required int64 response_size = 14; + optional string referrer = 15; + optional string user_agent = 16; + required string url_map_entry = 17; + required string combined = 18; + optional int64 api_mcycles = 19; + optional string host = 20; + optional double cost = 21; + + optional string task_queue_name = 22; + optional string task_name = 23; + + optional bool was_loading_request = 24; + optional int64 pending_time = 25; + optional int32 replica_index = 26 [default = -1]; + optional bool finished = 27 [default = true]; + optional bytes clone_key = 28; + + repeated LogLine line = 29; + + optional bool lines_incomplete = 36; + optional bytes app_engine_release = 38; + + optional int32 exit_reason = 30; + optional bool was_throttled_for_time = 31; + optional bool was_throttled_for_requests = 32; + optional int64 throttled_time = 33; + + optional bytes server_name = 34; +} + +message LogModuleVersion { + optional string module_id = 1 [default="default"]; + optional string version_id = 2; +} + +message LogReadRequest { + required string app_id = 1; + repeated string version_id = 2; + repeated LogModuleVersion module_version = 19; + + optional int64 start_time = 3; + optional int64 end_time = 4; + optional LogOffset offset = 5; + repeated bytes request_id = 6; + + optional int32 minimum_log_level = 7; + optional bool include_incomplete = 8; + optional int64 count = 9; + + optional string combined_log_regex = 14; + optional string host_regex = 15; + optional int32 replica_index = 16; + + optional bool include_app_logs = 10; + optional int32 app_logs_per_request = 17; + optional bool include_host = 11; + optional bool include_all = 12; + optional bool cache_iterator = 13; + optional int32 num_shards = 18; +} + +message LogReadResponse { + repeated RequestLog log = 1; + optional LogOffset offset = 2; + optional int64 last_end_time = 3; +} + +message LogUsageRecord { + optional string version_id = 1; + optional int32 start_time = 2; + optional int32 end_time = 3; + optional int64 count = 4; + optional int64 total_size = 5; + optional int32 records = 6; +} + +message LogUsageRequest { + required string app_id = 1; + repeated string version_id = 2; + optional int32 start_time = 3; + optional int32 end_time = 4; + optional uint32 resolution_hours = 5 [default = 1]; + optional bool combine_versions = 6; + optional int32 usage_version = 7; + optional bool versions_only = 8; +} + +message LogUsageResponse { + repeated LogUsageRecord usage = 1; + optional LogUsageRecord summary = 2; +} diff --git a/vendor/google.golang.org/appengine/internal/main.go b/vendor/google.golang.org/appengine/internal/main.go new file mode 100644 index 000000000000..1e765312fd18 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/main.go @@ -0,0 +1,16 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build appengine + +package internal + +import ( + "appengine_internal" +) + +func Main() { + MainPath = "" + appengine_internal.Main() +} diff --git a/vendor/google.golang.org/appengine/internal/main_common.go b/vendor/google.golang.org/appengine/internal/main_common.go new file mode 100644 index 000000000000..357dce4dd012 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/main_common.go @@ -0,0 +1,7 @@ +package internal + +// MainPath stores the file path of the main package. On App Engine Standard +// using Go version 1.9 and below, this will be unset. On App Engine Flex and +// App Engine Standard second-gen (Go 1.11 and above), this will be the +// filepath to package main. +var MainPath string diff --git a/vendor/google.golang.org/appengine/internal/main_vm.go b/vendor/google.golang.org/appengine/internal/main_vm.go new file mode 100644 index 000000000000..ddb79a333879 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/main_vm.go @@ -0,0 +1,69 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// +build !appengine + +package internal + +import ( + "io" + "log" + "net/http" + "net/url" + "os" + "path/filepath" + "runtime" +) + +func Main() { + MainPath = filepath.Dir(findMainPath()) + installHealthChecker(http.DefaultServeMux) + + port := "8080" + if s := os.Getenv("PORT"); s != "" { + port = s + } + + host := "" + if IsDevAppServer() { + host = "127.0.0.1" + } + if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil { + log.Fatalf("http.ListenAndServe: %v", err) + } +} + +// Find the path to package main by looking at the root Caller. +func findMainPath() string { + pc := make([]uintptr, 100) + n := runtime.Callers(2, pc) + frames := runtime.CallersFrames(pc[:n]) + for { + frame, more := frames.Next() + // Tests won't have package main, instead they have testing.tRunner + if frame.Function == "main.main" || frame.Function == "testing.tRunner" { + return frame.File + } + if !more { + break + } + } + return "" +} + +func installHealthChecker(mux *http.ServeMux) { + // If no health check handler has been installed by this point, add a trivial one. + const healthPath = "/_ah/health" + hreq := &http.Request{ + Method: "GET", + URL: &url.URL{ + Path: healthPath, + }, + } + if _, pat := mux.Handler(hreq); pat != healthPath { + mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "ok") + }) + } +} diff --git a/vendor/google.golang.org/appengine/internal/metadata.go b/vendor/google.golang.org/appengine/internal/metadata.go new file mode 100644 index 000000000000..c4ba63bb4819 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/metadata.go @@ -0,0 +1,60 @@ +// Copyright 2014 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package internal + +// This file has code for accessing metadata. +// +// References: +// https://cloud.google.com/compute/docs/metadata + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" +) + +const ( + metadataHost = "metadata" + metadataPath = "/computeMetadata/v1/" +) + +var ( + metadataRequestHeaders = http.Header{ + "Metadata-Flavor": []string{"Google"}, + } +) + +// TODO(dsymonds): Do we need to support default values, like Python? +func mustGetMetadata(key string) []byte { + b, err := getMetadata(key) + if err != nil { + panic(fmt.Sprintf("Metadata fetch failed for '%s': %v", key, err)) + } + return b +} + +func getMetadata(key string) ([]byte, error) { + // TODO(dsymonds): May need to use url.Parse to support keys with query args. + req := &http.Request{ + Method: "GET", + URL: &url.URL{ + Scheme: "http", + Host: metadataHost, + Path: metadataPath + key, + }, + Header: metadataRequestHeaders, + Host: metadataHost, + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return nil, fmt.Errorf("metadata server returned HTTP %d", resp.StatusCode) + } + return ioutil.ReadAll(resp.Body) +} diff --git a/vendor/google.golang.org/appengine/internal/modules/modules_service.pb.go b/vendor/google.golang.org/appengine/internal/modules/modules_service.pb.go new file mode 100644 index 000000000000..ddfc0c04a126 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/modules/modules_service.pb.go @@ -0,0 +1,786 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google.golang.org/appengine/internal/modules/modules_service.proto + +package modules + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type ModulesServiceError_ErrorCode int32 + +const ( + ModulesServiceError_OK ModulesServiceError_ErrorCode = 0 + ModulesServiceError_INVALID_MODULE ModulesServiceError_ErrorCode = 1 + ModulesServiceError_INVALID_VERSION ModulesServiceError_ErrorCode = 2 + ModulesServiceError_INVALID_INSTANCES ModulesServiceError_ErrorCode = 3 + ModulesServiceError_TRANSIENT_ERROR ModulesServiceError_ErrorCode = 4 + ModulesServiceError_UNEXPECTED_STATE ModulesServiceError_ErrorCode = 5 +) + +var ModulesServiceError_ErrorCode_name = map[int32]string{ + 0: "OK", + 1: "INVALID_MODULE", + 2: "INVALID_VERSION", + 3: "INVALID_INSTANCES", + 4: "TRANSIENT_ERROR", + 5: "UNEXPECTED_STATE", +} +var ModulesServiceError_ErrorCode_value = map[string]int32{ + "OK": 0, + "INVALID_MODULE": 1, + "INVALID_VERSION": 2, + "INVALID_INSTANCES": 3, + "TRANSIENT_ERROR": 4, + "UNEXPECTED_STATE": 5, +} + +func (x ModulesServiceError_ErrorCode) Enum() *ModulesServiceError_ErrorCode { + p := new(ModulesServiceError_ErrorCode) + *p = x + return p +} +func (x ModulesServiceError_ErrorCode) String() string { + return proto.EnumName(ModulesServiceError_ErrorCode_name, int32(x)) +} +func (x *ModulesServiceError_ErrorCode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(ModulesServiceError_ErrorCode_value, data, "ModulesServiceError_ErrorCode") + if err != nil { + return err + } + *x = ModulesServiceError_ErrorCode(value) + return nil +} +func (ModulesServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{0, 0} +} + +type ModulesServiceError struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ModulesServiceError) Reset() { *m = ModulesServiceError{} } +func (m *ModulesServiceError) String() string { return proto.CompactTextString(m) } +func (*ModulesServiceError) ProtoMessage() {} +func (*ModulesServiceError) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{0} +} +func (m *ModulesServiceError) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ModulesServiceError.Unmarshal(m, b) +} +func (m *ModulesServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ModulesServiceError.Marshal(b, m, deterministic) +} +func (dst *ModulesServiceError) XXX_Merge(src proto.Message) { + xxx_messageInfo_ModulesServiceError.Merge(dst, src) +} +func (m *ModulesServiceError) XXX_Size() int { + return xxx_messageInfo_ModulesServiceError.Size(m) +} +func (m *ModulesServiceError) XXX_DiscardUnknown() { + xxx_messageInfo_ModulesServiceError.DiscardUnknown(m) +} + +var xxx_messageInfo_ModulesServiceError proto.InternalMessageInfo + +type GetModulesRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetModulesRequest) Reset() { *m = GetModulesRequest{} } +func (m *GetModulesRequest) String() string { return proto.CompactTextString(m) } +func (*GetModulesRequest) ProtoMessage() {} +func (*GetModulesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{1} +} +func (m *GetModulesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetModulesRequest.Unmarshal(m, b) +} +func (m *GetModulesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetModulesRequest.Marshal(b, m, deterministic) +} +func (dst *GetModulesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetModulesRequest.Merge(dst, src) +} +func (m *GetModulesRequest) XXX_Size() int { + return xxx_messageInfo_GetModulesRequest.Size(m) +} +func (m *GetModulesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetModulesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetModulesRequest proto.InternalMessageInfo + +type GetModulesResponse struct { + Module []string `protobuf:"bytes,1,rep,name=module" json:"module,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetModulesResponse) Reset() { *m = GetModulesResponse{} } +func (m *GetModulesResponse) String() string { return proto.CompactTextString(m) } +func (*GetModulesResponse) ProtoMessage() {} +func (*GetModulesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{2} +} +func (m *GetModulesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetModulesResponse.Unmarshal(m, b) +} +func (m *GetModulesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetModulesResponse.Marshal(b, m, deterministic) +} +func (dst *GetModulesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetModulesResponse.Merge(dst, src) +} +func (m *GetModulesResponse) XXX_Size() int { + return xxx_messageInfo_GetModulesResponse.Size(m) +} +func (m *GetModulesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetModulesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetModulesResponse proto.InternalMessageInfo + +func (m *GetModulesResponse) GetModule() []string { + if m != nil { + return m.Module + } + return nil +} + +type GetVersionsRequest struct { + Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetVersionsRequest) Reset() { *m = GetVersionsRequest{} } +func (m *GetVersionsRequest) String() string { return proto.CompactTextString(m) } +func (*GetVersionsRequest) ProtoMessage() {} +func (*GetVersionsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{3} +} +func (m *GetVersionsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetVersionsRequest.Unmarshal(m, b) +} +func (m *GetVersionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetVersionsRequest.Marshal(b, m, deterministic) +} +func (dst *GetVersionsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetVersionsRequest.Merge(dst, src) +} +func (m *GetVersionsRequest) XXX_Size() int { + return xxx_messageInfo_GetVersionsRequest.Size(m) +} +func (m *GetVersionsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetVersionsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetVersionsRequest proto.InternalMessageInfo + +func (m *GetVersionsRequest) GetModule() string { + if m != nil && m.Module != nil { + return *m.Module + } + return "" +} + +type GetVersionsResponse struct { + Version []string `protobuf:"bytes,1,rep,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetVersionsResponse) Reset() { *m = GetVersionsResponse{} } +func (m *GetVersionsResponse) String() string { return proto.CompactTextString(m) } +func (*GetVersionsResponse) ProtoMessage() {} +func (*GetVersionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{4} +} +func (m *GetVersionsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetVersionsResponse.Unmarshal(m, b) +} +func (m *GetVersionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetVersionsResponse.Marshal(b, m, deterministic) +} +func (dst *GetVersionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetVersionsResponse.Merge(dst, src) +} +func (m *GetVersionsResponse) XXX_Size() int { + return xxx_messageInfo_GetVersionsResponse.Size(m) +} +func (m *GetVersionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetVersionsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetVersionsResponse proto.InternalMessageInfo + +func (m *GetVersionsResponse) GetVersion() []string { + if m != nil { + return m.Version + } + return nil +} + +type GetDefaultVersionRequest struct { + Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetDefaultVersionRequest) Reset() { *m = GetDefaultVersionRequest{} } +func (m *GetDefaultVersionRequest) String() string { return proto.CompactTextString(m) } +func (*GetDefaultVersionRequest) ProtoMessage() {} +func (*GetDefaultVersionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{5} +} +func (m *GetDefaultVersionRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetDefaultVersionRequest.Unmarshal(m, b) +} +func (m *GetDefaultVersionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetDefaultVersionRequest.Marshal(b, m, deterministic) +} +func (dst *GetDefaultVersionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetDefaultVersionRequest.Merge(dst, src) +} +func (m *GetDefaultVersionRequest) XXX_Size() int { + return xxx_messageInfo_GetDefaultVersionRequest.Size(m) +} +func (m *GetDefaultVersionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetDefaultVersionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetDefaultVersionRequest proto.InternalMessageInfo + +func (m *GetDefaultVersionRequest) GetModule() string { + if m != nil && m.Module != nil { + return *m.Module + } + return "" +} + +type GetDefaultVersionResponse struct { + Version *string `protobuf:"bytes,1,req,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetDefaultVersionResponse) Reset() { *m = GetDefaultVersionResponse{} } +func (m *GetDefaultVersionResponse) String() string { return proto.CompactTextString(m) } +func (*GetDefaultVersionResponse) ProtoMessage() {} +func (*GetDefaultVersionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{6} +} +func (m *GetDefaultVersionResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetDefaultVersionResponse.Unmarshal(m, b) +} +func (m *GetDefaultVersionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetDefaultVersionResponse.Marshal(b, m, deterministic) +} +func (dst *GetDefaultVersionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetDefaultVersionResponse.Merge(dst, src) +} +func (m *GetDefaultVersionResponse) XXX_Size() int { + return xxx_messageInfo_GetDefaultVersionResponse.Size(m) +} +func (m *GetDefaultVersionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetDefaultVersionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetDefaultVersionResponse proto.InternalMessageInfo + +func (m *GetDefaultVersionResponse) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +type GetNumInstancesRequest struct { + Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"` + Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetNumInstancesRequest) Reset() { *m = GetNumInstancesRequest{} } +func (m *GetNumInstancesRequest) String() string { return proto.CompactTextString(m) } +func (*GetNumInstancesRequest) ProtoMessage() {} +func (*GetNumInstancesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{7} +} +func (m *GetNumInstancesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetNumInstancesRequest.Unmarshal(m, b) +} +func (m *GetNumInstancesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetNumInstancesRequest.Marshal(b, m, deterministic) +} +func (dst *GetNumInstancesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetNumInstancesRequest.Merge(dst, src) +} +func (m *GetNumInstancesRequest) XXX_Size() int { + return xxx_messageInfo_GetNumInstancesRequest.Size(m) +} +func (m *GetNumInstancesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetNumInstancesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetNumInstancesRequest proto.InternalMessageInfo + +func (m *GetNumInstancesRequest) GetModule() string { + if m != nil && m.Module != nil { + return *m.Module + } + return "" +} + +func (m *GetNumInstancesRequest) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +type GetNumInstancesResponse struct { + Instances *int64 `protobuf:"varint,1,req,name=instances" json:"instances,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetNumInstancesResponse) Reset() { *m = GetNumInstancesResponse{} } +func (m *GetNumInstancesResponse) String() string { return proto.CompactTextString(m) } +func (*GetNumInstancesResponse) ProtoMessage() {} +func (*GetNumInstancesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{8} +} +func (m *GetNumInstancesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetNumInstancesResponse.Unmarshal(m, b) +} +func (m *GetNumInstancesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetNumInstancesResponse.Marshal(b, m, deterministic) +} +func (dst *GetNumInstancesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetNumInstancesResponse.Merge(dst, src) +} +func (m *GetNumInstancesResponse) XXX_Size() int { + return xxx_messageInfo_GetNumInstancesResponse.Size(m) +} +func (m *GetNumInstancesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetNumInstancesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetNumInstancesResponse proto.InternalMessageInfo + +func (m *GetNumInstancesResponse) GetInstances() int64 { + if m != nil && m.Instances != nil { + return *m.Instances + } + return 0 +} + +type SetNumInstancesRequest struct { + Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"` + Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` + Instances *int64 `protobuf:"varint,3,req,name=instances" json:"instances,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetNumInstancesRequest) Reset() { *m = SetNumInstancesRequest{} } +func (m *SetNumInstancesRequest) String() string { return proto.CompactTextString(m) } +func (*SetNumInstancesRequest) ProtoMessage() {} +func (*SetNumInstancesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{9} +} +func (m *SetNumInstancesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetNumInstancesRequest.Unmarshal(m, b) +} +func (m *SetNumInstancesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetNumInstancesRequest.Marshal(b, m, deterministic) +} +func (dst *SetNumInstancesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetNumInstancesRequest.Merge(dst, src) +} +func (m *SetNumInstancesRequest) XXX_Size() int { + return xxx_messageInfo_SetNumInstancesRequest.Size(m) +} +func (m *SetNumInstancesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SetNumInstancesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SetNumInstancesRequest proto.InternalMessageInfo + +func (m *SetNumInstancesRequest) GetModule() string { + if m != nil && m.Module != nil { + return *m.Module + } + return "" +} + +func (m *SetNumInstancesRequest) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +func (m *SetNumInstancesRequest) GetInstances() int64 { + if m != nil && m.Instances != nil { + return *m.Instances + } + return 0 +} + +type SetNumInstancesResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetNumInstancesResponse) Reset() { *m = SetNumInstancesResponse{} } +func (m *SetNumInstancesResponse) String() string { return proto.CompactTextString(m) } +func (*SetNumInstancesResponse) ProtoMessage() {} +func (*SetNumInstancesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{10} +} +func (m *SetNumInstancesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetNumInstancesResponse.Unmarshal(m, b) +} +func (m *SetNumInstancesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetNumInstancesResponse.Marshal(b, m, deterministic) +} +func (dst *SetNumInstancesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetNumInstancesResponse.Merge(dst, src) +} +func (m *SetNumInstancesResponse) XXX_Size() int { + return xxx_messageInfo_SetNumInstancesResponse.Size(m) +} +func (m *SetNumInstancesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SetNumInstancesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SetNumInstancesResponse proto.InternalMessageInfo + +type StartModuleRequest struct { + Module *string `protobuf:"bytes,1,req,name=module" json:"module,omitempty"` + Version *string `protobuf:"bytes,2,req,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StartModuleRequest) Reset() { *m = StartModuleRequest{} } +func (m *StartModuleRequest) String() string { return proto.CompactTextString(m) } +func (*StartModuleRequest) ProtoMessage() {} +func (*StartModuleRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{11} +} +func (m *StartModuleRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StartModuleRequest.Unmarshal(m, b) +} +func (m *StartModuleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StartModuleRequest.Marshal(b, m, deterministic) +} +func (dst *StartModuleRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartModuleRequest.Merge(dst, src) +} +func (m *StartModuleRequest) XXX_Size() int { + return xxx_messageInfo_StartModuleRequest.Size(m) +} +func (m *StartModuleRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StartModuleRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StartModuleRequest proto.InternalMessageInfo + +func (m *StartModuleRequest) GetModule() string { + if m != nil && m.Module != nil { + return *m.Module + } + return "" +} + +func (m *StartModuleRequest) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +type StartModuleResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StartModuleResponse) Reset() { *m = StartModuleResponse{} } +func (m *StartModuleResponse) String() string { return proto.CompactTextString(m) } +func (*StartModuleResponse) ProtoMessage() {} +func (*StartModuleResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{12} +} +func (m *StartModuleResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StartModuleResponse.Unmarshal(m, b) +} +func (m *StartModuleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StartModuleResponse.Marshal(b, m, deterministic) +} +func (dst *StartModuleResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartModuleResponse.Merge(dst, src) +} +func (m *StartModuleResponse) XXX_Size() int { + return xxx_messageInfo_StartModuleResponse.Size(m) +} +func (m *StartModuleResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StartModuleResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StartModuleResponse proto.InternalMessageInfo + +type StopModuleRequest struct { + Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"` + Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StopModuleRequest) Reset() { *m = StopModuleRequest{} } +func (m *StopModuleRequest) String() string { return proto.CompactTextString(m) } +func (*StopModuleRequest) ProtoMessage() {} +func (*StopModuleRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{13} +} +func (m *StopModuleRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StopModuleRequest.Unmarshal(m, b) +} +func (m *StopModuleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StopModuleRequest.Marshal(b, m, deterministic) +} +func (dst *StopModuleRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopModuleRequest.Merge(dst, src) +} +func (m *StopModuleRequest) XXX_Size() int { + return xxx_messageInfo_StopModuleRequest.Size(m) +} +func (m *StopModuleRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StopModuleRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StopModuleRequest proto.InternalMessageInfo + +func (m *StopModuleRequest) GetModule() string { + if m != nil && m.Module != nil { + return *m.Module + } + return "" +} + +func (m *StopModuleRequest) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +type StopModuleResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StopModuleResponse) Reset() { *m = StopModuleResponse{} } +func (m *StopModuleResponse) String() string { return proto.CompactTextString(m) } +func (*StopModuleResponse) ProtoMessage() {} +func (*StopModuleResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{14} +} +func (m *StopModuleResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StopModuleResponse.Unmarshal(m, b) +} +func (m *StopModuleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StopModuleResponse.Marshal(b, m, deterministic) +} +func (dst *StopModuleResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopModuleResponse.Merge(dst, src) +} +func (m *StopModuleResponse) XXX_Size() int { + return xxx_messageInfo_StopModuleResponse.Size(m) +} +func (m *StopModuleResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StopModuleResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StopModuleResponse proto.InternalMessageInfo + +type GetHostnameRequest struct { + Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"` + Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` + Instance *string `protobuf:"bytes,3,opt,name=instance" json:"instance,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetHostnameRequest) Reset() { *m = GetHostnameRequest{} } +func (m *GetHostnameRequest) String() string { return proto.CompactTextString(m) } +func (*GetHostnameRequest) ProtoMessage() {} +func (*GetHostnameRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{15} +} +func (m *GetHostnameRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetHostnameRequest.Unmarshal(m, b) +} +func (m *GetHostnameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetHostnameRequest.Marshal(b, m, deterministic) +} +func (dst *GetHostnameRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetHostnameRequest.Merge(dst, src) +} +func (m *GetHostnameRequest) XXX_Size() int { + return xxx_messageInfo_GetHostnameRequest.Size(m) +} +func (m *GetHostnameRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetHostnameRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetHostnameRequest proto.InternalMessageInfo + +func (m *GetHostnameRequest) GetModule() string { + if m != nil && m.Module != nil { + return *m.Module + } + return "" +} + +func (m *GetHostnameRequest) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +func (m *GetHostnameRequest) GetInstance() string { + if m != nil && m.Instance != nil { + return *m.Instance + } + return "" +} + +type GetHostnameResponse struct { + Hostname *string `protobuf:"bytes,1,req,name=hostname" json:"hostname,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetHostnameResponse) Reset() { *m = GetHostnameResponse{} } +func (m *GetHostnameResponse) String() string { return proto.CompactTextString(m) } +func (*GetHostnameResponse) ProtoMessage() {} +func (*GetHostnameResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{16} +} +func (m *GetHostnameResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetHostnameResponse.Unmarshal(m, b) +} +func (m *GetHostnameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetHostnameResponse.Marshal(b, m, deterministic) +} +func (dst *GetHostnameResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetHostnameResponse.Merge(dst, src) +} +func (m *GetHostnameResponse) XXX_Size() int { + return xxx_messageInfo_GetHostnameResponse.Size(m) +} +func (m *GetHostnameResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetHostnameResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetHostnameResponse proto.InternalMessageInfo + +func (m *GetHostnameResponse) GetHostname() string { + if m != nil && m.Hostname != nil { + return *m.Hostname + } + return "" +} + +func init() { + proto.RegisterType((*ModulesServiceError)(nil), "appengine.ModulesServiceError") + proto.RegisterType((*GetModulesRequest)(nil), "appengine.GetModulesRequest") + proto.RegisterType((*GetModulesResponse)(nil), "appengine.GetModulesResponse") + proto.RegisterType((*GetVersionsRequest)(nil), "appengine.GetVersionsRequest") + proto.RegisterType((*GetVersionsResponse)(nil), "appengine.GetVersionsResponse") + proto.RegisterType((*GetDefaultVersionRequest)(nil), "appengine.GetDefaultVersionRequest") + proto.RegisterType((*GetDefaultVersionResponse)(nil), "appengine.GetDefaultVersionResponse") + proto.RegisterType((*GetNumInstancesRequest)(nil), "appengine.GetNumInstancesRequest") + proto.RegisterType((*GetNumInstancesResponse)(nil), "appengine.GetNumInstancesResponse") + proto.RegisterType((*SetNumInstancesRequest)(nil), "appengine.SetNumInstancesRequest") + proto.RegisterType((*SetNumInstancesResponse)(nil), "appengine.SetNumInstancesResponse") + proto.RegisterType((*StartModuleRequest)(nil), "appengine.StartModuleRequest") + proto.RegisterType((*StartModuleResponse)(nil), "appengine.StartModuleResponse") + proto.RegisterType((*StopModuleRequest)(nil), "appengine.StopModuleRequest") + proto.RegisterType((*StopModuleResponse)(nil), "appengine.StopModuleResponse") + proto.RegisterType((*GetHostnameRequest)(nil), "appengine.GetHostnameRequest") + proto.RegisterType((*GetHostnameResponse)(nil), "appengine.GetHostnameResponse") +} + +func init() { + proto.RegisterFile("google.golang.org/appengine/internal/modules/modules_service.proto", fileDescriptor_modules_service_9cd3bffe4e91c59a) +} + +var fileDescriptor_modules_service_9cd3bffe4e91c59a = []byte{ + // 457 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0xc1, 0x6f, 0xd3, 0x30, + 0x14, 0xc6, 0x69, 0x02, 0xdb, 0xf2, 0x0e, 0x90, 0x3a, 0x5b, 0xd7, 0x4d, 0x1c, 0x50, 0x4e, 0x1c, + 0x50, 0x2b, 0x90, 0x10, 0xe7, 0xae, 0x35, 0x25, 0xb0, 0xa5, 0x28, 0xce, 0x2a, 0xc4, 0xa5, 0x0a, + 0xdb, 0x23, 0x8b, 0x94, 0xda, 0xc1, 0x76, 0x77, 0xe4, 0xbf, 0xe0, 0xff, 0x45, 0x4b, 0xed, 0xb6, + 0x81, 0x4e, 0x45, 0x68, 0xa7, 0xe4, 0x7d, 0xfe, 0xfc, 0x7b, 0x9f, 0x5f, 0xac, 0xc0, 0x59, 0x2e, + 0x44, 0x5e, 0x62, 0x2f, 0x17, 0x65, 0xc6, 0xf3, 0x9e, 0x90, 0x79, 0x3f, 0xab, 0x2a, 0xe4, 0x79, + 0xc1, 0xb1, 0x5f, 0x70, 0x8d, 0x92, 0x67, 0x65, 0x7f, 0x2e, 0xae, 0x17, 0x25, 0x2a, 0xfb, 0x9c, + 0x29, 0x94, 0xb7, 0xc5, 0x15, 0xf6, 0x2a, 0x29, 0xb4, 0x20, 0xde, 0x6a, 0x47, 0xf8, 0xab, 0x05, + 0xc1, 0xc5, 0xd2, 0xc4, 0x96, 0x1e, 0x2a, 0xa5, 0x90, 0xe1, 0x4f, 0xf0, 0xea, 0x97, 0xa1, 0xb8, + 0x46, 0xb2, 0x07, 0xce, 0xe4, 0x93, 0xff, 0x88, 0x10, 0x78, 0x1a, 0xc5, 0xd3, 0xc1, 0x79, 0x34, + 0x9a, 0x5d, 0x4c, 0x46, 0x97, 0xe7, 0xd4, 0x6f, 0x91, 0x00, 0x9e, 0x59, 0x6d, 0x4a, 0x13, 0x16, + 0x4d, 0x62, 0xdf, 0x21, 0x47, 0xd0, 0xb6, 0x62, 0x14, 0xb3, 0x74, 0x10, 0x0f, 0x29, 0xf3, 0xdd, + 0x3b, 0x6f, 0x9a, 0x0c, 0x62, 0x16, 0xd1, 0x38, 0x9d, 0xd1, 0x24, 0x99, 0x24, 0xfe, 0x63, 0x72, + 0x08, 0xfe, 0x65, 0x4c, 0xbf, 0x7c, 0xa6, 0xc3, 0x94, 0x8e, 0x66, 0x2c, 0x1d, 0xa4, 0xd4, 0x7f, + 0x12, 0x06, 0xd0, 0x1e, 0xa3, 0x36, 0xc9, 0x12, 0xfc, 0xb1, 0x40, 0xa5, 0xc3, 0x57, 0x40, 0x36, + 0x45, 0x55, 0x09, 0xae, 0x90, 0x74, 0x60, 0x6f, 0x79, 0xcc, 0x6e, 0xeb, 0x85, 0xfb, 0xd2, 0x4b, + 0x4c, 0x65, 0xdc, 0x53, 0x94, 0xaa, 0x10, 0xdc, 0x32, 0x1a, 0xee, 0xd6, 0x86, 0xbb, 0x0f, 0x41, + 0xc3, 0x6d, 0xe0, 0x5d, 0xd8, 0xbf, 0x5d, 0x6a, 0x86, 0x6e, 0xcb, 0xf0, 0x0d, 0x74, 0xc7, 0xa8, + 0x47, 0xf8, 0x3d, 0x5b, 0x94, 0x76, 0xdf, 0xae, 0x26, 0x6f, 0xe1, 0x64, 0xcb, 0x9e, 0x6d, 0xad, + 0x9c, 0xcd, 0x56, 0x1f, 0xa1, 0x33, 0x46, 0x1d, 0x2f, 0xe6, 0x11, 0x57, 0x3a, 0xe3, 0x57, 0xb8, + 0xeb, 0x34, 0x9b, 0x2c, 0xa7, 0x5e, 0x58, 0xb1, 0xde, 0xc1, 0xf1, 0x5f, 0x2c, 0x13, 0xe0, 0x39, + 0x78, 0x85, 0x15, 0xeb, 0x08, 0x6e, 0xb2, 0x16, 0xc2, 0x1b, 0xe8, 0xb0, 0x07, 0x0a, 0xd1, 0xec, + 0xe4, 0xfe, 0xd9, 0xe9, 0x04, 0x8e, 0xd9, 0xf6, 0x88, 0xe1, 0x7b, 0x20, 0x4c, 0x67, 0xd2, 0xdc, + 0x81, 0x6d, 0x01, 0x9c, 0xfb, 0x02, 0x34, 0x26, 0x7a, 0x04, 0x41, 0x83, 0x63, 0xf0, 0x14, 0xda, + 0x4c, 0x8b, 0xea, 0x7e, 0xfa, 0xbf, 0xcd, 0xf8, 0xf0, 0x2e, 0xe5, 0x1a, 0x63, 0xe0, 0xdf, 0xea, + 0xfb, 0xf8, 0x41, 0x28, 0xcd, 0xb3, 0xf9, 0xff, 0xd3, 0xc9, 0x29, 0x1c, 0xd8, 0x59, 0x75, 0xdd, + 0x7a, 0x69, 0x55, 0x87, 0xaf, 0xeb, 0x5b, 0xbc, 0xee, 0x61, 0xbe, 0xec, 0x29, 0x1c, 0xdc, 0x18, + 0xcd, 0x8c, 0x68, 0x55, 0x9f, 0x79, 0x5f, 0xf7, 0xcd, 0x5f, 0xe2, 0x77, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x6e, 0xbc, 0xe0, 0x61, 0x5c, 0x04, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/appengine/internal/modules/modules_service.proto b/vendor/google.golang.org/appengine/internal/modules/modules_service.proto new file mode 100644 index 000000000000..d29f0065a2f8 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/modules/modules_service.proto @@ -0,0 +1,80 @@ +syntax = "proto2"; +option go_package = "modules"; + +package appengine; + +message ModulesServiceError { + enum ErrorCode { + OK = 0; + INVALID_MODULE = 1; + INVALID_VERSION = 2; + INVALID_INSTANCES = 3; + TRANSIENT_ERROR = 4; + UNEXPECTED_STATE = 5; + } +} + +message GetModulesRequest { +} + +message GetModulesResponse { + repeated string module = 1; +} + +message GetVersionsRequest { + optional string module = 1; +} + +message GetVersionsResponse { + repeated string version = 1; +} + +message GetDefaultVersionRequest { + optional string module = 1; +} + +message GetDefaultVersionResponse { + required string version = 1; +} + +message GetNumInstancesRequest { + optional string module = 1; + optional string version = 2; +} + +message GetNumInstancesResponse { + required int64 instances = 1; +} + +message SetNumInstancesRequest { + optional string module = 1; + optional string version = 2; + required int64 instances = 3; +} + +message SetNumInstancesResponse {} + +message StartModuleRequest { + required string module = 1; + required string version = 2; +} + +message StartModuleResponse {} + +message StopModuleRequest { + optional string module = 1; + optional string version = 2; +} + +message StopModuleResponse {} + +message GetHostnameRequest { + optional string module = 1; + optional string version = 2; + optional string instance = 3; +} + +message GetHostnameResponse { + required string hostname = 1; +} + diff --git a/vendor/google.golang.org/appengine/internal/net.go b/vendor/google.golang.org/appengine/internal/net.go new file mode 100644 index 000000000000..3b94cf0c6a8b --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/net.go @@ -0,0 +1,56 @@ +// Copyright 2014 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package internal + +// This file implements a network dialer that limits the number of concurrent connections. +// It is only used for API calls. + +import ( + "log" + "net" + "runtime" + "sync" + "time" +) + +var limitSem = make(chan int, 100) // TODO(dsymonds): Use environment variable. + +func limitRelease() { + // non-blocking + select { + case <-limitSem: + default: + // This should not normally happen. + log.Print("appengine: unbalanced limitSem release!") + } +} + +func limitDial(network, addr string) (net.Conn, error) { + limitSem <- 1 + + // Dial with a timeout in case the API host is MIA. + // The connection should normally be very fast. + conn, err := net.DialTimeout(network, addr, 500*time.Millisecond) + if err != nil { + limitRelease() + return nil, err + } + lc := &limitConn{Conn: conn} + runtime.SetFinalizer(lc, (*limitConn).Close) // shouldn't usually be required + return lc, nil +} + +type limitConn struct { + close sync.Once + net.Conn +} + +func (lc *limitConn) Close() error { + defer lc.close.Do(func() { + limitRelease() + runtime.SetFinalizer(lc, nil) + }) + return lc.Conn.Close() +} diff --git a/vendor/google.golang.org/appengine/internal/regen.sh b/vendor/google.golang.org/appengine/internal/regen.sh new file mode 100644 index 000000000000..2fdb546a6333 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/regen.sh @@ -0,0 +1,40 @@ +#!/bin/bash -e +# +# This script rebuilds the generated code for the protocol buffers. +# To run this you will need protoc and goprotobuf installed; +# see https://github.com/golang/protobuf for instructions. + +PKG=google.golang.org/appengine + +function die() { + echo 1>&2 $* + exit 1 +} + +# Sanity check that the right tools are accessible. +for tool in go protoc protoc-gen-go; do + q=$(which $tool) || die "didn't find $tool" + echo 1>&2 "$tool: $q" +done + +echo -n 1>&2 "finding package dir... " +pkgdir=$(go list -f '{{.Dir}}' $PKG) +echo 1>&2 $pkgdir +base=$(echo $pkgdir | sed "s,/$PKG\$,,") +echo 1>&2 "base: $base" +cd $base + +# Run protoc once per package. +for dir in $(find $PKG/internal -name '*.proto' | xargs dirname | sort | uniq); do + echo 1>&2 "* $dir" + protoc --go_out=. $dir/*.proto +done + +for f in $(find $PKG/internal -name '*.pb.go'); do + # Remove proto.RegisterEnum calls. + # These cause duplicate registration panics when these packages + # are used on classic App Engine. proto.RegisterEnum only affects + # parsing the text format; we don't care about that. + # https://code.google.com/p/googleappengine/issues/detail?id=11670#c17 + sed -i '/proto.RegisterEnum/d' $f +done diff --git a/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go new file mode 100644 index 000000000000..8d782a38e172 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go @@ -0,0 +1,361 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google.golang.org/appengine/internal/remote_api/remote_api.proto + +package remote_api + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type RpcError_ErrorCode int32 + +const ( + RpcError_UNKNOWN RpcError_ErrorCode = 0 + RpcError_CALL_NOT_FOUND RpcError_ErrorCode = 1 + RpcError_PARSE_ERROR RpcError_ErrorCode = 2 + RpcError_SECURITY_VIOLATION RpcError_ErrorCode = 3 + RpcError_OVER_QUOTA RpcError_ErrorCode = 4 + RpcError_REQUEST_TOO_LARGE RpcError_ErrorCode = 5 + RpcError_CAPABILITY_DISABLED RpcError_ErrorCode = 6 + RpcError_FEATURE_DISABLED RpcError_ErrorCode = 7 + RpcError_BAD_REQUEST RpcError_ErrorCode = 8 + RpcError_RESPONSE_TOO_LARGE RpcError_ErrorCode = 9 + RpcError_CANCELLED RpcError_ErrorCode = 10 + RpcError_REPLAY_ERROR RpcError_ErrorCode = 11 + RpcError_DEADLINE_EXCEEDED RpcError_ErrorCode = 12 +) + +var RpcError_ErrorCode_name = map[int32]string{ + 0: "UNKNOWN", + 1: "CALL_NOT_FOUND", + 2: "PARSE_ERROR", + 3: "SECURITY_VIOLATION", + 4: "OVER_QUOTA", + 5: "REQUEST_TOO_LARGE", + 6: "CAPABILITY_DISABLED", + 7: "FEATURE_DISABLED", + 8: "BAD_REQUEST", + 9: "RESPONSE_TOO_LARGE", + 10: "CANCELLED", + 11: "REPLAY_ERROR", + 12: "DEADLINE_EXCEEDED", +} +var RpcError_ErrorCode_value = map[string]int32{ + "UNKNOWN": 0, + "CALL_NOT_FOUND": 1, + "PARSE_ERROR": 2, + "SECURITY_VIOLATION": 3, + "OVER_QUOTA": 4, + "REQUEST_TOO_LARGE": 5, + "CAPABILITY_DISABLED": 6, + "FEATURE_DISABLED": 7, + "BAD_REQUEST": 8, + "RESPONSE_TOO_LARGE": 9, + "CANCELLED": 10, + "REPLAY_ERROR": 11, + "DEADLINE_EXCEEDED": 12, +} + +func (x RpcError_ErrorCode) Enum() *RpcError_ErrorCode { + p := new(RpcError_ErrorCode) + *p = x + return p +} +func (x RpcError_ErrorCode) String() string { + return proto.EnumName(RpcError_ErrorCode_name, int32(x)) +} +func (x *RpcError_ErrorCode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(RpcError_ErrorCode_value, data, "RpcError_ErrorCode") + if err != nil { + return err + } + *x = RpcError_ErrorCode(value) + return nil +} +func (RpcError_ErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_remote_api_1978114ec33a273d, []int{2, 0} +} + +type Request struct { + ServiceName *string `protobuf:"bytes,2,req,name=service_name,json=serviceName" json:"service_name,omitempty"` + Method *string `protobuf:"bytes,3,req,name=method" json:"method,omitempty"` + Request []byte `protobuf:"bytes,4,req,name=request" json:"request,omitempty"` + RequestId *string `protobuf:"bytes,5,opt,name=request_id,json=requestId" json:"request_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Request) Reset() { *m = Request{} } +func (m *Request) String() string { return proto.CompactTextString(m) } +func (*Request) ProtoMessage() {} +func (*Request) Descriptor() ([]byte, []int) { + return fileDescriptor_remote_api_1978114ec33a273d, []int{0} +} +func (m *Request) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Request.Unmarshal(m, b) +} +func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Request.Marshal(b, m, deterministic) +} +func (dst *Request) XXX_Merge(src proto.Message) { + xxx_messageInfo_Request.Merge(dst, src) +} +func (m *Request) XXX_Size() int { + return xxx_messageInfo_Request.Size(m) +} +func (m *Request) XXX_DiscardUnknown() { + xxx_messageInfo_Request.DiscardUnknown(m) +} + +var xxx_messageInfo_Request proto.InternalMessageInfo + +func (m *Request) GetServiceName() string { + if m != nil && m.ServiceName != nil { + return *m.ServiceName + } + return "" +} + +func (m *Request) GetMethod() string { + if m != nil && m.Method != nil { + return *m.Method + } + return "" +} + +func (m *Request) GetRequest() []byte { + if m != nil { + return m.Request + } + return nil +} + +func (m *Request) GetRequestId() string { + if m != nil && m.RequestId != nil { + return *m.RequestId + } + return "" +} + +type ApplicationError struct { + Code *int32 `protobuf:"varint,1,req,name=code" json:"code,omitempty"` + Detail *string `protobuf:"bytes,2,req,name=detail" json:"detail,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationError) Reset() { *m = ApplicationError{} } +func (m *ApplicationError) String() string { return proto.CompactTextString(m) } +func (*ApplicationError) ProtoMessage() {} +func (*ApplicationError) Descriptor() ([]byte, []int) { + return fileDescriptor_remote_api_1978114ec33a273d, []int{1} +} +func (m *ApplicationError) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApplicationError.Unmarshal(m, b) +} +func (m *ApplicationError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApplicationError.Marshal(b, m, deterministic) +} +func (dst *ApplicationError) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationError.Merge(dst, src) +} +func (m *ApplicationError) XXX_Size() int { + return xxx_messageInfo_ApplicationError.Size(m) +} +func (m *ApplicationError) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationError.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationError proto.InternalMessageInfo + +func (m *ApplicationError) GetCode() int32 { + if m != nil && m.Code != nil { + return *m.Code + } + return 0 +} + +func (m *ApplicationError) GetDetail() string { + if m != nil && m.Detail != nil { + return *m.Detail + } + return "" +} + +type RpcError struct { + Code *int32 `protobuf:"varint,1,req,name=code" json:"code,omitempty"` + Detail *string `protobuf:"bytes,2,opt,name=detail" json:"detail,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RpcError) Reset() { *m = RpcError{} } +func (m *RpcError) String() string { return proto.CompactTextString(m) } +func (*RpcError) ProtoMessage() {} +func (*RpcError) Descriptor() ([]byte, []int) { + return fileDescriptor_remote_api_1978114ec33a273d, []int{2} +} +func (m *RpcError) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RpcError.Unmarshal(m, b) +} +func (m *RpcError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RpcError.Marshal(b, m, deterministic) +} +func (dst *RpcError) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcError.Merge(dst, src) +} +func (m *RpcError) XXX_Size() int { + return xxx_messageInfo_RpcError.Size(m) +} +func (m *RpcError) XXX_DiscardUnknown() { + xxx_messageInfo_RpcError.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcError proto.InternalMessageInfo + +func (m *RpcError) GetCode() int32 { + if m != nil && m.Code != nil { + return *m.Code + } + return 0 +} + +func (m *RpcError) GetDetail() string { + if m != nil && m.Detail != nil { + return *m.Detail + } + return "" +} + +type Response struct { + Response []byte `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"` + Exception []byte `protobuf:"bytes,2,opt,name=exception" json:"exception,omitempty"` + ApplicationError *ApplicationError `protobuf:"bytes,3,opt,name=application_error,json=applicationError" json:"application_error,omitempty"` + JavaException []byte `protobuf:"bytes,4,opt,name=java_exception,json=javaException" json:"java_exception,omitempty"` + RpcError *RpcError `protobuf:"bytes,5,opt,name=rpc_error,json=rpcError" json:"rpc_error,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Response) Reset() { *m = Response{} } +func (m *Response) String() string { return proto.CompactTextString(m) } +func (*Response) ProtoMessage() {} +func (*Response) Descriptor() ([]byte, []int) { + return fileDescriptor_remote_api_1978114ec33a273d, []int{3} +} +func (m *Response) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Response.Unmarshal(m, b) +} +func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Response.Marshal(b, m, deterministic) +} +func (dst *Response) XXX_Merge(src proto.Message) { + xxx_messageInfo_Response.Merge(dst, src) +} +func (m *Response) XXX_Size() int { + return xxx_messageInfo_Response.Size(m) +} +func (m *Response) XXX_DiscardUnknown() { + xxx_messageInfo_Response.DiscardUnknown(m) +} + +var xxx_messageInfo_Response proto.InternalMessageInfo + +func (m *Response) GetResponse() []byte { + if m != nil { + return m.Response + } + return nil +} + +func (m *Response) GetException() []byte { + if m != nil { + return m.Exception + } + return nil +} + +func (m *Response) GetApplicationError() *ApplicationError { + if m != nil { + return m.ApplicationError + } + return nil +} + +func (m *Response) GetJavaException() []byte { + if m != nil { + return m.JavaException + } + return nil +} + +func (m *Response) GetRpcError() *RpcError { + if m != nil { + return m.RpcError + } + return nil +} + +func init() { + proto.RegisterType((*Request)(nil), "remote_api.Request") + proto.RegisterType((*ApplicationError)(nil), "remote_api.ApplicationError") + proto.RegisterType((*RpcError)(nil), "remote_api.RpcError") + proto.RegisterType((*Response)(nil), "remote_api.Response") +} + +func init() { + proto.RegisterFile("google.golang.org/appengine/internal/remote_api/remote_api.proto", fileDescriptor_remote_api_1978114ec33a273d) +} + +var fileDescriptor_remote_api_1978114ec33a273d = []byte{ + // 531 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x51, 0x6e, 0xd3, 0x40, + 0x10, 0x86, 0xb1, 0x9b, 0x34, 0xf1, 0xc4, 0x2d, 0xdb, 0xa5, 0x14, 0x0b, 0x15, 0x29, 0x44, 0x42, + 0xca, 0x53, 0x2a, 0x38, 0x00, 0x62, 0x63, 0x6f, 0x91, 0x85, 0x65, 0xa7, 0x6b, 0xbb, 0x50, 0x5e, + 0x56, 0x2b, 0x67, 0x65, 0x8c, 0x12, 0xaf, 0xd9, 0x98, 0x8a, 0x17, 0x6e, 0xc0, 0xb5, 0x38, 0x0c, + 0xb7, 0x40, 0x36, 0x6e, 0x63, 0xf5, 0x89, 0xb7, 0x7f, 0x7e, 0x7b, 0xe6, 0x1b, 0xcd, 0xcc, 0xc2, + 0xbb, 0x5c, 0xa9, 0x7c, 0x23, 0x17, 0xb9, 0xda, 0x88, 0x32, 0x5f, 0x28, 0x9d, 0x5f, 0x88, 0xaa, + 0x92, 0x65, 0x5e, 0x94, 0xf2, 0xa2, 0x28, 0x6b, 0xa9, 0x4b, 0xb1, 0xb9, 0xd0, 0x72, 0xab, 0x6a, + 0xc9, 0x45, 0x55, 0xf4, 0xe4, 0xa2, 0xd2, 0xaa, 0x56, 0x18, 0xf6, 0xce, 0xec, 0x27, 0x8c, 0x98, + 0xfc, 0xf6, 0x5d, 0xee, 0x6a, 0xfc, 0x12, 0xec, 0x9d, 0xd4, 0xb7, 0x45, 0x26, 0x79, 0x29, 0xb6, + 0xd2, 0x31, 0xa7, 0xe6, 0xdc, 0x62, 0x93, 0xce, 0x0b, 0xc5, 0x56, 0xe2, 0x33, 0x38, 0xdc, 0xca, + 0xfa, 0x8b, 0x5a, 0x3b, 0x07, 0xed, 0xc7, 0x2e, 0xc2, 0x0e, 0x8c, 0xf4, 0xbf, 0x2a, 0xce, 0x60, + 0x6a, 0xce, 0x6d, 0x76, 0x17, 0xe2, 0x17, 0x00, 0x9d, 0xe4, 0xc5, 0xda, 0x19, 0x4e, 0x8d, 0xb9, + 0xc5, 0xac, 0xce, 0xf1, 0xd7, 0xb3, 0xb7, 0x80, 0x48, 0x55, 0x6d, 0x8a, 0x4c, 0xd4, 0x85, 0x2a, + 0xa9, 0xd6, 0x4a, 0x63, 0x0c, 0x83, 0x4c, 0xad, 0xa5, 0x63, 0x4c, 0xcd, 0xf9, 0x90, 0xb5, 0xba, + 0x01, 0xaf, 0x65, 0x2d, 0x8a, 0x4d, 0xd7, 0x55, 0x17, 0xcd, 0x7e, 0x9b, 0x30, 0x66, 0x55, 0xf6, + 0x7f, 0x89, 0x46, 0x2f, 0xf1, 0x97, 0x09, 0x56, 0x9b, 0xe5, 0x36, 0x7f, 0x4d, 0x60, 0x94, 0x86, + 0x1f, 0xc2, 0xe8, 0x63, 0x88, 0x1e, 0x61, 0x0c, 0xc7, 0x2e, 0x09, 0x02, 0x1e, 0x46, 0x09, 0xbf, + 0x8c, 0xd2, 0xd0, 0x43, 0x06, 0x7e, 0x0c, 0x93, 0x15, 0x61, 0x31, 0xe5, 0x94, 0xb1, 0x88, 0x21, + 0x13, 0x9f, 0x01, 0x8e, 0xa9, 0x9b, 0x32, 0x3f, 0xb9, 0xe1, 0xd7, 0x7e, 0x14, 0x90, 0xc4, 0x8f, + 0x42, 0x74, 0x80, 0x8f, 0x01, 0xa2, 0x6b, 0xca, 0xf8, 0x55, 0x1a, 0x25, 0x04, 0x0d, 0xf0, 0x53, + 0x38, 0x61, 0xf4, 0x2a, 0xa5, 0x71, 0xc2, 0x93, 0x28, 0xe2, 0x01, 0x61, 0xef, 0x29, 0x1a, 0xe2, + 0x67, 0xf0, 0xc4, 0x25, 0x2b, 0xb2, 0xf4, 0x83, 0xa6, 0x80, 0xe7, 0xc7, 0x64, 0x19, 0x50, 0x0f, + 0x1d, 0xe2, 0x53, 0x40, 0x97, 0x94, 0x24, 0x29, 0xa3, 0x7b, 0x77, 0xd4, 0xe0, 0x97, 0xc4, 0xe3, + 0x5d, 0x25, 0x34, 0x6e, 0xf0, 0x8c, 0xc6, 0xab, 0x28, 0x8c, 0x69, 0xaf, 0xae, 0x85, 0x8f, 0xc0, + 0x72, 0x49, 0xe8, 0xd2, 0xa0, 0xc9, 0x03, 0x8c, 0xc0, 0x66, 0x74, 0x15, 0x90, 0x9b, 0xae, 0xef, + 0x49, 0xd3, 0x8f, 0x47, 0x89, 0x17, 0xf8, 0x21, 0xe5, 0xf4, 0x93, 0x4b, 0xa9, 0x47, 0x3d, 0x64, + 0xcf, 0xfe, 0x18, 0x30, 0x66, 0x72, 0x57, 0xa9, 0x72, 0x27, 0xf1, 0x73, 0x18, 0xeb, 0x4e, 0x3b, + 0xc6, 0xd4, 0x98, 0xdb, 0xec, 0x3e, 0xc6, 0xe7, 0x60, 0xc9, 0x1f, 0x99, 0xac, 0x9a, 0x75, 0xb5, + 0x23, 0xb5, 0xd9, 0xde, 0xc0, 0x3e, 0x9c, 0x88, 0xfd, 0x3a, 0xb9, 0x6c, 0x06, 0xec, 0x1c, 0x4c, + 0x8d, 0xf9, 0xe4, 0xcd, 0xf9, 0xa2, 0x77, 0x87, 0x0f, 0x77, 0xce, 0x90, 0x78, 0x78, 0x05, 0xaf, + 0xe0, 0xf8, 0xab, 0xb8, 0x15, 0x7c, 0x4f, 0x1b, 0xb4, 0xb4, 0xa3, 0xc6, 0xa5, 0xf7, 0xc4, 0xd7, + 0x60, 0xe9, 0x2a, 0xeb, 0x48, 0xc3, 0x96, 0x74, 0xda, 0x27, 0xdd, 0x1d, 0x07, 0x1b, 0xeb, 0x4e, + 0x2d, 0xed, 0xcf, 0xbd, 0x07, 0xf0, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0xd1, 0x0f, 0x22, 0x4f, + 0x03, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto new file mode 100644 index 000000000000..f21763a4e239 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto @@ -0,0 +1,44 @@ +syntax = "proto2"; +option go_package = "remote_api"; + +package remote_api; + +message Request { + required string service_name = 2; + required string method = 3; + required bytes request = 4; + optional string request_id = 5; +} + +message ApplicationError { + required int32 code = 1; + required string detail = 2; +} + +message RpcError { + enum ErrorCode { + UNKNOWN = 0; + CALL_NOT_FOUND = 1; + PARSE_ERROR = 2; + SECURITY_VIOLATION = 3; + OVER_QUOTA = 4; + REQUEST_TOO_LARGE = 5; + CAPABILITY_DISABLED = 6; + FEATURE_DISABLED = 7; + BAD_REQUEST = 8; + RESPONSE_TOO_LARGE = 9; + CANCELLED = 10; + REPLAY_ERROR = 11; + DEADLINE_EXCEEDED = 12; + } + required int32 code = 1; + optional string detail = 2; +} + +message Response { + optional bytes response = 1; + optional bytes exception = 2; + optional ApplicationError application_error = 3; + optional bytes java_exception = 4; + optional RpcError rpc_error = 5; +} diff --git a/vendor/google.golang.org/appengine/internal/transaction.go b/vendor/google.golang.org/appengine/internal/transaction.go new file mode 100644 index 000000000000..9006ae65380a --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/transaction.go @@ -0,0 +1,115 @@ +// Copyright 2014 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package internal + +// This file implements hooks for applying datastore transactions. + +import ( + "errors" + "reflect" + + "github.com/golang/protobuf/proto" + netcontext "golang.org/x/net/context" + + basepb "google.golang.org/appengine/internal/base" + pb "google.golang.org/appengine/internal/datastore" +) + +var transactionSetters = make(map[reflect.Type]reflect.Value) + +// RegisterTransactionSetter registers a function that sets transaction information +// in a protocol buffer message. f should be a function with two arguments, +// the first being a protocol buffer type, and the second being *datastore.Transaction. +func RegisterTransactionSetter(f interface{}) { + v := reflect.ValueOf(f) + transactionSetters[v.Type().In(0)] = v +} + +// applyTransaction applies the transaction t to message pb +// by using the relevant setter passed to RegisterTransactionSetter. +func applyTransaction(pb proto.Message, t *pb.Transaction) { + v := reflect.ValueOf(pb) + if f, ok := transactionSetters[v.Type()]; ok { + f.Call([]reflect.Value{v, reflect.ValueOf(t)}) + } +} + +var transactionKey = "used for *Transaction" + +func transactionFromContext(ctx netcontext.Context) *transaction { + t, _ := ctx.Value(&transactionKey).(*transaction) + return t +} + +func withTransaction(ctx netcontext.Context, t *transaction) netcontext.Context { + return netcontext.WithValue(ctx, &transactionKey, t) +} + +type transaction struct { + transaction pb.Transaction + finished bool +} + +var ErrConcurrentTransaction = errors.New("internal: concurrent transaction") + +func RunTransactionOnce(c netcontext.Context, f func(netcontext.Context) error, xg bool, readOnly bool, previousTransaction *pb.Transaction) (*pb.Transaction, error) { + if transactionFromContext(c) != nil { + return nil, errors.New("nested transactions are not supported") + } + + // Begin the transaction. + t := &transaction{} + req := &pb.BeginTransactionRequest{ + App: proto.String(FullyQualifiedAppID(c)), + } + if xg { + req.AllowMultipleEg = proto.Bool(true) + } + if previousTransaction != nil { + req.PreviousTransaction = previousTransaction + } + if readOnly { + req.Mode = pb.BeginTransactionRequest_READ_ONLY.Enum() + } else { + req.Mode = pb.BeginTransactionRequest_READ_WRITE.Enum() + } + if err := Call(c, "datastore_v3", "BeginTransaction", req, &t.transaction); err != nil { + return nil, err + } + + // Call f, rolling back the transaction if f returns a non-nil error, or panics. + // The panic is not recovered. + defer func() { + if t.finished { + return + } + t.finished = true + // Ignore the error return value, since we are already returning a non-nil + // error (or we're panicking). + Call(c, "datastore_v3", "Rollback", &t.transaction, &basepb.VoidProto{}) + }() + if err := f(withTransaction(c, t)); err != nil { + return &t.transaction, err + } + t.finished = true + + // Commit the transaction. + res := &pb.CommitResponse{} + err := Call(c, "datastore_v3", "Commit", &t.transaction, res) + if ae, ok := err.(*APIError); ok { + /* TODO: restore this conditional + if appengine.IsDevAppServer() { + */ + // The Python Dev AppServer raises an ApplicationError with error code 2 (which is + // Error.CONCURRENT_TRANSACTION) and message "Concurrency exception.". + if ae.Code == int32(pb.Error_BAD_REQUEST) && ae.Detail == "ApplicationError: 2 Concurrency exception." { + return &t.transaction, ErrConcurrentTransaction + } + if ae.Code == int32(pb.Error_CONCURRENT_TRANSACTION) { + return &t.transaction, ErrConcurrentTransaction + } + } + return &t.transaction, err +} diff --git a/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go new file mode 100644 index 000000000000..5f727750adc7 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go @@ -0,0 +1,527 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto + +package urlfetch + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type URLFetchServiceError_ErrorCode int32 + +const ( + URLFetchServiceError_OK URLFetchServiceError_ErrorCode = 0 + URLFetchServiceError_INVALID_URL URLFetchServiceError_ErrorCode = 1 + URLFetchServiceError_FETCH_ERROR URLFetchServiceError_ErrorCode = 2 + URLFetchServiceError_UNSPECIFIED_ERROR URLFetchServiceError_ErrorCode = 3 + URLFetchServiceError_RESPONSE_TOO_LARGE URLFetchServiceError_ErrorCode = 4 + URLFetchServiceError_DEADLINE_EXCEEDED URLFetchServiceError_ErrorCode = 5 + URLFetchServiceError_SSL_CERTIFICATE_ERROR URLFetchServiceError_ErrorCode = 6 + URLFetchServiceError_DNS_ERROR URLFetchServiceError_ErrorCode = 7 + URLFetchServiceError_CLOSED URLFetchServiceError_ErrorCode = 8 + URLFetchServiceError_INTERNAL_TRANSIENT_ERROR URLFetchServiceError_ErrorCode = 9 + URLFetchServiceError_TOO_MANY_REDIRECTS URLFetchServiceError_ErrorCode = 10 + URLFetchServiceError_MALFORMED_REPLY URLFetchServiceError_ErrorCode = 11 + URLFetchServiceError_CONNECTION_ERROR URLFetchServiceError_ErrorCode = 12 +) + +var URLFetchServiceError_ErrorCode_name = map[int32]string{ + 0: "OK", + 1: "INVALID_URL", + 2: "FETCH_ERROR", + 3: "UNSPECIFIED_ERROR", + 4: "RESPONSE_TOO_LARGE", + 5: "DEADLINE_EXCEEDED", + 6: "SSL_CERTIFICATE_ERROR", + 7: "DNS_ERROR", + 8: "CLOSED", + 9: "INTERNAL_TRANSIENT_ERROR", + 10: "TOO_MANY_REDIRECTS", + 11: "MALFORMED_REPLY", + 12: "CONNECTION_ERROR", +} +var URLFetchServiceError_ErrorCode_value = map[string]int32{ + "OK": 0, + "INVALID_URL": 1, + "FETCH_ERROR": 2, + "UNSPECIFIED_ERROR": 3, + "RESPONSE_TOO_LARGE": 4, + "DEADLINE_EXCEEDED": 5, + "SSL_CERTIFICATE_ERROR": 6, + "DNS_ERROR": 7, + "CLOSED": 8, + "INTERNAL_TRANSIENT_ERROR": 9, + "TOO_MANY_REDIRECTS": 10, + "MALFORMED_REPLY": 11, + "CONNECTION_ERROR": 12, +} + +func (x URLFetchServiceError_ErrorCode) Enum() *URLFetchServiceError_ErrorCode { + p := new(URLFetchServiceError_ErrorCode) + *p = x + return p +} +func (x URLFetchServiceError_ErrorCode) String() string { + return proto.EnumName(URLFetchServiceError_ErrorCode_name, int32(x)) +} +func (x *URLFetchServiceError_ErrorCode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(URLFetchServiceError_ErrorCode_value, data, "URLFetchServiceError_ErrorCode") + if err != nil { + return err + } + *x = URLFetchServiceError_ErrorCode(value) + return nil +} +func (URLFetchServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{0, 0} +} + +type URLFetchRequest_RequestMethod int32 + +const ( + URLFetchRequest_GET URLFetchRequest_RequestMethod = 1 + URLFetchRequest_POST URLFetchRequest_RequestMethod = 2 + URLFetchRequest_HEAD URLFetchRequest_RequestMethod = 3 + URLFetchRequest_PUT URLFetchRequest_RequestMethod = 4 + URLFetchRequest_DELETE URLFetchRequest_RequestMethod = 5 + URLFetchRequest_PATCH URLFetchRequest_RequestMethod = 6 +) + +var URLFetchRequest_RequestMethod_name = map[int32]string{ + 1: "GET", + 2: "POST", + 3: "HEAD", + 4: "PUT", + 5: "DELETE", + 6: "PATCH", +} +var URLFetchRequest_RequestMethod_value = map[string]int32{ + "GET": 1, + "POST": 2, + "HEAD": 3, + "PUT": 4, + "DELETE": 5, + "PATCH": 6, +} + +func (x URLFetchRequest_RequestMethod) Enum() *URLFetchRequest_RequestMethod { + p := new(URLFetchRequest_RequestMethod) + *p = x + return p +} +func (x URLFetchRequest_RequestMethod) String() string { + return proto.EnumName(URLFetchRequest_RequestMethod_name, int32(x)) +} +func (x *URLFetchRequest_RequestMethod) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(URLFetchRequest_RequestMethod_value, data, "URLFetchRequest_RequestMethod") + if err != nil { + return err + } + *x = URLFetchRequest_RequestMethod(value) + return nil +} +func (URLFetchRequest_RequestMethod) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1, 0} +} + +type URLFetchServiceError struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *URLFetchServiceError) Reset() { *m = URLFetchServiceError{} } +func (m *URLFetchServiceError) String() string { return proto.CompactTextString(m) } +func (*URLFetchServiceError) ProtoMessage() {} +func (*URLFetchServiceError) Descriptor() ([]byte, []int) { + return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{0} +} +func (m *URLFetchServiceError) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_URLFetchServiceError.Unmarshal(m, b) +} +func (m *URLFetchServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_URLFetchServiceError.Marshal(b, m, deterministic) +} +func (dst *URLFetchServiceError) XXX_Merge(src proto.Message) { + xxx_messageInfo_URLFetchServiceError.Merge(dst, src) +} +func (m *URLFetchServiceError) XXX_Size() int { + return xxx_messageInfo_URLFetchServiceError.Size(m) +} +func (m *URLFetchServiceError) XXX_DiscardUnknown() { + xxx_messageInfo_URLFetchServiceError.DiscardUnknown(m) +} + +var xxx_messageInfo_URLFetchServiceError proto.InternalMessageInfo + +type URLFetchRequest struct { + Method *URLFetchRequest_RequestMethod `protobuf:"varint,1,req,name=Method,enum=appengine.URLFetchRequest_RequestMethod" json:"Method,omitempty"` + Url *string `protobuf:"bytes,2,req,name=Url" json:"Url,omitempty"` + Header []*URLFetchRequest_Header `protobuf:"group,3,rep,name=Header,json=header" json:"header,omitempty"` + Payload []byte `protobuf:"bytes,6,opt,name=Payload" json:"Payload,omitempty"` + FollowRedirects *bool `protobuf:"varint,7,opt,name=FollowRedirects,def=1" json:"FollowRedirects,omitempty"` + Deadline *float64 `protobuf:"fixed64,8,opt,name=Deadline" json:"Deadline,omitempty"` + MustValidateServerCertificate *bool `protobuf:"varint,9,opt,name=MustValidateServerCertificate,def=1" json:"MustValidateServerCertificate,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *URLFetchRequest) Reset() { *m = URLFetchRequest{} } +func (m *URLFetchRequest) String() string { return proto.CompactTextString(m) } +func (*URLFetchRequest) ProtoMessage() {} +func (*URLFetchRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1} +} +func (m *URLFetchRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_URLFetchRequest.Unmarshal(m, b) +} +func (m *URLFetchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_URLFetchRequest.Marshal(b, m, deterministic) +} +func (dst *URLFetchRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_URLFetchRequest.Merge(dst, src) +} +func (m *URLFetchRequest) XXX_Size() int { + return xxx_messageInfo_URLFetchRequest.Size(m) +} +func (m *URLFetchRequest) XXX_DiscardUnknown() { + xxx_messageInfo_URLFetchRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_URLFetchRequest proto.InternalMessageInfo + +const Default_URLFetchRequest_FollowRedirects bool = true +const Default_URLFetchRequest_MustValidateServerCertificate bool = true + +func (m *URLFetchRequest) GetMethod() URLFetchRequest_RequestMethod { + if m != nil && m.Method != nil { + return *m.Method + } + return URLFetchRequest_GET +} + +func (m *URLFetchRequest) GetUrl() string { + if m != nil && m.Url != nil { + return *m.Url + } + return "" +} + +func (m *URLFetchRequest) GetHeader() []*URLFetchRequest_Header { + if m != nil { + return m.Header + } + return nil +} + +func (m *URLFetchRequest) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *URLFetchRequest) GetFollowRedirects() bool { + if m != nil && m.FollowRedirects != nil { + return *m.FollowRedirects + } + return Default_URLFetchRequest_FollowRedirects +} + +func (m *URLFetchRequest) GetDeadline() float64 { + if m != nil && m.Deadline != nil { + return *m.Deadline + } + return 0 +} + +func (m *URLFetchRequest) GetMustValidateServerCertificate() bool { + if m != nil && m.MustValidateServerCertificate != nil { + return *m.MustValidateServerCertificate + } + return Default_URLFetchRequest_MustValidateServerCertificate +} + +type URLFetchRequest_Header struct { + Key *string `protobuf:"bytes,4,req,name=Key" json:"Key,omitempty"` + Value *string `protobuf:"bytes,5,req,name=Value" json:"Value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *URLFetchRequest_Header) Reset() { *m = URLFetchRequest_Header{} } +func (m *URLFetchRequest_Header) String() string { return proto.CompactTextString(m) } +func (*URLFetchRequest_Header) ProtoMessage() {} +func (*URLFetchRequest_Header) Descriptor() ([]byte, []int) { + return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1, 0} +} +func (m *URLFetchRequest_Header) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_URLFetchRequest_Header.Unmarshal(m, b) +} +func (m *URLFetchRequest_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_URLFetchRequest_Header.Marshal(b, m, deterministic) +} +func (dst *URLFetchRequest_Header) XXX_Merge(src proto.Message) { + xxx_messageInfo_URLFetchRequest_Header.Merge(dst, src) +} +func (m *URLFetchRequest_Header) XXX_Size() int { + return xxx_messageInfo_URLFetchRequest_Header.Size(m) +} +func (m *URLFetchRequest_Header) XXX_DiscardUnknown() { + xxx_messageInfo_URLFetchRequest_Header.DiscardUnknown(m) +} + +var xxx_messageInfo_URLFetchRequest_Header proto.InternalMessageInfo + +func (m *URLFetchRequest_Header) GetKey() string { + if m != nil && m.Key != nil { + return *m.Key + } + return "" +} + +func (m *URLFetchRequest_Header) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +type URLFetchResponse struct { + Content []byte `protobuf:"bytes,1,opt,name=Content" json:"Content,omitempty"` + StatusCode *int32 `protobuf:"varint,2,req,name=StatusCode" json:"StatusCode,omitempty"` + Header []*URLFetchResponse_Header `protobuf:"group,3,rep,name=Header,json=header" json:"header,omitempty"` + ContentWasTruncated *bool `protobuf:"varint,6,opt,name=ContentWasTruncated,def=0" json:"ContentWasTruncated,omitempty"` + ExternalBytesSent *int64 `protobuf:"varint,7,opt,name=ExternalBytesSent" json:"ExternalBytesSent,omitempty"` + ExternalBytesReceived *int64 `protobuf:"varint,8,opt,name=ExternalBytesReceived" json:"ExternalBytesReceived,omitempty"` + FinalUrl *string `protobuf:"bytes,9,opt,name=FinalUrl" json:"FinalUrl,omitempty"` + ApiCpuMilliseconds *int64 `protobuf:"varint,10,opt,name=ApiCpuMilliseconds,def=0" json:"ApiCpuMilliseconds,omitempty"` + ApiBytesSent *int64 `protobuf:"varint,11,opt,name=ApiBytesSent,def=0" json:"ApiBytesSent,omitempty"` + ApiBytesReceived *int64 `protobuf:"varint,12,opt,name=ApiBytesReceived,def=0" json:"ApiBytesReceived,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *URLFetchResponse) Reset() { *m = URLFetchResponse{} } +func (m *URLFetchResponse) String() string { return proto.CompactTextString(m) } +func (*URLFetchResponse) ProtoMessage() {} +func (*URLFetchResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{2} +} +func (m *URLFetchResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_URLFetchResponse.Unmarshal(m, b) +} +func (m *URLFetchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_URLFetchResponse.Marshal(b, m, deterministic) +} +func (dst *URLFetchResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_URLFetchResponse.Merge(dst, src) +} +func (m *URLFetchResponse) XXX_Size() int { + return xxx_messageInfo_URLFetchResponse.Size(m) +} +func (m *URLFetchResponse) XXX_DiscardUnknown() { + xxx_messageInfo_URLFetchResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_URLFetchResponse proto.InternalMessageInfo + +const Default_URLFetchResponse_ContentWasTruncated bool = false +const Default_URLFetchResponse_ApiCpuMilliseconds int64 = 0 +const Default_URLFetchResponse_ApiBytesSent int64 = 0 +const Default_URLFetchResponse_ApiBytesReceived int64 = 0 + +func (m *URLFetchResponse) GetContent() []byte { + if m != nil { + return m.Content + } + return nil +} + +func (m *URLFetchResponse) GetStatusCode() int32 { + if m != nil && m.StatusCode != nil { + return *m.StatusCode + } + return 0 +} + +func (m *URLFetchResponse) GetHeader() []*URLFetchResponse_Header { + if m != nil { + return m.Header + } + return nil +} + +func (m *URLFetchResponse) GetContentWasTruncated() bool { + if m != nil && m.ContentWasTruncated != nil { + return *m.ContentWasTruncated + } + return Default_URLFetchResponse_ContentWasTruncated +} + +func (m *URLFetchResponse) GetExternalBytesSent() int64 { + if m != nil && m.ExternalBytesSent != nil { + return *m.ExternalBytesSent + } + return 0 +} + +func (m *URLFetchResponse) GetExternalBytesReceived() int64 { + if m != nil && m.ExternalBytesReceived != nil { + return *m.ExternalBytesReceived + } + return 0 +} + +func (m *URLFetchResponse) GetFinalUrl() string { + if m != nil && m.FinalUrl != nil { + return *m.FinalUrl + } + return "" +} + +func (m *URLFetchResponse) GetApiCpuMilliseconds() int64 { + if m != nil && m.ApiCpuMilliseconds != nil { + return *m.ApiCpuMilliseconds + } + return Default_URLFetchResponse_ApiCpuMilliseconds +} + +func (m *URLFetchResponse) GetApiBytesSent() int64 { + if m != nil && m.ApiBytesSent != nil { + return *m.ApiBytesSent + } + return Default_URLFetchResponse_ApiBytesSent +} + +func (m *URLFetchResponse) GetApiBytesReceived() int64 { + if m != nil && m.ApiBytesReceived != nil { + return *m.ApiBytesReceived + } + return Default_URLFetchResponse_ApiBytesReceived +} + +type URLFetchResponse_Header struct { + Key *string `protobuf:"bytes,4,req,name=Key" json:"Key,omitempty"` + Value *string `protobuf:"bytes,5,req,name=Value" json:"Value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *URLFetchResponse_Header) Reset() { *m = URLFetchResponse_Header{} } +func (m *URLFetchResponse_Header) String() string { return proto.CompactTextString(m) } +func (*URLFetchResponse_Header) ProtoMessage() {} +func (*URLFetchResponse_Header) Descriptor() ([]byte, []int) { + return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{2, 0} +} +func (m *URLFetchResponse_Header) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_URLFetchResponse_Header.Unmarshal(m, b) +} +func (m *URLFetchResponse_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_URLFetchResponse_Header.Marshal(b, m, deterministic) +} +func (dst *URLFetchResponse_Header) XXX_Merge(src proto.Message) { + xxx_messageInfo_URLFetchResponse_Header.Merge(dst, src) +} +func (m *URLFetchResponse_Header) XXX_Size() int { + return xxx_messageInfo_URLFetchResponse_Header.Size(m) +} +func (m *URLFetchResponse_Header) XXX_DiscardUnknown() { + xxx_messageInfo_URLFetchResponse_Header.DiscardUnknown(m) +} + +var xxx_messageInfo_URLFetchResponse_Header proto.InternalMessageInfo + +func (m *URLFetchResponse_Header) GetKey() string { + if m != nil && m.Key != nil { + return *m.Key + } + return "" +} + +func (m *URLFetchResponse_Header) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +func init() { + proto.RegisterType((*URLFetchServiceError)(nil), "appengine.URLFetchServiceError") + proto.RegisterType((*URLFetchRequest)(nil), "appengine.URLFetchRequest") + proto.RegisterType((*URLFetchRequest_Header)(nil), "appengine.URLFetchRequest.Header") + proto.RegisterType((*URLFetchResponse)(nil), "appengine.URLFetchResponse") + proto.RegisterType((*URLFetchResponse_Header)(nil), "appengine.URLFetchResponse.Header") +} + +func init() { + proto.RegisterFile("google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto", fileDescriptor_urlfetch_service_b245a7065f33bced) +} + +var fileDescriptor_urlfetch_service_b245a7065f33bced = []byte{ + // 770 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6e, 0xe3, 0x54, + 0x10, 0xc6, 0x76, 0x7e, 0xa7, 0x5d, 0x7a, 0x76, 0xb6, 0x45, 0x66, 0xb5, 0xa0, 0x10, 0x09, 0x29, + 0x17, 0x90, 0x2e, 0x2b, 0x24, 0x44, 0xaf, 0x70, 0xed, 0x93, 0xad, 0xa9, 0x63, 0x47, 0xc7, 0x4e, + 0x61, 0xb9, 0xb1, 0xac, 0x78, 0x9a, 0x5a, 0xb2, 0xec, 0x60, 0x9f, 0x2c, 0xf4, 0x35, 0x78, 0x0d, + 0xde, 0x87, 0xa7, 0xe1, 0x02, 0x9d, 0xc4, 0xc9, 0x6e, 0xbb, 0xd1, 0x4a, 0x5c, 0x65, 0xe6, 0x9b, + 0xef, 0xcc, 0x99, 0x7c, 0xdf, 0xf8, 0x80, 0xb3, 0x2c, 0xcb, 0x65, 0x4e, 0xe3, 0x65, 0x99, 0x27, + 0xc5, 0x72, 0x5c, 0x56, 0xcb, 0xf3, 0x64, 0xb5, 0xa2, 0x62, 0x99, 0x15, 0x74, 0x9e, 0x15, 0x92, + 0xaa, 0x22, 0xc9, 0xcf, 0xd7, 0x55, 0x7e, 0x4b, 0x72, 0x71, 0xb7, 0x0f, 0xe2, 0x9a, 0xaa, 0xb7, + 0xd9, 0x82, 0xc6, 0xab, 0xaa, 0x94, 0x25, 0xf6, 0xf7, 0x67, 0x86, 0x7f, 0xeb, 0x70, 0x3a, 0x17, + 0xde, 0x44, 0xb1, 0xc2, 0x2d, 0x89, 0x57, 0x55, 0x59, 0x0d, 0xff, 0xd2, 0xa1, 0xbf, 0x89, 0xec, + 0x32, 0x25, 0xec, 0x80, 0x1e, 0x5c, 0xb3, 0x4f, 0xf0, 0x04, 0x8e, 0x5c, 0xff, 0xc6, 0xf2, 0x5c, + 0x27, 0x9e, 0x0b, 0x8f, 0x69, 0x0a, 0x98, 0xf0, 0xc8, 0xbe, 0x8a, 0xb9, 0x10, 0x81, 0x60, 0x3a, + 0x9e, 0xc1, 0xd3, 0xb9, 0x1f, 0xce, 0xb8, 0xed, 0x4e, 0x5c, 0xee, 0x34, 0xb0, 0x81, 0x9f, 0x01, + 0x0a, 0x1e, 0xce, 0x02, 0x3f, 0xe4, 0x71, 0x14, 0x04, 0xb1, 0x67, 0x89, 0xd7, 0x9c, 0xb5, 0x14, + 0xdd, 0xe1, 0x96, 0xe3, 0xb9, 0x3e, 0x8f, 0xf9, 0xaf, 0x36, 0xe7, 0x0e, 0x77, 0x58, 0x1b, 0x3f, + 0x87, 0xb3, 0x30, 0xf4, 0x62, 0x9b, 0x8b, 0xc8, 0x9d, 0xb8, 0xb6, 0x15, 0xf1, 0xa6, 0x53, 0x07, + 0x9f, 0x40, 0xdf, 0xf1, 0xc3, 0x26, 0xed, 0x22, 0x40, 0xc7, 0xf6, 0x82, 0x90, 0x3b, 0xac, 0x87, + 0x2f, 0xc0, 0x74, 0xfd, 0x88, 0x0b, 0xdf, 0xf2, 0xe2, 0x48, 0x58, 0x7e, 0xe8, 0x72, 0x3f, 0x6a, + 0x98, 0x7d, 0x35, 0x82, 0xba, 0x79, 0x6a, 0xf9, 0x6f, 0x62, 0xc1, 0x1d, 0x57, 0x70, 0x3b, 0x0a, + 0x19, 0xe0, 0x33, 0x38, 0x99, 0x5a, 0xde, 0x24, 0x10, 0x53, 0xee, 0xc4, 0x82, 0xcf, 0xbc, 0x37, + 0xec, 0x08, 0x4f, 0x81, 0xd9, 0x81, 0xef, 0x73, 0x3b, 0x72, 0x03, 0xbf, 0x69, 0x71, 0x3c, 0xfc, + 0xc7, 0x80, 0x93, 0x9d, 0x5a, 0x82, 0x7e, 0x5f, 0x53, 0x2d, 0xf1, 0x27, 0xe8, 0x4c, 0x49, 0xde, + 0x95, 0xa9, 0xa9, 0x0d, 0xf4, 0xd1, 0xa7, 0xaf, 0x46, 0xe3, 0xbd, 0xba, 0xe3, 0x47, 0xdc, 0x71, + 0xf3, 0xbb, 0xe5, 0x8b, 0xe6, 0x1c, 0x32, 0x30, 0xe6, 0x55, 0x6e, 0xea, 0x03, 0x7d, 0xd4, 0x17, + 0x2a, 0xc4, 0x1f, 0xa1, 0x73, 0x47, 0x49, 0x4a, 0x95, 0x69, 0x0c, 0x8c, 0x11, 0xbc, 0xfa, 0xea, + 0x23, 0x3d, 0xaf, 0x36, 0x44, 0xd1, 0x1c, 0xc0, 0x17, 0xd0, 0x9d, 0x25, 0xf7, 0x79, 0x99, 0xa4, + 0x66, 0x67, 0xa0, 0x8d, 0x8e, 0x2f, 0xf5, 0x9e, 0x26, 0x76, 0x10, 0x8e, 0xe1, 0x64, 0x52, 0xe6, + 0x79, 0xf9, 0x87, 0xa0, 0x34, 0xab, 0x68, 0x21, 0x6b, 0xb3, 0x3b, 0xd0, 0x46, 0xbd, 0x8b, 0x96, + 0xac, 0xd6, 0x24, 0x1e, 0x17, 0xf1, 0x39, 0xf4, 0x1c, 0x4a, 0xd2, 0x3c, 0x2b, 0xc8, 0xec, 0x0d, + 0xb4, 0x91, 0x26, 0xf6, 0x39, 0xfe, 0x0c, 0x5f, 0x4c, 0xd7, 0xb5, 0xbc, 0x49, 0xf2, 0x2c, 0x4d, + 0x24, 0xa9, 0xed, 0xa1, 0xca, 0xa6, 0x4a, 0x66, 0xb7, 0xd9, 0x22, 0x91, 0x64, 0xf6, 0xdf, 0xeb, + 0xfc, 0x71, 0xea, 0xf3, 0x97, 0xd0, 0xd9, 0xfe, 0x0f, 0x25, 0xc6, 0x35, 0xdd, 0x9b, 0xad, 0xad, + 0x18, 0xd7, 0x74, 0x8f, 0xa7, 0xd0, 0xbe, 0x49, 0xf2, 0x35, 0x99, 0xed, 0x0d, 0xb6, 0x4d, 0x86, + 0x1e, 0x3c, 0x79, 0xa0, 0x26, 0x76, 0xc1, 0x78, 0xcd, 0x23, 0xa6, 0x61, 0x0f, 0x5a, 0xb3, 0x20, + 0x8c, 0x98, 0xae, 0xa2, 0x2b, 0x6e, 0x39, 0xcc, 0x50, 0xc5, 0xd9, 0x3c, 0x62, 0x2d, 0xb5, 0x2e, + 0x0e, 0xf7, 0x78, 0xc4, 0x59, 0x1b, 0xfb, 0xd0, 0x9e, 0x59, 0x91, 0x7d, 0xc5, 0x3a, 0xc3, 0x7f, + 0x0d, 0x60, 0xef, 0x84, 0xad, 0x57, 0x65, 0x51, 0x13, 0x9a, 0xd0, 0xb5, 0xcb, 0x42, 0x52, 0x21, + 0x4d, 0x4d, 0x49, 0x29, 0x76, 0x29, 0x7e, 0x09, 0x10, 0xca, 0x44, 0xae, 0x6b, 0xf5, 0x71, 0x6c, + 0x8c, 0x6b, 0x8b, 0xf7, 0x10, 0xbc, 0x78, 0xe4, 0xdf, 0xf0, 0xa0, 0x7f, 0xdb, 0x6b, 0x1e, 0x1b, + 0xf8, 0x03, 0x3c, 0x6b, 0xae, 0xf9, 0x25, 0xa9, 0xa3, 0x6a, 0x5d, 0x28, 0x81, 0xb6, 0x66, 0xf6, + 0x2e, 0xda, 0xb7, 0x49, 0x5e, 0x93, 0x38, 0xc4, 0xc0, 0x6f, 0xe0, 0x29, 0xff, 0x73, 0xfb, 0x02, + 0x5c, 0xde, 0x4b, 0xaa, 0x43, 0x35, 0xb8, 0x72, 0xd7, 0x10, 0x1f, 0x16, 0xf0, 0x7b, 0x38, 0x7b, + 0x00, 0x0a, 0x5a, 0x50, 0xf6, 0x96, 0xd2, 0x8d, 0xcd, 0x86, 0x38, 0x5c, 0x54, 0xfb, 0x30, 0xc9, + 0x8a, 0x24, 0x57, 0xfb, 0xaa, 0xec, 0xed, 0x8b, 0x7d, 0x8e, 0xdf, 0x01, 0x5a, 0xab, 0xcc, 0x5e, + 0xad, 0xa7, 0x59, 0x9e, 0x67, 0x35, 0x2d, 0xca, 0x22, 0xad, 0x4d, 0x50, 0xed, 0x2e, 0xb4, 0x97, + 0xe2, 0x40, 0x11, 0xbf, 0x86, 0x63, 0x6b, 0x95, 0xbd, 0x9b, 0xf6, 0x68, 0x47, 0x7e, 0x00, 0xe3, + 0xb7, 0xc0, 0x76, 0xf9, 0x7e, 0xcc, 0xe3, 0x1d, 0xf5, 0x83, 0xd2, 0xff, 0x5f, 0xa6, 0x4b, 0xf8, + 0xad, 0xb7, 0x7b, 0x2a, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x9f, 0x6d, 0x24, 0x63, 0x05, + 0x00, 0x00, +} diff --git a/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto new file mode 100644 index 000000000000..f695edf6a907 --- /dev/null +++ b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto @@ -0,0 +1,64 @@ +syntax = "proto2"; +option go_package = "urlfetch"; + +package appengine; + +message URLFetchServiceError { + enum ErrorCode { + OK = 0; + INVALID_URL = 1; + FETCH_ERROR = 2; + UNSPECIFIED_ERROR = 3; + RESPONSE_TOO_LARGE = 4; + DEADLINE_EXCEEDED = 5; + SSL_CERTIFICATE_ERROR = 6; + DNS_ERROR = 7; + CLOSED = 8; + INTERNAL_TRANSIENT_ERROR = 9; + TOO_MANY_REDIRECTS = 10; + MALFORMED_REPLY = 11; + CONNECTION_ERROR = 12; + } +} + +message URLFetchRequest { + enum RequestMethod { + GET = 1; + POST = 2; + HEAD = 3; + PUT = 4; + DELETE = 5; + PATCH = 6; + } + required RequestMethod Method = 1; + required string Url = 2; + repeated group Header = 3 { + required string Key = 4; + required string Value = 5; + } + optional bytes Payload = 6 [ctype=CORD]; + + optional bool FollowRedirects = 7 [default=true]; + + optional double Deadline = 8; + + optional bool MustValidateServerCertificate = 9 [default=true]; +} + +message URLFetchResponse { + optional bytes Content = 1; + required int32 StatusCode = 2; + repeated group Header = 3 { + required string Key = 4; + required string Value = 5; + } + optional bool ContentWasTruncated = 6 [default=false]; + optional int64 ExternalBytesSent = 7; + optional int64 ExternalBytesReceived = 8; + + optional string FinalUrl = 9; + + optional int64 ApiCpuMilliseconds = 10 [default=0]; + optional int64 ApiBytesSent = 11 [default=0]; + optional int64 ApiBytesReceived = 12 [default=0]; +} diff --git a/vendor/google.golang.org/appengine/namespace.go b/vendor/google.golang.org/appengine/namespace.go new file mode 100644 index 000000000000..21860ca08227 --- /dev/null +++ b/vendor/google.golang.org/appengine/namespace.go @@ -0,0 +1,25 @@ +// Copyright 2012 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package appengine + +import ( + "fmt" + "regexp" + + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" +) + +// Namespace returns a replacement context that operates within the given namespace. +func Namespace(c context.Context, namespace string) (context.Context, error) { + if !validNamespace.MatchString(namespace) { + return nil, fmt.Errorf("appengine: namespace %q does not match /%s/", namespace, validNamespace) + } + return internal.NamespacedContext(c, namespace), nil +} + +// validNamespace matches valid namespace names. +var validNamespace = regexp.MustCompile(`^[0-9A-Za-z._-]{0,100}$`) diff --git a/vendor/google.golang.org/appengine/timeout.go b/vendor/google.golang.org/appengine/timeout.go new file mode 100644 index 000000000000..05642a992a39 --- /dev/null +++ b/vendor/google.golang.org/appengine/timeout.go @@ -0,0 +1,20 @@ +// Copyright 2013 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package appengine + +import "golang.org/x/net/context" + +// IsTimeoutError reports whether err is a timeout error. +func IsTimeoutError(err error) bool { + if err == context.DeadlineExceeded { + return true + } + if t, ok := err.(interface { + IsTimeout() bool + }); ok { + return t.IsTimeout() + } + return false +} diff --git a/vendor/google.golang.org/appengine/travis_install.sh b/vendor/google.golang.org/appengine/travis_install.sh new file mode 100644 index 000000000000..785b62f46e8e --- /dev/null +++ b/vendor/google.golang.org/appengine/travis_install.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +if [[ $GO111MODULE == "on" ]]; then + go get . +else + go get -u -v $(go list -f '{{join .Imports "\n"}}{{"\n"}}{{join .TestImports "\n"}}' ./... | sort | uniq | grep -v appengine) +fi + +if [[ $GOAPP == "true" ]]; then + mkdir /tmp/sdk + curl -o /tmp/sdk.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.68.zip" + unzip -q /tmp/sdk.zip -d /tmp/sdk + # NOTE: Set the following env vars in the test script: + # export PATH="$PATH:/tmp/sdk/go_appengine" + # export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py +fi + diff --git a/vendor/google.golang.org/appengine/travis_test.sh b/vendor/google.golang.org/appengine/travis_test.sh new file mode 100644 index 000000000000..d4390f045b6a --- /dev/null +++ b/vendor/google.golang.org/appengine/travis_test.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +go version +go test -v google.golang.org/appengine/... +go test -v -race google.golang.org/appengine/... +if [[ $GOAPP == "true" ]]; then + export PATH="$PATH:/tmp/sdk/go_appengine" + export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py + goapp version + goapp test -v google.golang.org/appengine/... +fi diff --git a/vendor/google.golang.org/appengine/urlfetch/urlfetch.go b/vendor/google.golang.org/appengine/urlfetch/urlfetch.go new file mode 100644 index 000000000000..6ffe1e6d901a --- /dev/null +++ b/vendor/google.golang.org/appengine/urlfetch/urlfetch.go @@ -0,0 +1,210 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// Package urlfetch provides an http.RoundTripper implementation +// for fetching URLs via App Engine's urlfetch service. +package urlfetch // import "google.golang.org/appengine/urlfetch" + +import ( + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + + "google.golang.org/appengine/internal" + pb "google.golang.org/appengine/internal/urlfetch" +) + +// Transport is an implementation of http.RoundTripper for +// App Engine. Users should generally create an http.Client using +// this transport and use the Client rather than using this transport +// directly. +type Transport struct { + Context context.Context + + // Controls whether the application checks the validity of SSL certificates + // over HTTPS connections. A value of false (the default) instructs the + // application to send a request to the server only if the certificate is + // valid and signed by a trusted certificate authority (CA), and also + // includes a hostname that matches the certificate. A value of true + // instructs the application to perform no certificate validation. + AllowInvalidServerCertificate bool +} + +// Verify statically that *Transport implements http.RoundTripper. +var _ http.RoundTripper = (*Transport)(nil) + +// Client returns an *http.Client using a default urlfetch Transport. This +// client will have the default deadline of 5 seconds, and will check the +// validity of SSL certificates. +// +// Any deadline of the provided context will be used for requests through this client; +// if the client does not have a deadline then a 5 second default is used. +func Client(ctx context.Context) *http.Client { + return &http.Client{ + Transport: &Transport{ + Context: ctx, + }, + } +} + +type bodyReader struct { + content []byte + truncated bool + closed bool +} + +// ErrTruncatedBody is the error returned after the final Read() from a +// response's Body if the body has been truncated by App Engine's proxy. +var ErrTruncatedBody = errors.New("urlfetch: truncated body") + +func statusCodeToText(code int) string { + if t := http.StatusText(code); t != "" { + return t + } + return strconv.Itoa(code) +} + +func (br *bodyReader) Read(p []byte) (n int, err error) { + if br.closed { + if br.truncated { + return 0, ErrTruncatedBody + } + return 0, io.EOF + } + n = copy(p, br.content) + if n > 0 { + br.content = br.content[n:] + return + } + if br.truncated { + br.closed = true + return 0, ErrTruncatedBody + } + return 0, io.EOF +} + +func (br *bodyReader) Close() error { + br.closed = true + br.content = nil + return nil +} + +// A map of the URL Fetch-accepted methods that take a request body. +var methodAcceptsRequestBody = map[string]bool{ + "POST": true, + "PUT": true, + "PATCH": true, +} + +// urlString returns a valid string given a URL. This function is necessary because +// the String method of URL doesn't correctly handle URLs with non-empty Opaque values. +// See http://code.google.com/p/go/issues/detail?id=4860. +func urlString(u *url.URL) string { + if u.Opaque == "" || strings.HasPrefix(u.Opaque, "//") { + return u.String() + } + aux := *u + aux.Opaque = "//" + aux.Host + aux.Opaque + return aux.String() +} + +// RoundTrip issues a single HTTP request and returns its response. Per the +// http.RoundTripper interface, RoundTrip only returns an error if there +// was an unsupported request or the URL Fetch proxy fails. +// Note that HTTP response codes such as 5xx, 403, 404, etc are not +// errors as far as the transport is concerned and will be returned +// with err set to nil. +func (t *Transport) RoundTrip(req *http.Request) (res *http.Response, err error) { + methNum, ok := pb.URLFetchRequest_RequestMethod_value[req.Method] + if !ok { + return nil, fmt.Errorf("urlfetch: unsupported HTTP method %q", req.Method) + } + + method := pb.URLFetchRequest_RequestMethod(methNum) + + freq := &pb.URLFetchRequest{ + Method: &method, + Url: proto.String(urlString(req.URL)), + FollowRedirects: proto.Bool(false), // http.Client's responsibility + MustValidateServerCertificate: proto.Bool(!t.AllowInvalidServerCertificate), + } + if deadline, ok := t.Context.Deadline(); ok { + freq.Deadline = proto.Float64(deadline.Sub(time.Now()).Seconds()) + } + + for k, vals := range req.Header { + for _, val := range vals { + freq.Header = append(freq.Header, &pb.URLFetchRequest_Header{ + Key: proto.String(k), + Value: proto.String(val), + }) + } + } + if methodAcceptsRequestBody[req.Method] && req.Body != nil { + // Avoid a []byte copy if req.Body has a Bytes method. + switch b := req.Body.(type) { + case interface { + Bytes() []byte + }: + freq.Payload = b.Bytes() + default: + freq.Payload, err = ioutil.ReadAll(req.Body) + if err != nil { + return nil, err + } + } + } + + fres := &pb.URLFetchResponse{} + if err := internal.Call(t.Context, "urlfetch", "Fetch", freq, fres); err != nil { + return nil, err + } + + res = &http.Response{} + res.StatusCode = int(*fres.StatusCode) + res.Status = fmt.Sprintf("%d %s", res.StatusCode, statusCodeToText(res.StatusCode)) + res.Header = make(http.Header) + res.Request = req + + // Faked: + res.ProtoMajor = 1 + res.ProtoMinor = 1 + res.Proto = "HTTP/1.1" + res.Close = true + + for _, h := range fres.Header { + hkey := http.CanonicalHeaderKey(*h.Key) + hval := *h.Value + if hkey == "Content-Length" { + // Will get filled in below for all but HEAD requests. + if req.Method == "HEAD" { + res.ContentLength, _ = strconv.ParseInt(hval, 10, 64) + } + continue + } + res.Header.Add(hkey, hval) + } + + if req.Method != "HEAD" { + res.ContentLength = int64(len(fres.Content)) + } + + truncated := fres.GetContentWasTruncated() + res.Body = &bodyReader{content: fres.Content, truncated: truncated} + return +} + +func init() { + internal.RegisterErrorCodeMap("urlfetch", pb.URLFetchServiceError_ErrorCode_name) + internal.RegisterTimeoutErrorCode("urlfetch", int32(pb.URLFetchServiceError_DEADLINE_EXCEEDED)) +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/annotations.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/annotations.pb.go new file mode 100644 index 000000000000..9521b50e9e87 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/annotations.pb.go @@ -0,0 +1,54 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/annotations.proto + +package annotations // import "google.golang.org/genproto/googleapis/api/annotations" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +var E_Http = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MethodOptions)(nil), + ExtensionType: (*HttpRule)(nil), + Field: 72295728, + Name: "google.api.http", + Tag: "bytes,72295728,opt,name=http", + Filename: "google/api/annotations.proto", +} + +func init() { + proto.RegisterExtension(E_Http) +} + +func init() { + proto.RegisterFile("google/api/annotations.proto", fileDescriptor_annotations_55609bb51d80951d) +} + +var fileDescriptor_annotations_55609bb51d80951d = []byte{ + // 208 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0xcf, 0xcf, 0x4f, + 0xcf, 0x49, 0xd5, 0x4f, 0x2c, 0xc8, 0xd4, 0x4f, 0xcc, 0xcb, 0xcb, 0x2f, 0x49, 0x2c, 0xc9, 0xcc, + 0xcf, 0x2b, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x82, 0xc8, 0xea, 0x25, 0x16, 0x64, + 0x4a, 0x89, 0x22, 0xa9, 0xcc, 0x28, 0x29, 0x29, 0x80, 0x28, 0x91, 0x52, 0x80, 0x0a, 0x83, 0x79, + 0x49, 0xa5, 0x69, 0xfa, 0x29, 0xa9, 0xc5, 0xc9, 0x45, 0x99, 0x05, 0x25, 0xf9, 0x45, 0x10, 0x15, + 0x56, 0xde, 0x5c, 0x2c, 0x20, 0xf5, 0x42, 0x72, 0x7a, 0x50, 0xd3, 0x60, 0x4a, 0xf5, 0x7c, 0x53, + 0x4b, 0x32, 0xf2, 0x53, 0xfc, 0x0b, 0xc0, 0x56, 0x4a, 0x6c, 0x38, 0xb5, 0x47, 0x49, 0x81, 0x51, + 0x83, 0xdb, 0x48, 0x44, 0x0f, 0x61, 0xad, 0x9e, 0x47, 0x49, 0x49, 0x41, 0x50, 0x69, 0x4e, 0x6a, + 0x10, 0xd8, 0x10, 0xa7, 0x3c, 0x2e, 0xbe, 0xe4, 0xfc, 0x5c, 0x24, 0x05, 0x4e, 0x02, 0x8e, 0x08, + 0x67, 0x07, 0x80, 0x4c, 0x0e, 0x60, 0x8c, 0x72, 0x84, 0xca, 0xa7, 0xe7, 0xe7, 0x24, 0xe6, 0xa5, + 0xeb, 0xe5, 0x17, 0xa5, 0xeb, 0xa7, 0xa7, 0xe6, 0x81, 0xed, 0xd5, 0x87, 0x48, 0x25, 0x16, 0x64, + 0x16, 0xa3, 0x7b, 0xda, 0x1a, 0x89, 0xbd, 0x88, 0x89, 0xc5, 0xdd, 0x31, 0xc0, 0x33, 0x89, 0x0d, + 0xac, 0xc9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xe3, 0x29, 0x19, 0x62, 0x28, 0x01, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go new file mode 100644 index 000000000000..d64b32280f0c --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go @@ -0,0 +1,76 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/client.proto + +package annotations // import "google.golang.org/genproto/googleapis/api/annotations" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +var E_MethodSignature = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.MethodOptions)(nil), + ExtensionType: ([]string)(nil), + Field: 1051, + Name: "google.api.method_signature", + Tag: "bytes,1051,rep,name=method_signature,json=methodSignature", + Filename: "google/api/client.proto", +} + +var E_DefaultHost = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.ServiceOptions)(nil), + ExtensionType: (*string)(nil), + Field: 1049, + Name: "google.api.default_host", + Tag: "bytes,1049,opt,name=default_host,json=defaultHost", + Filename: "google/api/client.proto", +} + +var E_OauthScopes = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.ServiceOptions)(nil), + ExtensionType: (*string)(nil), + Field: 1050, + Name: "google.api.oauth_scopes", + Tag: "bytes,1050,opt,name=oauth_scopes,json=oauthScopes", + Filename: "google/api/client.proto", +} + +func init() { + proto.RegisterExtension(E_MethodSignature) + proto.RegisterExtension(E_DefaultHost) + proto.RegisterExtension(E_OauthScopes) +} + +func init() { proto.RegisterFile("google/api/client.proto", fileDescriptor_client_1608614df476619f) } + +var fileDescriptor_client_1608614df476619f = []byte{ + // 262 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x90, 0x3f, 0x4f, 0xc3, 0x30, + 0x10, 0xc5, 0x55, 0x40, 0xa8, 0x75, 0x11, 0xa0, 0x2c, 0x20, 0x06, 0xc8, 0xd8, 0xc9, 0x1e, 0xd8, + 0xca, 0xd4, 0x76, 0xe0, 0x8f, 0x84, 0x88, 0x9a, 0x8d, 0x25, 0x72, 0x9d, 0xab, 0x63, 0x29, 0xf5, + 0x59, 0xf6, 0x85, 0xef, 0x02, 0x6c, 0x7c, 0x52, 0x54, 0xc7, 0x11, 0x48, 0x0c, 0x6c, 0x27, 0xbd, + 0xf7, 0xfb, 0x9d, 0xf4, 0xd8, 0x85, 0x46, 0xd4, 0x2d, 0x08, 0xe9, 0x8c, 0x50, 0xad, 0x01, 0x4b, + 0xdc, 0x79, 0x24, 0xcc, 0x58, 0x1f, 0x70, 0xe9, 0xcc, 0x55, 0x9e, 0x4a, 0x31, 0xd9, 0x74, 0x5b, + 0x51, 0x43, 0x50, 0xde, 0x38, 0x42, 0xdf, 0xb7, 0xe7, 0x4f, 0xec, 0x7c, 0x07, 0xd4, 0x60, 0x5d, + 0x05, 0xa3, 0xad, 0xa4, 0xce, 0x43, 0x76, 0xcd, 0x93, 0x62, 0xc0, 0xf8, 0x73, 0xac, 0xbc, 0x38, + 0x32, 0x68, 0xc3, 0xe5, 0xe7, 0x38, 0x3f, 0x9c, 0x4d, 0xd6, 0x67, 0x3d, 0x58, 0x0e, 0xdc, 0x7c, + 0xc5, 0x4e, 0x6a, 0xd8, 0xca, 0xae, 0xa5, 0xaa, 0xc1, 0x40, 0xd9, 0xcd, 0x1f, 0x4f, 0x09, 0xfe, + 0xcd, 0x28, 0x18, 0x44, 0xef, 0xe3, 0x7c, 0x34, 0x9b, 0xac, 0xa7, 0x89, 0x7a, 0xc0, 0x40, 0x7b, + 0x09, 0xca, 0x8e, 0x9a, 0x2a, 0x28, 0x74, 0x10, 0xfe, 0x97, 0x7c, 0x24, 0x49, 0xa4, 0xca, 0x08, + 0x2d, 0x0d, 0x3b, 0x55, 0xb8, 0xe3, 0x3f, 0x4b, 0x2c, 0xa7, 0xab, 0xb8, 0x51, 0xb1, 0x97, 0x14, + 0xa3, 0xd7, 0x45, 0x8a, 0x34, 0xb6, 0xd2, 0x6a, 0x8e, 0x5e, 0x0b, 0x0d, 0x36, 0xbe, 0x10, 0x7d, + 0x24, 0x9d, 0x09, 0x71, 0x5c, 0x69, 0x2d, 0x92, 0x8c, 0xbf, 0xee, 0x7e, 0xdd, 0x5f, 0x07, 0x47, + 0xf7, 0x8b, 0xe2, 0x71, 0x73, 0x1c, 0xa1, 0xdb, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xc2, + 0xcf, 0x71, 0x90, 0x01, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/field_behavior.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/field_behavior.pb.go new file mode 100644 index 000000000000..9a9ab1242fea --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/field_behavior.pb.go @@ -0,0 +1,119 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/field_behavior.proto + +package annotations // import "google.golang.org/genproto/googleapis/api/annotations" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// An indicator of the behavior of a given field (for example, that a field +// is required in requests, or given as output but ignored as input). +// This **does not** change the behavior in protocol buffers itself; it only +// denotes the behavior and may affect how API tooling handles the field. +// +// Note: This enum **may** receive new values in the future. +type FieldBehavior int32 + +const ( + // Conventional default for enums. Do not use this. + FieldBehavior_FIELD_BEHAVIOR_UNSPECIFIED FieldBehavior = 0 + // Specifically denotes a field as optional. + // While all fields in protocol buffers are optional, this may be specified + // for emphasis if appropriate. + FieldBehavior_OPTIONAL FieldBehavior = 1 + // Denotes a field as required. + // This indicates that the field **must** be provided as part of the request, + // and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + FieldBehavior_REQUIRED FieldBehavior = 2 + // Denotes a field as output only. + // This indicates that the field is provided in responses, but including the + // field in a request does nothing (the server *must* ignore it and + // *must not* throw an error as a result of the field's presence). + FieldBehavior_OUTPUT_ONLY FieldBehavior = 3 + // Denotes a field as input only. + // This indicates that the field is provided in requests, and the + // corresponding field is not included in output. + FieldBehavior_INPUT_ONLY FieldBehavior = 4 + // Denotes a field as immutable. + // This indicates that the field may be set once in a request to create a + // resource, but may not be changed thereafter. + FieldBehavior_IMMUTABLE FieldBehavior = 5 +) + +var FieldBehavior_name = map[int32]string{ + 0: "FIELD_BEHAVIOR_UNSPECIFIED", + 1: "OPTIONAL", + 2: "REQUIRED", + 3: "OUTPUT_ONLY", + 4: "INPUT_ONLY", + 5: "IMMUTABLE", +} +var FieldBehavior_value = map[string]int32{ + "FIELD_BEHAVIOR_UNSPECIFIED": 0, + "OPTIONAL": 1, + "REQUIRED": 2, + "OUTPUT_ONLY": 3, + "INPUT_ONLY": 4, + "IMMUTABLE": 5, +} + +func (x FieldBehavior) String() string { + return proto.EnumName(FieldBehavior_name, int32(x)) +} +func (FieldBehavior) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_field_behavior_ddf5c982f789c6a3, []int{0} +} + +var E_FieldBehavior = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: ([]FieldBehavior)(nil), + Field: 1052, + Name: "google.api.field_behavior", + Tag: "varint,1052,rep,name=field_behavior,json=fieldBehavior,enum=google.api.FieldBehavior", + Filename: "google/api/field_behavior.proto", +} + +func init() { + proto.RegisterEnum("google.api.FieldBehavior", FieldBehavior_name, FieldBehavior_value) + proto.RegisterExtension(E_FieldBehavior) +} + +func init() { + proto.RegisterFile("google/api/field_behavior.proto", fileDescriptor_field_behavior_ddf5c982f789c6a3) +} + +var fileDescriptor_field_behavior_ddf5c982f789c6a3 = []byte{ + // 303 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0x4f, 0x4f, 0xb3, 0x30, + 0x1c, 0xc7, 0x9f, 0xfd, 0x79, 0xcc, 0xac, 0x0e, 0x49, 0x4f, 0xba, 0x44, 0xdd, 0xd1, 0x78, 0x28, + 0x89, 0xde, 0xf4, 0x04, 0xae, 0xd3, 0x26, 0x8c, 0x56, 0x04, 0x13, 0xbd, 0x60, 0xb7, 0xb1, 0xda, + 0x64, 0xd2, 0x06, 0xd0, 0x8b, 0x6f, 0xc5, 0x93, 0xaf, 0xd4, 0xd0, 0x31, 0x85, 0x5b, 0xbf, 0xf9, + 0x7d, 0xfa, 0xeb, 0xe7, 0x5b, 0x70, 0x2a, 0x94, 0x12, 0xeb, 0xd4, 0xe1, 0x5a, 0x3a, 0x2b, 0x99, + 0xae, 0x97, 0xc9, 0x3c, 0x7d, 0xe5, 0x1f, 0x52, 0xe5, 0x48, 0xe7, 0xaa, 0x54, 0x10, 0x6c, 0x00, + 0xc4, 0xb5, 0x1c, 0x8d, 0x6b, 0xd8, 0x4c, 0xe6, 0xef, 0x2b, 0x67, 0x99, 0x16, 0x8b, 0x5c, 0xea, + 0x72, 0x4b, 0x9f, 0x7f, 0x82, 0xe1, 0xb4, 0xda, 0xe2, 0xd5, 0x4b, 0xe0, 0x09, 0x18, 0x4d, 0x09, + 0xf6, 0x27, 0x89, 0x87, 0xef, 0xdc, 0x47, 0x42, 0xc3, 0x24, 0x0e, 0x1e, 0x18, 0xbe, 0x21, 0x53, + 0x82, 0x27, 0xf6, 0x3f, 0xb8, 0x0f, 0x06, 0x94, 0x45, 0x84, 0x06, 0xae, 0x6f, 0x77, 0xaa, 0x14, + 0xe2, 0xfb, 0x98, 0x84, 0x78, 0x62, 0x77, 0xe1, 0x01, 0xd8, 0xa3, 0x71, 0xc4, 0xe2, 0x28, 0xa1, + 0x81, 0xff, 0x64, 0xf7, 0xa0, 0x05, 0x00, 0x09, 0x7e, 0x73, 0x1f, 0x0e, 0xc1, 0x2e, 0x99, 0xcd, + 0xe2, 0xc8, 0xf5, 0x7c, 0x6c, 0xff, 0xbf, 0x7a, 0x01, 0x56, 0xbb, 0x02, 0x3c, 0x46, 0xb5, 0xfd, + 0xd6, 0x18, 0x19, 0x3b, 0xaa, 0x4b, 0xa9, 0xb2, 0xe2, 0xf0, 0x6b, 0x30, 0xee, 0x9d, 0x59, 0x17, + 0x47, 0xe8, 0xaf, 0x23, 0x6a, 0xe9, 0x87, 0xc3, 0x55, 0x33, 0x7a, 0x1a, 0x58, 0x0b, 0xf5, 0xd6, + 0xc0, 0x3d, 0xd8, 0xe2, 0x59, 0xf5, 0x0c, 0xeb, 0x3c, 0xbb, 0x35, 0x21, 0xd4, 0x9a, 0x67, 0x02, + 0xa9, 0x5c, 0x38, 0x22, 0xcd, 0x8c, 0x84, 0xb3, 0x19, 0x71, 0x2d, 0x0b, 0xf3, 0xe9, 0x3c, 0xcb, + 0x54, 0xc9, 0x8d, 0xcf, 0x75, 0xe3, 0xfc, 0xdd, 0xed, 0xdf, 0xba, 0x8c, 0xcc, 0x77, 0xcc, 0xa5, + 0xcb, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x94, 0x57, 0x94, 0xa8, 0x01, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/http.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/http.pb.go new file mode 100644 index 000000000000..b4487662db2b --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/http.pb.go @@ -0,0 +1,749 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/http.proto + +package annotations // import "google.golang.org/genproto/googleapis/api/annotations" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +type Http struct { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + Rules []*HttpRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` + // When set to true, URL path parmeters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + FullyDecodeReservedExpansion bool `protobuf:"varint,2,opt,name=fully_decode_reserved_expansion,json=fullyDecodeReservedExpansion,proto3" json:"fully_decode_reserved_expansion,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Http) Reset() { *m = Http{} } +func (m *Http) String() string { return proto.CompactTextString(m) } +func (*Http) ProtoMessage() {} +func (*Http) Descriptor() ([]byte, []int) { + return fileDescriptor_http_6617e93ffeeff0ad, []int{0} +} +func (m *Http) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Http.Unmarshal(m, b) +} +func (m *Http) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Http.Marshal(b, m, deterministic) +} +func (dst *Http) XXX_Merge(src proto.Message) { + xxx_messageInfo_Http.Merge(dst, src) +} +func (m *Http) XXX_Size() int { + return xxx_messageInfo_Http.Size(m) +} +func (m *Http) XXX_DiscardUnknown() { + xxx_messageInfo_Http.DiscardUnknown(m) +} + +var xxx_messageInfo_Http proto.InternalMessageInfo + +func (m *Http) GetRules() []*HttpRule { + if m != nil { + return m.Rules + } + return nil +} + +func (m *Http) GetFullyDecodeReservedExpansion() bool { + if m != nil { + return m.FullyDecodeReservedExpansion + } + return false +} + +// # gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | +// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: +// "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: +// "123456")` +// +// ## Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They +// are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL +// query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP +// request body, all +// fields are passed via URL path and URL query parameters. +// +// ### Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// ## Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// Example: +// +// http: +// rules: +// # Selects a gRPC method and applies HttpRule to it. +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// ## Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +type HttpRule struct { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + Selector string `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"` + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + // + // Types that are valid to be assigned to Pattern: + // *HttpRule_Get + // *HttpRule_Put + // *HttpRule_Post + // *HttpRule_Delete + // *HttpRule_Patch + // *HttpRule_Custom + Pattern isHttpRule_Pattern `protobuf_oneof:"pattern"` + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + Body string `protobuf:"bytes,7,opt,name=body,proto3" json:"body,omitempty"` + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + ResponseBody string `protobuf:"bytes,12,opt,name=response_body,json=responseBody,proto3" json:"response_body,omitempty"` + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + AdditionalBindings []*HttpRule `protobuf:"bytes,11,rep,name=additional_bindings,json=additionalBindings,proto3" json:"additional_bindings,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HttpRule) Reset() { *m = HttpRule{} } +func (m *HttpRule) String() string { return proto.CompactTextString(m) } +func (*HttpRule) ProtoMessage() {} +func (*HttpRule) Descriptor() ([]byte, []int) { + return fileDescriptor_http_6617e93ffeeff0ad, []int{1} +} +func (m *HttpRule) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HttpRule.Unmarshal(m, b) +} +func (m *HttpRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HttpRule.Marshal(b, m, deterministic) +} +func (dst *HttpRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_HttpRule.Merge(dst, src) +} +func (m *HttpRule) XXX_Size() int { + return xxx_messageInfo_HttpRule.Size(m) +} +func (m *HttpRule) XXX_DiscardUnknown() { + xxx_messageInfo_HttpRule.DiscardUnknown(m) +} + +var xxx_messageInfo_HttpRule proto.InternalMessageInfo + +func (m *HttpRule) GetSelector() string { + if m != nil { + return m.Selector + } + return "" +} + +type isHttpRule_Pattern interface { + isHttpRule_Pattern() +} + +type HttpRule_Get struct { + Get string `protobuf:"bytes,2,opt,name=get,proto3,oneof"` +} + +type HttpRule_Put struct { + Put string `protobuf:"bytes,3,opt,name=put,proto3,oneof"` +} + +type HttpRule_Post struct { + Post string `protobuf:"bytes,4,opt,name=post,proto3,oneof"` +} + +type HttpRule_Delete struct { + Delete string `protobuf:"bytes,5,opt,name=delete,proto3,oneof"` +} + +type HttpRule_Patch struct { + Patch string `protobuf:"bytes,6,opt,name=patch,proto3,oneof"` +} + +type HttpRule_Custom struct { + Custom *CustomHttpPattern `protobuf:"bytes,8,opt,name=custom,proto3,oneof"` +} + +func (*HttpRule_Get) isHttpRule_Pattern() {} + +func (*HttpRule_Put) isHttpRule_Pattern() {} + +func (*HttpRule_Post) isHttpRule_Pattern() {} + +func (*HttpRule_Delete) isHttpRule_Pattern() {} + +func (*HttpRule_Patch) isHttpRule_Pattern() {} + +func (*HttpRule_Custom) isHttpRule_Pattern() {} + +func (m *HttpRule) GetPattern() isHttpRule_Pattern { + if m != nil { + return m.Pattern + } + return nil +} + +func (m *HttpRule) GetGet() string { + if x, ok := m.GetPattern().(*HttpRule_Get); ok { + return x.Get + } + return "" +} + +func (m *HttpRule) GetPut() string { + if x, ok := m.GetPattern().(*HttpRule_Put); ok { + return x.Put + } + return "" +} + +func (m *HttpRule) GetPost() string { + if x, ok := m.GetPattern().(*HttpRule_Post); ok { + return x.Post + } + return "" +} + +func (m *HttpRule) GetDelete() string { + if x, ok := m.GetPattern().(*HttpRule_Delete); ok { + return x.Delete + } + return "" +} + +func (m *HttpRule) GetPatch() string { + if x, ok := m.GetPattern().(*HttpRule_Patch); ok { + return x.Patch + } + return "" +} + +func (m *HttpRule) GetCustom() *CustomHttpPattern { + if x, ok := m.GetPattern().(*HttpRule_Custom); ok { + return x.Custom + } + return nil +} + +func (m *HttpRule) GetBody() string { + if m != nil { + return m.Body + } + return "" +} + +func (m *HttpRule) GetResponseBody() string { + if m != nil { + return m.ResponseBody + } + return "" +} + +func (m *HttpRule) GetAdditionalBindings() []*HttpRule { + if m != nil { + return m.AdditionalBindings + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*HttpRule) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _HttpRule_OneofMarshaler, _HttpRule_OneofUnmarshaler, _HttpRule_OneofSizer, []interface{}{ + (*HttpRule_Get)(nil), + (*HttpRule_Put)(nil), + (*HttpRule_Post)(nil), + (*HttpRule_Delete)(nil), + (*HttpRule_Patch)(nil), + (*HttpRule_Custom)(nil), + } +} + +func _HttpRule_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*HttpRule) + // pattern + switch x := m.Pattern.(type) { + case *HttpRule_Get: + b.EncodeVarint(2<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Get) + case *HttpRule_Put: + b.EncodeVarint(3<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Put) + case *HttpRule_Post: + b.EncodeVarint(4<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Post) + case *HttpRule_Delete: + b.EncodeVarint(5<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Delete) + case *HttpRule_Patch: + b.EncodeVarint(6<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Patch) + case *HttpRule_Custom: + b.EncodeVarint(8<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Custom); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("HttpRule.Pattern has unexpected type %T", x) + } + return nil +} + +func _HttpRule_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*HttpRule) + switch tag { + case 2: // pattern.get + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Pattern = &HttpRule_Get{x} + return true, err + case 3: // pattern.put + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Pattern = &HttpRule_Put{x} + return true, err + case 4: // pattern.post + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Pattern = &HttpRule_Post{x} + return true, err + case 5: // pattern.delete + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Pattern = &HttpRule_Delete{x} + return true, err + case 6: // pattern.patch + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Pattern = &HttpRule_Patch{x} + return true, err + case 8: // pattern.custom + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(CustomHttpPattern) + err := b.DecodeMessage(msg) + m.Pattern = &HttpRule_Custom{msg} + return true, err + default: + return false, nil + } +} + +func _HttpRule_OneofSizer(msg proto.Message) (n int) { + m := msg.(*HttpRule) + // pattern + switch x := m.Pattern.(type) { + case *HttpRule_Get: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.Get))) + n += len(x.Get) + case *HttpRule_Put: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.Put))) + n += len(x.Put) + case *HttpRule_Post: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.Post))) + n += len(x.Post) + case *HttpRule_Delete: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.Delete))) + n += len(x.Delete) + case *HttpRule_Patch: + n += 1 // tag and wire + n += proto.SizeVarint(uint64(len(x.Patch))) + n += len(x.Patch) + case *HttpRule_Custom: + s := proto.Size(x.Custom) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// A custom pattern is used for defining custom HTTP verb. +type CustomHttpPattern struct { + // The name of this custom HTTP verb. + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + // The path matched by this custom verb. + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CustomHttpPattern) Reset() { *m = CustomHttpPattern{} } +func (m *CustomHttpPattern) String() string { return proto.CompactTextString(m) } +func (*CustomHttpPattern) ProtoMessage() {} +func (*CustomHttpPattern) Descriptor() ([]byte, []int) { + return fileDescriptor_http_6617e93ffeeff0ad, []int{2} +} +func (m *CustomHttpPattern) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CustomHttpPattern.Unmarshal(m, b) +} +func (m *CustomHttpPattern) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CustomHttpPattern.Marshal(b, m, deterministic) +} +func (dst *CustomHttpPattern) XXX_Merge(src proto.Message) { + xxx_messageInfo_CustomHttpPattern.Merge(dst, src) +} +func (m *CustomHttpPattern) XXX_Size() int { + return xxx_messageInfo_CustomHttpPattern.Size(m) +} +func (m *CustomHttpPattern) XXX_DiscardUnknown() { + xxx_messageInfo_CustomHttpPattern.DiscardUnknown(m) +} + +var xxx_messageInfo_CustomHttpPattern proto.InternalMessageInfo + +func (m *CustomHttpPattern) GetKind() string { + if m != nil { + return m.Kind + } + return "" +} + +func (m *CustomHttpPattern) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func init() { + proto.RegisterType((*Http)(nil), "google.api.Http") + proto.RegisterType((*HttpRule)(nil), "google.api.HttpRule") + proto.RegisterType((*CustomHttpPattern)(nil), "google.api.CustomHttpPattern") +} + +func init() { proto.RegisterFile("google/api/http.proto", fileDescriptor_http_6617e93ffeeff0ad) } + +var fileDescriptor_http_6617e93ffeeff0ad = []byte{ + // 419 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xc1, 0x8e, 0xd3, 0x30, + 0x10, 0x86, 0x49, 0x9b, 0x76, 0xdb, 0xe9, 0x82, 0x84, 0x59, 0x90, 0x85, 0x40, 0x54, 0xe5, 0x52, + 0x71, 0x48, 0xa5, 0xe5, 0xc0, 0x61, 0x4f, 0x1b, 0xa8, 0x58, 0x6e, 0x55, 0x8e, 0x5c, 0x22, 0x37, + 0x1e, 0x52, 0x83, 0xd7, 0xb6, 0xe2, 0x09, 0xa2, 0xaf, 0xc3, 0x63, 0xf1, 0x24, 0x1c, 0x91, 0x9d, + 0x84, 0x56, 0x42, 0xe2, 0x36, 0xf3, 0xff, 0x9f, 0xa7, 0x7f, 0x27, 0x03, 0x4f, 0x6b, 0x6b, 0x6b, + 0x8d, 0x1b, 0xe1, 0xd4, 0xe6, 0x40, 0xe4, 0x32, 0xd7, 0x58, 0xb2, 0x0c, 0x3a, 0x39, 0x13, 0x4e, + 0xad, 0x8e, 0x90, 0xde, 0x11, 0x39, 0xf6, 0x06, 0x26, 0x4d, 0xab, 0xd1, 0xf3, 0x64, 0x39, 0x5e, + 0x2f, 0xae, 0xaf, 0xb2, 0x13, 0x93, 0x05, 0xa0, 0x68, 0x35, 0x16, 0x1d, 0xc2, 0xb6, 0xf0, 0xea, + 0x4b, 0xab, 0xf5, 0xb1, 0x94, 0x58, 0x59, 0x89, 0x65, 0x83, 0x1e, 0x9b, 0xef, 0x28, 0x4b, 0xfc, + 0xe1, 0x84, 0xf1, 0xca, 0x1a, 0x3e, 0x5a, 0x26, 0xeb, 0x59, 0xf1, 0x22, 0x62, 0x1f, 0x22, 0x55, + 0xf4, 0xd0, 0x76, 0x60, 0x56, 0xbf, 0x46, 0x30, 0x1b, 0x46, 0xb3, 0xe7, 0x30, 0xf3, 0xa8, 0xb1, + 0x22, 0xdb, 0xf0, 0x64, 0x99, 0xac, 0xe7, 0xc5, 0xdf, 0x9e, 0x31, 0x18, 0xd7, 0x48, 0x71, 0xe6, + 0xfc, 0xee, 0x41, 0x11, 0x9a, 0xa0, 0xb9, 0x96, 0xf8, 0x78, 0xd0, 0x5c, 0x4b, 0xec, 0x0a, 0x52, + 0x67, 0x3d, 0xf1, 0xb4, 0x17, 0x63, 0xc7, 0x38, 0x4c, 0x25, 0x6a, 0x24, 0xe4, 0x93, 0x5e, 0xef, + 0x7b, 0xf6, 0x0c, 0x26, 0x4e, 0x50, 0x75, 0xe0, 0xd3, 0xde, 0xe8, 0x5a, 0xf6, 0x0e, 0xa6, 0x55, + 0xeb, 0xc9, 0xde, 0xf3, 0xd9, 0x32, 0x59, 0x2f, 0xae, 0x5f, 0x9e, 0x2f, 0xe3, 0x7d, 0x74, 0x42, + 0xee, 0x9d, 0x20, 0xc2, 0xc6, 0x84, 0x81, 0x1d, 0xce, 0x18, 0xa4, 0x7b, 0x2b, 0x8f, 0xfc, 0x22, + 0xfe, 0x81, 0x58, 0xb3, 0xd7, 0xf0, 0xb0, 0x41, 0xef, 0xac, 0xf1, 0x58, 0x46, 0xf3, 0x32, 0x9a, + 0x97, 0x83, 0x98, 0x07, 0x68, 0x0b, 0x4f, 0x84, 0x94, 0x8a, 0x94, 0x35, 0x42, 0x97, 0x7b, 0x65, + 0xa4, 0x32, 0xb5, 0xe7, 0x8b, 0xff, 0x7c, 0x0b, 0x76, 0x7a, 0x90, 0xf7, 0x7c, 0x3e, 0x87, 0x0b, + 0xd7, 0x85, 0x5a, 0xdd, 0xc0, 0xe3, 0x7f, 0x92, 0x86, 0x7c, 0xdf, 0x94, 0x91, 0xfd, 0x82, 0x63, + 0x1d, 0x34, 0x27, 0xe8, 0xd0, 0x6d, 0xb7, 0x88, 0x75, 0xfe, 0x15, 0x1e, 0x55, 0xf6, 0xfe, 0xec, + 0x67, 0xf3, 0x79, 0x1c, 0x13, 0xae, 0x67, 0x97, 0x7c, 0xbe, 0xed, 0x8d, 0xda, 0x6a, 0x61, 0xea, + 0xcc, 0x36, 0xf5, 0xa6, 0x46, 0x13, 0x6f, 0x6b, 0xd3, 0x59, 0xc2, 0x29, 0x1f, 0xaf, 0x4e, 0x18, + 0x63, 0x49, 0x84, 0x98, 0xfe, 0xe6, 0xac, 0xfe, 0x9d, 0x24, 0x3f, 0x47, 0xe9, 0xc7, 0xdb, 0xdd, + 0xa7, 0xfd, 0x34, 0xbe, 0x7b, 0xfb, 0x27, 0x00, 0x00, 0xff, 0xff, 0xae, 0xde, 0xa1, 0xd0, 0xac, + 0x02, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/resource.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/resource.pb.go new file mode 100644 index 000000000000..a395f960cd5d --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/resource.pb.go @@ -0,0 +1,153 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/api/resource.proto + +package annotations // import "google.golang.org/genproto/googleapis/api/annotations" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// An annotation designating that this field designates a resource. +// +// Example: +// +// message Topic { +// string name = 1 [(google.api.resource) = { +// name: "projects/{project}/topics/{topic}" +// }]; +// } +type Resource struct { + // Required. The resource's name template. + // + // Examples: + // - "projects/{project}/topics/{topic}" + // - "projects/{project}/knowledgeBases/{knowledge_base}" + Pattern string `protobuf:"bytes,1,opt,name=pattern,proto3" json:"pattern,omitempty"` + // The name that should be used in code to describe the resource, + // in PascalCase. + // + // If omitted, this is inferred from the name of the message. + // This is required if the resource is being defined without the context + // of a message (see `resource_definition`, below). + // + // Example: + // option (google.api.resource_definition) = { + // pattern: "projects/{project}" + // symbol: "Project" + // }; + Symbol string `protobuf:"bytes,2,opt,name=symbol,proto3" json:"symbol,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Resource) Reset() { *m = Resource{} } +func (m *Resource) String() string { return proto.CompactTextString(m) } +func (*Resource) ProtoMessage() {} +func (*Resource) Descriptor() ([]byte, []int) { + return fileDescriptor_resource_232de5e6fd811932, []int{0} +} +func (m *Resource) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Resource.Unmarshal(m, b) +} +func (m *Resource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Resource.Marshal(b, m, deterministic) +} +func (dst *Resource) XXX_Merge(src proto.Message) { + xxx_messageInfo_Resource.Merge(dst, src) +} +func (m *Resource) XXX_Size() int { + return xxx_messageInfo_Resource.Size(m) +} +func (m *Resource) XXX_DiscardUnknown() { + xxx_messageInfo_Resource.DiscardUnknown(m) +} + +var xxx_messageInfo_Resource proto.InternalMessageInfo + +func (m *Resource) GetPattern() string { + if m != nil { + return m.Pattern + } + return "" +} + +func (m *Resource) GetSymbol() string { + if m != nil { + return m.Symbol + } + return "" +} + +var E_Resource = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*Resource)(nil), + Field: 1053, + Name: "google.api.resource", + Tag: "bytes,1053,opt,name=resource", + Filename: "google/api/resource.proto", +} + +var E_ResourceReference = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 1055, + Name: "google.api.resource_reference", + Tag: "bytes,1055,opt,name=resource_reference,json=resourceReference", + Filename: "google/api/resource.proto", +} + +var E_ResourceDefinition = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: ([]*Resource)(nil), + Field: 1053, + Name: "google.api.resource_definition", + Tag: "bytes,1053,rep,name=resource_definition,json=resourceDefinition", + Filename: "google/api/resource.proto", +} + +func init() { + proto.RegisterType((*Resource)(nil), "google.api.Resource") + proto.RegisterExtension(E_Resource) + proto.RegisterExtension(E_ResourceReference) + proto.RegisterExtension(E_ResourceDefinition) +} + +func init() { proto.RegisterFile("google/api/resource.proto", fileDescriptor_resource_232de5e6fd811932) } + +var fileDescriptor_resource_232de5e6fd811932 = []byte{ + // 334 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xc1, 0x4a, 0xeb, 0x40, + 0x18, 0x85, 0x49, 0xef, 0xa5, 0xcd, 0x9d, 0xab, 0x82, 0xa3, 0x48, 0x94, 0x16, 0x8a, 0xab, 0x2e, + 0x64, 0x06, 0x74, 0x57, 0xdd, 0xa4, 0x88, 0xe2, 0x42, 0x1a, 0xb2, 0x74, 0x23, 0xd3, 0x64, 0x3a, + 0x8c, 0xa4, 0xf3, 0x0f, 0x93, 0xe9, 0x42, 0x4b, 0x1f, 0x45, 0x04, 0x1f, 0xc3, 0x47, 0xea, 0x53, + 0x48, 0x27, 0x99, 0x98, 0x85, 0xe2, 0xee, 0x3f, 0x9c, 0x39, 0xe7, 0x3b, 0x81, 0xa0, 0x63, 0x01, + 0x20, 0x0a, 0x4e, 0x99, 0x96, 0xd4, 0xf0, 0x12, 0x96, 0x26, 0xe3, 0x44, 0x1b, 0xb0, 0x80, 0x51, + 0x65, 0x11, 0xa6, 0xe5, 0xc9, 0xb0, 0x7e, 0xe6, 0x9c, 0xd9, 0x72, 0x4e, 0x73, 0x5e, 0x66, 0x46, + 0x6a, 0x0b, 0xa6, 0x7a, 0x7d, 0x7a, 0x85, 0xc2, 0xb4, 0xce, 0xe3, 0x08, 0xf5, 0x34, 0xb3, 0x96, + 0x1b, 0x15, 0x05, 0xc3, 0x60, 0xf4, 0x2f, 0xf5, 0x12, 0x1f, 0xa1, 0x6e, 0xf9, 0xbc, 0x98, 0x41, + 0x11, 0x75, 0x9c, 0x51, 0xab, 0x71, 0x82, 0x42, 0x4f, 0xc7, 0x03, 0x52, 0x83, 0x3d, 0x8c, 0xdc, + 0x48, 0x5e, 0xe4, 0x53, 0x6d, 0x25, 0xa8, 0x32, 0x7a, 0x0d, 0x87, 0xc1, 0xe8, 0xff, 0xf9, 0x21, + 0xf9, 0x9a, 0x47, 0x3c, 0x39, 0x6d, 0x5a, 0xc6, 0xf7, 0x08, 0xfb, 0xfb, 0xd1, 0xf0, 0x39, 0x37, + 0x5c, 0xfd, 0xde, 0xfd, 0x16, 0xba, 0x55, 0xfb, 0x3e, 0x99, 0xfa, 0xe0, 0x38, 0x47, 0x07, 0x4d, + 0x5d, 0xce, 0xe7, 0x52, 0xc9, 0x6d, 0x02, 0xf7, 0xbf, 0xe9, 0x2b, 0x78, 0x6b, 0xea, 0x9f, 0x1f, + 0xa7, 0x36, 0xf3, 0xae, 0x9b, 0xba, 0xc9, 0x47, 0xb0, 0x89, 0x07, 0x08, 0x6b, 0x03, 0x4f, 0x3c, + 0xb3, 0x25, 0x5d, 0xd5, 0xd7, 0x1a, 0xf7, 0x92, 0xea, 0xda, 0xc4, 0x67, 0xa8, 0x0f, 0x46, 0x30, + 0x25, 0x5f, 0x98, 0xa3, 0xd0, 0x55, 0x5b, 0xae, 0xf1, 0xce, 0xb4, 0x25, 0xd1, 0x5e, 0x06, 0x8b, + 0x16, 0x7e, 0xb2, 0xeb, 0xf9, 0xc9, 0x76, 0x70, 0x12, 0x3c, 0xc4, 0xb5, 0x29, 0xa0, 0x60, 0x4a, + 0x10, 0x30, 0x82, 0x0a, 0xae, 0xdc, 0xe7, 0xd0, 0xca, 0x62, 0x5a, 0x96, 0xee, 0xff, 0x60, 0x4a, + 0x81, 0xad, 0xa0, 0x97, 0xad, 0xfb, 0xbd, 0xf3, 0xf7, 0x36, 0x4e, 0xee, 0x66, 0x5d, 0x17, 0xba, + 0xf8, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xcf, 0x7e, 0x96, 0xa2, 0x53, 0x02, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/iam/v1/iam_policy.pb.go b/vendor/google.golang.org/genproto/googleapis/iam/v1/iam_policy.pb.go new file mode 100644 index 000000000000..c2f676eceb75 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/iam/v1/iam_policy.pb.go @@ -0,0 +1,411 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/iam/v1/iam_policy.proto + +package iam // import "google.golang.org/genproto/googleapis/iam/v1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Request message for `SetIamPolicy` method. +type SetIamPolicyRequest struct { + // REQUIRED: The resource for which the policy is being specified. + // `resource` is usually specified as a path. For example, a Project + // resource is specified as `projects/{project}`. + Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` + // REQUIRED: The complete policy to be applied to the `resource`. The size of + // the policy is limited to a few 10s of KB. An empty policy is a + // valid policy but certain Cloud Platform services (such as Projects) + // might reject them. + Policy *Policy `protobuf:"bytes,2,opt,name=policy,proto3" json:"policy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetIamPolicyRequest) Reset() { *m = SetIamPolicyRequest{} } +func (m *SetIamPolicyRequest) String() string { return proto.CompactTextString(m) } +func (*SetIamPolicyRequest) ProtoMessage() {} +func (*SetIamPolicyRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_iam_policy_364532d533b79e88, []int{0} +} +func (m *SetIamPolicyRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetIamPolicyRequest.Unmarshal(m, b) +} +func (m *SetIamPolicyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetIamPolicyRequest.Marshal(b, m, deterministic) +} +func (dst *SetIamPolicyRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetIamPolicyRequest.Merge(dst, src) +} +func (m *SetIamPolicyRequest) XXX_Size() int { + return xxx_messageInfo_SetIamPolicyRequest.Size(m) +} +func (m *SetIamPolicyRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SetIamPolicyRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SetIamPolicyRequest proto.InternalMessageInfo + +func (m *SetIamPolicyRequest) GetResource() string { + if m != nil { + return m.Resource + } + return "" +} + +func (m *SetIamPolicyRequest) GetPolicy() *Policy { + if m != nil { + return m.Policy + } + return nil +} + +// Request message for `GetIamPolicy` method. +type GetIamPolicyRequest struct { + // REQUIRED: The resource for which the policy is being requested. + // `resource` is usually specified as a path. For example, a Project + // resource is specified as `projects/{project}`. + Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetIamPolicyRequest) Reset() { *m = GetIamPolicyRequest{} } +func (m *GetIamPolicyRequest) String() string { return proto.CompactTextString(m) } +func (*GetIamPolicyRequest) ProtoMessage() {} +func (*GetIamPolicyRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_iam_policy_364532d533b79e88, []int{1} +} +func (m *GetIamPolicyRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetIamPolicyRequest.Unmarshal(m, b) +} +func (m *GetIamPolicyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetIamPolicyRequest.Marshal(b, m, deterministic) +} +func (dst *GetIamPolicyRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetIamPolicyRequest.Merge(dst, src) +} +func (m *GetIamPolicyRequest) XXX_Size() int { + return xxx_messageInfo_GetIamPolicyRequest.Size(m) +} +func (m *GetIamPolicyRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetIamPolicyRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetIamPolicyRequest proto.InternalMessageInfo + +func (m *GetIamPolicyRequest) GetResource() string { + if m != nil { + return m.Resource + } + return "" +} + +// Request message for `TestIamPermissions` method. +type TestIamPermissionsRequest struct { + // REQUIRED: The resource for which the policy detail is being requested. + // `resource` is usually specified as a path. For example, a Project + // resource is specified as `projects/{project}`. + Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` + // The set of permissions to check for the `resource`. Permissions with + // wildcards (such as '*' or 'storage.*') are not allowed. For more + // information see + // [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions). + Permissions []string `protobuf:"bytes,2,rep,name=permissions,proto3" json:"permissions,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TestIamPermissionsRequest) Reset() { *m = TestIamPermissionsRequest{} } +func (m *TestIamPermissionsRequest) String() string { return proto.CompactTextString(m) } +func (*TestIamPermissionsRequest) ProtoMessage() {} +func (*TestIamPermissionsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_iam_policy_364532d533b79e88, []int{2} +} +func (m *TestIamPermissionsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TestIamPermissionsRequest.Unmarshal(m, b) +} +func (m *TestIamPermissionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TestIamPermissionsRequest.Marshal(b, m, deterministic) +} +func (dst *TestIamPermissionsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TestIamPermissionsRequest.Merge(dst, src) +} +func (m *TestIamPermissionsRequest) XXX_Size() int { + return xxx_messageInfo_TestIamPermissionsRequest.Size(m) +} +func (m *TestIamPermissionsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_TestIamPermissionsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_TestIamPermissionsRequest proto.InternalMessageInfo + +func (m *TestIamPermissionsRequest) GetResource() string { + if m != nil { + return m.Resource + } + return "" +} + +func (m *TestIamPermissionsRequest) GetPermissions() []string { + if m != nil { + return m.Permissions + } + return nil +} + +// Response message for `TestIamPermissions` method. +type TestIamPermissionsResponse struct { + // A subset of `TestPermissionsRequest.permissions` that the caller is + // allowed. + Permissions []string `protobuf:"bytes,1,rep,name=permissions,proto3" json:"permissions,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TestIamPermissionsResponse) Reset() { *m = TestIamPermissionsResponse{} } +func (m *TestIamPermissionsResponse) String() string { return proto.CompactTextString(m) } +func (*TestIamPermissionsResponse) ProtoMessage() {} +func (*TestIamPermissionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_iam_policy_364532d533b79e88, []int{3} +} +func (m *TestIamPermissionsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TestIamPermissionsResponse.Unmarshal(m, b) +} +func (m *TestIamPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TestIamPermissionsResponse.Marshal(b, m, deterministic) +} +func (dst *TestIamPermissionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TestIamPermissionsResponse.Merge(dst, src) +} +func (m *TestIamPermissionsResponse) XXX_Size() int { + return xxx_messageInfo_TestIamPermissionsResponse.Size(m) +} +func (m *TestIamPermissionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TestIamPermissionsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TestIamPermissionsResponse proto.InternalMessageInfo + +func (m *TestIamPermissionsResponse) GetPermissions() []string { + if m != nil { + return m.Permissions + } + return nil +} + +func init() { + proto.RegisterType((*SetIamPolicyRequest)(nil), "google.iam.v1.SetIamPolicyRequest") + proto.RegisterType((*GetIamPolicyRequest)(nil), "google.iam.v1.GetIamPolicyRequest") + proto.RegisterType((*TestIamPermissionsRequest)(nil), "google.iam.v1.TestIamPermissionsRequest") + proto.RegisterType((*TestIamPermissionsResponse)(nil), "google.iam.v1.TestIamPermissionsResponse") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// IAMPolicyClient is the client API for IAMPolicy service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type IAMPolicyClient interface { + // Sets the access control policy on the specified resource. Replaces any + // existing policy. + SetIamPolicy(ctx context.Context, in *SetIamPolicyRequest, opts ...grpc.CallOption) (*Policy, error) + // Gets the access control policy for a resource. + // Returns an empty policy if the resource exists and does not have a policy + // set. + GetIamPolicy(ctx context.Context, in *GetIamPolicyRequest, opts ...grpc.CallOption) (*Policy, error) + // Returns permissions that a caller has on the specified resource. + // If the resource does not exist, this will return an empty set of + // permissions, not a NOT_FOUND error. + TestIamPermissions(ctx context.Context, in *TestIamPermissionsRequest, opts ...grpc.CallOption) (*TestIamPermissionsResponse, error) +} + +type iAMPolicyClient struct { + cc *grpc.ClientConn +} + +func NewIAMPolicyClient(cc *grpc.ClientConn) IAMPolicyClient { + return &iAMPolicyClient{cc} +} + +func (c *iAMPolicyClient) SetIamPolicy(ctx context.Context, in *SetIamPolicyRequest, opts ...grpc.CallOption) (*Policy, error) { + out := new(Policy) + err := c.cc.Invoke(ctx, "/google.iam.v1.IAMPolicy/SetIamPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iAMPolicyClient) GetIamPolicy(ctx context.Context, in *GetIamPolicyRequest, opts ...grpc.CallOption) (*Policy, error) { + out := new(Policy) + err := c.cc.Invoke(ctx, "/google.iam.v1.IAMPolicy/GetIamPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *iAMPolicyClient) TestIamPermissions(ctx context.Context, in *TestIamPermissionsRequest, opts ...grpc.CallOption) (*TestIamPermissionsResponse, error) { + out := new(TestIamPermissionsResponse) + err := c.cc.Invoke(ctx, "/google.iam.v1.IAMPolicy/TestIamPermissions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// IAMPolicyServer is the server API for IAMPolicy service. +type IAMPolicyServer interface { + // Sets the access control policy on the specified resource. Replaces any + // existing policy. + SetIamPolicy(context.Context, *SetIamPolicyRequest) (*Policy, error) + // Gets the access control policy for a resource. + // Returns an empty policy if the resource exists and does not have a policy + // set. + GetIamPolicy(context.Context, *GetIamPolicyRequest) (*Policy, error) + // Returns permissions that a caller has on the specified resource. + // If the resource does not exist, this will return an empty set of + // permissions, not a NOT_FOUND error. + TestIamPermissions(context.Context, *TestIamPermissionsRequest) (*TestIamPermissionsResponse, error) +} + +func RegisterIAMPolicyServer(s *grpc.Server, srv IAMPolicyServer) { + s.RegisterService(&_IAMPolicy_serviceDesc, srv) +} + +func _IAMPolicy_SetIamPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetIamPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IAMPolicyServer).SetIamPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.iam.v1.IAMPolicy/SetIamPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IAMPolicyServer).SetIamPolicy(ctx, req.(*SetIamPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IAMPolicy_GetIamPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetIamPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IAMPolicyServer).GetIamPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.iam.v1.IAMPolicy/GetIamPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IAMPolicyServer).GetIamPolicy(ctx, req.(*GetIamPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _IAMPolicy_TestIamPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TestIamPermissionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IAMPolicyServer).TestIamPermissions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.iam.v1.IAMPolicy/TestIamPermissions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IAMPolicyServer).TestIamPermissions(ctx, req.(*TestIamPermissionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _IAMPolicy_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.iam.v1.IAMPolicy", + HandlerType: (*IAMPolicyServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SetIamPolicy", + Handler: _IAMPolicy_SetIamPolicy_Handler, + }, + { + MethodName: "GetIamPolicy", + Handler: _IAMPolicy_GetIamPolicy_Handler, + }, + { + MethodName: "TestIamPermissions", + Handler: _IAMPolicy_TestIamPermissions_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/iam/v1/iam_policy.proto", +} + +func init() { + proto.RegisterFile("google/iam/v1/iam_policy.proto", fileDescriptor_iam_policy_364532d533b79e88) +} + +var fileDescriptor_iam_policy_364532d533b79e88 = []byte{ + // 411 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f, + 0xcf, 0x49, 0xd5, 0xcf, 0x4c, 0xcc, 0xd5, 0x2f, 0x33, 0x04, 0x51, 0xf1, 0x05, 0xf9, 0x39, 0x99, + 0xc9, 0x95, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xbc, 0x10, 0x79, 0xbd, 0xcc, 0xc4, 0x5c, + 0xbd, 0x32, 0x43, 0x29, 0x19, 0xa8, 0xf2, 0xc4, 0x82, 0x4c, 0xfd, 0xc4, 0xbc, 0xbc, 0xfc, 0x92, + 0xc4, 0x92, 0xcc, 0xfc, 0xbc, 0x62, 0x88, 0x62, 0x29, 0x29, 0x54, 0xc3, 0x90, 0x0d, 0x52, 0x4a, + 0xe0, 0x12, 0x0e, 0x4e, 0x2d, 0xf1, 0x4c, 0xcc, 0x0d, 0x00, 0x8b, 0x06, 0xa5, 0x16, 0x96, 0xa6, + 0x16, 0x97, 0x08, 0x49, 0x71, 0x71, 0x14, 0xa5, 0x16, 0xe7, 0x97, 0x16, 0x25, 0xa7, 0x4a, 0x30, + 0x2a, 0x30, 0x6a, 0x70, 0x06, 0xc1, 0xf9, 0x42, 0xba, 0x5c, 0x6c, 0x10, 0x23, 0x24, 0x98, 0x14, + 0x18, 0x35, 0xb8, 0x8d, 0x44, 0xf5, 0x50, 0x1c, 0xa3, 0x07, 0x35, 0x09, 0xaa, 0x48, 0xc9, 0x90, + 0x4b, 0xd8, 0x9d, 0x34, 0x1b, 0x94, 0x22, 0xb9, 0x24, 0x43, 0x52, 0x8b, 0xc1, 0x7a, 0x52, 0x8b, + 0x72, 0x33, 0x8b, 0x8b, 0x41, 0x9e, 0x21, 0xc6, 0x69, 0x0a, 0x5c, 0xdc, 0x05, 0x08, 0x1d, 0x12, + 0x4c, 0x0a, 0xcc, 0x1a, 0x9c, 0x41, 0xc8, 0x42, 0x4a, 0x76, 0x5c, 0x52, 0xd8, 0x8c, 0x2e, 0x2e, + 0xc8, 0xcf, 0x2b, 0xc6, 0xd0, 0xcf, 0x88, 0xa1, 0xdf, 0x68, 0x0a, 0x33, 0x17, 0xa7, 0xa7, 0xa3, + 0x2f, 0xc4, 0x2f, 0x42, 0x25, 0x5c, 0x3c, 0xc8, 0xa1, 0x27, 0xa4, 0x84, 0x16, 0x14, 0x58, 0x82, + 0x56, 0x0a, 0x7b, 0x70, 0x29, 0x69, 0x36, 0x5d, 0x7e, 0x32, 0x99, 0x49, 0x59, 0x49, 0x0e, 0x14, + 0x45, 0xd5, 0x30, 0x1f, 0xd9, 0x6a, 0x69, 0xd5, 0x5a, 0x15, 0x23, 0x99, 0x62, 0xc5, 0xa8, 0x05, + 0xb2, 0xd5, 0x1d, 0x9f, 0xad, 0xee, 0x54, 0xb1, 0x35, 0x1d, 0xcd, 0xd6, 0x59, 0x8c, 0x5c, 0x42, + 0x98, 0x41, 0x27, 0xa4, 0x81, 0x66, 0x30, 0xce, 0x88, 0x93, 0xd2, 0x24, 0x42, 0x25, 0x24, 0x1e, + 0x94, 0xf4, 0xc1, 0xce, 0xd2, 0x54, 0x52, 0xc1, 0x74, 0x56, 0x09, 0x86, 0x2e, 0x2b, 0x46, 0x2d, + 0xa7, 0x36, 0x46, 0x2e, 0xc1, 0xe4, 0xfc, 0x5c, 0x54, 0x1b, 0x9c, 0xf8, 0xe0, 0x1e, 0x08, 0x00, + 0x25, 0xf6, 0x00, 0xc6, 0x28, 0x03, 0xa8, 0x82, 0xf4, 0xfc, 0x9c, 0xc4, 0xbc, 0x74, 0xbd, 0xfc, + 0xa2, 0x74, 0xfd, 0xf4, 0xd4, 0x3c, 0x70, 0x56, 0xd0, 0x87, 0x48, 0x25, 0x16, 0x64, 0x16, 0x43, + 0x73, 0x8a, 0x75, 0x66, 0x62, 0xee, 0x0f, 0x46, 0xc6, 0x55, 0x4c, 0xc2, 0xee, 0x10, 0x5d, 0xce, + 0x39, 0xf9, 0xa5, 0x29, 0x7a, 0x9e, 0x89, 0xb9, 0x7a, 0x61, 0x86, 0xa7, 0x60, 0xa2, 0x31, 0x60, + 0xd1, 0x18, 0xcf, 0xc4, 0xdc, 0x98, 0x30, 0xc3, 0x24, 0x36, 0xb0, 0x59, 0xc6, 0x80, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xea, 0x62, 0x8f, 0x22, 0xc1, 0x03, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/iam/v1/policy.pb.go b/vendor/google.golang.org/genproto/googleapis/iam/v1/policy.pb.go new file mode 100644 index 000000000000..6fad84d99544 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/iam/v1/policy.pb.go @@ -0,0 +1,366 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/iam/v1/policy.proto + +package iam // import "google.golang.org/genproto/googleapis/iam/v1" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// The type of action performed on a Binding in a policy. +type BindingDelta_Action int32 + +const ( + // Unspecified. + BindingDelta_ACTION_UNSPECIFIED BindingDelta_Action = 0 + // Addition of a Binding. + BindingDelta_ADD BindingDelta_Action = 1 + // Removal of a Binding. + BindingDelta_REMOVE BindingDelta_Action = 2 +) + +var BindingDelta_Action_name = map[int32]string{ + 0: "ACTION_UNSPECIFIED", + 1: "ADD", + 2: "REMOVE", +} +var BindingDelta_Action_value = map[string]int32{ + "ACTION_UNSPECIFIED": 0, + "ADD": 1, + "REMOVE": 2, +} + +func (x BindingDelta_Action) String() string { + return proto.EnumName(BindingDelta_Action_name, int32(x)) +} +func (BindingDelta_Action) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_policy_76d1e02555c18b4a, []int{3, 0} +} + +// Defines an Identity and Access Management (IAM) policy. It is used to +// specify access control policies for Cloud Platform resources. +// +// +// A `Policy` consists of a list of `bindings`. A `Binding` binds a list of +// `members` to a `role`, where the members can be user accounts, Google groups, +// Google domains, and service accounts. A `role` is a named list of permissions +// defined by IAM. +// +// **Example** +// +// { +// "bindings": [ +// { +// "role": "roles/owner", +// "members": [ +// "user:mike@example.com", +// "group:admins@example.com", +// "domain:google.com", +// "serviceAccount:my-other-app@appspot.gserviceaccount.com", +// ] +// }, +// { +// "role": "roles/viewer", +// "members": ["user:sean@example.com"] +// } +// ] +// } +// +// For a description of IAM and its features, see the +// [IAM developer's guide](https://cloud.google.com/iam). +type Policy struct { + // Version of the `Policy`. The default version is 0. + Version int32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + // Associates a list of `members` to a `role`. + // Multiple `bindings` must not be specified for the same `role`. + // `bindings` with no members will result in an error. + Bindings []*Binding `protobuf:"bytes,4,rep,name=bindings,proto3" json:"bindings,omitempty"` + // `etag` is used for optimistic concurrency control as a way to help + // prevent simultaneous updates of a policy from overwriting each other. + // It is strongly suggested that systems make use of the `etag` in the + // read-modify-write cycle to perform policy updates in order to avoid race + // conditions: An `etag` is returned in the response to `getIamPolicy`, and + // systems are expected to put that etag in the request to `setIamPolicy` to + // ensure that their change will be applied to the same version of the policy. + // + // If no `etag` is provided in the call to `setIamPolicy`, then the existing + // policy is overwritten blindly. + Etag []byte `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Policy) Reset() { *m = Policy{} } +func (m *Policy) String() string { return proto.CompactTextString(m) } +func (*Policy) ProtoMessage() {} +func (*Policy) Descriptor() ([]byte, []int) { + return fileDescriptor_policy_76d1e02555c18b4a, []int{0} +} +func (m *Policy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Policy.Unmarshal(m, b) +} +func (m *Policy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Policy.Marshal(b, m, deterministic) +} +func (dst *Policy) XXX_Merge(src proto.Message) { + xxx_messageInfo_Policy.Merge(dst, src) +} +func (m *Policy) XXX_Size() int { + return xxx_messageInfo_Policy.Size(m) +} +func (m *Policy) XXX_DiscardUnknown() { + xxx_messageInfo_Policy.DiscardUnknown(m) +} + +var xxx_messageInfo_Policy proto.InternalMessageInfo + +func (m *Policy) GetVersion() int32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *Policy) GetBindings() []*Binding { + if m != nil { + return m.Bindings + } + return nil +} + +func (m *Policy) GetEtag() []byte { + if m != nil { + return m.Etag + } + return nil +} + +// Associates `members` with a `role`. +type Binding struct { + // Role that is assigned to `members`. + // For example, `roles/viewer`, `roles/editor`, or `roles/owner`. + // Required + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` + // Specifies the identities requesting access for a Cloud Platform resource. + // `members` can have the following values: + // + // * `allUsers`: A special identifier that represents anyone who is + // on the internet; with or without a Google account. + // + // * `allAuthenticatedUsers`: A special identifier that represents anyone + // who is authenticated with a Google account or a service account. + // + // * `user:{emailid}`: An email address that represents a specific Google + // account. For example, `alice@gmail.com` or `joe@example.com`. + // + // + // * `serviceAccount:{emailid}`: An email address that represents a service + // account. For example, `my-other-app@appspot.gserviceaccount.com`. + // + // * `group:{emailid}`: An email address that represents a Google group. + // For example, `admins@example.com`. + // + // * `domain:{domain}`: A Google Apps domain name that represents all the + // users of that domain. For example, `google.com` or `example.com`. + // + // + Members []string `protobuf:"bytes,2,rep,name=members,proto3" json:"members,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Binding) Reset() { *m = Binding{} } +func (m *Binding) String() string { return proto.CompactTextString(m) } +func (*Binding) ProtoMessage() {} +func (*Binding) Descriptor() ([]byte, []int) { + return fileDescriptor_policy_76d1e02555c18b4a, []int{1} +} +func (m *Binding) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Binding.Unmarshal(m, b) +} +func (m *Binding) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Binding.Marshal(b, m, deterministic) +} +func (dst *Binding) XXX_Merge(src proto.Message) { + xxx_messageInfo_Binding.Merge(dst, src) +} +func (m *Binding) XXX_Size() int { + return xxx_messageInfo_Binding.Size(m) +} +func (m *Binding) XXX_DiscardUnknown() { + xxx_messageInfo_Binding.DiscardUnknown(m) +} + +var xxx_messageInfo_Binding proto.InternalMessageInfo + +func (m *Binding) GetRole() string { + if m != nil { + return m.Role + } + return "" +} + +func (m *Binding) GetMembers() []string { + if m != nil { + return m.Members + } + return nil +} + +// The difference delta between two policies. +type PolicyDelta struct { + // The delta for Bindings between two policies. + BindingDeltas []*BindingDelta `protobuf:"bytes,1,rep,name=binding_deltas,json=bindingDeltas,proto3" json:"binding_deltas,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PolicyDelta) Reset() { *m = PolicyDelta{} } +func (m *PolicyDelta) String() string { return proto.CompactTextString(m) } +func (*PolicyDelta) ProtoMessage() {} +func (*PolicyDelta) Descriptor() ([]byte, []int) { + return fileDescriptor_policy_76d1e02555c18b4a, []int{2} +} +func (m *PolicyDelta) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PolicyDelta.Unmarshal(m, b) +} +func (m *PolicyDelta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PolicyDelta.Marshal(b, m, deterministic) +} +func (dst *PolicyDelta) XXX_Merge(src proto.Message) { + xxx_messageInfo_PolicyDelta.Merge(dst, src) +} +func (m *PolicyDelta) XXX_Size() int { + return xxx_messageInfo_PolicyDelta.Size(m) +} +func (m *PolicyDelta) XXX_DiscardUnknown() { + xxx_messageInfo_PolicyDelta.DiscardUnknown(m) +} + +var xxx_messageInfo_PolicyDelta proto.InternalMessageInfo + +func (m *PolicyDelta) GetBindingDeltas() []*BindingDelta { + if m != nil { + return m.BindingDeltas + } + return nil +} + +// One delta entry for Binding. Each individual change (only one member in each +// entry) to a binding will be a separate entry. +type BindingDelta struct { + // The action that was performed on a Binding. + // Required + Action BindingDelta_Action `protobuf:"varint,1,opt,name=action,proto3,enum=google.iam.v1.BindingDelta_Action" json:"action,omitempty"` + // Role that is assigned to `members`. + // For example, `roles/viewer`, `roles/editor`, or `roles/owner`. + // Required + Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"` + // A single identity requesting access for a Cloud Platform resource. + // Follows the same format of Binding.members. + // Required + Member string `protobuf:"bytes,3,opt,name=member,proto3" json:"member,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BindingDelta) Reset() { *m = BindingDelta{} } +func (m *BindingDelta) String() string { return proto.CompactTextString(m) } +func (*BindingDelta) ProtoMessage() {} +func (*BindingDelta) Descriptor() ([]byte, []int) { + return fileDescriptor_policy_76d1e02555c18b4a, []int{3} +} +func (m *BindingDelta) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BindingDelta.Unmarshal(m, b) +} +func (m *BindingDelta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BindingDelta.Marshal(b, m, deterministic) +} +func (dst *BindingDelta) XXX_Merge(src proto.Message) { + xxx_messageInfo_BindingDelta.Merge(dst, src) +} +func (m *BindingDelta) XXX_Size() int { + return xxx_messageInfo_BindingDelta.Size(m) +} +func (m *BindingDelta) XXX_DiscardUnknown() { + xxx_messageInfo_BindingDelta.DiscardUnknown(m) +} + +var xxx_messageInfo_BindingDelta proto.InternalMessageInfo + +func (m *BindingDelta) GetAction() BindingDelta_Action { + if m != nil { + return m.Action + } + return BindingDelta_ACTION_UNSPECIFIED +} + +func (m *BindingDelta) GetRole() string { + if m != nil { + return m.Role + } + return "" +} + +func (m *BindingDelta) GetMember() string { + if m != nil { + return m.Member + } + return "" +} + +func init() { + proto.RegisterType((*Policy)(nil), "google.iam.v1.Policy") + proto.RegisterType((*Binding)(nil), "google.iam.v1.Binding") + proto.RegisterType((*PolicyDelta)(nil), "google.iam.v1.PolicyDelta") + proto.RegisterType((*BindingDelta)(nil), "google.iam.v1.BindingDelta") + proto.RegisterEnum("google.iam.v1.BindingDelta_Action", BindingDelta_Action_name, BindingDelta_Action_value) +} + +func init() { proto.RegisterFile("google/iam/v1/policy.proto", fileDescriptor_policy_76d1e02555c18b4a) } + +var fileDescriptor_policy_76d1e02555c18b4a = []byte{ + // 403 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0x4d, 0xab, 0x13, 0x31, + 0x14, 0x35, 0xed, 0x73, 0x6a, 0xef, 0xfb, 0xa0, 0x46, 0x28, 0xc3, 0xd3, 0x45, 0x99, 0x55, 0x57, + 0x19, 0x5b, 0x11, 0x41, 0x57, 0xfd, 0x18, 0x65, 0x16, 0xbe, 0x37, 0x46, 0xed, 0x42, 0x0a, 0x8f, + 0x4c, 0x1b, 0x42, 0x64, 0x92, 0x0c, 0x33, 0x63, 0xc1, 0xb5, 0xff, 0x46, 0xf0, 0x8f, 0xf8, 0x8b, + 0x5c, 0xca, 0x24, 0x99, 0x47, 0x0b, 0xe2, 0x2e, 0xe7, 0x9e, 0x73, 0x72, 0xcf, 0xcd, 0x0d, 0x5c, + 0x0b, 0x63, 0x44, 0xc1, 0x63, 0xc9, 0x54, 0x7c, 0x98, 0xc5, 0xa5, 0x29, 0xe4, 0xee, 0x3b, 0x29, + 0x2b, 0xd3, 0x18, 0x7c, 0xe9, 0x38, 0x22, 0x99, 0x22, 0x87, 0xd9, 0xf5, 0x33, 0x2f, 0x65, 0xa5, + 0x8c, 0x99, 0xd6, 0xa6, 0x61, 0x8d, 0x34, 0xba, 0x76, 0xe2, 0xe8, 0x2b, 0x04, 0x99, 0x35, 0xe3, + 0x10, 0x06, 0x07, 0x5e, 0xd5, 0xd2, 0xe8, 0x10, 0x4d, 0xd0, 0xf4, 0x21, 0xed, 0x20, 0x9e, 0xc3, + 0xa3, 0x5c, 0xea, 0xbd, 0xd4, 0xa2, 0x0e, 0xcf, 0x26, 0xfd, 0xe9, 0xf9, 0x7c, 0x4c, 0x4e, 0x7a, + 0x90, 0xa5, 0xa3, 0xe9, 0xbd, 0x0e, 0x63, 0x38, 0xe3, 0x0d, 0x13, 0x61, 0x7f, 0x82, 0xa6, 0x17, + 0xd4, 0x9e, 0xa3, 0x57, 0x30, 0xf0, 0xc2, 0x96, 0xae, 0x4c, 0xc1, 0x6d, 0xa7, 0x21, 0xb5, 0xe7, + 0x36, 0x80, 0xe2, 0x2a, 0xe7, 0x55, 0x1d, 0xf6, 0x26, 0xfd, 0xe9, 0x90, 0x76, 0x30, 0xfa, 0x00, + 0xe7, 0x2e, 0xe4, 0x9a, 0x17, 0x0d, 0xc3, 0x4b, 0xb8, 0xf2, 0x7d, 0xee, 0xf6, 0x6d, 0xa1, 0x0e, + 0x91, 0x4d, 0xf5, 0xf4, 0xdf, 0xa9, 0xac, 0x89, 0x5e, 0xe6, 0x47, 0xa8, 0x8e, 0x7e, 0x21, 0xb8, + 0x38, 0xe6, 0xf1, 0x6b, 0x08, 0xd8, 0xae, 0xe9, 0xa6, 0xbf, 0x9a, 0x47, 0xff, 0xb9, 0x8c, 0x2c, + 0xac, 0x92, 0x7a, 0xc7, 0xfd, 0x34, 0xbd, 0xa3, 0x69, 0xc6, 0x10, 0xb8, 0xf8, 0xf6, 0x09, 0x86, + 0xd4, 0xa3, 0xe8, 0x25, 0x04, 0xce, 0x8d, 0xc7, 0x80, 0x17, 0xab, 0x4f, 0xe9, 0xed, 0xcd, 0xdd, + 0xe7, 0x9b, 0x8f, 0x59, 0xb2, 0x4a, 0xdf, 0xa6, 0xc9, 0x7a, 0xf4, 0x00, 0x0f, 0xa0, 0xbf, 0x58, + 0xaf, 0x47, 0x08, 0x03, 0x04, 0x34, 0x79, 0x7f, 0xbb, 0x49, 0x46, 0xbd, 0xe5, 0x0f, 0x04, 0x8f, + 0x77, 0x46, 0x9d, 0x86, 0x5a, 0xfa, 0x67, 0xc9, 0xda, 0x55, 0x66, 0xe8, 0xcb, 0x73, 0xcf, 0x0a, + 0x53, 0x30, 0x2d, 0x88, 0xa9, 0x44, 0x2c, 0xb8, 0xb6, 0x8b, 0x8e, 0x1d, 0xc5, 0x4a, 0x59, 0xfb, + 0x4f, 0xf3, 0x46, 0x32, 0xf5, 0x07, 0xa1, 0x9f, 0xbd, 0x27, 0xef, 0x9c, 0x6b, 0x55, 0x98, 0x6f, + 0x7b, 0x92, 0x32, 0x45, 0x36, 0xb3, 0xdf, 0x5d, 0x75, 0x6b, 0xab, 0xdb, 0x94, 0xa9, 0xed, 0x66, + 0x96, 0x07, 0xf6, 0xae, 0x17, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x18, 0xca, 0xaa, 0x7f, + 0x02, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/rpc/code/code.pb.go b/vendor/google.golang.org/genproto/googleapis/rpc/code/code.pb.go new file mode 100644 index 000000000000..d00261a3afe7 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/rpc/code/code.pb.go @@ -0,0 +1,246 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/rpc/code.proto + +package code // import "google.golang.org/genproto/googleapis/rpc/code" + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// The canonical error codes for Google APIs. +// +// +// Sometimes multiple error codes may apply. Services should return +// the most specific error code that applies. For example, prefer +// `OUT_OF_RANGE` over `FAILED_PRECONDITION` if both codes apply. +// Similarly prefer `NOT_FOUND` or `ALREADY_EXISTS` over `FAILED_PRECONDITION`. +type Code int32 + +const ( + // Not an error; returned on success + // + // HTTP Mapping: 200 OK + Code_OK Code = 0 + // The operation was cancelled, typically by the caller. + // + // HTTP Mapping: 499 Client Closed Request + Code_CANCELLED Code = 1 + // Unknown error. For example, this error may be returned when + // a `Status` value received from another address space belongs to + // an error space that is not known in this address space. Also + // errors raised by APIs that do not return enough error information + // may be converted to this error. + // + // HTTP Mapping: 500 Internal Server Error + Code_UNKNOWN Code = 2 + // The client specified an invalid argument. Note that this differs + // from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments + // that are problematic regardless of the state of the system + // (e.g., a malformed file name). + // + // HTTP Mapping: 400 Bad Request + Code_INVALID_ARGUMENT Code = 3 + // The deadline expired before the operation could complete. For operations + // that change the state of the system, this error may be returned + // even if the operation has completed successfully. For example, a + // successful response from a server could have been delayed long + // enough for the deadline to expire. + // + // HTTP Mapping: 504 Gateway Timeout + Code_DEADLINE_EXCEEDED Code = 4 + // Some requested entity (e.g., file or directory) was not found. + // + // Note to server developers: if a request is denied for an entire class + // of users, such as gradual feature rollout or undocumented whitelist, + // `NOT_FOUND` may be used. If a request is denied for some users within + // a class of users, such as user-based access control, `PERMISSION_DENIED` + // must be used. + // + // HTTP Mapping: 404 Not Found + Code_NOT_FOUND Code = 5 + // The entity that a client attempted to create (e.g., file or directory) + // already exists. + // + // HTTP Mapping: 409 Conflict + Code_ALREADY_EXISTS Code = 6 + // The caller does not have permission to execute the specified + // operation. `PERMISSION_DENIED` must not be used for rejections + // caused by exhausting some resource (use `RESOURCE_EXHAUSTED` + // instead for those errors). `PERMISSION_DENIED` must not be + // used if the caller can not be identified (use `UNAUTHENTICATED` + // instead for those errors). This error code does not imply the + // request is valid or the requested entity exists or satisfies + // other pre-conditions. + // + // HTTP Mapping: 403 Forbidden + Code_PERMISSION_DENIED Code = 7 + // The request does not have valid authentication credentials for the + // operation. + // + // HTTP Mapping: 401 Unauthorized + Code_UNAUTHENTICATED Code = 16 + // Some resource has been exhausted, perhaps a per-user quota, or + // perhaps the entire file system is out of space. + // + // HTTP Mapping: 429 Too Many Requests + Code_RESOURCE_EXHAUSTED Code = 8 + // The operation was rejected because the system is not in a state + // required for the operation's execution. For example, the directory + // to be deleted is non-empty, an rmdir operation is applied to + // a non-directory, etc. + // + // Service implementors can use the following guidelines to decide + // between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: + // (a) Use `UNAVAILABLE` if the client can retry just the failing call. + // (b) Use `ABORTED` if the client should retry at a higher level + // (e.g., when a client-specified test-and-set fails, indicating the + // client should restart a read-modify-write sequence). + // (c) Use `FAILED_PRECONDITION` if the client should not retry until + // the system state has been explicitly fixed. E.g., if an "rmdir" + // fails because the directory is non-empty, `FAILED_PRECONDITION` + // should be returned since the client should not retry unless + // the files are deleted from the directory. + // + // HTTP Mapping: 400 Bad Request + Code_FAILED_PRECONDITION Code = 9 + // The operation was aborted, typically due to a concurrency issue such as + // a sequencer check failure or transaction abort. + // + // See the guidelines above for deciding between `FAILED_PRECONDITION`, + // `ABORTED`, and `UNAVAILABLE`. + // + // HTTP Mapping: 409 Conflict + Code_ABORTED Code = 10 + // The operation was attempted past the valid range. E.g., seeking or + // reading past end-of-file. + // + // Unlike `INVALID_ARGUMENT`, this error indicates a problem that may + // be fixed if the system state changes. For example, a 32-bit file + // system will generate `INVALID_ARGUMENT` if asked to read at an + // offset that is not in the range [0,2^32-1], but it will generate + // `OUT_OF_RANGE` if asked to read from an offset past the current + // file size. + // + // There is a fair bit of overlap between `FAILED_PRECONDITION` and + // `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific + // error) when it applies so that callers who are iterating through + // a space can easily look for an `OUT_OF_RANGE` error to detect when + // they are done. + // + // HTTP Mapping: 400 Bad Request + Code_OUT_OF_RANGE Code = 11 + // The operation is not implemented or is not supported/enabled in this + // service. + // + // HTTP Mapping: 501 Not Implemented + Code_UNIMPLEMENTED Code = 12 + // Internal errors. This means that some invariants expected by the + // underlying system have been broken. This error code is reserved + // for serious errors. + // + // HTTP Mapping: 500 Internal Server Error + Code_INTERNAL Code = 13 + // The service is currently unavailable. This is most likely a + // transient condition, which can be corrected by retrying with + // a backoff. + // + // See the guidelines above for deciding between `FAILED_PRECONDITION`, + // `ABORTED`, and `UNAVAILABLE`. + // + // HTTP Mapping: 503 Service Unavailable + Code_UNAVAILABLE Code = 14 + // Unrecoverable data loss or corruption. + // + // HTTP Mapping: 500 Internal Server Error + Code_DATA_LOSS Code = 15 +) + +var Code_name = map[int32]string{ + 0: "OK", + 1: "CANCELLED", + 2: "UNKNOWN", + 3: "INVALID_ARGUMENT", + 4: "DEADLINE_EXCEEDED", + 5: "NOT_FOUND", + 6: "ALREADY_EXISTS", + 7: "PERMISSION_DENIED", + 16: "UNAUTHENTICATED", + 8: "RESOURCE_EXHAUSTED", + 9: "FAILED_PRECONDITION", + 10: "ABORTED", + 11: "OUT_OF_RANGE", + 12: "UNIMPLEMENTED", + 13: "INTERNAL", + 14: "UNAVAILABLE", + 15: "DATA_LOSS", +} +var Code_value = map[string]int32{ + "OK": 0, + "CANCELLED": 1, + "UNKNOWN": 2, + "INVALID_ARGUMENT": 3, + "DEADLINE_EXCEEDED": 4, + "NOT_FOUND": 5, + "ALREADY_EXISTS": 6, + "PERMISSION_DENIED": 7, + "UNAUTHENTICATED": 16, + "RESOURCE_EXHAUSTED": 8, + "FAILED_PRECONDITION": 9, + "ABORTED": 10, + "OUT_OF_RANGE": 11, + "UNIMPLEMENTED": 12, + "INTERNAL": 13, + "UNAVAILABLE": 14, + "DATA_LOSS": 15, +} + +func (x Code) String() string { + return proto.EnumName(Code_name, int32(x)) +} +func (Code) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_code_8ba741a7091890dd, []int{0} +} + +func init() { + proto.RegisterEnum("google.rpc.Code", Code_name, Code_value) +} + +func init() { proto.RegisterFile("google/rpc/code.proto", fileDescriptor_code_8ba741a7091890dd) } + +var fileDescriptor_code_8ba741a7091890dd = []byte{ + // 362 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x51, 0xcd, 0x6e, 0x93, 0x31, + 0x10, 0xa4, 0x69, 0x49, 0x9b, 0xcd, 0xdf, 0xd6, 0xa5, 0xf0, 0x0e, 0x1c, 0x92, 0x43, 0x8f, 0x9c, + 0x36, 0x9f, 0x37, 0xad, 0x55, 0x67, 0xfd, 0xc9, 0x3f, 0x25, 0x70, 0xb1, 0x4a, 0x1a, 0x7d, 0x42, + 0x2a, 0x75, 0xf4, 0xc1, 0x13, 0xf1, 0x12, 0xbc, 0x1e, 0x72, 0x8b, 0xe8, 0xc5, 0x87, 0x99, 0xf1, + 0xee, 0xce, 0x0c, 0x5c, 0x76, 0xa5, 0x74, 0x8f, 0xfb, 0x65, 0x7f, 0xd8, 0x2d, 0x77, 0xe5, 0x61, + 0xbf, 0x38, 0xf4, 0xe5, 0x57, 0x51, 0xf0, 0x02, 0x2f, 0xfa, 0xc3, 0xee, 0xe3, 0x9f, 0x01, 0x9c, + 0x34, 0xe5, 0x61, 0xaf, 0x86, 0x30, 0x70, 0xb7, 0xf8, 0x46, 0x4d, 0x61, 0xd4, 0x90, 0x34, 0x6c, + 0x2d, 0x6b, 0x3c, 0x52, 0x63, 0x38, 0x4d, 0x72, 0x2b, 0xee, 0xb3, 0xe0, 0x40, 0xbd, 0x03, 0x34, + 0x72, 0x47, 0xd6, 0xe8, 0x4c, 0xfe, 0x3a, 0x6d, 0x58, 0x22, 0x1e, 0xab, 0x4b, 0x38, 0xd7, 0x4c, + 0xda, 0x1a, 0xe1, 0xcc, 0xdb, 0x86, 0x59, 0xb3, 0xc6, 0x93, 0x3a, 0x48, 0x5c, 0xcc, 0x6b, 0x97, + 0x44, 0xe3, 0x5b, 0xa5, 0x60, 0x46, 0xd6, 0x33, 0xe9, 0x2f, 0x99, 0xb7, 0x26, 0xc4, 0x80, 0xc3, + 0xfa, 0xb3, 0x65, 0xbf, 0x31, 0x21, 0x18, 0x27, 0x59, 0xb3, 0x18, 0xd6, 0x78, 0xaa, 0x2e, 0x60, + 0x9e, 0x84, 0x52, 0xbc, 0x61, 0x89, 0xa6, 0xa1, 0xc8, 0x1a, 0x51, 0xbd, 0x07, 0xe5, 0x39, 0xb8, + 0xe4, 0x9b, 0xba, 0xe5, 0x86, 0x52, 0xa8, 0xf8, 0x99, 0xfa, 0x00, 0x17, 0x6b, 0x32, 0x96, 0x75, + 0x6e, 0x3d, 0x37, 0x4e, 0xb4, 0x89, 0xc6, 0x09, 0x8e, 0xea, 0xe5, 0xb4, 0x72, 0xbe, 0xaa, 0x40, + 0x21, 0x4c, 0x5c, 0x8a, 0xd9, 0xad, 0xb3, 0x27, 0xb9, 0x66, 0x1c, 0xab, 0x73, 0x98, 0x26, 0x31, + 0x9b, 0xd6, 0x72, 0xb5, 0xc1, 0x1a, 0x27, 0x6a, 0x02, 0x67, 0x46, 0x22, 0x7b, 0x21, 0x8b, 0x53, + 0x35, 0x87, 0x71, 0x12, 0xba, 0x23, 0x63, 0x69, 0x65, 0x19, 0x67, 0xd5, 0x90, 0xa6, 0x48, 0xd9, + 0xba, 0x10, 0x70, 0xbe, 0xda, 0xc2, 0x6c, 0x57, 0x7e, 0x2c, 0x5e, 0xb3, 0x5c, 0x8d, 0x6a, 0x90, + 0x6d, 0x8d, 0xb8, 0x3d, 0xfa, 0x7a, 0xf5, 0x8f, 0xe8, 0xca, 0xe3, 0xfd, 0x53, 0xb7, 0x28, 0x7d, + 0xb7, 0xec, 0xf6, 0x4f, 0xcf, 0x05, 0x2c, 0x5f, 0xa8, 0xfb, 0xc3, 0xf7, 0x9f, 0xff, 0xab, 0xf9, + 0x54, 0x9f, 0xdf, 0x83, 0x63, 0xdf, 0x36, 0xdf, 0x86, 0xcf, 0xaa, 0xab, 0xbf, 0x01, 0x00, 0x00, + 0xff, 0xff, 0x8e, 0x97, 0x77, 0xc2, 0xbf, 0x01, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go b/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go index 7bfe37a3db70..57ae35f6b528 100644 --- a/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go @@ -19,24 +19,25 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package -// The `Status` type defines a logical error model that is suitable for different -// programming environments, including REST APIs and RPC APIs. It is used by -// [gRPC](https://github.com/grpc). The error model is designed to be: +// The `Status` type defines a logical error model that is suitable for +// different programming environments, including REST APIs and RPC APIs. It is +// used by [gRPC](https://github.com/grpc). The error model is designed to be: // // - Simple to use and understand for most users // - Flexible enough to meet unexpected needs // // # Overview // -// The `Status` message contains three pieces of data: error code, error message, -// and error details. The error code should be an enum value of -// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The -// error message should be a developer-facing English message that helps -// developers *understand* and *resolve* the error. If a localized user-facing -// error message is needed, put the localized message in the error details or -// localize it in the client. The optional error details may contain arbitrary -// information about the error. There is a predefined set of error detail types -// in the package `google.rpc` that can be used for common error conditions. +// The `Status` message contains three pieces of data: error code, error +// message, and error details. The error code should be an enum value of +// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes +// if needed. The error message should be a developer-facing English message +// that helps developers *understand* and *resolve* the error. If a localized +// user-facing error message is needed, put the localized message in the error +// details or localize it in the client. The optional error details may contain +// arbitrary information about the error. There is a predefined set of error +// detail types in the package `google.rpc` that can be used for common error +// conditions. // // # Language mapping // @@ -72,11 +73,13 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // - Logging. If some API errors are stored in logs, the message `Status` could // be used directly after any stripping needed for security/privacy reasons. type Status struct { - // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + // The status code, which should be an enum value of + // [google.rpc.Code][google.rpc.Code]. Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` // A developer-facing error message, which should be in English. Any // user-facing error message should be localized and sent in the - // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + // [google.rpc.Status.details][google.rpc.Status.details] field, or localized + // by the client. Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // A list of messages that carry the error details. There is a common set of // message types for APIs to use. @@ -90,7 +93,7 @@ func (m *Status) Reset() { *m = Status{} } func (m *Status) String() string { return proto.CompactTextString(m) } func (*Status) ProtoMessage() {} func (*Status) Descriptor() ([]byte, []int) { - return fileDescriptor_status_c6e4de62dcdf2edf, []int{0} + return fileDescriptor_status_ced6ddf76350620b, []int{0} } func (m *Status) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status.Unmarshal(m, b) @@ -135,9 +138,9 @@ func init() { proto.RegisterType((*Status)(nil), "google.rpc.Status") } -func init() { proto.RegisterFile("google/rpc/status.proto", fileDescriptor_status_c6e4de62dcdf2edf) } +func init() { proto.RegisterFile("google/rpc/status.proto", fileDescriptor_status_ced6ddf76350620b) } -var fileDescriptor_status_c6e4de62dcdf2edf = []byte{ +var fileDescriptor_status_ced6ddf76350620b = []byte{ // 209 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4f, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x2f, 0x2a, 0x48, 0xd6, 0x2f, 0x2e, 0x49, 0x2c, 0x29, 0x2d, 0xd6, 0x2b, 0x28, diff --git a/vendor/google.golang.org/grpc/.travis.yml b/vendor/google.golang.org/grpc/.travis.yml index f443eec9a0b4..591343edfb9c 100644 --- a/vendor/google.golang.org/grpc/.travis.yml +++ b/vendor/google.golang.org/grpc/.travis.yml @@ -2,6 +2,8 @@ language: go matrix: include: + - go: 1.12.x + env: GO111MODULE=on - go: 1.11.x env: VET=1 GO111MODULE=on - go: 1.11.x diff --git a/vendor/google.golang.org/grpc/CONTRIBUTING.md b/vendor/google.golang.org/grpc/CONTRIBUTING.md index 0863eb26b602..ca34e8aa0dae 100644 --- a/vendor/google.golang.org/grpc/CONTRIBUTING.md +++ b/vendor/google.golang.org/grpc/CONTRIBUTING.md @@ -31,6 +31,7 @@ How to get your contributions merged smoothly and quickly. - `make vet` to catch vet errors - `make test` to run the tests - `make testrace` to run tests in race mode + - optional `make testappengine` to run tests with appengine - Exceptions to the rules can be made if there's a compelling reason for doing so. diff --git a/vendor/google.golang.org/grpc/Makefile b/vendor/google.golang.org/grpc/Makefile index 41a754f97728..db982aabde6f 100644 --- a/vendor/google.golang.org/grpc/Makefile +++ b/vendor/google.golang.org/grpc/Makefile @@ -1,4 +1,4 @@ -all: vet test testrace testappengine +all: vet test testrace build: deps go build google.golang.org/grpc/... diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md index e3fb3c75ae3c..f5eec6717f31 100644 --- a/vendor/google.golang.org/grpc/README.md +++ b/vendor/google.golang.org/grpc/README.md @@ -20,7 +20,7 @@ gRPC-Go requires Go 1.9 or later. Constraints ----------- -The grpc package should only depend on standard Go packages and a small number of exceptions. If your contribution introduces new dependencies which are NOT in the [list](http://godoc.org/google.golang.org/grpc?imports), you need a discussion with gRPC-Go authors and consultants. +The grpc package should only depend on standard Go packages and a small number of exceptions. If your contribution introduces new dependencies which are NOT in the [list](https://godoc.org/google.golang.org/grpc?imports), you need a discussion with gRPC-Go authors and consultants. Documentation ------------- diff --git a/vendor/google.golang.org/grpc/backoff.go b/vendor/google.golang.org/grpc/backoff.go index fa31565fd283..97c6e2568f45 100644 --- a/vendor/google.golang.org/grpc/backoff.go +++ b/vendor/google.golang.org/grpc/backoff.go @@ -17,7 +17,7 @@ */ // See internal/backoff package for the backoff implementation. This file is -// kept for the exported types and API backward compatility. +// kept for the exported types and API backward compatibility. package grpc diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index 1bf46aafe6fb..fafede238c13 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -28,6 +28,7 @@ import ( "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/internal" "google.golang.org/grpc/metadata" "google.golang.org/grpc/resolver" ) @@ -47,8 +48,20 @@ func Register(b Builder) { m[strings.ToLower(b.Name())] = b } +// unregisterForTesting deletes the balancer with the given name from the +// balancer map. +// +// This function is not thread-safe. +func unregisterForTesting(name string) { + delete(m, name) +} + +func init() { + internal.BalancerUnregister = unregisterForTesting +} + // Get returns the resolver builder registered with the given name. -// Note that the compare is done in a case-insenstive fashion. +// Note that the compare is done in a case-insensitive fashion. // If no builder is register with the name, nil will be returned. func Get(name string) Builder { if b, ok := m[strings.ToLower(name)]; ok { @@ -114,7 +127,7 @@ type ClientConn interface { // The SubConn will be shutdown. RemoveSubConn(SubConn) - // UpdateBalancerState is called by balancer to nofity gRPC that some internal + // UpdateBalancerState is called by balancer to notify gRPC that some internal // state in balancer has changed. // // gRPC will update the connectivity state of the ClientConn, and will call pick @@ -158,9 +171,6 @@ type PickOptions struct { // FullMethodName is the method name that NewClientStream() is called // with. The canonical format is /service/Method. FullMethodName string - // Header contains the metadata from the RPC's client header. The metadata - // should not be modified; make a copy first if needed. - Header metadata.MD } // DoneInfo contains additional information for done. @@ -173,6 +183,11 @@ type DoneInfo struct { BytesSent bool // BytesReceived indicates if any byte has been received from the server. BytesReceived bool + // ServerLoad is the load received from server. It's usually sent as part of + // trailing metadata. + // + // The only supported type now is *orca_v1.LoadReport. + ServerLoad interface{} } var ( @@ -202,8 +217,10 @@ type Picker interface { // // If a SubConn is returned: // - If it is READY, gRPC will send the RPC on it; - // - If it is not ready, or becomes not ready after it's returned, gRPC will block - // until UpdateBalancerState() is called and will call pick on the new picker. + // - If it is not ready, or becomes not ready after it's returned, gRPC will + // block until UpdateBalancerState() is called and will call pick on the + // new picker. The done function returned from Pick(), if not nil, will be + // called with nil error, no bytes sent and no bytes received. // // If the returned error is not nil: // - If the error is ErrNoSubConnAvailable, gRPC will block until UpdateBalancerState() @@ -214,9 +231,10 @@ type Picker interface { // - Else (error is other non-nil error): // - The RPC will fail with unavailable error. // - // The returned done() function will be called once the rpc has finished, with the - // final status of that RPC. - // done may be nil if balancer doesn't care about the RPC status. + // The returned done() function will be called once the rpc has finished, + // with the final status of that RPC. If the SubConn returned is not a + // valid SubConn type, done may not be called. done may be nil if balancer + // doesn't care about the RPC status. Pick(ctx context.Context, opts PickOptions) (conn SubConn, done func(DoneInfo), err error) } @@ -235,18 +253,46 @@ type Balancer interface { // that back to gRPC. // Balancer should also generate and update Pickers when its internal state has // been changed by the new state. + // + // Deprecated: if V2Balancer is implemented by the Balancer, + // UpdateSubConnState will be called instead. HandleSubConnStateChange(sc SubConn, state connectivity.State) // HandleResolvedAddrs is called by gRPC to send updated resolved addresses to // balancers. // Balancer can create new SubConn or remove SubConn with the addresses. // An empty address slice and a non-nil error will be passed if the resolver returns // non-nil error to gRPC. + // + // Deprecated: if V2Balancer is implemented by the Balancer, + // UpdateResolverState will be called instead. HandleResolvedAddrs([]resolver.Address, error) // Close closes the balancer. The balancer is not required to call // ClientConn.RemoveSubConn for its existing SubConns. Close() } +// SubConnState describes the state of a SubConn. +type SubConnState struct { + ConnectivityState connectivity.State + // TODO: add last connection error +} + +// V2Balancer is defined for documentation purposes. If a Balancer also +// implements V2Balancer, its UpdateResolverState method will be called instead +// of HandleResolvedAddrs and its UpdateSubConnState will be called instead of +// HandleSubConnStateChange. +type V2Balancer interface { + // UpdateResolverState is called by gRPC when the state of the resolver + // changes. + UpdateResolverState(resolver.State) + // UpdateSubConnState is called by gRPC when the state of a SubConn + // changes. + UpdateSubConnState(SubConn, SubConnState) + // Close closes the balancer. The balancer is not required to call + // ClientConn.RemoveSubConn for its existing SubConns. + Close() +} + // ConnectivityStateEvaluator takes the connectivity states of multiple SubConns // and returns one aggregated connectivity state. // diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go index 5f55b274f440..c5a51bd1d992 100644 --- a/vendor/google.golang.org/grpc/balancer/base/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go @@ -40,7 +40,7 @@ func (bb *baseBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) subConns: make(map[resolver.Address]balancer.SubConn), scStates: make(map[balancer.SubConn]connectivity.State), - csEvltr: &connectivityStateEvaluator{}, + csEvltr: &balancer.ConnectivityStateEvaluator{}, // Initialize picker to a picker that always return // ErrNoSubConnAvailable, because when state of a SubConn changes, we // may call UpdateBalancerState with this picker. @@ -57,7 +57,7 @@ type baseBalancer struct { cc balancer.ClientConn pickerBuilder PickerBuilder - csEvltr *connectivityStateEvaluator + csEvltr *balancer.ConnectivityStateEvaluator state connectivity.State subConns map[resolver.Address]balancer.SubConn @@ -67,14 +67,16 @@ type baseBalancer struct { } func (b *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) { - if err != nil { - grpclog.Infof("base.baseBalancer: HandleResolvedAddrs called with error %v", err) - return - } - grpclog.Infoln("base.baseBalancer: got new resolved addresses: ", addrs) + panic("not implemented") +} + +func (b *baseBalancer) UpdateResolverState(s resolver.State) { + // TODO: handle s.Err (log if not nil) once implemented. + // TODO: handle s.ServiceConfig? + grpclog.Infoln("base.baseBalancer: got new resolver state: ", s) // addrsSet is the set converted from addrs, it's used for quick lookup of an address. addrsSet := make(map[resolver.Address]struct{}) - for _, a := range addrs { + for _, a := range s.Addresses { addrsSet[a] = struct{}{} if _, ok := b.subConns[a]; !ok { // a is a new address (not existing in b.subConns). @@ -120,6 +122,11 @@ func (b *baseBalancer) regeneratePicker() { } func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) { + panic("not implemented") +} + +func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { + s := state.ConnectivityState grpclog.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s) oldS, ok := b.scStates[sc] if !ok { @@ -137,7 +144,7 @@ func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectiv } oldAggrState := b.state - b.state = b.csEvltr.recordTransition(oldS, s) + b.state = b.csEvltr.RecordTransition(oldS, s) // Regenerate picker when one of the following happens: // - this sc became ready from not-ready @@ -169,44 +176,3 @@ type errPicker struct { func (p *errPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { return nil, nil, p.err } - -// connectivityStateEvaluator gets updated by addrConns when their -// states transition, based on which it evaluates the state of -// ClientConn. -type connectivityStateEvaluator struct { - numReady uint64 // Number of addrConns in ready state. - numConnecting uint64 // Number of addrConns in connecting state. - numTransientFailure uint64 // Number of addrConns in transientFailure. -} - -// recordTransition records state change happening in every subConn and based on -// that it evaluates what aggregated state should be. -// It can only transition between Ready, Connecting and TransientFailure. Other states, -// Idle and Shutdown are transitioned into by ClientConn; in the beginning of the connection -// before any subConn is created ClientConn is in idle state. In the end when ClientConn -// closes it is in Shutdown state. -// -// recordTransition should only be called synchronously from the same goroutine. -func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) connectivity.State { - // Update counters. - for idx, state := range []connectivity.State{oldState, newState} { - updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new. - switch state { - case connectivity.Ready: - cse.numReady += updateVal - case connectivity.Connecting: - cse.numConnecting += updateVal - case connectivity.TransientFailure: - cse.numTransientFailure += updateVal - } - } - - // Evaluate. - if cse.numReady > 0 { - return connectivity.Ready - } - if cse.numConnecting > 0 { - return connectivity.Connecting - } - return connectivity.TransientFailure -} diff --git a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go index 57aea9fb4d2d..29f7a4ddd68f 100644 --- a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go +++ b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go @@ -28,6 +28,7 @@ import ( "google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer/base" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/resolver" ) @@ -47,12 +48,19 @@ type rrPickerBuilder struct{} func (*rrPickerBuilder) Build(readySCs map[resolver.Address]balancer.SubConn) balancer.Picker { grpclog.Infof("roundrobinPicker: newPicker called with readySCs: %v", readySCs) + if len(readySCs) == 0 { + return base.NewErrPicker(balancer.ErrNoSubConnAvailable) + } var scs []balancer.SubConn for _, sc := range readySCs { scs = append(scs, sc) } return &rrPicker{ subConns: scs, + // Start at a random index, as the same RR balancer rebuilds a new + // picker when SubConn states change, and we don't want to apply excess + // load to the first server in the list. + next: grpcrand.Intn(len(scs)), } } @@ -67,10 +75,6 @@ type rrPicker struct { } func (p *rrPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { - if len(p.subConns) <= 0 { - return nil, nil, balancer.ErrNoSubConnAvailable - } - p.mu.Lock() sc := p.subConns[p.next] p.next = (p.next + 1) % len(p.subConns) diff --git a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go index 77b68477564a..bc965f0acaaa 100644 --- a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go +++ b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go @@ -82,20 +82,13 @@ func (b *scStateUpdateBuffer) get() <-chan *scStateUpdate { return b.c } -// resolverUpdate contains the new resolved addresses or error if there's -// any. -type resolverUpdate struct { - addrs []resolver.Address - err error -} - // ccBalancerWrapper is a wrapper on top of cc for balancers. // It implements balancer.ClientConn interface. type ccBalancerWrapper struct { cc *ClientConn balancer balancer.Balancer stateChangeQueue *scStateUpdateBuffer - resolverUpdateCh chan *resolverUpdate + resolverUpdateCh chan *resolver.State done chan struct{} mu sync.Mutex @@ -106,7 +99,7 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui ccb := &ccBalancerWrapper{ cc: cc, stateChangeQueue: newSCStateUpdateBuffer(), - resolverUpdateCh: make(chan *resolverUpdate, 1), + resolverUpdateCh: make(chan *resolver.State, 1), done: make(chan struct{}), subConns: make(map[*acBalancerWrapper]struct{}), } @@ -128,15 +121,23 @@ func (ccb *ccBalancerWrapper) watcher() { return default: } - ccb.balancer.HandleSubConnStateChange(t.sc, t.state) - case t := <-ccb.resolverUpdateCh: + if ub, ok := ccb.balancer.(balancer.V2Balancer); ok { + ub.UpdateSubConnState(t.sc, balancer.SubConnState{ConnectivityState: t.state}) + } else { + ccb.balancer.HandleSubConnStateChange(t.sc, t.state) + } + case s := <-ccb.resolverUpdateCh: select { case <-ccb.done: ccb.balancer.Close() return default: } - ccb.balancer.HandleResolvedAddrs(t.addrs, t.err) + if ub, ok := ccb.balancer.(balancer.V2Balancer); ok { + ub.UpdateResolverState(*s) + } else { + ccb.balancer.HandleResolvedAddrs(s.Addresses, nil) + } case <-ccb.done: } @@ -177,15 +178,23 @@ func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s co }) } -func (ccb *ccBalancerWrapper) handleResolvedAddrs(addrs []resolver.Address, err error) { +func (ccb *ccBalancerWrapper) updateResolverState(s resolver.State) { + if ccb.cc.curBalancerName != grpclbName { + // Filter any grpclb addresses since we don't have the grpclb balancer. + for i := 0; i < len(s.Addresses); { + if s.Addresses[i].Type == resolver.GRPCLB { + copy(s.Addresses[i:], s.Addresses[i+1:]) + s.Addresses = s.Addresses[:len(s.Addresses)-1] + continue + } + i++ + } + } select { case <-ccb.resolverUpdateCh: default: } - ccb.resolverUpdateCh <- &resolverUpdate{ - addrs: addrs, - err: err, - } + ccb.resolverUpdateCh <- &s } func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { diff --git a/vendor/google.golang.org/grpc/balancer_v1_wrapper.go b/vendor/google.golang.org/grpc/balancer_v1_wrapper.go index ca07c154b2d4..29bda6353dd5 100644 --- a/vendor/google.golang.org/grpc/balancer_v1_wrapper.go +++ b/vendor/google.golang.org/grpc/balancer_v1_wrapper.go @@ -24,11 +24,9 @@ import ( "sync" "google.golang.org/grpc/balancer" - "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/resolver" - "google.golang.org/grpc/status" ) type balancerWrapperBuilder struct { @@ -283,9 +281,8 @@ func (bw *balancerWrapper) Close() { } // The picker is the balancerWrapper itself. -// Pick should never return ErrNoSubConnAvailable. // It either blocks or returns error, consistent with v1 balancer Get(). -func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) { +func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions) (sc balancer.SubConn, done func(balancer.DoneInfo), err error) { failfast := true // Default failfast is true. if ss, ok := rpcInfoFromContext(ctx); ok { failfast = ss.failfast @@ -294,35 +291,51 @@ func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions) if err != nil { return nil, nil, err } - var done func(balancer.DoneInfo) if p != nil { - done = func(i balancer.DoneInfo) { p() } + done = func(balancer.DoneInfo) { p() } + defer func() { + if err != nil { + p() + } + }() } - var sc balancer.SubConn + bw.mu.Lock() defer bw.mu.Unlock() if bw.pickfirst { // Get the first sc in conns. - for _, sc = range bw.conns { - break - } - } else { - var ok bool - sc, ok = bw.conns[resolver.Address{ - Addr: a.Addr, - Type: resolver.Backend, - ServerName: "", - Metadata: a.Metadata, - }] - if !ok && failfast { - return nil, nil, status.Errorf(codes.Unavailable, "there is no connection available") - } - if s, ok := bw.connSt[sc]; failfast && (!ok || s.s != connectivity.Ready) { - // If the returned sc is not ready and RPC is failfast, - // return error, and this RPC will fail. - return nil, nil, status.Errorf(codes.Unavailable, "there is no connection available") + for _, sc := range bw.conns { + return sc, done, nil } + return nil, nil, balancer.ErrNoSubConnAvailable + } + sc, ok1 := bw.conns[resolver.Address{ + Addr: a.Addr, + Type: resolver.Backend, + ServerName: "", + Metadata: a.Metadata, + }] + s, ok2 := bw.connSt[sc] + if !ok1 || !ok2 { + // This can only happen due to a race where Get() returned an address + // that was subsequently removed by Notify. In this case we should + // retry always. + return nil, nil, balancer.ErrNoSubConnAvailable + } + switch s.s { + case connectivity.Ready, connectivity.Idle: + return sc, done, nil + case connectivity.Shutdown, connectivity.TransientFailure: + // If the returned sc has been shut down or is in transient failure, + // return error, and this RPC will fail or wait for another picker (if + // non-failfast). + return nil, nil, balancer.ErrTransientFailure + default: + // For other states (connecting or unknown), the v1 balancer would + // traditionally wait until ready and then issue the RPC. Returning + // ErrNoSubConnAvailable will be a slight improvement in that it will + // allow the balancer to choose another address in case others are + // connected. + return nil, nil, balancer.ErrNoSubConnAvailable } - - return sc, done, nil } diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index 100f05dc7421..9e20e4d385f9 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -40,7 +40,7 @@ func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply int func combine(o1 []CallOption, o2 []CallOption) []CallOption { // we don't use append because o1 could have extra capacity whose // elements would be overwritten, which could cause inadvertent - // sharing (and race connditions) between concurrent calls + // sharing (and race conditions) between concurrent calls if len(o1) == 0 { return o2 } else if len(o2) == 0 { diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index 84b6dbe3eabf..bd2d2b317798 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -36,14 +36,12 @@ import ( "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" - "google.golang.org/grpc/metadata" "google.golang.org/grpc/resolver" _ "google.golang.org/grpc/resolver/dns" // To register dns resolver. _ "google.golang.org/grpc/resolver/passthrough" // To register passthrough resolver. @@ -70,11 +68,9 @@ var ( errConnClosing = errors.New("grpc: the connection is closing") // errBalancerClosed indicates that the balancer is closed. errBalancerClosed = errors.New("grpc: balancer is closed") - // We use an accessor so that minConnectTimeout can be - // atomically read and updated while testing. - getMinConnectTimeout = func() time.Duration { - return minConnectTimeout - } + // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default + // service config. + invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid" ) // The following errors are returned from Dial and DialContext @@ -87,7 +83,7 @@ var ( // with other individual Transport Credentials. errTransportCredsAndBundle = errors.New("grpc: credentials.Bundle may not be used with individual TransportCredentials") // errTransportCredentialsMissing indicates that users want to transmit security - // information (e.g., oauth2 token) which requires secure connection on an insecure + // information (e.g., OAuth2 token) which requires secure connection on an insecure // connection. errTransportCredentialsMissing = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportCredentials() to set)") // errCredentialsConflict indicates that grpc.WithTransportCredentials() @@ -141,6 +137,12 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * opt.apply(&cc.dopts) } + defer func() { + if err != nil { + cc.Close() + } + }() + if channelz.IsOn() { if cc.dopts.channelzParentID != 0 { cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, cc.dopts.channelzParentID, target) @@ -180,6 +182,13 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } } + if cc.dopts.defaultServiceConfigRawJSON != nil { + sc, err := parseServiceConfig(*cc.dopts.defaultServiceConfigRawJSON) + if err != nil { + return nil, fmt.Errorf("%s: %v", invalidDefaultServiceConfigErrPrefix, err) + } + cc.dopts.defaultServiceConfig = sc + } cc.mkp = cc.dopts.copts.KeepaliveParams if cc.dopts.copts.Dialer == nil { @@ -202,17 +211,12 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * ctx, cancel = context.WithTimeout(ctx, cc.dopts.timeout) defer cancel() } - defer func() { select { case <-ctx.Done(): conn, err = nil, ctx.Err() default: } - - if err != nil { - cc.Close() - } }() scSet := false @@ -221,7 +225,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * select { case sc, ok := <-cc.dopts.scChan: if ok { - cc.sc = sc + cc.sc = &sc scSet = true } default: @@ -238,9 +242,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * grpclog.Infof("parsed scheme: %q", cc.parsedTarget.Scheme) cc.dopts.resolverBuilder = resolver.Get(cc.parsedTarget.Scheme) if cc.dopts.resolverBuilder == nil { - // If resolver builder is still nil, the parse target's scheme is + // If resolver builder is still nil, the parsed target's scheme is // not registered. Fallback to default resolver and set Endpoint to - // the original unparsed target. + // the original target. grpclog.Infof("scheme %q not registered, fallback to default scheme", cc.parsedTarget.Scheme) cc.parsedTarget = resolver.Target{ Scheme: resolver.GetDefaultScheme(), @@ -267,7 +271,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * select { case sc, ok := <-cc.dopts.scChan: if ok { - cc.sc = sc + cc.sc = &sc } case <-ctx.Done(): return nil, ctx.Err() @@ -389,14 +393,11 @@ type ClientConn struct { mu sync.RWMutex resolverWrapper *ccResolverWrapper - sc ServiceConfig - scRaw string + sc *ServiceConfig conns map[*addrConn]struct{} // Keepalive parameter can be updated if a GoAway is received. mkp keepalive.ClientParameters curBalancerName string - preBalancerName string // previous balancer name. - curAddresses []resolver.Address balancerWrapper *ccBalancerWrapper retryThrottler atomic.Value @@ -437,9 +438,8 @@ func (cc *ClientConn) scWatcher() { } cc.mu.Lock() // TODO: load balance policy runtime change is ignored. - // We may revist this decision in the future. - cc.sc = sc - cc.scRaw = "" + // We may revisit this decision in the future. + cc.sc = &sc cc.mu.Unlock() case <-cc.ctx.Done(): return @@ -466,50 +466,72 @@ func (cc *ClientConn) waitForResolvedAddrs(ctx context.Context) error { } } -func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) { +// gRPC should resort to default service config when: +// * resolver service config is disabled +// * or, resolver does not return a service config or returns an invalid one. +func (cc *ClientConn) fallbackToDefaultServiceConfig(sc string) bool { + if cc.dopts.disableServiceConfig { + return true + } + // The logic below is temporary, will be removed once we change the resolver.State ServiceConfig field type. + // Right now, we assume that empty service config string means resolver does not return a config. + if sc == "" { + return true + } + // TODO: the logic below is temporary. Once we finish the logic to validate service config + // in resolver, we will replace the logic below. + _, err := parseServiceConfig(sc) + return err != nil +} + +func (cc *ClientConn) updateResolverState(s resolver.State) error { cc.mu.Lock() defer cc.mu.Unlock() + // Check if the ClientConn is already closed. Some fields (e.g. + // balancerWrapper) are set to nil when closing the ClientConn, and could + // cause nil pointer panic if we don't have this check. if cc.conns == nil { - // cc was closed. - return + return nil } - if reflect.DeepEqual(cc.curAddresses, addrs) { - return + if cc.fallbackToDefaultServiceConfig(s.ServiceConfig) { + if cc.dopts.defaultServiceConfig != nil && cc.sc == nil { + cc.applyServiceConfig(cc.dopts.defaultServiceConfig) + } + } else { + // TODO: the parsing logic below will be moved inside resolver. + sc, err := parseServiceConfig(s.ServiceConfig) + if err != nil { + return err + } + if cc.sc == nil || cc.sc.rawJSONString != s.ServiceConfig { + cc.applyServiceConfig(sc) + } } - cc.curAddresses = addrs - cc.firstResolveEvent.Fire() + // update the service config that will be sent to balancer. + if cc.sc != nil { + s.ServiceConfig = cc.sc.rawJSONString + } if cc.dopts.balancerBuilder == nil { // Only look at balancer types and switch balancer if balancer dial // option is not set. var isGRPCLB bool - for _, a := range addrs { + for _, a := range s.Addresses { if a.Type == resolver.GRPCLB { isGRPCLB = true break } } var newBalancerName string + // TODO: use new loadBalancerConfig field with appropriate priority. if isGRPCLB { newBalancerName = grpclbName + } else if cc.sc != nil && cc.sc.LB != nil { + newBalancerName = *cc.sc.LB } else { - // Address list doesn't contain grpclb address. Try to pick a - // non-grpclb balancer. - newBalancerName = cc.curBalancerName - // If current balancer is grpclb, switch to the previous one. - if newBalancerName == grpclbName { - newBalancerName = cc.preBalancerName - } - // The following could be true in two cases: - // - the first time handling resolved addresses - // (curBalancerName="") - // - the first time handling non-grpclb addresses - // (curBalancerName="grpclb", preBalancerName="") - if newBalancerName == "" { - newBalancerName = PickFirstBalancerName - } + newBalancerName = PickFirstBalancerName } cc.switchBalancer(newBalancerName) } else if cc.balancerWrapper == nil { @@ -518,7 +540,9 @@ func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) { cc.balancerWrapper = newCCBalancerWrapper(cc, cc.dopts.balancerBuilder, cc.balancerBuildOpts) } - cc.balancerWrapper.handleResolvedAddrs(addrs, nil) + cc.balancerWrapper.updateResolverState(s) + cc.firstResolveEvent.Fire() + return nil } // switchBalancer starts the switching from current balancer to the balancer @@ -530,10 +554,6 @@ func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) { // // Caller must hold cc.mu. func (cc *ClientConn) switchBalancer(name string) { - if cc.conns == nil { - return - } - if strings.ToLower(cc.curBalancerName) == strings.ToLower(name) { return } @@ -543,15 +563,11 @@ func (cc *ClientConn) switchBalancer(name string) { grpclog.Infoln("ignoring balancer switching: Balancer DialOption used instead") return } - // TODO(bar switching) change this to two steps: drain and close. - // Keep track of sc in wrapper. if cc.balancerWrapper != nil { cc.balancerWrapper.close() } builder := balancer.Get(name) - // TODO(yuxuanli): If user send a service config that does not contain a valid balancer name, should - // we reuse previous one? if channelz.IsOn() { if builder == nil { channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{ @@ -570,7 +586,6 @@ func (cc *ClientConn) switchBalancer(name string) { builder = newPickfirstBuilder() } - cc.preBalancerName = cc.curBalancerName cc.curBalancerName = builder.Name() cc.balancerWrapper = newCCBalancerWrapper(cc, builder, cc.balancerBuildOpts) } @@ -592,13 +607,12 @@ func (cc *ClientConn) handleSubConnStateChange(sc balancer.SubConn, s connectivi // Caller needs to make sure len(addrs) > 0. func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (*addrConn, error) { ac := &addrConn{ - cc: cc, - addrs: addrs, - scopts: opts, - dopts: cc.dopts, - czData: new(channelzData), - successfulHandshake: true, // make the first nextAddr() call _not_ move addrIdx up by 1 - resetBackoff: make(chan struct{}), + cc: cc, + addrs: addrs, + scopts: opts, + dopts: cc.dopts, + czData: new(channelzData), + resetBackoff: make(chan struct{}), } ac.ctx, ac.cancel = context.WithCancel(cc.ctx) // Track ac in cc. This needs to be done before any getTransport(...) is called. @@ -680,11 +694,10 @@ func (ac *addrConn) connect() error { return nil } ac.updateConnectivityState(connectivity.Connecting) - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) ac.mu.Unlock() // Start a goroutine connecting to the server asynchronously. - go ac.resetTransport(false) + go ac.resetTransport() return nil } @@ -703,6 +716,12 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { return true } + // Unless we're busy reconnecting already, let's reconnect from the top of + // the list. + if ac.state != connectivity.Ready { + return false + } + var curAddrFound bool for _, a := range addrs { if reflect.DeepEqual(ac.curAddr, a) { @@ -713,7 +732,6 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { grpclog.Infof("addrConn: tryUpdateAddrs curAddrFound: %v", curAddrFound) if curAddrFound { ac.addrs = addrs - ac.addrIdx = 0 // Start reconnecting from beginning in the new list. } return curAddrFound @@ -730,6 +748,9 @@ func (cc *ClientConn) GetMethodConfig(method string) MethodConfig { // TODO: Avoid the locking here. cc.mu.RLock() defer cc.mu.RUnlock() + if cc.sc == nil { + return MethodConfig{} + } m, ok := cc.sc.Methods[method] if !ok { i := strings.LastIndex(method, "/") @@ -741,14 +762,15 @@ func (cc *ClientConn) GetMethodConfig(method string) MethodConfig { func (cc *ClientConn) healthCheckConfig() *healthCheckConfig { cc.mu.RLock() defer cc.mu.RUnlock() + if cc.sc == nil { + return nil + } return cc.sc.healthCheckConfig } func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, func(balancer.DoneInfo), error) { - hdr, _ := metadata.FromOutgoingContext(ctx) t, done, err := cc.blockingpicker.pick(ctx, failfast, balancer.PickOptions{ FullMethodName: method, - Header: hdr, }) if err != nil { return nil, nil, toRPCErr(err) @@ -756,65 +778,25 @@ func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method st return t, done, nil } -// handleServiceConfig parses the service config string in JSON format to Go native -// struct ServiceConfig, and store both the struct and the JSON string in ClientConn. -func (cc *ClientConn) handleServiceConfig(js string) error { - if cc.dopts.disableServiceConfig { - return nil +func (cc *ClientConn) applyServiceConfig(sc *ServiceConfig) error { + if sc == nil { + // should never reach here. + return fmt.Errorf("got nil pointer for service config") } - if cc.scRaw == js { - return nil - } - if channelz.IsOn() { - channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{ - // The special formatting of \"%s\" instead of %q is to provide nice printing of service config - // for human consumption. - Desc: fmt.Sprintf("Channel has a new service config \"%s\"", js), - Severity: channelz.CtINFO, - }) - } - sc, err := parseServiceConfig(js) - if err != nil { - return err - } - cc.mu.Lock() - // Check if the ClientConn is already closed. Some fields (e.g. - // balancerWrapper) are set to nil when closing the ClientConn, and could - // cause nil pointer panic if we don't have this check. - if cc.conns == nil { - cc.mu.Unlock() - return nil - } - cc.scRaw = js cc.sc = sc - if sc.retryThrottling != nil { + if cc.sc.retryThrottling != nil { newThrottler := &retryThrottler{ - tokens: sc.retryThrottling.MaxTokens, - max: sc.retryThrottling.MaxTokens, - thresh: sc.retryThrottling.MaxTokens / 2, - ratio: sc.retryThrottling.TokenRatio, + tokens: cc.sc.retryThrottling.MaxTokens, + max: cc.sc.retryThrottling.MaxTokens, + thresh: cc.sc.retryThrottling.MaxTokens / 2, + ratio: cc.sc.retryThrottling.TokenRatio, } cc.retryThrottler.Store(newThrottler) } else { cc.retryThrottler.Store((*retryThrottler)(nil)) } - if sc.LB != nil && *sc.LB != grpclbName { // "grpclb" is not a valid balancer option in service config. - if cc.curBalancerName == grpclbName { - // If current balancer is grpclb, there's at least one grpclb - // balancer address in the resolved list. Don't switch the balancer, - // but change the previous balancer name, so if a new resolved - // address list doesn't contain grpclb address, balancer will be - // switched to *sc.LB. - cc.preBalancerName = *sc.LB - } else { - cc.switchBalancer(*sc.LB) - cc.balancerWrapper.handleResolvedAddrs(cc.curAddresses, nil) - } - } - - cc.mu.Unlock() return nil } @@ -890,7 +872,7 @@ func (cc *ClientConn) Close() error { } channelz.AddTraceEvent(cc.channelzID, ted) // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add trace reference to - // the entity beng deleted, and thus prevent it from being deleted right away. + // the entity being deleted, and thus prevent it from being deleted right away. channelz.RemoveEntry(cc.channelzID) } return nil @@ -913,42 +895,34 @@ type addrConn struct { transport transport.ClientTransport // The current transport. mu sync.Mutex - addrIdx int // The index in addrs list to start reconnecting from. curAddr resolver.Address // The current address. addrs []resolver.Address // All addresses that the resolver resolved to. // Use updateConnectivityState for updating addrConn's connectivity state. state connectivity.State - tearDownErr error // The reason this addrConn is torn down. - - backoffIdx int - // backoffDeadline is the time until which resetTransport needs to - // wait before increasing backoffIdx count. - backoffDeadline time.Time - // connectDeadline is the time by which all connection - // negotiations must complete. - connectDeadline time.Time - + backoffIdx int // Needs to be stateful for resetConnectBackoff. resetBackoff chan struct{} - channelzID int64 // channelz unique identification number + channelzID int64 // channelz unique identification number. czData *channelzData - - successfulHandshake bool - - healthCheckEnabled bool } // Note: this requires a lock on ac.mu. func (ac *addrConn) updateConnectivityState(s connectivity.State) { + if ac.state == s { + return + } + + updateMsg := fmt.Sprintf("Subchannel Connectivity change to %v", s) ac.state = s if channelz.IsOn() { channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Subchannel Connectivity change to %v", s), + Desc: updateMsg, Severity: channelz.CtINFO, }) } + ac.cc.handleSubConnStateChange(ac.acbw, s) } // adjustParams updates parameters used to create transports upon @@ -965,24 +939,10 @@ func (ac *addrConn) adjustParams(r transport.GoAwayReason) { } } -// resetTransport makes sure that a healthy ac.transport exists. -// -// The transport will close itself when it encounters an error, or on GOAWAY, or on deadline waiting for handshake, or -// when the clientconn is closed. Each iteration creating a new transport will try a different address that the balancer -// assigned to the addrConn, until it has tried all addresses. Once it has tried all addresses, it will re-resolve to -// get a new address list. If an error is received, the list is re-resolved and the next reset attempt will try from the -// beginning. This method has backoff built in. The backoff amount starts at 0 and increases each time resolution occurs -// (addresses are exhausted). The backoff amount is reset to 0 each time a handshake is received. -// -// If the DialOption WithWaitForHandshake was set, resetTransport returns successfully only after handshake is received. -func (ac *addrConn) resetTransport(resolveNow bool) { - for { - // If this is the first in a line of resets, we want to resolve immediately. The only other time we - // want to reset is if we have tried all the addresses handed to us. - if resolveNow { - ac.mu.Lock() +func (ac *addrConn) resetTransport() { + for i := 0; ; i++ { + if i > 0 { ac.cc.resolveNow(resolver.ResolveNowOption{}) - ac.mu.Unlock() } ac.mu.Lock() @@ -991,63 +951,128 @@ func (ac *addrConn) resetTransport(resolveNow bool) { return } - // The transport that was used before is no longer viable. - ac.transport = nil - // If the connection is READY, a failure must have occurred. - // Otherwise, we'll consider this is a transient failure when: - // We've exhausted all addresses - // We're in CONNECTING - // And it's not the very first addr to try TODO(deklerk) find a better way to do this than checking ac.successfulHandshake - if ac.state == connectivity.Ready || (ac.addrIdx == len(ac.addrs)-1 && ac.state == connectivity.Connecting && !ac.successfulHandshake) { - ac.updateConnectivityState(connectivity.TransientFailure) - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) + addrs := ac.addrs + backoffFor := ac.dopts.bs.Backoff(ac.backoffIdx) + // This will be the duration that dial gets to finish. + dialDuration := minConnectTimeout + if ac.dopts.minConnectTimeout != nil { + dialDuration = ac.dopts.minConnectTimeout() } - ac.transport = nil + + if dialDuration < backoffFor { + // Give dial more time as we keep failing to connect. + dialDuration = backoffFor + } + // We can potentially spend all the time trying the first address, and + // if the server accepts the connection and then hangs, the following + // addresses will never be tried. + // + // The spec doesn't mention what should be done for multiple addresses. + // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm + connectDeadline := time.Now().Add(dialDuration) ac.mu.Unlock() - if err := ac.nextAddr(); err != nil { - return + newTr, addr, reconnect, err := ac.tryAllAddrs(addrs, connectDeadline) + if err != nil { + // After exhausting all addresses, the addrConn enters + // TRANSIENT_FAILURE. + ac.mu.Lock() + if ac.state == connectivity.Shutdown { + ac.mu.Unlock() + return + } + ac.updateConnectivityState(connectivity.TransientFailure) + + // Backoff. + b := ac.resetBackoff + ac.mu.Unlock() + + timer := time.NewTimer(backoffFor) + select { + case <-timer.C: + ac.mu.Lock() + ac.backoffIdx++ + ac.mu.Unlock() + case <-b: + timer.Stop() + case <-ac.ctx.Done(): + timer.Stop() + return + } + continue } ac.mu.Lock() if ac.state == connectivity.Shutdown { + newTr.Close() ac.mu.Unlock() return } + ac.curAddr = addr + ac.transport = newTr + ac.backoffIdx = 0 - backoffIdx := ac.backoffIdx - backoffFor := ac.dopts.bs.Backoff(backoffIdx) - - // This will be the duration that dial gets to finish. - dialDuration := getMinConnectTimeout() - if backoffFor > dialDuration { - // Give dial more time as we keep failing to connect. - dialDuration = backoffFor + healthCheckConfig := ac.cc.healthCheckConfig() + // LB channel health checking is only enabled when all the four requirements below are met: + // 1. it is not disabled by the user with the WithDisableHealthCheck DialOption, + // 2. the internal.HealthCheckFunc is set by importing the grpc/healthcheck package, + // 3. a service config with non-empty healthCheckConfig field is provided, + // 4. the current load balancer allows it. + hctx, hcancel := context.WithCancel(ac.ctx) + healthcheckManagingState := false + if !ac.cc.dopts.disableHealthCheck && healthCheckConfig != nil && ac.scopts.HealthCheckEnabled { + if ac.cc.dopts.healthCheckFunc == nil { + // TODO: add a link to the health check doc in the error message. + grpclog.Error("the client side LB channel health check function has not been set.") + } else { + // TODO(deklerk) refactor to just return transport + go ac.startHealthCheck(hctx, newTr, addr, healthCheckConfig.ServiceName) + healthcheckManagingState = true + } + } + if !healthcheckManagingState { + ac.updateConnectivityState(connectivity.Ready) } - start := time.Now() - connectDeadline := start.Add(dialDuration) - ac.backoffDeadline = start.Add(backoffFor) - ac.connectDeadline = connectDeadline - ac.mu.Unlock() - ac.cc.mu.RLock() - ac.dopts.copts.KeepaliveParams = ac.cc.mkp - ac.cc.mu.RUnlock() - + // Block until the created transport is down. And when this happens, + // we restart from the top of the addr list. + <-reconnect.Done() + hcancel() + + // Need to reconnect after a READY, the addrConn enters + // TRANSIENT_FAILURE. + // + // This will set addrConn to TRANSIENT_FAILURE for a very short period + // of time, and turns CONNECTING. It seems reasonable to skip this, but + // READY-CONNECTING is not a valid transition. ac.mu.Lock() - if ac.state == connectivity.Shutdown { ac.mu.Unlock() return } + ac.updateConnectivityState(connectivity.TransientFailure) + ac.mu.Unlock() + } +} - if ac.state != connectivity.Connecting { - ac.updateConnectivityState(connectivity.Connecting) - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) +// tryAllAddrs tries to creates a connection to the addresses, and stop when at the +// first successful one. It returns the transport, the address and a Event in +// the successful case. The Event fires when the returned transport disconnects. +func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.Time) (transport.ClientTransport, resolver.Address, *grpcsync.Event, error) { + for _, addr := range addrs { + ac.mu.Lock() + if ac.state == connectivity.Shutdown { + ac.mu.Unlock() + return nil, resolver.Address{}, nil, errConnClosing } + ac.updateConnectivityState(connectivity.Connecting) + ac.transport = nil + + ac.cc.mu.RLock() + ac.dopts.copts.KeepaliveParams = ac.cc.mkp + ac.cc.mu.RUnlock() - addr := ac.addrs[ac.addrIdx] copts := ac.dopts.copts if ac.scopts.CredsBundle != nil { copts.CredsBundle = ac.scopts.CredsBundle @@ -1061,77 +1086,45 @@ func (ac *addrConn) resetTransport(resolveNow bool) { }) } - if err := ac.createTransport(backoffIdx, addr, copts, connectDeadline); err != nil { - continue + newTr, reconnect, err := ac.createTransport(addr, copts, connectDeadline) + if err == nil { + return newTr, addr, reconnect, nil } - - return + ac.cc.blockingpicker.updateConnectionError(err) } + + // Couldn't connect to any address. + return nil, resolver.Address{}, nil, fmt.Errorf("couldn't connect to any address") } -// createTransport creates a connection to one of the backends in addrs. -func (ac *addrConn) createTransport(backoffNum int, addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) error { - oneReset := sync.Once{} - skipReset := make(chan struct{}) - allowedToReset := make(chan struct{}) +// createTransport creates a connection to addr. It returns the transport and a +// Event in the successful case. The Event fires when the returned transport +// disconnects. +func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) (transport.ClientTransport, *grpcsync.Event, error) { prefaceReceived := make(chan struct{}) onCloseCalled := make(chan struct{}) + reconnect := grpcsync.NewEvent() - var prefaceMu sync.Mutex - var serverPrefaceReceived bool - var clientPrefaceWrote bool - - hcCtx, hcCancel := context.WithCancel(ac.ctx) + target := transport.TargetInfo{ + Addr: addr.Addr, + Metadata: addr.Metadata, + Authority: ac.cc.authority, + } onGoAway := func(r transport.GoAwayReason) { - hcCancel() ac.mu.Lock() ac.adjustParams(r) ac.mu.Unlock() - select { - case <-skipReset: // The outer resetTransport loop will handle reconnection. - return - case <-allowedToReset: // We're in the clear to reset. - go oneReset.Do(func() { ac.resetTransport(false) }) - } + reconnect.Fire() } - prefaceTimer := time.NewTimer(connectDeadline.Sub(time.Now())) - onClose := func() { - hcCancel() close(onCloseCalled) - prefaceTimer.Stop() - - select { - case <-skipReset: // The outer resetTransport loop will handle reconnection. - return - case <-allowedToReset: // We're in the clear to reset. - oneReset.Do(func() { ac.resetTransport(false) }) - } - } - - target := transport.TargetInfo{ - Addr: addr.Addr, - Metadata: addr.Metadata, - Authority: ac.cc.authority, + reconnect.Fire() } onPrefaceReceipt := func() { close(prefaceReceived) - prefaceTimer.Stop() - - // TODO(deklerk): optimization; does anyone else actually use this lock? maybe we can just remove it for this scope - ac.mu.Lock() - - prefaceMu.Lock() - serverPrefaceReceived = true - if clientPrefaceWrote { - ac.successfulHandshake = true - } - prefaceMu.Unlock() - - ac.mu.Unlock() } connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline) @@ -1141,115 +1134,28 @@ func (ac *addrConn) createTransport(backoffNum int, addr resolver.Address, copts } newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, target, copts, onPrefaceReceipt, onGoAway, onClose) - - if err == nil { - prefaceMu.Lock() - clientPrefaceWrote = true - if serverPrefaceReceived || ac.dopts.reqHandshake == envconfig.RequireHandshakeOff { - ac.successfulHandshake = true - } - prefaceMu.Unlock() - - if ac.dopts.reqHandshake == envconfig.RequireHandshakeOn { - select { - case <-prefaceTimer.C: - // We didn't get the preface in time. - newTr.Close() - err = errors.New("timed out waiting for server handshake") - case <-prefaceReceived: - // We got the preface - huzzah! things are good. - case <-onCloseCalled: - // The transport has already closed - noop. - close(allowedToReset) - return nil - } - } else if ac.dopts.reqHandshake == envconfig.RequireHandshakeHybrid { - go func() { - select { - case <-prefaceTimer.C: - // We didn't get the preface in time. - newTr.Close() - case <-prefaceReceived: - // We got the preface just in the nick of time - huzzah! - case <-onCloseCalled: - // The transport has already closed - noop. - } - }() - } - } - if err != nil { // newTr is either nil, or closed. - ac.cc.blockingpicker.updateConnectionError(err) - ac.mu.Lock() - if ac.state == connectivity.Shutdown { - // ac.tearDown(...) has been invoked. - ac.mu.Unlock() - - // We don't want to reset during this close because we prefer to kick out of this function and let the loop - // in resetTransport take care of reconnecting. - close(skipReset) - - return errConnClosing - } - ac.mu.Unlock() grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v. Err :%v. Reconnecting...", addr, err) - - // We don't want to reset during this close because we prefer to kick out of this function and let the loop - // in resetTransport take care of reconnecting. - close(skipReset) - - return err + return nil, nil, err } - // Now there is a viable transport to be use, so set ac.transport to reflect the new viable transport. - ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - close(skipReset) - newTr.Close() - return nil - } - ac.transport = newTr - ac.mu.Unlock() - - healthCheckConfig := ac.cc.healthCheckConfig() - // LB channel health checking is only enabled when all the four requirements below are met: - // 1. it is not disabled by the user with the WithDisableHealthCheck DialOption, - // 2. the internal.HealthCheckFunc is set by importing the grpc/healthcheck package, - // 3. a service config with non-empty healthCheckConfig field is provided, - // 4. the current load balancer allows it. - if !ac.cc.dopts.disableHealthCheck && healthCheckConfig != nil && ac.scopts.HealthCheckEnabled { - if internal.HealthCheckFunc != nil { - go ac.startHealthCheck(hcCtx, newTr, addr, healthCheckConfig.ServiceName) - close(allowedToReset) - return nil + if ac.dopts.reqHandshake == envconfig.RequireHandshakeOn { + select { + case <-time.After(connectDeadline.Sub(time.Now())): + // We didn't get the preface in time. + newTr.Close() + grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr) + return nil, nil, errors.New("timed out waiting for server handshake") + case <-prefaceReceived: + // We got the preface - huzzah! things are good. + case <-onCloseCalled: + // The transport has already closed - noop. + return nil, nil, errors.New("connection closed") + // TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix. } - // TODO: add a link to the health check doc in the error message. - grpclog.Error("the client side LB channel health check function has not been set.") - } - - // No LB channel health check case - ac.mu.Lock() - - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - - // unblock onGoAway/onClose callback. - close(skipReset) - return errConnClosing } - - ac.updateConnectivityState(connectivity.Ready) - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) - ac.curAddr = addr - - ac.mu.Unlock() - - // Ok, _now_ we will finally let the transport reset if it encounters a closable error. Without this, the reader - // goroutine failing races with all the code in this method that sets the connection to "ready". - close(allowedToReset) - return nil + return newTr, reconnect, nil } func (ac *addrConn) startHealthCheck(ctx context.Context, newTr transport.ClientTransport, addr resolver.Address, serviceName string) { @@ -1269,19 +1175,12 @@ func (ac *addrConn) startHealthCheck(ctx context.Context, newTr transport.Client firstReady = false ac.curAddr = addr } - if ac.state != connectivity.Ready { - ac.updateConnectivityState(connectivity.Ready) - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) - } + ac.updateConnectivityState(connectivity.Ready) } else { - if ac.state != connectivity.TransientFailure { - ac.updateConnectivityState(connectivity.TransientFailure) - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) - } + ac.updateConnectivityState(connectivity.TransientFailure) } } - - err := internal.HealthCheckFunc(ctx, newStream, reportHealth, serviceName) + err := ac.cc.dopts.healthCheckFunc(ctx, newStream, reportHealth, serviceName) if err != nil { if status.Code(err) == codes.Unimplemented { if channelz.IsOn() { @@ -1297,55 +1196,6 @@ func (ac *addrConn) startHealthCheck(ctx context.Context, newTr transport.Client } } -// nextAddr increments the addrIdx if there are more addresses to try. If -// there are no more addrs to try it will re-resolve, set addrIdx to 0, and -// increment the backoffIdx. -// -// nextAddr must be called without ac.mu being held. -func (ac *addrConn) nextAddr() error { - ac.mu.Lock() - - // If a handshake has been observed, we want the next usage to start at - // index 0 immediately. - if ac.successfulHandshake { - ac.successfulHandshake = false - ac.backoffDeadline = time.Time{} - ac.connectDeadline = time.Time{} - ac.addrIdx = 0 - ac.backoffIdx = 0 - ac.mu.Unlock() - return nil - } - - if ac.addrIdx < len(ac.addrs)-1 { - ac.addrIdx++ - ac.mu.Unlock() - return nil - } - - ac.addrIdx = 0 - ac.backoffIdx++ - - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - return errConnClosing - } - ac.cc.resolveNow(resolver.ResolveNowOption{}) - backoffDeadline := ac.backoffDeadline - b := ac.resetBackoff - ac.mu.Unlock() - timer := time.NewTimer(backoffDeadline.Sub(time.Now())) - select { - case <-timer.C: - case <-b: - timer.Stop() - case <-ac.ctx.Done(): - timer.Stop() - return ac.ctx.Err() - } - return nil -} - func (ac *addrConn) resetConnectBackoff() { ac.mu.Lock() close(ac.resetBackoff) @@ -1393,8 +1243,6 @@ func (ac *addrConn) tearDown(err error) { // between setting the state and logic that waits on context cancelation / etc. ac.updateConnectivityState(connectivity.Shutdown) ac.cancel() - ac.tearDownErr = err - ac.cc.handleSubConnStateChange(ac.acbw, ac.state) ac.curAddr = resolver.Address{} if err == errConnDrain && curTr != nil { // GracefulClose(...) may be executed multiple times when diff --git a/vendor/google.golang.org/grpc/connectivity/connectivity.go b/vendor/google.golang.org/grpc/connectivity/connectivity.go index b1d7dbc5470d..34ec36fbf6d9 100644 --- a/vendor/google.golang.org/grpc/connectivity/connectivity.go +++ b/vendor/google.golang.org/grpc/connectivity/connectivity.go @@ -52,7 +52,7 @@ func (s State) String() string { const ( // Idle indicates the ClientConn is idle. Idle State = iota - // Connecting indicates the ClienConn is connecting. + // Connecting indicates the ClientConn is connecting. Connecting // Ready indicates the ClientConn is ready for work. Ready diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index a851560456b4..88aff94596a1 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -36,9 +36,6 @@ import ( "google.golang.org/grpc/credentials/internal" ) -// alpnProtoStr are the specified application level protocols for gRPC. -var alpnProtoStr = []string{"h2"} - // PerRPCCredentials defines the common interface for the credentials which need to // attach security information to every RPC (e.g., oauth2). type PerRPCCredentials interface { @@ -208,10 +205,23 @@ func (c *tlsCreds) OverrideServerName(serverNameOverride string) error { return nil } +const alpnProtoStrH2 = "h2" + +func appendH2ToNextProtos(ps []string) []string { + for _, p := range ps { + if p == alpnProtoStrH2 { + return ps + } + } + ret := make([]string, 0, len(ps)+1) + ret = append(ret, ps...) + return append(ret, alpnProtoStrH2) +} + // NewTLS uses c to construct a TransportCredentials based on TLS. func NewTLS(c *tls.Config) TransportCredentials { tc := &tlsCreds{cloneTLSConfig(c)} - tc.config.NextProtos = alpnProtoStr + tc.config.NextProtos = appendH2ToNextProtos(tc.config.NextProtos) return tc } diff --git a/vendor/google.golang.org/grpc/credentials/tls13.go b/vendor/google.golang.org/grpc/credentials/tls13.go new file mode 100644 index 000000000000..ccbf35b33125 --- /dev/null +++ b/vendor/google.golang.org/grpc/credentials/tls13.go @@ -0,0 +1,30 @@ +// +build go1.12 + +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package credentials + +import "crypto/tls" + +// This init function adds cipher suite constants only defined in Go 1.12. +func init() { + cipherSuiteLookup[tls.TLS_AES_128_GCM_SHA256] = "TLS_AES_128_GCM_SHA256" + cipherSuiteLookup[tls.TLS_AES_256_GCM_SHA384] = "TLS_AES_256_GCM_SHA384" + cipherSuiteLookup[tls.TLS_CHACHA20_POLY1305_SHA256] = "TLS_CHACHA20_POLY1305_SHA256" +} diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index fe00a254d065..e114fecbb7b4 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -26,6 +26,7 @@ import ( "google.golang.org/grpc/balancer" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/envconfig" @@ -54,12 +55,16 @@ type dialOptions struct { // balancer, and also by WithBalancerName dial option. balancerBuilder balancer.Builder // This is to support grpclb. - resolverBuilder resolver.Builder - reqHandshake envconfig.RequireHandshakeSetting - channelzParentID int64 - disableServiceConfig bool - disableRetry bool - disableHealthCheck bool + resolverBuilder resolver.Builder + reqHandshake envconfig.RequireHandshakeSetting + channelzParentID int64 + disableServiceConfig bool + disableRetry bool + disableHealthCheck bool + healthCheckFunc internal.HealthChecker + minConnectTimeout func() time.Duration + defaultServiceConfig *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON. + defaultServiceConfigRawJSON *string } // DialOption configures how we set up the connection. @@ -94,10 +99,8 @@ func newFuncDialOption(f func(*dialOptions)) *funcDialOption { // WithWaitForHandshake blocks until the initial settings frame is received from // the server before assigning RPCs to the connection. // -// Deprecated: this will become the default behavior in the 1.17 release, and -// will be removed after the 1.18 release. To override the default behavior in -// the 1.17 release, either use this dial option or set the environment -// variable GRPC_GO_READY_BEFORE_HANDSHAKE=on. +// Deprecated: this is the default behavior, and this option will be removed +// after the 1.18 release. func WithWaitForHandshake() DialOption { return newFuncDialOption(func(o *dialOptions) { o.reqHandshake = envconfig.RequireHandshakeOn @@ -165,7 +168,7 @@ func WithDefaultCallOptions(cos ...CallOption) DialOption { // WithCodec returns a DialOption which sets a codec for message marshaling and // unmarshaling. // -// Deprecated: use WithDefaultCallOptions(CallCustomCodec(c)) instead. +// Deprecated: use WithDefaultCallOptions(ForceCodec(_)) instead. func WithCodec(c Codec) DialOption { return WithDefaultCallOptions(CallCustomCodec(c)) } @@ -329,26 +332,32 @@ func WithTimeout(d time.Duration) DialOption { }) } -func withContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption { +// WithContextDialer returns a DialOption that sets a dialer to create +// connections. If FailOnNonTempDialError() is set to true, and an error is +// returned by f, gRPC checks the error's Temporary() method to decide if it +// should try to reconnect to the network address. +func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption { return newFuncDialOption(func(o *dialOptions) { o.copts.Dialer = f }) } func init() { - internal.WithContextDialer = withContextDialer internal.WithResolverBuilder = withResolverBuilder + internal.WithHealthCheckFunc = withHealthCheckFunc } // WithDialer returns a DialOption that specifies a function to use for dialing // network addresses. If FailOnNonTempDialError() is set to true, and an error // is returned by f, gRPC checks the error's Temporary() method to decide if it // should try to reconnect to the network address. +// +// Deprecated: use WithContextDialer instead func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { - return withContextDialer( + return WithContextDialer( func(ctx context.Context, addr string) (net.Conn, error) { if deadline, ok := ctx.Deadline(); ok { - return f(addr, deadline.Sub(time.Now())) + return f(addr, time.Until(deadline)) } return f(addr, 0) }) @@ -388,6 +397,10 @@ func WithUserAgent(s string) DialOption { // WithKeepaliveParams returns a DialOption that specifies keepalive parameters // for the client transport. func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption { + if kp.Time < internal.KeepaliveMinPingTime { + grpclog.Warningf("Adjusting keepalive ping interval to minimum period of %v", internal.KeepaliveMinPingTime) + kp.Time = internal.KeepaliveMinPingTime + } return newFuncDialOption(func(o *dialOptions) { o.copts.KeepaliveParams = kp }) @@ -430,12 +443,27 @@ func WithChannelzParentID(id int64) DialOption { // WithDisableServiceConfig returns a DialOption that causes grpc to ignore any // service config provided by the resolver and provides a hint to the resolver // to not fetch service configs. +// +// Note that, this dial option only disables service config from resolver. If +// default service config is provided, grpc will use the default service config. func WithDisableServiceConfig() DialOption { return newFuncDialOption(func(o *dialOptions) { o.disableServiceConfig = true }) } +// WithDefaultServiceConfig returns a DialOption that configures the default +// service config, which will be used in cases where: +// 1. WithDisableServiceConfig is called. +// 2. Resolver does not return service config or if the resolver gets and invalid config. +// +// This API is EXPERIMENTAL. +func WithDefaultServiceConfig(s string) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.defaultServiceConfigRawJSON = &s + }) +} + // WithDisableRetry returns a DialOption that disables retries, even if the // service config enables them. This does not impact transparent retries, which // will happen automatically if no data is written to the wire or if the RPC is @@ -460,7 +488,8 @@ func WithMaxHeaderListSize(s uint32) DialOption { }) } -// WithDisableHealthCheck disables the LB channel health checking for all SubConns of this ClientConn. +// WithDisableHealthCheck disables the LB channel health checking for all +// SubConns of this ClientConn. // // This API is EXPERIMENTAL. func WithDisableHealthCheck() DialOption { @@ -468,13 +497,36 @@ func WithDisableHealthCheck() DialOption { o.disableHealthCheck = true }) } + +// withHealthCheckFunc replaces the default health check function with the +// provided one. It makes tests easier to change the health check function. +// +// For testing purpose only. +func withHealthCheckFunc(f internal.HealthChecker) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.healthCheckFunc = f + }) +} + func defaultDialOptions() dialOptions { return dialOptions{ - disableRetry: !envconfig.Retry, - reqHandshake: envconfig.RequireHandshake, + disableRetry: !envconfig.Retry, + reqHandshake: envconfig.RequireHandshake, + healthCheckFunc: internal.HealthCheckFunc, copts: transport.ConnectOptions{ WriteBufferSize: defaultWriteBufSize, ReadBufferSize: defaultReadBufSize, }, } } + +// withGetMinConnectDeadline specifies the function that clientconn uses to +// get minConnectDeadline. This can be used to make connection attempts happen +// faster/slower. +// +// For testing purpose only. +func withMinConnectDeadline(f func() time.Duration) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.minConnectTimeout = f + }) +} diff --git a/vendor/google.golang.org/grpc/encoding/encoding.go b/vendor/google.golang.org/grpc/encoding/encoding.go index ade8b7cec73a..30a75da99d5e 100644 --- a/vendor/google.golang.org/grpc/encoding/encoding.go +++ b/vendor/google.golang.org/grpc/encoding/encoding.go @@ -102,10 +102,10 @@ func RegisterCodec(codec Codec) { if codec == nil { panic("cannot register a nil Codec") } - contentSubtype := strings.ToLower(codec.Name()) - if contentSubtype == "" { - panic("cannot register Codec with empty string result for String()") + if codec.Name() == "" { + panic("cannot register Codec with empty string result for Name()") } + contentSubtype := strings.ToLower(codec.Name()) registeredCodecs[contentSubtype] = codec } diff --git a/vendor/google.golang.org/grpc/go.mod b/vendor/google.golang.org/grpc/go.mod index f296dcf4e6e4..9f3ef3a539c6 100644 --- a/vendor/google.golang.org/grpc/go.mod +++ b/vendor/google.golang.org/grpc/go.mod @@ -2,19 +2,18 @@ module google.golang.org/grpc require ( cloud.google.com/go v0.26.0 // indirect + github.com/BurntSushi/toml v0.3.1 // indirect github.com/client9/misspell v0.3.4 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/mock v1.1.1 github.com/golang/protobuf v1.2.0 - github.com/kisielk/gotool v1.0.0 // indirect - golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 - golang.org/x/net v0.0.0-20180826012351-8a410e7b638d + golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 + golang.org/x/net v0.0.0-20190311183353-d8887717615a golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect - golang.org/x/sys v0.0.0-20180830151530-49385e6e1522 - golang.org/x/text v0.3.0 // indirect - golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52 + golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a + golang.org/x/tools v0.0.0-20190311212946-11955173bddd google.golang.org/appengine v1.1.0 // indirect google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 - honnef.co/go/tools v0.0.0-20180728063816-88497007e858 + honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099 ) diff --git a/vendor/google.golang.org/grpc/go.sum b/vendor/google.golang.org/grpc/go.sum index bfb6bb7c0ed4..b8638ce769dd 100644 --- a/vendor/google.golang.org/grpc/go.sum +++ b/vendor/google.golang.org/grpc/go.sum @@ -1,5 +1,7 @@ cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= @@ -8,25 +10,24 @@ github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 h1:x/bBzNauLQAlE3fLku/xy92Y8QwKX5HZymrMz2IiKFc= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522 h1:Ve1ORMCxvRmSXBwJK+t3Oy+V2vRW2OetUQBq4rJIkZE= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52 h1:JG/0uqcGdTNgq7FdU+61l5Pdmb8putNZlXb65bJBROs= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858 h1:wN+eVZ7U+gqdqkec6C6VXR1OFf9a5Ul9ETzeYsYv20g= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099 h1:XJP7lxbSxWLOMNdBE4B/STaqVy6L73o0knwj2vIlxnw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/google.golang.org/grpc/grpclog/grpclog.go b/vendor/google.golang.org/grpc/grpclog/grpclog.go index 1fabb11e1bab..51bb9457cdab 100644 --- a/vendor/google.golang.org/grpc/grpclog/grpclog.go +++ b/vendor/google.golang.org/grpc/grpclog/grpclog.go @@ -18,7 +18,7 @@ // Package grpclog defines logging for grpc. // -// All logs in transport package only go to verbose level 2. +// All logs in transport and grpclb packages only go to verbose level 2. // All logs in other packages in grpc are logged in spite of the verbosity level. // // In the default logger, diff --git a/vendor/google.golang.org/grpc/health/server.go b/vendor/google.golang.org/grpc/health/server.go index c86e4998897d..c79f9d2ab80c 100644 --- a/vendor/google.golang.org/grpc/health/server.go +++ b/vendor/google.golang.org/grpc/health/server.go @@ -27,6 +27,7 @@ import ( "sync" "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" healthgrpc "google.golang.org/grpc/health/grpc_health_v1" healthpb "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/status" @@ -35,6 +36,9 @@ import ( // Server implements `service Health`. type Server struct { mu sync.Mutex + // If shutdown is true, it's expected all serving status is NOT_SERVING, and + // will stay in NOT_SERVING. + shutdown bool // statusMap stores the serving status of the services this Server monitors. statusMap map[string]healthpb.HealthCheckResponse_ServingStatus updates map[string]map[healthgrpc.Health_WatchServer]chan healthpb.HealthCheckResponse_ServingStatus @@ -110,7 +114,15 @@ func (s *Server) Watch(in *healthpb.HealthCheckRequest, stream healthgrpc.Health func (s *Server) SetServingStatus(service string, servingStatus healthpb.HealthCheckResponse_ServingStatus) { s.mu.Lock() defer s.mu.Unlock() + if s.shutdown { + grpclog.Infof("health: status changing for %s to %v is ignored because health service is shutdown", service, servingStatus) + return + } + + s.setServingStatusLocked(service, servingStatus) +} +func (s *Server) setServingStatusLocked(service string, servingStatus healthpb.HealthCheckResponse_ServingStatus) { s.statusMap[service] = servingStatus for _, update := range s.updates[service] { // Clears previous updates, that are not sent to the client, from the channel. @@ -123,3 +135,31 @@ func (s *Server) SetServingStatus(service string, servingStatus healthpb.HealthC update <- servingStatus } } + +// Shutdown sets all serving status to NOT_SERVING, and configures the server to +// ignore all future status changes. +// +// This changes serving status for all services. To set status for a perticular +// services, call SetServingStatus(). +func (s *Server) Shutdown() { + s.mu.Lock() + defer s.mu.Unlock() + s.shutdown = true + for service := range s.statusMap { + s.setServingStatusLocked(service, healthpb.HealthCheckResponse_NOT_SERVING) + } +} + +// Resume sets all serving status to SERVING, and configures the server to +// accept all future status changes. +// +// This changes serving status for all services. To set status for a perticular +// services, call SetServingStatus(). +func (s *Server) Resume() { + s.mu.Lock() + defer s.mu.Unlock() + s.shutdown = false + for service := range s.statusMap { + s.setServingStatusLocked(service, healthpb.HealthCheckResponse_SERVING) + } +} diff --git a/vendor/google.golang.org/grpc/internal/balancerload/load.go b/vendor/google.golang.org/grpc/internal/balancerload/load.go new file mode 100644 index 000000000000..3a905d96657e --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/balancerload/load.go @@ -0,0 +1,46 @@ +/* + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Package balancerload defines APIs to parse server loads in trailers. The +// parsed loads are sent to balancers in DoneInfo. +package balancerload + +import ( + "google.golang.org/grpc/metadata" +) + +// Parser converts loads from metadata into a concrete type. +type Parser interface { + // Parse parses loads from metadata. + Parse(md metadata.MD) interface{} +} + +var parser Parser + +// SetParser sets the load parser. +// +// Not mutex-protected, should be called before any gRPC functions. +func SetParser(lr Parser) { + parser = lr +} + +// Parse calls parser.Read(). +func Parse(md metadata.MD) interface{} { + if parser == nil { + return nil + } + return parser.Parse(md) +} diff --git a/vendor/google.golang.org/grpc/internal/binarylog/env_config.go b/vendor/google.golang.org/grpc/internal/binarylog/env_config.go index eb188eae5a3e..4cc2525df7fb 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/env_config.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/env_config.go @@ -180,7 +180,7 @@ func parseHeaderMessageLengthConfig(c string) (hdrLenStr, msgLenStr uint64, err if s := match[1]; s != "" { msgLenStr, err = strconv.ParseUint(s, 10, 64) if err != nil { - return 0, 0, fmt.Errorf("Failed to convert %q to uint", s) + return 0, 0, fmt.Errorf("failed to convert %q to uint", s) } return 0, msgLenStr, nil } @@ -195,13 +195,13 @@ func parseHeaderMessageLengthConfig(c string) (hdrLenStr, msgLenStr uint64, err if s := match[1]; s != "" { hdrLenStr, err = strconv.ParseUint(s, 10, 64) if err != nil { - return 0, 0, fmt.Errorf("Failed to convert %q to uint", s) + return 0, 0, fmt.Errorf("failed to convert %q to uint", s) } } if s := match[2]; s != "" { msgLenStr, err = strconv.ParseUint(s, 10, 64) if err != nil { - return 0, 0, fmt.Errorf("Failed to convert %q to uint", s) + return 0, 0, fmt.Errorf("failed to convert %q to uint", s) } } return hdrLenStr, msgLenStr, nil diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go index b06cdd4d43b4..160f6e8616f5 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -377,10 +377,7 @@ func metadataKeyOmit(key string) bool { case "grpc-trace-bin": // grpc-trace-bin is special because it's visiable to users. return false } - if strings.HasPrefix(key, "grpc-") { - return true - } - return false + return strings.HasPrefix(key, "grpc-") } func mdToMetadataProto(md metadata.MD) *pb.Metadata { diff --git a/vendor/google.golang.org/grpc/internal/channelz/funcs.go b/vendor/google.golang.org/grpc/internal/channelz/funcs.go index 3021a31a525c..041520d35199 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/funcs.go +++ b/vendor/google.golang.org/grpc/internal/channelz/funcs.go @@ -40,7 +40,7 @@ var ( db dbWrapper idGen idGenerator // EntryPerPage defines the number of channelz entries to be shown on a web page. - EntryPerPage = 50 + EntryPerPage = int64(50) curState int32 maxTraceEntry = defaultMaxTraceEntry ) @@ -113,20 +113,20 @@ func NewChannelzStorage() { // boolean indicating whether there's more top channels to be queried for. // // The arg id specifies that only top channel with id at or above it will be included -// in the result. The returned slice is up to a length of EntryPerPage, and is -// sorted in ascending id order. -func GetTopChannels(id int64) ([]*ChannelMetric, bool) { - return db.get().GetTopChannels(id) +// in the result. The returned slice is up to a length of the arg maxResults or +// EntryPerPage if maxResults is zero, and is sorted in ascending id order. +func GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { + return db.get().GetTopChannels(id, maxResults) } // GetServers returns a slice of server's ServerMetric, along with a // boolean indicating whether there's more servers to be queried for. // // The arg id specifies that only server with id at or above it will be included -// in the result. The returned slice is up to a length of EntryPerPage, and is -// sorted in ascending id order. -func GetServers(id int64) ([]*ServerMetric, bool) { - return db.get().GetServers(id) +// in the result. The returned slice is up to a length of the arg maxResults or +// EntryPerPage if maxResults is zero, and is sorted in ascending id order. +func GetServers(id int64, maxResults int64) ([]*ServerMetric, bool) { + return db.get().GetServers(id, maxResults) } // GetServerSockets returns a slice of server's (identified by id) normal socket's @@ -134,10 +134,10 @@ func GetServers(id int64) ([]*ServerMetric, bool) { // be queried for. // // The arg startID specifies that only sockets with id at or above it will be -// included in the result. The returned slice is up to a length of EntryPerPage, -// and is sorted in ascending id order. -func GetServerSockets(id int64, startID int64) ([]*SocketMetric, bool) { - return db.get().GetServerSockets(id, startID) +// included in the result. The returned slice is up to a length of the arg maxResults +// or EntryPerPage if maxResults is zero, and is sorted in ascending id order. +func GetServerSockets(id int64, startID int64, maxResults int64) ([]*SocketMetric, bool) { + return db.get().GetServerSockets(id, startID, maxResults) } // GetChannel returns the ChannelMetric for the channel (identified by id). @@ -155,6 +155,11 @@ func GetSocket(id int64) *SocketMetric { return db.get().GetSocket(id) } +// GetServer returns the ServerMetric for the server (identified by id). +func GetServer(id int64) *ServerMetric { + return db.get().GetServer(id) +} + // RegisterChannel registers the given channel c in channelz database with ref // as its reference name, and add it to the child list of its parent (identified // by pid). pid = 0 means no parent. It returns the unique channelz tracking id @@ -447,29 +452,32 @@ func copyMap(m map[int64]string) map[int64]string { return n } -func min(a, b int) int { +func min(a, b int64) int64 { if a < b { return a } return b } -func (c *channelMap) GetTopChannels(id int64) ([]*ChannelMetric, bool) { +func (c *channelMap) GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { + if maxResults <= 0 { + maxResults = EntryPerPage + } c.mu.RLock() - l := len(c.topLevelChannels) + l := int64(len(c.topLevelChannels)) ids := make([]int64, 0, l) - cns := make([]*channel, 0, min(l, EntryPerPage)) + cns := make([]*channel, 0, min(l, maxResults)) for k := range c.topLevelChannels { ids = append(ids, k) } sort.Sort(int64Slice(ids)) idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := 0 + count := int64(0) var end bool var t []*ChannelMetric for i, v := range ids[idx:] { - if count == EntryPerPage { + if count == maxResults { break } if cn, ok := c.channels[v]; ok { @@ -499,21 +507,24 @@ func (c *channelMap) GetTopChannels(id int64) ([]*ChannelMetric, bool) { return t, end } -func (c *channelMap) GetServers(id int64) ([]*ServerMetric, bool) { +func (c *channelMap) GetServers(id, maxResults int64) ([]*ServerMetric, bool) { + if maxResults <= 0 { + maxResults = EntryPerPage + } c.mu.RLock() - l := len(c.servers) + l := int64(len(c.servers)) ids := make([]int64, 0, l) - ss := make([]*server, 0, min(l, EntryPerPage)) + ss := make([]*server, 0, min(l, maxResults)) for k := range c.servers { ids = append(ids, k) } sort.Sort(int64Slice(ids)) idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := 0 + count := int64(0) var end bool var s []*ServerMetric for i, v := range ids[idx:] { - if count == EntryPerPage { + if count == maxResults { break } if svr, ok := c.servers[v]; ok { @@ -541,7 +552,10 @@ func (c *channelMap) GetServers(id int64) ([]*ServerMetric, bool) { return s, end } -func (c *channelMap) GetServerSockets(id int64, startID int64) ([]*SocketMetric, bool) { +func (c *channelMap) GetServerSockets(id int64, startID int64, maxResults int64) ([]*SocketMetric, bool) { + if maxResults <= 0 { + maxResults = EntryPerPage + } var svr *server var ok bool c.mu.RLock() @@ -551,18 +565,18 @@ func (c *channelMap) GetServerSockets(id int64, startID int64) ([]*SocketMetric, return nil, true } svrskts := svr.sockets - l := len(svrskts) + l := int64(len(svrskts)) ids := make([]int64, 0, l) - sks := make([]*normalSocket, 0, min(l, EntryPerPage)) + sks := make([]*normalSocket, 0, min(l, maxResults)) for k := range svrskts { ids = append(ids, k) } sort.Sort(int64Slice(ids)) idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= startID }) - count := 0 + count := int64(0) var end bool for i, v := range ids[idx:] { - if count == EntryPerPage { + if count == maxResults { break } if ns, ok := c.normalSockets[v]; ok { @@ -655,6 +669,23 @@ func (c *channelMap) GetSocket(id int64) *SocketMetric { return nil } +func (c *channelMap) GetServer(id int64) *ServerMetric { + sm := &ServerMetric{} + var svr *server + var ok bool + c.mu.RLock() + if svr, ok = c.servers[id]; !ok { + c.mu.RUnlock() + return nil + } + sm.ListenSockets = copyMap(svr.listenSockets) + c.mu.RUnlock() + sm.ID = svr.id + sm.RefName = svr.refName + sm.ServerData = svr.s.ChannelzMetric() + return sm +} + type idGenerator struct { id int64 } diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index a3e02b661947..11be7cd08c50 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -34,13 +34,9 @@ const ( type RequireHandshakeSetting int const ( - // RequireHandshakeHybrid (default, deprecated) indicates to wait for - // handshake before considering a connection ready, but wait before - // considering successful. - RequireHandshakeHybrid RequireHandshakeSetting = iota - // RequireHandshakeOn (default after the 1.17 release) indicates to wait - // for handshake before considering a connection ready/successful. - RequireHandshakeOn + // RequireHandshakeOn indicates to wait for handshake before considering a + // connection ready/successful. + RequireHandshakeOn RequireHandshakeSetting = iota // RequireHandshakeOff indicates to not wait for handshake before // considering a connection ready/successful. RequireHandshakeOff @@ -53,17 +49,16 @@ var ( // environment variable. // // Will be removed after the 1.18 release. - RequireHandshake RequireHandshakeSetting + RequireHandshake = RequireHandshakeOn ) func init() { switch strings.ToLower(os.Getenv(requireHandshakeStr)) { case "on": + fallthrough + default: RequireHandshake = RequireHandshakeOn case "off": RequireHandshake = RequireHandshakeOff - case "hybrid": - // Will be removed after the 1.17 release. - RequireHandshake = RequireHandshakeHybrid } } diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index f8932b1d86aa..c1d2c690ca4e 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -20,17 +20,28 @@ // symbols to avoid circular dependencies. package internal -import "context" +import ( + "context" + "time" +) var ( - // WithContextDialer is exported by clientconn.go - WithContextDialer interface{} // func(context.Context, string) (net.Conn, error) grpc.DialOption - // WithResolverBuilder is exported by clientconn.go + // WithResolverBuilder is exported by dialoptions.go WithResolverBuilder interface{} // func (resolver.Builder) grpc.DialOption + // WithHealthCheckFunc is not exported by dialoptions.go + WithHealthCheckFunc interface{} // func (HealthChecker) DialOption // HealthCheckFunc is used to provide client-side LB channel health checking - HealthCheckFunc func(ctx context.Context, newStream func() (interface{}, error), reportHealth func(bool), serviceName string) error + HealthCheckFunc HealthChecker + // BalancerUnregister is exported by package balancer to unregister a balancer. + BalancerUnregister func(name string) + // KeepaliveMinPingTime is the minimum ping interval. This must be 10s by + // default, but tests may wish to set it lower for convenience. + KeepaliveMinPingTime = 10 * time.Second ) +// HealthChecker defines the signature of the client-side LB channel health checking function. +type HealthChecker func(ctx context.Context, newStream func() (interface{}, error), reportHealth func(bool), serviceName string) error + const ( // CredsBundleModeFallback switches GoogleDefaultCreds to fallback mode. CredsBundleModeFallback = "fallback" diff --git a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go index 61678feb0044..d3fd9dab3331 100644 --- a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go @@ -22,18 +22,24 @@ package syscall import ( "net" + "sync" "time" "google.golang.org/grpc/grpclog" ) -func init() { - grpclog.Info("CPU time info is unavailable on non-linux or appengine environment.") +var once sync.Once + +func log() { + once.Do(func() { + grpclog.Info("CPU time info is unavailable on non-linux or appengine environment.") + }) } // GetCPUTime returns the how much CPU time has passed since the start of this process. // It always returns 0 under non-linux or appengine environment. func GetCPUTime() int64 { + log() return 0 } @@ -42,22 +48,26 @@ type Rusage struct{} // GetRusage is a no-op function under non-linux or appengine environment. func GetRusage() (rusage *Rusage) { + log() return nil } // CPUTimeDiff returns the differences of user CPU time and system CPU time used // between two Rusage structs. It a no-op function for non-linux or appengine environment. func CPUTimeDiff(first *Rusage, latest *Rusage) (float64, float64) { + log() return 0, 0 } // SetTCPUserTimeout is a no-op function under non-linux or appengine environments func SetTCPUserTimeout(conn net.Conn, timeout time.Duration) error { + log() return nil } // GetTCPUserTimeout is a no-op function under non-linux or appengine environments // a negative return value indicates the operation is not supported func GetTCPUserTimeout(conn net.Conn) (int, error) { + log() return -1, nil } diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index 73b41ea7e0b0..f2de84d43a81 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -63,9 +63,6 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats sta if _, ok := w.(http.Flusher); !ok { return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher") } - if _, ok := w.(http.CloseNotifier); !ok { - return nil, errors.New("gRPC requires a ResponseWriter supporting http.CloseNotifier") - } st := &serverHandlerTransport{ rw: w, @@ -176,17 +173,11 @@ func (a strAddr) String() string { return string(a) } // do runs fn in the ServeHTTP goroutine. func (ht *serverHandlerTransport) do(fn func()) error { - // Avoid a panic writing to closed channel. Imperfect but maybe good enough. select { case <-ht.closedCh: return ErrConnClosing - default: - select { - case ht.writes <- fn: - return nil - case <-ht.closedCh: - return ErrConnClosing - } + case ht.writes <- fn: + return nil } } @@ -237,7 +228,6 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro if ht.stats != nil { ht.stats.HandleRPC(s.Context(), &stats.OutTrailer{}) } - close(ht.writes) } ht.Close() return err @@ -315,19 +305,13 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace ctx, cancel = context.WithCancel(ctx) } - // requestOver is closed when either the request's context is done - // or the status has been written via WriteStatus. + // requestOver is closed when the status has been written via WriteStatus. requestOver := make(chan struct{}) - - // clientGone receives a single value if peer is gone, either - // because the underlying connection is dead or because the - // peer sends an http2 RST_STREAM. - clientGone := ht.rw.(http.CloseNotifier).CloseNotify() go func() { select { case <-requestOver: case <-ht.closedCh: - case <-clientGone: + case <-ht.req.Context().Done(): } cancel() ht.Close() @@ -407,10 +391,7 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace func (ht *serverHandlerTransport) runStream() { for { select { - case fn, ok := <-ht.writes: - if !ok { - return - } + case fn := <-ht.writes: fn() case <-ht.closedCh: return diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index 39208b146e09..9dee6db61d9d 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -91,10 +91,10 @@ type http2Client struct { maxSendHeaderListSize *uint32 bdpEst *bdpEstimator - // onSuccess is a callback that client transport calls upon + // onPrefaceReceipt is a callback that client transport calls upon // receiving server preface to signal that a succefull HTTP2 // connection was established. - onSuccess func() + onPrefaceReceipt func() maxConcurrentStreams uint32 streamQuota int64 @@ -145,7 +145,7 @@ func isTemporary(err error) bool { // newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2 // and starts to receive messages on it. Non-nil error returns if construction // fails. -func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts ConnectOptions, onSuccess func(), onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) { +func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) { scheme := "http" ctx, cancel := context.WithCancel(ctx) defer func() { @@ -240,7 +240,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne kp: kp, statsHandler: opts.StatsHandler, initialWindowSize: initialWindowSize, - onSuccess: onSuccess, + onPrefaceReceipt: onPrefaceReceipt, nextID: 1, maxConcurrentStreams: defaultMaxStreamsClient, streamQuota: defaultMaxStreamsClient, @@ -322,7 +322,9 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne } } - t.framer.writer.Flush() + if err := t.framer.writer.Flush(); err != nil { + return nil, err + } go func() { t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst) err := t.loopy.run() @@ -362,6 +364,9 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { ctx: s.ctx, ctxDone: s.ctx.Done(), recv: s.buf, + closeStream: func(err error) { + t.CloseStream(s, err) + }, }, windowHandler: func(n int) { t.updateWindow(s, uint32(n)) @@ -414,7 +419,7 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) if dl, ok := ctx.Deadline(); ok { // Send out timeout regardless its value. The server can detect timeout context by itself. // TODO(mmukhi): Perhaps this field should be updated when actually writing out to the wire. - timeout := dl.Sub(time.Now()) + timeout := time.Until(dl) headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-timeout", Value: encodeTimeout(timeout)}) } for k, v := range authData { @@ -780,7 +785,7 @@ func (t *http2Client) Close() error { } t.statsHandler.HandleConn(t.ctx, connEnd) } - go t.onClose() + t.onClose() return err } @@ -1135,15 +1140,27 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { if !ok { return } + endStream := frame.StreamEnded() atomic.StoreUint32(&s.bytesReceived, 1) - var state decodeState + initialHeader := atomic.SwapUint32(&s.headerDone, 1) == 0 + + if !initialHeader && !endStream { + // As specified by RFC 7540, a HEADERS frame (and associated CONTINUATION frames) can only appear + // at the start or end of a stream. Therefore, second HEADERS frame must have EOS bit set. + st := status.New(codes.Internal, "a HEADERS frame cannot appear in the middle of a stream") + t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, false) + return + } + + state := &decodeState{} + // Initialize isGRPC value to be !initialHeader, since if a gRPC ResponseHeader has been received + // which indicates peer speaking gRPC, we are in gRPC mode. + state.data.isGRPC = !initialHeader if err := state.decodeHeader(frame); err != nil { - t.closeStream(s, err, true, http2.ErrCodeProtocol, status.New(codes.Internal, err.Error()), nil, false) - // Something wrong. Stops reading even when there is remaining. + t.closeStream(s, err, true, http2.ErrCodeProtocol, status.Convert(err), nil, endStream) return } - endStream := frame.StreamEnded() var isHeader bool defer func() { if t.statsHandler != nil { @@ -1162,29 +1179,30 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { } } }() + // If headers haven't been received yet. - if atomic.SwapUint32(&s.headerDone, 1) == 0 { + if initialHeader { if !endStream { - // Headers frame is not actually a trailers-only frame. + // Headers frame is ResponseHeader. isHeader = true // These values can be set without any synchronization because // stream goroutine will read it only after seeing a closed // headerChan which we'll close after setting this. - s.recvCompress = state.encoding - if len(state.mdata) > 0 { - s.header = state.mdata + s.recvCompress = state.data.encoding + if len(state.data.mdata) > 0 { + s.header = state.data.mdata } - } else { - s.noHeaders = true + close(s.headerChan) + return } + // Headers frame is Trailers-only. + s.noHeaders = true close(s.headerChan) } - if !endStream { - return - } + // if client received END_STREAM from server while stream was still active, send RST_STREAM rst := s.getState() == streamActive - t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, state.status(), state.mdata, true) + t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, state.status(), state.data.mdata, true) } // reader runs as a separate goroutine in charge of reading data from network @@ -1210,7 +1228,7 @@ func (t *http2Client) reader() { t.Close() // this kicks off resetTransport, so must be last before return return } - t.onSuccess() + t.onPrefaceReceipt() t.handleSettings(sf, true) // loop to keep reading incoming messages on this transport. @@ -1351,6 +1369,8 @@ func (t *http2Client) ChannelzMetric() *channelz.SocketInternalMetric { return &s } +func (t *http2Client) RemoteAddr() net.Addr { return t.remoteAddr } + func (t *http2Client) IncrMsgSent() { atomic.AddInt64(&t.czData.msgSent, 1) atomic.StoreInt64(&t.czData.lastMsgSentTime, time.Now().UnixNano()) diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index df2740398bd4..435092e5c853 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -286,7 +286,9 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err // operateHeader takes action on the decoded headers. func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (fatal bool) { streamID := frame.Header().StreamID - state := decodeState{serverSide: true} + state := &decodeState{ + serverSide: true, + } if err := state.decodeHeader(frame); err != nil { if se, ok := status.FromError(err); ok { t.controlBuf.put(&cleanupStream{ @@ -305,16 +307,16 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( st: t, buf: buf, fc: &inFlow{limit: uint32(t.initialWindowSize)}, - recvCompress: state.encoding, - method: state.method, - contentSubtype: state.contentSubtype, + recvCompress: state.data.encoding, + method: state.data.method, + contentSubtype: state.data.contentSubtype, } if frame.StreamEnded() { // s is just created by the caller. No lock needed. s.state = streamReadDone } - if state.timeoutSet { - s.ctx, s.cancel = context.WithTimeout(t.ctx, state.timeout) + if state.data.timeoutSet { + s.ctx, s.cancel = context.WithTimeout(t.ctx, state.data.timeout) } else { s.ctx, s.cancel = context.WithCancel(t.ctx) } @@ -327,19 +329,19 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } s.ctx = peer.NewContext(s.ctx, pr) // Attach the received metadata to the context. - if len(state.mdata) > 0 { - s.ctx = metadata.NewIncomingContext(s.ctx, state.mdata) + if len(state.data.mdata) > 0 { + s.ctx = metadata.NewIncomingContext(s.ctx, state.data.mdata) } - if state.statsTags != nil { - s.ctx = stats.SetIncomingTags(s.ctx, state.statsTags) + if state.data.statsTags != nil { + s.ctx = stats.SetIncomingTags(s.ctx, state.data.statsTags) } - if state.statsTrace != nil { - s.ctx = stats.SetIncomingTrace(s.ctx, state.statsTrace) + if state.data.statsTrace != nil { + s.ctx = stats.SetIncomingTrace(s.ctx, state.data.statsTrace) } if t.inTapHandle != nil { var err error info := &tap.Info{ - FullMethodName: state.method, + FullMethodName: state.data.method, } s.ctx, err = t.inTapHandle(s.ctx, info) if err != nil { @@ -435,7 +437,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context. s := t.activeStreams[se.StreamID] t.mu.Unlock() if s != nil { - t.closeStream(s, true, se.Code, nil, false) + t.closeStream(s, true, se.Code, false) } else { t.controlBuf.put(&cleanupStream{ streamID: se.StreamID, @@ -577,7 +579,7 @@ func (t *http2Server) handleData(f *http2.DataFrame) { } if size > 0 { if err := s.fc.onData(size); err != nil { - t.closeStream(s, true, http2.ErrCodeFlowControl, nil, false) + t.closeStream(s, true, http2.ErrCodeFlowControl, false) return } if f.Header().Flags.Has(http2.FlagDataPadded) { @@ -602,11 +604,18 @@ func (t *http2Server) handleData(f *http2.DataFrame) { } func (t *http2Server) handleRSTStream(f *http2.RSTStreamFrame) { - s, ok := t.getStream(f) - if !ok { + // If the stream is not deleted from the transport's active streams map, then do a regular close stream. + if s, ok := t.getStream(f); ok { + t.closeStream(s, false, 0, false) return } - t.closeStream(s, false, 0, nil, false) + // If the stream is already deleted from the active streams map, then put a cleanupStream item into controlbuf to delete the stream from loopy writer's established streams map. + t.controlBuf.put(&cleanupStream{ + streamID: f.Header().StreamID, + rst: false, + rstCode: 0, + onWrite: func() {}, + }) } func (t *http2Server) handleSettings(f *http2.SettingsFrame) { @@ -770,7 +779,7 @@ func (t *http2Server) writeHeaderLocked(s *Stream) error { if err != nil { return err } - t.closeStream(s, true, http2.ErrCodeInternal, nil, false) + t.closeStream(s, true, http2.ErrCodeInternal, false) return ErrHeaderListSizeLimitViolation } if t.stats != nil { @@ -834,10 +843,12 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { if err != nil { return err } - t.closeStream(s, true, http2.ErrCodeInternal, nil, false) + t.closeStream(s, true, http2.ErrCodeInternal, false) return ErrHeaderListSizeLimitViolation } - t.closeStream(s, false, 0, trailingHeader, true) + // Send a RST_STREAM after the trailers if the client has not already half-closed. + rst := s.getState() == streamActive + t.finishStream(s, rst, http2.ErrCodeNo, trailingHeader, true) if t.stats != nil { t.stats.HandleRPC(s.Context(), &stats.OutTrailer{}) } @@ -849,6 +860,9 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) error { if !s.isHeaderSent() { // Headers haven't been written yet. if err := t.WriteHeader(s, nil); err != nil { + if _, ok := err.(ConnectionError); ok { + return err + } // TODO(mmukhi, dfawley): Make sure this is the right code to return. return status.Errorf(codes.Internal, "transport: %v", err) } @@ -1004,45 +1018,65 @@ func (t *http2Server) Close() error { return err } -// closeStream clears the footprint of a stream when the stream is not needed -// any more. -func (t *http2Server) closeStream(s *Stream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) { - if s.swapState(streamDone) == streamDone { +// deleteStream deletes the stream s from transport's active streams. +func (t *http2Server) deleteStream(s *Stream, eosReceived bool) (oldState streamState) { + oldState = s.swapState(streamDone) + if oldState == streamDone { // If the stream was already done, return. - return + return oldState } + // In case stream sending and receiving are invoked in separate // goroutines (e.g., bi-directional streaming), cancel needs to be // called to interrupt the potential blocking on other goroutines. s.cancel() - cleanup := &cleanupStream{ + + t.mu.Lock() + if _, ok := t.activeStreams[s.id]; ok { + delete(t.activeStreams, s.id) + if len(t.activeStreams) == 0 { + t.idle = time.Now() + } + } + t.mu.Unlock() + + if channelz.IsOn() { + if eosReceived { + atomic.AddInt64(&t.czData.streamsSucceeded, 1) + } else { + atomic.AddInt64(&t.czData.streamsFailed, 1) + } + } + + return oldState +} + +// finishStream closes the stream and puts the trailing headerFrame into controlbuf. +func (t *http2Server) finishStream(s *Stream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) { + oldState := t.deleteStream(s, eosReceived) + // If the stream is already closed, then don't put trailing header to controlbuf. + if oldState == streamDone { + return + } + + hdr.cleanup = &cleanupStream{ streamID: s.id, rst: rst, rstCode: rstCode, - onWrite: func() { - t.mu.Lock() - if t.activeStreams != nil { - delete(t.activeStreams, s.id) - if len(t.activeStreams) == 0 { - t.idle = time.Now() - } - } - t.mu.Unlock() - if channelz.IsOn() { - if eosReceived { - atomic.AddInt64(&t.czData.streamsSucceeded, 1) - } else { - atomic.AddInt64(&t.czData.streamsFailed, 1) - } - } - }, - } - if hdr != nil { - hdr.cleanup = cleanup - t.controlBuf.put(hdr) - } else { - t.controlBuf.put(cleanup) + onWrite: func() {}, } + t.controlBuf.put(hdr) +} + +// closeStream clears the footprint of a stream when the stream is not needed any more. +func (t *http2Server) closeStream(s *Stream, rst bool, rstCode http2.ErrCode, eosReceived bool) { + t.deleteStream(s, eosReceived) + t.controlBuf.put(&cleanupStream{ + streamID: s.id, + rst: rst, + rstCode: rstCode, + onWrite: func() {}, + }) } func (t *http2Server) RemoteAddr() net.Addr { @@ -1155,7 +1189,7 @@ func (t *http2Server) IncrMsgRecv() { } func (t *http2Server) getOutFlowWindow() int64 { - resp := make(chan uint32) + resp := make(chan uint32, 1) timer := time.NewTimer(time.Second) defer timer.Stop() t.controlBuf.put(&outFlowControlSizeRequest{resp}) diff --git a/vendor/google.golang.org/grpc/internal/transport/http_util.go b/vendor/google.golang.org/grpc/internal/transport/http_util.go index 77a2cfaaef33..9d212867ce2e 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http_util.go +++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -78,7 +78,8 @@ var ( codes.ResourceExhausted: http2.ErrCodeEnhanceYourCalm, codes.PermissionDenied: http2.ErrCodeInadequateSecurity, } - httpStatusConvTab = map[int]codes.Code{ + // HTTPStatusConvTab is the HTTP status code to gRPC error code conversion table. + HTTPStatusConvTab = map[int]codes.Code{ // 400 Bad Request - INTERNAL. http.StatusBadRequest: codes.Internal, // 401 Unauthorized - UNAUTHENTICATED. @@ -98,9 +99,7 @@ var ( } ) -// Records the states during HPACK decoding. Must be reset once the -// decoding of the entire headers are finished. -type decodeState struct { +type parsedHeaderData struct { encoding string // statusGen caches the stream status received from the trailer the server // sent. Client side only. Do not access directly. After all trailers are @@ -120,8 +119,30 @@ type decodeState struct { statsTags []byte statsTrace []byte contentSubtype string + + // isGRPC field indicates whether the peer is speaking gRPC (otherwise HTTP). + // + // We are in gRPC mode (peer speaking gRPC) if: + // * We are client side and have already received a HEADER frame that indicates gRPC peer. + // * The header contains valid a content-type, i.e. a string starts with "application/grpc" + // And we should handle error specific to gRPC. + // + // Otherwise (i.e. a content-type string starts without "application/grpc", or does not exist), we + // are in HTTP fallback mode, and should handle error specific to HTTP. + isGRPC bool + grpcErr error + httpErr error + contentTypeErr string +} + +// decodeState configures decoding criteria and records the decoded data. +type decodeState struct { // whether decoding on server side or not serverSide bool + + // Records the states during HPACK decoding. It will be filled with info parsed from HTTP HEADERS + // frame once decodeHeader function has been invoked and returned. + data parsedHeaderData } // isReservedHeader checks whether hdr belongs to HTTP2 headers @@ -202,11 +223,11 @@ func contentType(contentSubtype string) string { } func (d *decodeState) status() *status.Status { - if d.statusGen == nil { + if d.data.statusGen == nil { // No status-details were provided; generate status using code/msg. - d.statusGen = status.New(codes.Code(int32(*(d.rawStatusCode))), d.rawStatusMsg) + d.data.statusGen = status.New(codes.Code(int32(*(d.data.rawStatusCode))), d.data.rawStatusMsg) } - return d.statusGen + return d.data.statusGen } const binHdrSuffix = "-bin" @@ -244,113 +265,146 @@ func (d *decodeState) decodeHeader(frame *http2.MetaHeadersFrame) error { if frame.Truncated { return status.Error(codes.Internal, "peer header list size exceeded limit") } + for _, hf := range frame.Fields { - if err := d.processHeaderField(hf); err != nil { - return err - } + d.processHeaderField(hf) } - if d.serverSide { + if d.data.isGRPC { + if d.data.grpcErr != nil { + return d.data.grpcErr + } + if d.serverSide { + return nil + } + if d.data.rawStatusCode == nil && d.data.statusGen == nil { + // gRPC status doesn't exist. + // Set rawStatusCode to be unknown and return nil error. + // So that, if the stream has ended this Unknown status + // will be propagated to the user. + // Otherwise, it will be ignored. In which case, status from + // a later trailer, that has StreamEnded flag set, is propagated. + code := int(codes.Unknown) + d.data.rawStatusCode = &code + } return nil } - // If grpc status exists, no need to check further. - if d.rawStatusCode != nil || d.statusGen != nil { - return nil + // HTTP fallback mode + if d.data.httpErr != nil { + return d.data.httpErr } - // If grpc status doesn't exist and http status doesn't exist, - // then it's a malformed header. - if d.httpStatus == nil { - return status.Error(codes.Internal, "malformed header: doesn't contain status(gRPC or HTTP)") - } + var ( + code = codes.Internal // when header does not include HTTP status, return INTERNAL + ok bool + ) - if *(d.httpStatus) != http.StatusOK { - code, ok := httpStatusConvTab[*(d.httpStatus)] + if d.data.httpStatus != nil { + code, ok = HTTPStatusConvTab[*(d.data.httpStatus)] if !ok { code = codes.Unknown } - return status.Error(code, http.StatusText(*(d.httpStatus))) - } - - // gRPC status doesn't exist and http status is OK. - // Set rawStatusCode to be unknown and return nil error. - // So that, if the stream has ended this Unknown status - // will be propagated to the user. - // Otherwise, it will be ignored. In which case, status from - // a later trailer, that has StreamEnded flag set, is propagated. - code := int(codes.Unknown) - d.rawStatusCode = &code - return nil + } + + return status.Error(code, d.constructHTTPErrMsg()) +} + +// constructErrMsg constructs error message to be returned in HTTP fallback mode. +// Format: HTTP status code and its corresponding message + content-type error message. +func (d *decodeState) constructHTTPErrMsg() string { + var errMsgs []string + + if d.data.httpStatus == nil { + errMsgs = append(errMsgs, "malformed header: missing HTTP status") + } else { + errMsgs = append(errMsgs, fmt.Sprintf("%s: HTTP status code %d", http.StatusText(*(d.data.httpStatus)), *d.data.httpStatus)) + } + + if d.data.contentTypeErr == "" { + errMsgs = append(errMsgs, "transport: missing content-type field") + } else { + errMsgs = append(errMsgs, d.data.contentTypeErr) + } + + return strings.Join(errMsgs, "; ") } func (d *decodeState) addMetadata(k, v string) { - if d.mdata == nil { - d.mdata = make(map[string][]string) + if d.data.mdata == nil { + d.data.mdata = make(map[string][]string) } - d.mdata[k] = append(d.mdata[k], v) + d.data.mdata[k] = append(d.data.mdata[k], v) } -func (d *decodeState) processHeaderField(f hpack.HeaderField) error { +func (d *decodeState) processHeaderField(f hpack.HeaderField) { switch f.Name { case "content-type": contentSubtype, validContentType := contentSubtype(f.Value) if !validContentType { - return status.Errorf(codes.Internal, "transport: received the unexpected content-type %q", f.Value) + d.data.contentTypeErr = fmt.Sprintf("transport: received the unexpected content-type %q", f.Value) + return } - d.contentSubtype = contentSubtype + d.data.contentSubtype = contentSubtype // TODO: do we want to propagate the whole content-type in the metadata, // or come up with a way to just propagate the content-subtype if it was set? // ie {"content-type": "application/grpc+proto"} or {"content-subtype": "proto"} // in the metadata? d.addMetadata(f.Name, f.Value) + d.data.isGRPC = true case "grpc-encoding": - d.encoding = f.Value + d.data.encoding = f.Value case "grpc-status": code, err := strconv.Atoi(f.Value) if err != nil { - return status.Errorf(codes.Internal, "transport: malformed grpc-status: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status: %v", err) + return } - d.rawStatusCode = &code + d.data.rawStatusCode = &code case "grpc-message": - d.rawStatusMsg = decodeGrpcMessage(f.Value) + d.data.rawStatusMsg = decodeGrpcMessage(f.Value) case "grpc-status-details-bin": v, err := decodeBinHeader(f.Value) if err != nil { - return status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + return } s := &spb.Status{} if err := proto.Unmarshal(v, s); err != nil { - return status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + return } - d.statusGen = status.FromProto(s) + d.data.statusGen = status.FromProto(s) case "grpc-timeout": - d.timeoutSet = true + d.data.timeoutSet = true var err error - if d.timeout, err = decodeTimeout(f.Value); err != nil { - return status.Errorf(codes.Internal, "transport: malformed time-out: %v", err) + if d.data.timeout, err = decodeTimeout(f.Value); err != nil { + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed time-out: %v", err) } case ":path": - d.method = f.Value + d.data.method = f.Value case ":status": code, err := strconv.Atoi(f.Value) if err != nil { - return status.Errorf(codes.Internal, "transport: malformed http-status: %v", err) + d.data.httpErr = status.Errorf(codes.Internal, "transport: malformed http-status: %v", err) + return } - d.httpStatus = &code + d.data.httpStatus = &code case "grpc-tags-bin": v, err := decodeBinHeader(f.Value) if err != nil { - return status.Errorf(codes.Internal, "transport: malformed grpc-tags-bin: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-tags-bin: %v", err) + return } - d.statsTags = v + d.data.statsTags = v d.addMetadata(f.Name, string(v)) case "grpc-trace-bin": v, err := decodeBinHeader(f.Value) if err != nil { - return status.Errorf(codes.Internal, "transport: malformed grpc-trace-bin: %v", err) + d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-trace-bin: %v", err) + return } - d.statsTrace = v + d.data.statsTrace = v d.addMetadata(f.Name, string(v)) default: if isReservedHeader(f.Name) && !isWhitelistedHeader(f.Name) { @@ -359,11 +413,10 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) error { v, err := decodeMetadataHeader(f.Name, f.Value) if err != nil { errorf("Failed to decode metadata header (%q, %q): %v", f.Name, f.Value, err) - return nil + return } d.addMetadata(f.Name, v) } - return nil } type timeoutUnit uint8 diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 4d7e89067c22..7f82cbb080df 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -110,15 +110,15 @@ func (b *recvBuffer) get() <-chan recvMsg { return b.c } -// // recvBufferReader implements io.Reader interface to read the data from // recvBuffer. type recvBufferReader struct { - ctx context.Context - ctxDone <-chan struct{} // cache of ctx.Done() (for performance). - recv *recvBuffer - last []byte // Stores the remaining data in the previous calls. - err error + closeStream func(error) // Closes the client transport stream with the given error and nil trailer metadata. + ctx context.Context + ctxDone <-chan struct{} // cache of ctx.Done() (for performance). + recv *recvBuffer + last []byte // Stores the remaining data in the previous calls. + err error } // Read reads the next len(p) bytes from last. If last is drained, it tries to @@ -128,31 +128,53 @@ func (r *recvBufferReader) Read(p []byte) (n int, err error) { if r.err != nil { return 0, r.err } - n, r.err = r.read(p) - return n, r.err -} - -func (r *recvBufferReader) read(p []byte) (n int, err error) { if r.last != nil && len(r.last) > 0 { // Read remaining data left in last call. copied := copy(p, r.last) r.last = r.last[copied:] return copied, nil } + if r.closeStream != nil { + n, r.err = r.readClient(p) + } else { + n, r.err = r.read(p) + } + return n, r.err +} + +func (r *recvBufferReader) read(p []byte) (n int, err error) { select { case <-r.ctxDone: return 0, ContextErr(r.ctx.Err()) case m := <-r.recv.get(): - r.recv.load() - if m.err != nil { - return 0, m.err - } - copied := copy(p, m.data) - r.last = m.data[copied:] - return copied, nil + return r.readAdditional(m, p) } } +func (r *recvBufferReader) readClient(p []byte) (n int, err error) { + // If the context is canceled, then closes the stream with nil metadata. + // closeStream writes its error parameter to r.recv as a recvMsg. + // r.readAdditional acts on that message and returns the necessary error. + select { + case <-r.ctxDone: + r.closeStream(ContextErr(r.ctx.Err())) + m := <-r.recv.get() + return r.readAdditional(m, p) + case m := <-r.recv.get(): + return r.readAdditional(m, p) + } +} + +func (r *recvBufferReader) readAdditional(m recvMsg, p []byte) (n int, err error) { + r.recv.load() + if m.err != nil { + return 0, m.err + } + copied := copy(p, m.data) + r.last = m.data[copied:] + return copied, nil +} + type streamState uint32 const ( @@ -305,8 +327,7 @@ func (s *Stream) TrailersOnly() (bool, error) { if err != nil { return false, err } - // if !headerDone, some other connection error occurred. - return s.noHeaders && atomic.LoadUint32(&s.headerDone) == 1, nil + return s.noHeaders, nil } // Trailer returns the cached trailer metedata. Note that if it is not called @@ -511,8 +532,8 @@ type TargetInfo struct { // NewClientTransport establishes the transport with the required ConnectOptions // and returns it to the caller. -func NewClientTransport(connectCtx, ctx context.Context, target TargetInfo, opts ConnectOptions, onSuccess func(), onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) { - return newHTTP2Client(connectCtx, ctx, target, opts, onSuccess, onGoAway, onClose) +func NewClientTransport(connectCtx, ctx context.Context, target TargetInfo, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) { + return newHTTP2Client(connectCtx, ctx, target, opts, onPrefaceReceipt, onGoAway, onClose) } // Options provides additional hints and information for message @@ -589,6 +610,9 @@ type ClientTransport interface { // GetGoAwayReason returns the reason why GoAway frame was received. GetGoAwayReason() GoAwayReason + // RemoteAddr returns the remote network address. + RemoteAddr() net.Addr + // IncrMsgSent increments the number of message sent through this transport. IncrMsgSent() diff --git a/vendor/google.golang.org/grpc/keepalive/keepalive.go b/vendor/google.golang.org/grpc/keepalive/keepalive.go index 78eea1fc93be..34d31b5e7d31 100644 --- a/vendor/google.golang.org/grpc/keepalive/keepalive.go +++ b/vendor/google.golang.org/grpc/keepalive/keepalive.go @@ -33,6 +33,7 @@ import ( type ClientParameters struct { // After a duration of this time if the client doesn't see any activity it // pings the server to see if the transport is still alive. + // If set below 10s, a minimum value of 10s will be used instead. Time time.Duration // The current default value is infinity. // After having pinged for keepalive check, the client waits for a duration // of Timeout and if no activity is seen even after that the connection is @@ -57,11 +58,12 @@ type ServerParameters struct { // random jitter of +/-10% will be added to MaxConnectionAge to spread out // connection storms. MaxConnectionAge time.Duration // The current default value is infinity. - // MaxConnectinoAgeGrace is an additive period after MaxConnectionAge after + // MaxConnectionAgeGrace is an additive period after MaxConnectionAge after // which the connection will be forcibly closed. MaxConnectionAgeGrace time.Duration // The current default value is infinity. // After a duration of this time if the server doesn't see any activity it // pings the client to see if the transport is still alive. + // If set below 1s, a minimum value of 1s will be used instead. Time time.Duration // The current default value is 2 hours. // After having pinged for keepalive check, the server waits for a duration // of Timeout and if no activity is seen even after that the connection is diff --git a/vendor/google.golang.org/grpc/naming/dns_resolver.go b/vendor/google.golang.org/grpc/naming/dns_resolver.go index fd8cd3b5a4ff..c9f79dc53362 100644 --- a/vendor/google.golang.org/grpc/naming/dns_resolver.go +++ b/vendor/google.golang.org/grpc/naming/dns_resolver.go @@ -76,8 +76,8 @@ func formatIP(addr string) (addrIP string, ok bool) { // parseTarget takes the user input target string, returns formatted host and port info. // If target doesn't specify a port, set the port to be the defaultPort. -// If target is in IPv6 format and host-name is enclosed in sqarue brackets, brackets -// are strippd when setting the host. +// If target is in IPv6 format and host-name is enclosed in square brackets, brackets +// are stripped when setting the host. // examples: // target: "www.google.com" returns host: "www.google.com", port: "443" // target: "ipv4-host:80" returns host: "ipv4-host", port: "80" @@ -221,7 +221,7 @@ func (w *dnsWatcher) lookupSRV() map[string]*Update { for _, s := range srvs { lbAddrs, err := lookupHost(w.ctx, s.Target) if err != nil { - grpclog.Warningf("grpc: failed load banlacer address dns lookup due to %v.\n", err) + grpclog.Warningf("grpc: failed load balancer address dns lookup due to %v.\n", err) continue } for _, a := range lbAddrs { diff --git a/vendor/google.golang.org/grpc/naming/naming.go b/vendor/google.golang.org/grpc/naming/naming.go index 8cc39e93758f..c99fdbef4353 100644 --- a/vendor/google.golang.org/grpc/naming/naming.go +++ b/vendor/google.golang.org/grpc/naming/naming.go @@ -17,7 +17,7 @@ */ // Package naming defines the naming API and related data structures for gRPC. -// The interface is EXPERIMENTAL and may be suject to change. +// The interface is EXPERIMENTAL and may be subject to change. // // Deprecated: please use package resolver. package naming diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index 14f915d6768a..f9625496c403 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -101,10 +101,7 @@ func doneChannelzWrapper(acw *acBalancerWrapper, done func(balancer.DoneInfo)) f // - the subConn returned by the current picker is not READY // When one of these situations happens, pick blocks until the picker gets updated. func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer.PickOptions) (transport.ClientTransport, func(balancer.DoneInfo), error) { - var ( - p balancer.Picker - ch chan struct{} - ) + var ch chan struct{} for { bp.mu.Lock() @@ -130,7 +127,7 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer. } ch = bp.blockingCh - p = bp.picker + p := bp.picker bp.mu.Unlock() subConn, done, err := p.Pick(ctx, opts) @@ -144,15 +141,22 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer. continue } return nil, nil, status.Errorf(codes.Unavailable, "%v, latest connection error: %v", err, bp.connectionError()) + case context.DeadlineExceeded: + return nil, nil, status.Error(codes.DeadlineExceeded, err.Error()) + case context.Canceled: + return nil, nil, status.Error(codes.Canceled, err.Error()) default: + if _, ok := status.FromError(err); ok { + return nil, nil, err + } // err is some other error. - return nil, nil, toRPCErr(err) + return nil, nil, status.Error(codes.Unknown, err.Error()) } } acw, ok := subConn.(*acBalancerWrapper) if !ok { - grpclog.Infof("subconn returned from pick is not *acBalancerWrapper") + grpclog.Error("subconn returned from pick is not *acBalancerWrapper") continue } if t, ok := acw.getAddrConn().getReadyTransport(); ok { @@ -161,6 +165,11 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer. } return t, done, nil } + if done != nil { + // Calling done with nil error, no bytes sent and no bytes received. + // DoneInfo with default value works. + done(balancer.DoneInfo{}) + } grpclog.Infof("blockingPicker: the picked transport is not ready, loop back to repick") // If ok == false, ac.state is not READY. // A valid picker always returns READY subConn. This means the state of ac diff --git a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go index f33189fede2d..58355990779b 100644 --- a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go @@ -47,6 +47,8 @@ const ( defaultFreq = time.Minute * 30 defaultDNSSvrPort = "53" golang = "GO" + // txtPrefix is the prefix string to be prepended to the host name for txt record lookup. + txtPrefix = "_grpc_config." // In DNS, service config is encoded in a TXT record via the mechanism // described in RFC-1464 using the attribute name grpc_config. txtAttribute = "grpc_config=" @@ -282,7 +284,7 @@ func (d *dnsResolver) lookupSRV() []resolver.Address { } func (d *dnsResolver) lookupTXT() string { - ss, err := d.resolver.LookupTXT(d.ctx, d.host) + ss, err := d.resolver.LookupTXT(d.ctx, txtPrefix+d.host) if err != nil { grpclog.Infof("grpc: failed dns TXT record lookup due to %v.\n", err) return "" @@ -346,8 +348,8 @@ func formatIP(addr string) (addrIP string, ok bool) { // parseTarget takes the user input target string and default port, returns formatted host and port info. // If target doesn't specify a port, set the port to be the defaultPort. -// If target is in IPv6 format and host-name is enclosed in sqarue brackets, brackets -// are strippd when setting the host. +// If target is in IPv6 format and host-name is enclosed in square brackets, brackets +// are stripped when setting the host. // examples: // target: "www.google.com" defaultPort: "443" returns host: "www.google.com", port: "443" // target: "ipv4-host:80" defaultPort: "443" returns host: "ipv4-host", port: "80" diff --git a/vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go b/vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go index b76010d74d14..893d5d12cb0c 100644 --- a/vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go +++ b/vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go @@ -45,7 +45,7 @@ type passthroughResolver struct { } func (r *passthroughResolver) start() { - r.cc.NewAddress([]resolver.Address{{Addr: r.target.Endpoint}}) + r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint}}}) } func (*passthroughResolver) ResolveNow(o resolver.ResolveNowOption) {} diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index 145cf477edb0..52ec603daa77 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -98,6 +98,15 @@ type BuildOption struct { DisableServiceConfig bool } +// State contains the current Resolver state relevant to the ClientConn. +type State struct { + Addresses []Address // Resolved addresses for the target + ServiceConfig string // JSON representation of the service config + + // TODO: add Err error + // TODO: add ParsedServiceConfig interface{} +} + // ClientConn contains the callbacks for resolver to notify any updates // to the gRPC ClientConn. // @@ -106,12 +115,18 @@ type BuildOption struct { // testing, the new implementation should embed this interface. This allows // gRPC to add new methods to this interface. type ClientConn interface { + // UpdateState updates the state of the ClientConn appropriately. + UpdateState(State) // NewAddress is called by resolver to notify ClientConn a new list // of resolved addresses. // The address list should be the complete list of resolved addresses. + // + // Deprecated: Use UpdateState instead. NewAddress(addresses []Address) // NewServiceConfig is called by resolver to notify ClientConn a new // service config. The service config should be provided as a json string. + // + // Deprecated: Use UpdateState instead. NewServiceConfig(serviceConfig string) } diff --git a/vendor/google.golang.org/grpc/resolver_conn_wrapper.go b/vendor/google.golang.org/grpc/resolver_conn_wrapper.go index 9d7602539fba..e9cef3a92b55 100644 --- a/vendor/google.golang.org/grpc/resolver_conn_wrapper.go +++ b/vendor/google.golang.org/grpc/resolver_conn_wrapper.go @@ -21,6 +21,7 @@ package grpc import ( "fmt" "strings" + "sync/atomic" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal/channelz" @@ -30,16 +31,16 @@ import ( // ccResolverWrapper is a wrapper on top of cc for resolvers. // It implements resolver.ClientConnection interface. type ccResolverWrapper struct { - cc *ClientConn - resolver resolver.Resolver - addrCh chan []resolver.Address - scCh chan string - done chan struct{} - lastAddressesCount int + cc *ClientConn + resolver resolver.Resolver + addrCh chan []resolver.Address + scCh chan string + done uint32 // accessed atomically; set to 1 when closed. + curState resolver.State } // split2 returns the values from strings.SplitN(s, sep, 2). -// If sep is not found, it returns ("", s, false) instead. +// If sep is not found, it returns ("", "", false) instead. func split2(s, sep string) (string, string, bool) { spl := strings.SplitN(s, sep, 2) if len(spl) < 2 { @@ -82,7 +83,6 @@ func newCCResolverWrapper(cc *ClientConn) (*ccResolverWrapper, error) { cc: cc, addrCh: make(chan []resolver.Address, 1), scCh: make(chan string, 1), - done: make(chan struct{}), } var err error @@ -99,57 +99,67 @@ func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOption) { func (ccr *ccResolverWrapper) close() { ccr.resolver.Close() - close(ccr.done) + atomic.StoreUint32(&ccr.done, 1) } -// NewAddress is called by the resolver implemenetion to send addresses to gRPC. +func (ccr *ccResolverWrapper) isDone() bool { + return atomic.LoadUint32(&ccr.done) == 1 +} + +func (ccr *ccResolverWrapper) UpdateState(s resolver.State) { + if ccr.isDone() { + return + } + grpclog.Infof("ccResolverWrapper: sending update to cc: %v", s) + if channelz.IsOn() { + ccr.addChannelzTraceEvent(s) + } + ccr.cc.updateResolverState(s) + ccr.curState = s +} + +// NewAddress is called by the resolver implementation to send addresses to gRPC. func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) { - select { - case <-ccr.done: + if ccr.isDone() { return - default: } grpclog.Infof("ccResolverWrapper: sending new addresses to cc: %v", addrs) if channelz.IsOn() { - ccr.addChannelzTraceEvent(addrs) + ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig}) } - ccr.cc.handleResolvedAddrs(addrs, nil) + ccr.curState.Addresses = addrs + ccr.cc.updateResolverState(ccr.curState) } -// NewServiceConfig is called by the resolver implemenetion to send service +// NewServiceConfig is called by the resolver implementation to send service // configs to gRPC. func (ccr *ccResolverWrapper) NewServiceConfig(sc string) { - select { - case <-ccr.done: + if ccr.isDone() { return - default: } grpclog.Infof("ccResolverWrapper: got new service config: %v", sc) - ccr.cc.handleServiceConfig(sc) + if channelz.IsOn() { + ccr.addChannelzTraceEvent(resolver.State{Addresses: ccr.curState.Addresses, ServiceConfig: sc}) + } + ccr.curState.ServiceConfig = sc + ccr.cc.updateResolverState(ccr.curState) } -func (ccr *ccResolverWrapper) addChannelzTraceEvent(addrs []resolver.Address) { - if len(addrs) == 0 && ccr.lastAddressesCount != 0 { - channelz.AddTraceEvent(ccr.cc.channelzID, &channelz.TraceEventDesc{ - Desc: "Resolver returns an empty address list", - Severity: channelz.CtWarning, - }) - } else if len(addrs) != 0 && ccr.lastAddressesCount == 0 { - var s string - for i, a := range addrs { - if a.ServerName != "" { - s += a.Addr + "(" + a.ServerName + ")" - } else { - s += a.Addr - } - if i != len(addrs)-1 { - s += " " - } - } - channelz.AddTraceEvent(ccr.cc.channelzID, &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Resolver returns a non-empty address list (previous one was empty) %q", s), - Severity: channelz.CtINFO, - }) +func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { + if s.ServiceConfig == ccr.curState.ServiceConfig && (len(ccr.curState.Addresses) == 0) == (len(s.Addresses) == 0) { + return + } + var updates []string + if s.ServiceConfig != ccr.curState.ServiceConfig { + updates = append(updates, "service config updated") + } + if len(ccr.curState.Addresses) > 0 && len(s.Addresses) == 0 { + updates = append(updates, "resolver returned an empty address list") + } else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 { + updates = append(updates, "resolver returned new addresses") } - ccr.lastAddressesCount = len(addrs) + channelz.AddTraceEvent(ccr.cc.channelzID, &channelz.TraceEventDesc{ + Desc: fmt.Sprintf("Resolver state updated: %+v (%v)", s, strings.Join(updates, "; ")), + Severity: channelz.CtINFO, + }) } diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 86f00e5a2d1f..2a595622d3cc 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -253,8 +253,8 @@ func (o PeerCallOption) after(c *callInfo) { } } -// FailFast configures the action to take when an RPC is attempted on broken -// connections or unreachable servers. If failFast is true, the RPC will fail +// WaitForReady configures the action to take when an RPC is attempted on broken +// connections or unreachable servers. If waitForReady is false, the RPC will fail // immediately. Otherwise, the RPC client will block the call until a // connection is available (or the call is canceled or times out) and will // retry the call if it fails due to a transient error. gRPC will not retry if @@ -262,7 +262,14 @@ func (o PeerCallOption) after(c *callInfo) { // the data. Please refer to // https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. // -// By default, RPCs are "Fail Fast". +// By default, RPCs don't "wait for ready". +func WaitForReady(waitForReady bool) CallOption { + return FailFastCallOption{FailFast: !waitForReady} +} + +// FailFast is the opposite of WaitForReady. +// +// Deprecated: use WaitForReady. func FailFast(failFast bool) CallOption { return FailFastCallOption{FailFast: failFast} } @@ -363,13 +370,13 @@ func (o CompressorCallOption) after(c *callInfo) {} // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for // more details. // -// If CallCustomCodec is not also used, the content-subtype will be used to -// look up the Codec to use in the registry controlled by RegisterCodec. See -// the documentation on RegisterCodec for details on registration. The lookup -// of content-subtype is case-insensitive. If no such Codec is found, the call +// If ForceCodec is not also used, the content-subtype will be used to look up +// the Codec to use in the registry controlled by RegisterCodec. See the +// documentation on RegisterCodec for details on registration. The lookup of +// content-subtype is case-insensitive. If no such Codec is found, the call // will result in an error with code codes.Internal. // -// If CallCustomCodec is also used, that Codec will be used for all request and +// If ForceCodec is also used, that Codec will be used for all request and // response messages, with the content-subtype set to the given contentSubtype // here for requests. func CallContentSubtype(contentSubtype string) CallOption { @@ -389,7 +396,7 @@ func (o ContentSubtypeCallOption) before(c *callInfo) error { } func (o ContentSubtypeCallOption) after(c *callInfo) {} -// CallCustomCodec returns a CallOption that will set the given Codec to be +// ForceCodec returns a CallOption that will set the given Codec to be // used for all request and response messages for a call. The result of calling // String() will be used as the content-subtype in a case-insensitive manner. // @@ -401,12 +408,37 @@ func (o ContentSubtypeCallOption) after(c *callInfo) {} // // This function is provided for advanced users; prefer to use only // CallContentSubtype to select a registered codec instead. +// +// This is an EXPERIMENTAL API. +func ForceCodec(codec encoding.Codec) CallOption { + return ForceCodecCallOption{Codec: codec} +} + +// ForceCodecCallOption is a CallOption that indicates the codec used for +// marshaling messages. +// +// This is an EXPERIMENTAL API. +type ForceCodecCallOption struct { + Codec encoding.Codec +} + +func (o ForceCodecCallOption) before(c *callInfo) error { + c.codec = o.Codec + return nil +} +func (o ForceCodecCallOption) after(c *callInfo) {} + +// CallCustomCodec behaves like ForceCodec, but accepts a grpc.Codec instead of +// an encoding.Codec. +// +// Deprecated: use ForceCodec instead. func CallCustomCodec(codec Codec) CallOption { return CustomCodecCallOption{Codec: codec} } // CustomCodecCallOption is a CallOption that indicates the codec used for // marshaling messages. +// // This is an EXPERIMENTAL API. type CustomCodecCallOption struct { Codec Codec @@ -629,7 +661,9 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei if err != nil { return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) } - d, err = ioutil.ReadAll(dcReader) + // Read from LimitReader with limit max+1. So if the underlying + // reader is over limit, the result will be bigger than max. + d, err = ioutil.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) if err != nil { return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) } @@ -678,23 +712,17 @@ func rpcInfoFromContext(ctx context.Context) (s *rpcInfo, ok bool) { // Code returns the error code for err if it was produced by the rpc system. // Otherwise, it returns codes.Unknown. // -// Deprecated: use status.FromError and Code method instead. +// Deprecated: use status.Code instead. func Code(err error) codes.Code { - if s, ok := status.FromError(err); ok { - return s.Code() - } - return codes.Unknown + return status.Code(err) } // ErrorDesc returns the error description of err if it was produced by the rpc system. // Otherwise, it returns err.Error() or empty string when err is nil. // -// Deprecated: use status.FromError and Message method instead. +// Deprecated: use status.Convert and Message method instead. func ErrorDesc(err error) string { - if s, ok := status.FromError(err); ok { - return s.Message() - } - return err.Error() + return status.Convert(err).Message() } // Errorf returns an error containing an error code and a description; diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index d705d7a80cd1..8115828fdf00 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -182,6 +182,11 @@ func InitialConnWindowSize(s int32) ServerOption { // KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server. func KeepaliveParams(kp keepalive.ServerParameters) ServerOption { + if kp.Time > 0 && kp.Time < time.Second { + grpclog.Warning("Adjusting keepalive ping interval to minimum period of 1s") + kp.Time = time.Second + } + return func(o *options) { o.keepaliveParams = kp } @@ -244,7 +249,7 @@ func MaxRecvMsgSize(m int) ServerOption { } // MaxSendMsgSize returns a ServerOption to set the max message size in bytes the server can send. -// If this is not set, gRPC uses the default 4MB. +// If this is not set, gRPC uses the default `math.MaxInt32`. func MaxSendMsgSize(m int) ServerOption { return func(o *options) { o.maxSendMessageSize = m @@ -609,12 +614,13 @@ func (s *Server) handleRawConn(rawConn net.Conn) { rawConn.SetDeadline(time.Now().Add(s.opts.connectionTimeout)) conn, authInfo, err := s.useTransportAuthenticator(rawConn) if err != nil { - s.mu.Lock() - s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) - s.mu.Unlock() - grpclog.Warningf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) - // If serverHandshake returns ErrConnDispatched, keep rawConn open. + // ErrConnDispatched means that the connection was dispatched away from + // gRPC; those connections should be left open. if err != credentials.ErrConnDispatched { + s.mu.Lock() + s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) + s.mu.Unlock() + grpclog.Warningf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) rawConn.Close() } rawConn.SetDeadline(time.Time{}) @@ -743,12 +749,13 @@ func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Strea trInfo = &traceInfo{ tr: tr, + firstLine: firstLine{ + client: false, + remoteAddr: st.RemoteAddr(), + }, } - trInfo.firstLine.client = false - trInfo.firstLine.remoteAddr = st.RemoteAddr() - if dl, ok := stream.Context().Deadline(); ok { - trInfo.firstLine.deadline = dl.Sub(time.Now()) + trInfo.firstLine.deadline = time.Until(dl) } return trInfo } @@ -854,7 +861,6 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } if trInfo != nil { defer trInfo.tr.Finish() - trInfo.firstLine.client = false trInfo.tr.LazyLog(&trInfo.firstLine, false) defer func() { if err != nil && err != io.EOF { @@ -874,7 +880,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. PeerAddr: nil, } if deadline, ok := ctx.Deadline(); ok { - logEntry.Timeout = deadline.Sub(time.Now()) + logEntry.Timeout = time.Until(deadline) if logEntry.Timeout < 0 { logEntry.Timeout = 0 } @@ -1106,7 +1112,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp PeerAddr: nil, } if deadline, ok := ctx.Deadline(); ok { - logEntry.Timeout = deadline.Sub(time.Now()) + logEntry.Timeout = time.Until(deadline) if logEntry.Timeout < 0 { logEntry.Timeout = 0 } @@ -1240,7 +1246,8 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str service := sm[:pos] method := sm[pos+1:] - if srv, ok := s.m[service]; ok { + srv, knownService := s.m[service] + if knownService { if md, ok := srv.md[method]; ok { s.processUnaryRPC(t, stream, srv, md, trInfo) return @@ -1255,11 +1262,16 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str s.processStreamingRPC(t, stream, nil, unknownDesc, trInfo) return } + var errDesc string + if !knownService { + errDesc = fmt.Sprintf("unknown service %v", service) + } else { + errDesc = fmt.Sprintf("unknown method %v for service %v", method, service) + } if trInfo != nil { - trInfo.tr.LazyLog(&fmtStringer{"Unknown service %v", []interface{}{service}}, true) + trInfo.tr.LazyPrintf("%s", errDesc) trInfo.tr.SetError() } - errDesc := fmt.Sprintf("unknown service %v", service) if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index 162857e204d5..1c5227426f49 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -99,6 +99,9 @@ type ServiceConfig struct { // healthCheckConfig must be set as one of the requirement to enable LB channel // health check. healthCheckConfig *healthCheckConfig + // rawJSONString stores service config json string that get parsed into + // this service config struct. + rawJSONString string } // healthCheckConfig defines the go-native version of the LB channel health check config. @@ -238,24 +241,22 @@ type jsonSC struct { HealthCheckConfig *healthCheckConfig } -func parseServiceConfig(js string) (ServiceConfig, error) { - if len(js) == 0 { - return ServiceConfig{}, fmt.Errorf("no JSON service config provided") - } +func parseServiceConfig(js string) (*ServiceConfig, error) { var rsc jsonSC err := json.Unmarshal([]byte(js), &rsc) if err != nil { grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) - return ServiceConfig{}, err + return nil, err } sc := ServiceConfig{ LB: rsc.LoadBalancingPolicy, Methods: make(map[string]MethodConfig), retryThrottling: rsc.RetryThrottling, healthCheckConfig: rsc.HealthCheckConfig, + rawJSONString: js, } if rsc.MethodConfig == nil { - return sc, nil + return &sc, nil } for _, m := range *rsc.MethodConfig { @@ -265,7 +266,7 @@ func parseServiceConfig(js string) (ServiceConfig, error) { d, err := parseDuration(m.Timeout) if err != nil { grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) - return ServiceConfig{}, err + return nil, err } mc := MethodConfig{ @@ -274,7 +275,7 @@ func parseServiceConfig(js string) (ServiceConfig, error) { } if mc.retryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil { grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err) - return ServiceConfig{}, err + return nil, err } if m.MaxRequestMessageBytes != nil { if *m.MaxRequestMessageBytes > int64(maxInt) { @@ -299,13 +300,13 @@ func parseServiceConfig(js string) (ServiceConfig, error) { if sc.retryThrottling != nil { if sc.retryThrottling.MaxTokens <= 0 || - sc.retryThrottling.MaxTokens >= 1000 || + sc.retryThrottling.MaxTokens > 1000 || sc.retryThrottling.TokenRatio <= 0 { // Illegal throttling config; disable throttling. sc.retryThrottling = nil } } - return sc, nil + return &sc, nil } func convertRetryPolicy(jrp *jsonRetryPolicy) (p *retryPolicy, err error) { diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index 84f77dafa58c..f3f593c84432 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -27,6 +27,8 @@ import ( "context" "net" "time" + + "google.golang.org/grpc/metadata" ) // RPCStats contains stats information about RPCs. @@ -172,6 +174,9 @@ type End struct { BeginTime time.Time // EndTime is the time when the RPC ends. EndTime time.Time + // Trailer contains the trailer metadata received from the server. This + // field is only valid if this End is from the client side. + Trailer metadata.MD // Error is the error the RPC ended with. It is an error generated from // status.Status and can be converted back to status.Status using // status.FromError if non-nil. diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 0c266d6f9a34..6e2bf51e0a09 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -33,6 +33,7 @@ import ( "google.golang.org/grpc/connectivity" "google.golang.org/grpc/encoding" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/balancerload" "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcrand" @@ -230,12 +231,16 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth if c.creds != nil { callHdr.Creds = c.creds } - var trInfo traceInfo + var trInfo *traceInfo if EnableTracing { - trInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method) - trInfo.firstLine.client = true + trInfo = &traceInfo{ + tr: trace.New("grpc.Sent."+methodFamily(method), method), + firstLine: firstLine{ + client: true, + }, + } if deadline, ok := ctx.Deadline(); ok { - trInfo.firstLine.deadline = deadline.Sub(time.Now()) + trInfo.firstLine.deadline = time.Until(deadline) } trInfo.tr.LazyLog(&trInfo.firstLine, false) ctx = trace.NewContext(ctx, trInfo.tr) @@ -297,7 +302,7 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth Authority: cs.cc.authority, } if deadline, ok := ctx.Deadline(); ok { - logEntry.Timeout = deadline.Sub(time.Now()) + logEntry.Timeout = time.Until(deadline) if logEntry.Timeout < 0 { logEntry.Timeout = 0 } @@ -323,7 +328,7 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth return cs, nil } -func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo traceInfo) error { +func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) error { cs.attempt = &csAttempt{ cs: cs, dc: cs.cc.dopts.dc, @@ -338,6 +343,9 @@ func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo traceInfo) err if err != nil { return err } + if trInfo != nil { + trInfo.firstLine.SetRemoteAddr(t.RemoteAddr()) + } cs.attempt.t = t cs.attempt.done = done return nil @@ -414,9 +422,10 @@ type csAttempt struct { decompSet bool mu sync.Mutex // guards trInfo.tr + // trInfo may be nil (if EnableTracing is false). // trInfo.tr is set when created (if EnableTracing is true), // and cleared when the finish method is called. - trInfo traceInfo + trInfo *traceInfo statsHandler stats.Handler } @@ -462,10 +471,7 @@ func (cs *clientStream) shouldRetry(err error) error { pushback := 0 hasPushback := false if cs.attempt.s != nil { - if to, toErr := cs.attempt.s.TrailersOnly(); toErr != nil { - // Context error; stop now. - return toErr - } else if !to { + if to, toErr := cs.attempt.s.TrailersOnly(); toErr != nil || !to { return err } @@ -543,7 +549,7 @@ func (cs *clientStream) retryLocked(lastErr error) error { cs.commitAttemptLocked() return err } - if err := cs.newAttemptLocked(nil, traceInfo{}); err != nil { + if err := cs.newAttemptLocked(nil, nil); err != nil { return err } if lastErr = cs.replayBufferLocked(); lastErr == nil { @@ -814,7 +820,7 @@ func (cs *clientStream) finish(err error) { func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error { cs := a.cs - if EnableTracing { + if a.trInfo != nil { a.mu.Lock() if a.trInfo.tr != nil { a.trInfo.tr.LazyLog(&payload{sent: true, msg: m}, true) @@ -871,7 +877,7 @@ func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { } return toRPCErr(err) } - if EnableTracing { + if a.trInfo != nil { a.mu.Lock() if a.trInfo.tr != nil { a.trInfo.tr.LazyLog(&payload{sent: false, msg: m}, true) @@ -884,8 +890,9 @@ func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { RecvTime: time.Now(), Payload: m, // TODO truncate large payload. - Data: payInfo.uncompressedBytes, - Length: len(payInfo.uncompressedBytes), + Data: payInfo.uncompressedBytes, + WireLength: payInfo.wireLength, + Length: len(payInfo.uncompressedBytes), }) } if channelz.IsOn() { @@ -918,22 +925,23 @@ func (a *csAttempt) finish(err error) { // Ending a stream with EOF indicates a success. err = nil } + var tr metadata.MD if a.s != nil { a.t.CloseStream(a.s, err) + tr = a.s.Trailer() } if a.done != nil { br := false - var tr metadata.MD if a.s != nil { br = a.s.BytesReceived() - tr = a.s.Trailer() } a.done(balancer.DoneInfo{ Err: err, Trailer: tr, BytesSent: a.s != nil, BytesReceived: br, + ServerLoad: balancerload.Parse(tr), }) } if a.statsHandler != nil { @@ -941,11 +949,12 @@ func (a *csAttempt) finish(err error) { Client: true, BeginTime: a.cs.beginTime, EndTime: time.Now(), + Trailer: tr, Error: err, } a.statsHandler.HandleRPC(a.cs.ctx, end) } - if a.trInfo.tr != nil { + if a.trInfo != nil && a.trInfo.tr != nil { if err == nil { a.trInfo.tr.LazyPrintf("RPC: [OK]") } else { @@ -1089,7 +1098,6 @@ type addrConnStream struct { dc Decompressor decomp encoding.Compressor p *parser - done func(balancer.DoneInfo) mu sync.Mutex finished bool } @@ -1470,8 +1478,9 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { RecvTime: time.Now(), Payload: m, // TODO truncate large payload. - Data: payInfo.uncompressedBytes, - Length: len(payInfo.uncompressedBytes), + Data: payInfo.uncompressedBytes, + WireLength: payInfo.wireLength, + Length: len(payInfo.uncompressedBytes), }) } if ss.binlog != nil { diff --git a/vendor/google.golang.org/grpc/test/bufconn/bufconn.go b/vendor/google.golang.org/grpc/test/bufconn/bufconn.go new file mode 100644 index 000000000000..60ae770f54e2 --- /dev/null +++ b/vendor/google.golang.org/grpc/test/bufconn/bufconn.go @@ -0,0 +1,244 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package bufconn provides a net.Conn implemented by a buffer and related +// dialing and listening functionality. +package bufconn + +import ( + "fmt" + "io" + "net" + "sync" + "time" +) + +// Listener implements a net.Listener that creates local, buffered net.Conns +// via its Accept and Dial method. +type Listener struct { + mu sync.Mutex + sz int + ch chan net.Conn + done chan struct{} +} + +var errClosed = fmt.Errorf("closed") + +// Listen returns a Listener that can only be contacted by its own Dialers and +// creates buffered connections between the two. +func Listen(sz int) *Listener { + return &Listener{sz: sz, ch: make(chan net.Conn), done: make(chan struct{})} +} + +// Accept blocks until Dial is called, then returns a net.Conn for the server +// half of the connection. +func (l *Listener) Accept() (net.Conn, error) { + select { + case <-l.done: + return nil, errClosed + case c := <-l.ch: + return c, nil + } +} + +// Close stops the listener. +func (l *Listener) Close() error { + l.mu.Lock() + defer l.mu.Unlock() + select { + case <-l.done: + // Already closed. + break + default: + close(l.done) + } + return nil +} + +// Addr reports the address of the listener. +func (l *Listener) Addr() net.Addr { return addr{} } + +// Dial creates an in-memory full-duplex network connection, unblocks Accept by +// providing it the server half of the connection, and returns the client half +// of the connection. +func (l *Listener) Dial() (net.Conn, error) { + p1, p2 := newPipe(l.sz), newPipe(l.sz) + select { + case <-l.done: + return nil, errClosed + case l.ch <- &conn{p1, p2}: + return &conn{p2, p1}, nil + } +} + +type pipe struct { + mu sync.Mutex + + // buf contains the data in the pipe. It is a ring buffer of fixed capacity, + // with r and w pointing to the offset to read and write, respsectively. + // + // Data is read between [r, w) and written to [w, r), wrapping around the end + // of the slice if necessary. + // + // The buffer is empty if r == len(buf), otherwise if r == w, it is full. + // + // w and r are always in the range [0, cap(buf)) and [0, len(buf)]. + buf []byte + w, r int + + wwait sync.Cond + rwait sync.Cond + + closed bool + writeClosed bool +} + +func newPipe(sz int) *pipe { + p := &pipe{buf: make([]byte, 0, sz)} + p.wwait.L = &p.mu + p.rwait.L = &p.mu + return p +} + +func (p *pipe) empty() bool { + return p.r == len(p.buf) +} + +func (p *pipe) full() bool { + return p.r < len(p.buf) && p.r == p.w +} + +func (p *pipe) Read(b []byte) (n int, err error) { + p.mu.Lock() + defer p.mu.Unlock() + // Block until p has data. + for { + if p.closed { + return 0, io.ErrClosedPipe + } + if !p.empty() { + break + } + if p.writeClosed { + return 0, io.EOF + } + p.rwait.Wait() + } + wasFull := p.full() + + n = copy(b, p.buf[p.r:len(p.buf)]) + p.r += n + if p.r == cap(p.buf) { + p.r = 0 + p.buf = p.buf[:p.w] + } + + // Signal a blocked writer, if any + if wasFull { + p.wwait.Signal() + } + + return n, nil +} + +func (p *pipe) Write(b []byte) (n int, err error) { + p.mu.Lock() + defer p.mu.Unlock() + if p.closed { + return 0, io.ErrClosedPipe + } + for len(b) > 0 { + // Block until p is not full. + for { + if p.closed || p.writeClosed { + return 0, io.ErrClosedPipe + } + if !p.full() { + break + } + p.wwait.Wait() + } + wasEmpty := p.empty() + + end := cap(p.buf) + if p.w < p.r { + end = p.r + } + x := copy(p.buf[p.w:end], b) + b = b[x:] + n += x + p.w += x + if p.w > len(p.buf) { + p.buf = p.buf[:p.w] + } + if p.w == cap(p.buf) { + p.w = 0 + } + + // Signal a blocked reader, if any. + if wasEmpty { + p.rwait.Signal() + } + } + return n, nil +} + +func (p *pipe) Close() error { + p.mu.Lock() + defer p.mu.Unlock() + p.closed = true + // Signal all blocked readers and writers to return an error. + p.rwait.Broadcast() + p.wwait.Broadcast() + return nil +} + +func (p *pipe) closeWrite() error { + p.mu.Lock() + defer p.mu.Unlock() + p.writeClosed = true + // Signal all blocked readers and writers to return an error. + p.rwait.Broadcast() + p.wwait.Broadcast() + return nil +} + +type conn struct { + io.Reader + io.Writer +} + +func (c *conn) Close() error { + err1 := c.Reader.(*pipe).Close() + err2 := c.Writer.(*pipe).closeWrite() + if err1 != nil { + return err1 + } + return err2 +} + +func (*conn) LocalAddr() net.Addr { return addr{} } +func (*conn) RemoteAddr() net.Addr { return addr{} } +func (c *conn) SetDeadline(t time.Time) error { return fmt.Errorf("unsupported") } +func (c *conn) SetReadDeadline(t time.Time) error { return fmt.Errorf("unsupported") } +func (c *conn) SetWriteDeadline(t time.Time) error { return fmt.Errorf("unsupported") } + +type addr struct{} + +func (addr) Network() string { return "bufconn" } +func (addr) String() string { return "bufconn" } diff --git a/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go index c1c96dedcb75..0a57b9994812 100644 --- a/vendor/google.golang.org/grpc/trace.go +++ b/vendor/google.golang.org/grpc/trace.go @@ -24,6 +24,7 @@ import ( "io" "net" "strings" + "sync" "time" "golang.org/x/net/trace" @@ -53,13 +54,25 @@ type traceInfo struct { } // firstLine is the first line of an RPC trace. +// It may be mutated after construction; remoteAddr specifically may change +// during client-side use. type firstLine struct { + mu sync.Mutex client bool // whether this is a client (outgoing) RPC remoteAddr net.Addr deadline time.Duration // may be zero } +func (f *firstLine) SetRemoteAddr(addr net.Addr) { + f.mu.Lock() + f.remoteAddr = addr + f.mu.Unlock() +} + func (f *firstLine) String() string { + f.mu.Lock() + defer f.mu.Unlock() + var line bytes.Buffer io.WriteString(&line, "RPC: ") if f.client { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 260f27c88040..092e088258da 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.17.0" +const Version = "1.20.1" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index 94d3d54e2fbb..bd5c8de90c33 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -13,26 +13,19 @@ die() { exit 1 } -# Check to make sure it's safe to modify the user's git repo. -if git status --porcelain | read; then - die "Uncommitted or untracked files found; commit changes first" -fi +fail_on_output() { + tee /dev/stderr | (! read) +} -if [[ -d "${GOPATH}/src" ]]; then - die "\${GOPATH}/src (${GOPATH}/src) exists; this script will delete it." -fi +# Check to make sure it's safe to modify the user's git repo. +git status --porcelain | fail_on_output # Undo any edits made by this script. cleanup() { - rm -rf "${GOPATH}/src" git reset --hard HEAD } trap cleanup EXIT -fail_on_output() { - tee /dev/stderr | (! read) -} - PATH="${GOPATH}/bin:${GOROOT}/bin:${PATH}" if [[ "$1" = "-install" ]]; then @@ -76,6 +69,10 @@ fi # - Ensure all source files contain a copyright message. git ls-files "*.go" | xargs grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)\|DO NOT EDIT" 2>&1 | fail_on_output +# - Make sure all tests in grpc and grpc/test use leakcheck via Teardown. +(! grep 'func Test[^(]' *_test.go) +(! grep 'func Test[^(]' test/*.go) + # - Do not import math/rand for real library code. Use internal/grpcrand for # thread safety. git ls-files "*.go" | xargs grep -l '"math/rand"' 2>&1 | (! grep -v '^examples\|^stress\|grpcrand') @@ -89,7 +86,7 @@ go list -f {{.Dir}} ./... | xargs go run test/go_vet/vet.go # - gofmt, goimports, golint (with exceptions for generated code), go vet. gofmt -s -d -l . 2>&1 | fail_on_output -goimports -l . 2>&1 | fail_on_output +goimports -l . 2>&1 | (! grep -vE "(_mock|\.pb)\.go:") | fail_on_output golint ./... 2>&1 | (! grep -vE "(_mock|\.pb)\.go:") go tool vet -all . @@ -108,29 +105,25 @@ if go help mod >& /dev/null; then fi # - Collection of static analysis checks -### HACK HACK HACK: Remove once staticcheck works with modules. -# Make a symlink in ${GOPATH}/src to its ${GOPATH}/pkg/mod equivalent for every package we use. -for x in $(find "${GOPATH}/pkg/mod" -name '*@*' | grep -v \/mod\/cache\/); do - pkg="$(echo ${x#"${GOPATH}/pkg/mod/"} | cut -f1 -d@)"; - # If multiple versions exist, just use the existing one. - if [[ -L "${GOPATH}/src/${pkg}" ]]; then continue; fi - mkdir -p "$(dirname "${GOPATH}/src/${pkg}")"; - ln -s $x "${GOPATH}/src/${pkg}"; -done -### END HACK HACK HACK - # TODO(menghanl): fix errors in transport_test. -staticcheck -ignore ' -balancer.go:SA1019 -balancer_test.go:SA1019 -clientconn_test.go:SA1019 -balancer/roundrobin/roundrobin_test.go:SA1019 -benchmark/benchmain/main.go:SA1019 -internal/transport/handler_server.go:SA1019 -internal/transport/handler_server_test.go:SA1019 -internal/transport/transport_test.go:SA2002 -stats/stats_test.go:SA1019 -test/channelz_test.go:SA1019 -test/end2end_test.go:SA1019 +staticcheck -go 1.9 -checks 'inherit,-ST1015' -ignore ' +google.golang.org/grpc/balancer.go:SA1019 +google.golang.org/grpc/balancer/roundrobin/roundrobin_test.go:SA1019 +google.golang.org/grpc/balancer/xds/edsbalancer/balancergroup.go:SA1019 +google.golang.org/grpc/balancer/xds/xds.go:SA1019 +google.golang.org/grpc/balancer_conn_wrappers.go:SA1019 +google.golang.org/grpc/balancer_test.go:SA1019 +google.golang.org/grpc/benchmark/benchmain/main.go:SA1019 +google.golang.org/grpc/benchmark/worker/benchmark_client.go:SA1019 +google.golang.org/grpc/clientconn.go:S1024 +google.golang.org/grpc/clientconn_state_transition_test.go:SA1019 +google.golang.org/grpc/clientconn_test.go:SA1019 +google.golang.org/grpc/internal/transport/handler_server.go:SA1019 +google.golang.org/grpc/internal/transport/handler_server_test.go:SA1019 +google.golang.org/grpc/resolver/dns/dns_resolver.go:SA1019 +google.golang.org/grpc/stats/stats_test.go:SA1019 +google.golang.org/grpc/test/channelz_test.go:SA1019 +google.golang.org/grpc/test/end2end_test.go:SA1019 +google.golang.org/grpc/test/healthcheck_test.go:SA1019 ' ./... misspell -error . diff --git a/vendor/modules.txt b/vendor/modules.txt index e0b2e579a4c6..0007eb48033b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,19 +1,27 @@ -# contrib.go.opencensus.io/exporter/ocagent v0.4.1 -contrib.go.opencensus.io/exporter/ocagent -# github.com/Azure/azure-sdk-for-go v25.1.0+incompatible +# cloud.google.com/go v0.36.0 +cloud.google.com/go/storage +cloud.google.com/go/iam +cloud.google.com/go/internal +cloud.google.com/go/internal/optional +cloud.google.com/go/internal/trace +cloud.google.com/go/internal/version +cloud.google.com/go/compute/metadata +# github.com/Azure/azure-sdk-for-go v32.5.0+incompatible github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources +github.com/Azure/azure-sdk-for-go/services/analysisservices/mgmt/2017-08-01/analysisservices github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement github.com/Azure/azure-sdk-for-go/services/appinsights/mgmt/2015-05-01/insights github.com/Azure/azure-sdk-for-go/services/automation/mgmt/2015-10-31/automation -github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2017-09-01/batch +github.com/Azure/azure-sdk-for-go/services/batch/mgmt/2018-12-01/batch github.com/Azure/azure-sdk-for-go/services/cdn/mgmt/2017-10-12/cdn github.com/Azure/azure-sdk-for-go/services/cognitiveservices/mgmt/2017-04-18/cognitiveservices github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-06-01/compute github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance -github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry -github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2018-03-31/containerservice +github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2018-09-01/containerregistry +github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2019-06-01/containerservice github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb github.com/Azure/azure-sdk-for-go/services/databricks/mgmt/2018-04-01/databricks +github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory github.com/Azure/azure-sdk-for-go/services/datalake/analytics/mgmt/2016-11-01/account github.com/Azure/azure-sdk-for-go/services/datalake/store/2016-11-01/filesystem github.com/Azure/azure-sdk-for-go/services/datalake/store/mgmt/2016-11-01/account @@ -23,31 +31,35 @@ github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2018-02-14/keyvault github.com/Azure/azure-sdk-for-go/services/logic/mgmt/2016-06-01/logic +github.com/Azure/azure-sdk-for-go/services/maps/mgmt/2018-05-01/maps +github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb github.com/Azure/azure-sdk-for-go/services/mediaservices/mgmt/2018-07-01/media github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql -github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network +github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network github.com/Azure/azure-sdk-for-go/services/notificationhubs/mgmt/2017-04-01/notificationhubs github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql -github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-01-01-preview/authorization +github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-09-01-preview/authorization github.com/Azure/azure-sdk-for-go/services/preview/devspaces/mgmt/2018-06-01-preview/devspaces github.com/Azure/azure-sdk-for-go/services/preview/dns/mgmt/2018-03-01-preview/dns github.com/Azure/azure-sdk-for-go/services/preview/eventgrid/mgmt/2018-09-15-preview/eventgrid +github.com/Azure/azure-sdk-for-go/services/preview/hdinsight/mgmt/2018-06-01-preview/hdinsight github.com/Azure/azure-sdk-for-go/services/preview/iothub/mgmt/2018-12-01-preview/devices -github.com/Azure/azure-sdk-for-go/services/preview/mariadb/mgmt/2018-06-01-preview/mariadb github.com/Azure/azure-sdk-for-go/services/preview/monitor/mgmt/2018-03-01/insights github.com/Azure/azure-sdk-for-go/services/preview/msi/mgmt/2015-08-31-preview/msi github.com/Azure/azure-sdk-for-go/services/preview/operationalinsights/mgmt/2015-11-01-preview/operationalinsights github.com/Azure/azure-sdk-for-go/services/preview/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement github.com/Azure/azure-sdk-for-go/services/preview/resources/mgmt/2018-03-01-preview/managementgroups -github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security +github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v1.0/security github.com/Azure/azure-sdk-for-go/services/preview/signalr/mgmt/2018-03-01-preview/signalr github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2017-10-01-preview/sql +github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns +github.com/Azure/azure-sdk-for-go/services/provisioningservices/mgmt/2018-01-22/iothub github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2016-06-01/recoveryservices github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2017-07-01/backup +github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2018-01-10/siterecovery github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis github.com/Azure/azure-sdk-for-go/services/relay/mgmt/2017-04-01/relay -github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-09-01/locks github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/policy github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources @@ -55,31 +67,41 @@ github.com/Azure/azure-sdk-for-go/services/scheduler/mgmt/2016-03-01/scheduler github.com/Azure/azure-sdk-for-go/services/search/mgmt/2015-08-19/search github.com/Azure/azure-sdk-for-go/services/servicebus/mgmt/2017-04-01/servicebus github.com/Azure/azure-sdk-for-go/services/servicefabric/mgmt/2018-02-01/servicefabric -github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-02-01/storage -github.com/Azure/azure-sdk-for-go/services/trafficmanager/mgmt/2017-05-01/trafficmanager +github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage +github.com/Azure/azure-sdk-for-go/services/streamanalytics/mgmt/2016-03-01/streamanalytics +github.com/Azure/azure-sdk-for-go/services/trafficmanager/mgmt/2018-04-01/trafficmanager github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web github.com/Azure/azure-sdk-for-go/storage +github.com/Azure/azure-sdk-for-go/services/kusto/mgmt/2019-01-21/kusto +github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-02-01/resources github.com/Azure/azure-sdk-for-go/version -# github.com/Azure/go-autorest v11.4.0+incompatible +# github.com/Azure/go-autorest/autorest v0.9.0 github.com/Azure/go-autorest/autorest -github.com/Azure/go-autorest/autorest/adal github.com/Azure/go-autorest/autorest/azure +# github.com/Azure/go-autorest/autorest/adal v0.6.0 +github.com/Azure/go-autorest/autorest/adal +# github.com/Azure/go-autorest/autorest/azure/cli v0.3.0 +github.com/Azure/go-autorest/autorest/azure/cli +# github.com/Azure/go-autorest/autorest/date v0.2.0 github.com/Azure/go-autorest/autorest/date +# github.com/Azure/go-autorest/autorest/to v0.3.0 github.com/Azure/go-autorest/autorest/to +# github.com/Azure/go-autorest/autorest/validation v0.2.0 github.com/Azure/go-autorest/autorest/validation -github.com/Azure/go-autorest/tracing +# github.com/Azure/go-autorest/logger v0.1.0 github.com/Azure/go-autorest/logger -github.com/Azure/go-autorest/autorest/azure/cli -# github.com/agext/levenshtein v1.2.1 +# github.com/Azure/go-autorest/tracing v0.5.0 +github.com/Azure/go-autorest/tracing +# github.com/agext/levenshtein v1.2.2 github.com/agext/levenshtein -# github.com/apparentlymart/go-cidr v0.0.0-20170418151526-7e4b007599d4 +# github.com/apparentlymart/go-cidr v1.0.0 github.com/apparentlymart/go-cidr/cidr -# github.com/apparentlymart/go-textseg v0.0.0-20170531203952-b836f5c4d331 +# github.com/apparentlymart/go-textseg v1.0.0 github.com/apparentlymart/go-textseg/textseg -# github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 +# github.com/armon/go-radix v1.0.0 github.com/armon/go-radix -# github.com/aws/aws-sdk-go v1.8.34 +# github.com/aws/aws-sdk-go v1.21.7 github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws/credentials github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds @@ -88,22 +110,33 @@ github.com/aws/aws-sdk-go/aws/session github.com/aws/aws-sdk-go/service/s3 github.com/aws/aws-sdk-go/aws/awserr github.com/aws/aws-sdk-go/aws/endpoints +github.com/aws/aws-sdk-go/internal/sdkio +github.com/aws/aws-sdk-go/internal/ini github.com/aws/aws-sdk-go/internal/shareddefaults github.com/aws/aws-sdk-go/aws/client -github.com/aws/aws-sdk-go/aws/client/metadata github.com/aws/aws-sdk-go/aws/request +github.com/aws/aws-sdk-go/internal/sdkuri +github.com/aws/aws-sdk-go/aws/client/metadata github.com/aws/aws-sdk-go/aws/corehandlers +github.com/aws/aws-sdk-go/aws/credentials/processcreds github.com/aws/aws-sdk-go/aws/credentials/stscreds +github.com/aws/aws-sdk-go/aws/csm github.com/aws/aws-sdk-go/aws/defaults github.com/aws/aws-sdk-go/aws/awsutil github.com/aws/aws-sdk-go/aws/signer/v4 +github.com/aws/aws-sdk-go/internal/s3err github.com/aws/aws-sdk-go/private/protocol +github.com/aws/aws-sdk-go/private/protocol/eventstream +github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi +github.com/aws/aws-sdk-go/private/protocol/rest github.com/aws/aws-sdk-go/private/protocol/restxml +github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil +github.com/aws/aws-sdk-go/internal/sdkrand github.com/aws/aws-sdk-go/service/sts +github.com/aws/aws-sdk-go/service/sts/stsiface github.com/aws/aws-sdk-go/aws/credentials/endpointcreds -github.com/aws/aws-sdk-go/private/protocol/rest github.com/aws/aws-sdk-go/private/protocol/query -github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil +github.com/aws/aws-sdk-go/private/protocol/json/jsonutil github.com/aws/aws-sdk-go/private/protocol/query/queryutil # github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d github.com/bgentry/go-netrc/netrc @@ -111,55 +144,62 @@ github.com/bgentry/go-netrc/netrc github.com/bgentry/speakeasy # github.com/blang/semver v3.5.1+incompatible github.com/blang/semver -# github.com/census-instrumentation/opencensus-proto v0.1.0 -github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1 -github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1 -github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1 -github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1 -github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1 -github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1 -# github.com/davecgh/go-spew v1.1.0 +# github.com/btubbs/datetime v0.1.0 +github.com/btubbs/datetime +# github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew/spew # github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go -# github.com/dimchansky/utfbom v1.0.0 +# github.com/dimchansky/utfbom v1.1.0 github.com/dimchansky/utfbom # github.com/fatih/color v1.7.0 github.com/fatih/color -# github.com/go-ini/ini v1.23.1 -github.com/go-ini/ini -# github.com/golang/protobuf v1.2.0 +# github.com/golang/protobuf v1.3.1 github.com/golang/protobuf/proto -github.com/golang/protobuf/ptypes/timestamp github.com/golang/protobuf/ptypes -github.com/golang/protobuf/ptypes/wrappers github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration -# github.com/google/uuid v0.0.0-20170814143639-7e072fc3a7be +github.com/golang/protobuf/ptypes/timestamp +github.com/golang/protobuf/protoc-gen-go/descriptor +# github.com/google/go-cmp v0.3.0 +github.com/google/go-cmp/cmp +github.com/google/go-cmp/cmp/internal/diff +github.com/google/go-cmp/cmp/internal/flags +github.com/google/go-cmp/cmp/internal/function +github.com/google/go-cmp/cmp/internal/value +# github.com/google/uuid v1.1.1 github.com/google/uuid +# github.com/googleapis/gax-go/v2 v2.0.3 +github.com/googleapis/gax-go/v2 # github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/errwrap -# github.com/hashicorp/go-azure-helpers v0.0.0-20181211121309-38db96513363 +# github.com/hashicorp/go-azure-helpers v0.7.0 github.com/hashicorp/go-azure-helpers/authentication github.com/hashicorp/go-azure-helpers/resourceproviders +github.com/hashicorp/go-azure-helpers/sender github.com/hashicorp/go-azure-helpers/storage github.com/hashicorp/go-azure-helpers/response -# github.com/hashicorp/go-cleanhttp v0.0.0-20170211013415-3573b8b52aa7 +# github.com/hashicorp/go-cleanhttp v0.5.0 github.com/hashicorp/go-cleanhttp -# github.com/hashicorp/go-getter v0.0.0-20180226183729-64040d90d4ab +# github.com/hashicorp/go-getter v1.3.1-0.20190627223108-da0323b9545e github.com/hashicorp/go-getter/helper/url github.com/hashicorp/go-getter -# github.com/hashicorp/go-hclog v0.0.0-20170903163258-8105cc0a3736 +# github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f github.com/hashicorp/go-hclog # github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/go-multierror -# github.com/hashicorp/go-plugin v0.0.0-20170816151819-a5174f84d7f8 +# github.com/hashicorp/go-plugin v1.0.1-0.20190610192547-a1bc61569a26 github.com/hashicorp/go-plugin -# github.com/hashicorp/go-uuid v0.0.0-20160120003506-36289988d83c +github.com/hashicorp/go-plugin/internal/plugin +# github.com/hashicorp/go-safetemp v1.0.0 +github.com/hashicorp/go-safetemp +# github.com/hashicorp/go-uuid v1.0.1 github.com/hashicorp/go-uuid -# github.com/hashicorp/go-version v0.0.0-20161031182605-e96d38404026 +# github.com/hashicorp/go-version v1.1.0 github.com/hashicorp/go-version -# github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f +# github.com/hashicorp/golang-lru v0.5.1 +github.com/hashicorp/golang-lru/simplelru +# github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/hcl github.com/hashicorp/hcl/hcl/ast github.com/hashicorp/hcl/hcl/parser @@ -169,65 +209,91 @@ github.com/hashicorp/hcl/hcl/scanner github.com/hashicorp/hcl/hcl/strconv github.com/hashicorp/hcl/json/scanner github.com/hashicorp/hcl/json/token -# github.com/hashicorp/hcl2 v0.0.0-20180227155456-998a3053e207 -github.com/hashicorp/hcl2/gohcl +# github.com/hashicorp/hcl2 v0.0.0-20190725010614-0c3fe388e450 github.com/hashicorp/hcl2/hcl -github.com/hashicorp/hcl2/hclparse -github.com/hashicorp/hcl2/hcldec github.com/hashicorp/hcl2/hcl/hclsyntax +github.com/hashicorp/hcl2/hcldec +github.com/hashicorp/hcl2/hcled +github.com/hashicorp/hcl2/hclparse +github.com/hashicorp/hcl2/ext/typeexpr +github.com/hashicorp/hcl2/gohcl +github.com/hashicorp/hcl2/ext/dynblock github.com/hashicorp/hcl2/hcl/json -# github.com/hashicorp/hil v0.0.0-20170512213305-fac2259da677 +github.com/hashicorp/hcl2/hclwrite +# github.com/hashicorp/hil v0.0.0-20190212112733-ab17b08d6590 github.com/hashicorp/hil github.com/hashicorp/hil/ast github.com/hashicorp/hil/parser github.com/hashicorp/hil/scanner -# github.com/hashicorp/logutils v0.0.0-20150609070431-0dc08b1671f3 +# github.com/hashicorp/logutils v1.0.0 github.com/hashicorp/logutils -# github.com/hashicorp/terraform v0.11.9 +# github.com/hashicorp/terraform v0.12.6 github.com/hashicorp/terraform/plugin github.com/hashicorp/terraform/helper/hashcode -github.com/hashicorp/terraform/helper/mutexkv github.com/hashicorp/terraform/helper/resource github.com/hashicorp/terraform/helper/schema github.com/hashicorp/terraform/helper/structure github.com/hashicorp/terraform/helper/validation -github.com/hashicorp/terraform/httpclient github.com/hashicorp/terraform/terraform github.com/hashicorp/terraform/helper/acctest +github.com/hashicorp/terraform/httpclient +github.com/hashicorp/terraform/helper/mutexkv +github.com/hashicorp/terraform/configs/configschema +github.com/hashicorp/terraform/helper/plugin +github.com/hashicorp/terraform/internal/tfplugin5 +github.com/hashicorp/terraform/plugin/convert github.com/hashicorp/terraform/plugin/discovery -github.com/hashicorp/terraform/config/module +github.com/hashicorp/terraform/providers +github.com/hashicorp/terraform/provisioners +github.com/hashicorp/terraform/version +github.com/hashicorp/terraform/addrs +github.com/hashicorp/terraform/command/format +github.com/hashicorp/terraform/config/hcl2shim +github.com/hashicorp/terraform/configs +github.com/hashicorp/terraform/configs/configload github.com/hashicorp/terraform/helper/config github.com/hashicorp/terraform/helper/logging +github.com/hashicorp/terraform/internal/initwd +github.com/hashicorp/terraform/plans +github.com/hashicorp/terraform/states +github.com/hashicorp/terraform/tfdiags github.com/hashicorp/terraform/config -github.com/hashicorp/terraform/config/configschema -github.com/hashicorp/terraform/version +github.com/hashicorp/terraform/config/module github.com/hashicorp/terraform/dag github.com/hashicorp/terraform/flatmap -github.com/hashicorp/terraform/helper/hilmapstructure +github.com/hashicorp/terraform/helper/didyoumean +github.com/hashicorp/terraform/lang github.com/hashicorp/terraform/moduledeps -github.com/hashicorp/terraform/tfdiags +github.com/hashicorp/terraform/plans/objchange +github.com/hashicorp/terraform/states/statefile github.com/hashicorp/terraform/registry github.com/hashicorp/terraform/registry/regsrc github.com/hashicorp/terraform/registry/response github.com/hashicorp/terraform/svchost/disco -github.com/hashicorp/terraform/config/hcl2shim +github.com/hashicorp/terraform/internal/modsdir +github.com/hashicorp/terraform/internal/earlyconfig +github.com/hashicorp/terraform/helper/hilmapstructure +github.com/hashicorp/terraform/lang/blocktoattr +github.com/hashicorp/terraform/lang/funcs github.com/hashicorp/terraform/svchost github.com/hashicorp/terraform/svchost/auth -# github.com/hashicorp/yamux v0.0.0-20160720233140-d1caa6c97c9f +# github.com/hashicorp/terraform-config-inspect v0.0.0-20190327195015-8022a2663a70 +github.com/hashicorp/terraform-config-inspect/tfconfig +# github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb github.com/hashicorp/yamux -# github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7 +# github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af github.com/jmespath/go-jmespath -# github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c -github.com/marstr/guid -# github.com/mattn/go-colorable v0.0.9 +# github.com/mattn/go-colorable v0.1.1 github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.3 +# github.com/mattn/go-isatty v0.0.5 github.com/mattn/go-isatty # github.com/mitchellh/cli v1.0.0 github.com/mitchellh/cli +# github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db +github.com/mitchellh/colorstring # github.com/mitchellh/copystructure v1.0.0 github.com/mitchellh/copystructure -# github.com/mitchellh/go-homedir v1.0.0 +# github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir # github.com/mitchellh/go-testing-interface v1.0.0 github.com/mitchellh/go-testing-interface @@ -239,46 +305,77 @@ github.com/mitchellh/hashstructure github.com/mitchellh/mapstructure # github.com/mitchellh/reflectwalk v1.0.0 github.com/mitchellh/reflectwalk -# github.com/posener/complete v1.1.1 +# github.com/oklog/run v1.0.0 +github.com/oklog/run +# github.com/posener/complete v1.2.1 github.com/posener/complete github.com/posener/complete/cmd/install github.com/posener/complete/cmd github.com/posener/complete/match -# github.com/satori/go.uuid v0.0.0-20160927100844-b061729afc07 +# github.com/satori/go.uuid v1.2.0 github.com/satori/go.uuid # github.com/satori/uuid v0.0.0-20160927100844-b061729afc07 github.com/satori/uuid -# github.com/ulikunitz/xz v0.5.4 +# github.com/spf13/afero v1.2.1 +github.com/spf13/afero +github.com/spf13/afero/mem +# github.com/terraform-providers/terraform-provider-azuread v0.6.0 +github.com/terraform-providers/terraform-provider-azuread/azuread +github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/ar +github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/graph +github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/p +github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/slices +github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/tf +github.com/terraform-providers/terraform-provider-azuread/azuread/helpers/validate +github.com/terraform-providers/terraform-provider-azuread/version +# github.com/tombuildsstuff/giovanni v0.4.0 +github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs +github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/containers +github.com/tombuildsstuff/giovanni/storage/2018-11-09/file/directories +github.com/tombuildsstuff/giovanni/storage/2018-11-09/file/shares +github.com/tombuildsstuff/giovanni/storage/2018-11-09/queue/queues +github.com/tombuildsstuff/giovanni/storage/2018-11-09/table/entities +github.com/tombuildsstuff/giovanni/storage/2018-11-09/table/tables +github.com/tombuildsstuff/giovanni/storage/internal/endpoints +github.com/tombuildsstuff/giovanni/storage/internal/metadata +github.com/tombuildsstuff/giovanni/version +# github.com/ulikunitz/xz v0.5.5 github.com/ulikunitz/xz github.com/ulikunitz/xz/internal/xlog github.com/ulikunitz/xz/lzma github.com/ulikunitz/xz/internal/hash -# github.com/zclconf/go-cty v0.0.0-20180227163247-7166230c635f +# github.com/vmihailenco/msgpack v4.0.1+incompatible +github.com/vmihailenco/msgpack +github.com/vmihailenco/msgpack/codes +# github.com/zclconf/go-cty v1.0.1-0.20190708163926-19588f92a98f github.com/zclconf/go-cty/cty +github.com/zclconf/go-cty/cty/msgpack github.com/zclconf/go-cty/cty/convert +github.com/zclconf/go-cty/cty/json +github.com/zclconf/go-cty/cty/gocty +github.com/zclconf/go-cty/cty/set github.com/zclconf/go-cty/cty/function github.com/zclconf/go-cty/cty/function/stdlib -github.com/zclconf/go-cty/cty/set -github.com/zclconf/go-cty/cty/gocty -github.com/zclconf/go-cty/cty/json -# go.opencensus.io v0.18.1-0.20181204023538-aab39bd6a98b -go.opencensus.io/plugin/ochttp -go.opencensus.io/plugin/ochttp/propagation/tracecontext -go.opencensus.io/stats/view +# github.com/zclconf/go-cty-yaml v1.0.1 +github.com/zclconf/go-cty-yaml +# go.opencensus.io v0.22.0 go.opencensus.io/trace -go.opencensus.io -go.opencensus.io/exemplar -go.opencensus.io/resource -go.opencensus.io/stats -go.opencensus.io/tag +go.opencensus.io/plugin/ochttp +go.opencensus.io/internal +go.opencensus.io/trace/internal go.opencensus.io/trace/tracestate go.opencensus.io/plugin/ochttp/propagation/b3 +go.opencensus.io/stats +go.opencensus.io/stats/view +go.opencensus.io/tag go.opencensus.io/trace/propagation -go.opencensus.io/internal/tagencoding +go.opencensus.io +go.opencensus.io/metric/metricdata go.opencensus.io/stats/internal -go.opencensus.io/internal -go.opencensus.io/trace/internal -# golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869 +go.opencensus.io/internal/tagencoding +go.opencensus.io/metric/metricproducer +go.opencensus.io/resource +# golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 golang.org/x/crypto/pkcs12 golang.org/x/crypto/ssh golang.org/x/crypto/openpgp @@ -297,31 +394,60 @@ golang.org/x/crypto/ed25519/internal/edwards25519 golang.org/x/crypto/internal/subtle golang.org/x/crypto/cast5 golang.org/x/crypto/openpgp/elgamal -# golang.org/x/net v0.0.0-20181217023233-e147a9138326 +# golang.org/x/net v0.0.0-20190502183928-7f726cade0ab golang.org/x/net/context -golang.org/x/net/html golang.org/x/net/trace -golang.org/x/net/html/atom golang.org/x/net/internal/timeseries golang.org/x/net/http2 golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/http/httpguts -# golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 -golang.org/x/sync/semaphore -# golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6 +golang.org/x/net/context/ctxhttp +# golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 +golang.org/x/oauth2 +golang.org/x/oauth2/google +golang.org/x/oauth2/internal +golang.org/x/oauth2/jws +golang.org/x/oauth2/jwt +# golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 golang.org/x/sys/unix -# golang.org/x/text v0.3.0 +golang.org/x/sys/cpu +# golang.org/x/text v0.3.2 golang.org/x/text/unicode/norm golang.org/x/text/transform golang.org/x/text/secure/bidirule golang.org/x/text/unicode/bidi -# google.golang.org/api v0.0.0-20181221000618-65a46cafb132 -google.golang.org/api/support/bundler -# google.golang.org/genproto v0.0.0-20181221175505-bd9b4fb69e2f +# google.golang.org/api v0.4.0 +google.golang.org/api/iterator +google.golang.org/api/googleapi +google.golang.org/api/option +google.golang.org/api/storage/v1 +google.golang.org/api/transport/http +google.golang.org/api/googleapi/internal/uritemplates +google.golang.org/api/internal +google.golang.org/api/gensupport +google.golang.org/api/googleapi/transport +google.golang.org/api/transport/http/internal/propagation +# google.golang.org/appengine v1.4.0 +google.golang.org/appengine/datastore +google.golang.org/appengine +google.golang.org/appengine/internal +google.golang.org/appengine/internal/datastore +google.golang.org/appengine/urlfetch +google.golang.org/appengine/internal/app_identity +google.golang.org/appengine/internal/modules +google.golang.org/appengine/internal/base +google.golang.org/appengine/internal/log +google.golang.org/appengine/internal/remote_api +google.golang.org/appengine/internal/urlfetch +# google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.17.0 +google.golang.org/genproto/googleapis/iam/v1 +google.golang.org/genproto/googleapis/rpc/code +google.golang.org/genproto/googleapis/api/annotations +# google.golang.org/grpc v1.20.1 google.golang.org/grpc +google.golang.org/grpc/test/bufconn google.golang.org/grpc/credentials google.golang.org/grpc/health google.golang.org/grpc/health/grpc_health_v1 @@ -334,6 +460,7 @@ google.golang.org/grpc/encoding/proto google.golang.org/grpc/grpclog google.golang.org/grpc/internal google.golang.org/grpc/internal/backoff +google.golang.org/grpc/internal/balancerload google.golang.org/grpc/internal/binarylog google.golang.org/grpc/internal/channelz google.golang.org/grpc/internal/envconfig diff --git a/website/azurerm.erb b/website/azurerm.erb index 4ed17d158218..c7781eb28ad2 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -3,1327 +3,1688 @@ <% content_for :sidebar do %> <div class="docs-sidebar hidden-print affix-top" role="complementary"> <ul class="nav docs-sidenav"> - <li<%= sidebar_current("docs-home") %>> + <li> <a href="/docs/providers/index.html">All Providers</a> </li> <li> <a href="#">Azure Providers</a> <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azuread-index") %>> + <li> <a href="/docs/providers/azuread/index.html">Azure Active Directory</a> </li> - <li<%= sidebar_current("docs-azurerm-index") %>> + <li> <a href="/docs/providers/azurerm/index.html">Azure</a> </li> - <li<%= sidebar_current("docs-azurestack-index") %>> + <li> <a href="/docs/providers/azurestack/index.html">Azure Stack</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-guide") %>> + <li> <a href="#">Guides</a> <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-guide-2.0-upgrade") %>> + <li> <a href="/docs/providers/azurerm/guides/2.0-upgrade-guide.html">Azure Provider 2.0 Upgrade Guide</a> </li> - <li<%= sidebar_current("docs-azurerm-guide-authentication-azure-cli") %>> + <li> <a href="/docs/providers/azurerm/auth/azure_cli.html">Authenticating using the Azure CLI</a> </li> - <li<%= sidebar_current("docs-azurerm-guide-authentication-managed-service-identity") %>> + <li> <a href="/docs/providers/azurerm/auth/managed_service_identity.html">Authenticating using Managed Service Identity</a> </li> - <li<%= sidebar_current("docs-azurerm-guide-authentication-service-principal-client-certificate") %>> + <li> <a href="/docs/providers/azurerm/auth/service_principal_client_certificate.html">Authenticating using a Service Principal with a Client Certificate</a> </li> - <li<%= sidebar_current("docs-azurerm-guide-authentication-service-principal-client-secret") %>> + <li> <a href="/docs/providers/azurerm/auth/service_principal_client_secret.html">Authenticating using a Service Principal with a Client Secret</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-community-events") %>> - <a href="#">Upcoming Community Events</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-community-events-gardening-fall-2018") %>> - <a href="/docs/extend/community/events/2018/fall-gardening.html">Community Gardening - Fall 2018</a> - </li> - </ul> - </li> - - <li<%= sidebar_current("docs-azurerm-datasource") %>> + <li> <a href="#">Data Sources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-datasource-api-management-x") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/d/api_management.html">azurerm_api_management</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-api-management-api-x") %>> + <li> <a href="/docs/providers/azurerm/d/api_management_api.html">azurerm_api_management_api</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-api-management-group") %>> + <li> <a href="/docs/providers/azurerm/d/api_management_group.html">azurerm_api_management_group</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-api-management-product") %>> + <li> <a href="/docs/providers/azurerm/d/api_management_product.html">azurerm_api_management_product</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-api-management-user") %>> + <li> <a href="/docs/providers/azurerm/d/api_management_user.html">azurerm_api_management_user</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-network-application-security-group") %>> + <li> <a href="/docs/providers/azurerm/d/application_security_group.html">azurerm_application_security_group</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-app-service-x") %>> + <li> <a href="/docs/providers/azurerm/d/app_service.html">azurerm_app_service</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-app-service-plan") %>> + <li> <a href="/docs/providers/azurerm/d/app_service_plan.html">azurerm_app_service_plan</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-application-insights") %>> + <li> <a href="/docs/providers/azurerm/d/application_insights.html">azurerm_application_insights</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-availability-set") %>> + <li> + <a href="/docs/providers/azurerm/d/automation_variable_bool.html">azurerm_automation_variable_bool</a> + </li> + + <li> + <a href="/docs/providers/azurerm/d/automation_variable_datetime.html">azurerm_automation_variable_datetime</a> + </li> + + <li> + <a href="/docs/providers/azurerm/d/automation_variable_int.html">azurerm_automation_variable_int</a> + </li> + + <li> + <a href="/docs/providers/azurerm/d/automation_variable_string.html">azurerm_automation_variable_string</a> + </li> + + <li> <a href="/docs/providers/azurerm/d/availability_set.html">azurerm_availability_set</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-azuread-application") %>> + <li> <a href="/docs/providers/azurerm/d/azuread_application.html">azurerm_azuread_application</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-azuread-service-principal") %>> + <li> <a href="/docs/providers/azurerm/d/azuread_service_principal.html">azurerm_azuread_service_principal</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-batch-account") %>> + <li> <a href="/docs/providers/azurerm/d/batch_account.html">azurerm_batch_account</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-batch-pool") %>> + <li> + <a href="/docs/providers/azurerm/d/batch_certificate.html">azurerm_batch_certificate</a> + </li> + + <li> <a href="/docs/providers/azurerm/d/batch_pool.html">azurerm_batch_pool</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-builtin-role-definition") %>> + <li> <a href="/docs/providers/azurerm/d/builtin_role_definition.html">azurerm_builtin_role_definition</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-cdn-profile") %>> + <li> <a href="/docs/providers/azurerm/d/cdn_profile.html">azurerm_cdn_profile</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-client-config") %>> + <li> <a href="/docs/providers/azurerm/d/client_config.html">azurerm_client_config</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-container-registry") %>> + <li> <a href="/docs/providers/azurerm/d/container_registry.html">azurerm_container_registry</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-cosmosdb-account") %>> + <li> <a href="/docs/providers/azurerm/d/cosmosdb_account.html">azurerm_cosmosdb_account</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-dns-zone") %>> + <li> <a href="/docs/providers/azurerm/d/dns_zone.html">azurerm_dns_zone</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-data-lake-store") %>> + <li> <a href="/docs/providers/azurerm/d/data_lake_store.html">azurerm_data_lake_store</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-dev-test-lab") %>> + <li> <a href="/docs/providers/azurerm/d/dev_test_lab.html">azurerm_dev_test_lab</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-eventhub-namespace") %>> + <li> <a href="/docs/providers/azurerm/d/eventhub_namespace.html">azurerm_eventhub_namespace</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-image") %>> + <li> + <a href="/docs/providers/azurerm/d/express_route_circuit.html">azurerm_express_route_circuit</a> + </li> + + <li> + <a href="/docs/providers/azurerm/d/firewall.html">azurerm_firewall</a> + </li> + + <li> + <a href="/docs/providers/azurerm/d/hdinsight_cluster.html">azurerm_hdinsight_cluster</a> + </li> + + <li> <a href="/docs/providers/azurerm/d/image.html">azurerm_image</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-key-vault-x") %>> + <li> <a href="/docs/providers/azurerm/d/key_vault.html">azurerm_key_vault</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-key-vault-access-policy") %>> + <li> <a href="/docs/providers/azurerm/d/key_vault_access_policy.html">azurerm_key_vault_access_policy</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-key-vault-key") %>> + <li> <a href="/docs/providers/azurerm/d/key_vault_key.html">azurerm_key_vault_key</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-key-vault-secret") %>> + <li> <a href="/docs/providers/azurerm/d/key_vault_secret.html">azurerm_key_vault_secret</a> </li> - <li<%= sidebar_current("docs-azurerm-data-source-kubernetes-cluster") %>> + <li> <a href="/docs/providers/azurerm/d/kubernetes_cluster.html">azurerm_kubernetes_cluster</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-load-balancer-x") %>> + <li> + <a href="/docs/providers/azurerm/d/kubernetes_service_versions.html">azurerm_kubernetes_service_versions</a> + </li> + + <li> <a href="/docs/providers/azurerm/d/loadbalancer.html">azurerm_lb</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-load-balancer-backend-address-pool") %>> + <li> <a href="/docs/providers/azurerm/d/loadbalancer_backend_address_pool.html">azurerm_lb_backend_address_pool</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-oms-log-analytics-workspace") %>> + <li> <a href="/docs/providers/azurerm/d/log_analytics_workspace.html">azurerm_log_analytics_workspace</a> </li> - <li<%= sidebar_current("docs-azurerm-data-source-logic-app-workflow") %>> + <li> <a href="/docs/providers/azurerm/d/logic_app_workflow.html">azurerm_logic_app_workflow</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-managed-disk") %>> + <li> <a href="/docs/providers/azurerm/d/managed_disk.html">azurerm_managed_disk</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-management-group") %>> + <li> <a href="/docs/providers/azurerm/d/management_group.html">azurerm_management_group</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-monitor-action-group") %>> + <li> + <a href="/docs/providers/azurerm/r/maps_account.html">azurerm_maps_account</a> + </li> + + <li> <a href="/docs/providers/azurerm/d/monitor_action_group.html">azurerm_monitor_action_group</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-monitor-diagnostic-categories") %>> + <li> <a href="/docs/providers/azurerm/d/monitor_diagnostic_categories.html">azurerm_monitor_diagnostic_categories</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-monitor-log-profile") %>> + <li> <a href="/docs/providers/azurerm/d/monitor_log_profile.html">azurerm_monitor_log_profile</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-network-interface") %>> + <li> + <a href="/docs/providers/azurerm/d/mssql_elasticpool.html">azurerm_mssql_elasticpool</a> + </li> + + <li> <a href="/docs/providers/azurerm/d/network_interface.html">azurerm_network_interface</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-network-security-group") %>> + <li> <a href="/docs/providers/azurerm/d/network_security_group.html">azurerm_network_security_group</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-network-watcher") %>> + <li> <a href="/docs/providers/azurerm/d/network_watcher.html">azurerm_network_watcher</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-notification-hub-namespace") %>> + <li> <a href="/docs/providers/azurerm/d/notification_hub_namespace.html">azurerm_notification_hub_namespace</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-platform-image") %>> + <li> <a href="/docs/providers/azurerm/d/platform_image.html">azurerm_platform_image</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-policy-definition") %>> + <li> <a href="/docs/providers/azurerm/d/policy_definition.html">azurerm_policy_definition</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-public-ip-x") %>> + <li> <a href="/docs/providers/azurerm/d/public_ip.html">azurerm_public_ip</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-public-ips") %>> + <li> <a href="/docs/providers/azurerm/d/public_ips.html">azurerm_public_ips</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-recovery-services-vault") %>> + <li> <a href="/docs/providers/azurerm/d/recovery_services_vault.html">azurerm_recovery_services_vault</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-recovery-services-protection-policy-vm") %>> + <li> <a href="/docs/providers/azurerm/d/recovery_services_protection_policy_vm.html">azurerm_recovery_services_protection_policy_vm</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-resource-group") %>> + <li> <a href="/docs/providers/azurerm/d/resource_group.html">azurerm_resource_group</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-role-definition") %>> + <li> <a href="/docs/providers/azurerm/d/role_definition.html">azurerm_role_definition</a> </li> - <li<%= sidebar_current("docs-azurerm-data-source-route-table") %>> + <li> <a href="/docs/providers/azurerm/d/route_table.html">azurerm_route_table</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-scheduler-job-collection") %>> + <li> <a href="/docs/providers/azurerm/d/scheduler_job_collection.html">azurerm_scheduler_job_collection</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-servicebus-namespace") %>> + <li> <a href="/docs/providers/azurerm/d/servicebus_namespace.html">azurerm_servicebus_namespace</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-shared-image-x") %>> + <li> <a href="/docs/providers/azurerm/d/shared_image.html">azurerm_shared_image</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-shared-image-gallery") %>> + <li> <a href="/docs/providers/azurerm/d/shared_image_gallery.html">azurerm_shared_image_gallery</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-shared-image-version") %>> + <li> <a href="/docs/providers/azurerm/d/shared_image_version.html">azurerm_shared_image_version</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-storage-account-x") %>> + <li> + <a href="/docs/providers/azurerm/d/sql_server.html">azurerm_sql_server</a> + </li> + + <li> + <a href="/docs/providers/azurerm/d/stream_analytics_job.html">azurerm_stream_analytics_job</a> + </li> + + <li> <a href="/docs/providers/azurerm/d/storage_account.html">azurerm_storage_account</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-storage-account-sas") %>> + <li> <a href="/docs/providers/azurerm/d/storage_account_sas.html">azurerm_storage_account_sas</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-subnet") %>> + <li> <a href="/docs/providers/azurerm/d/subnet.html">azurerm_subnet</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-subscription-x") %>> + <li> <a href="/docs/providers/azurerm/d/subscription.html">azurerm_subscription</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-subscriptions") %>> + <li> <a href="/docs/providers/azurerm/d/subscriptions.html">azurerm_subscriptions</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-traffic-manager-geographical-location") %>> + <li> <a href="/docs/providers/azurerm/d/traffic_manager_geographical_location.html">azurerm_traffic_manager_geographical_location</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-virtual-machine") %>> + <li> + <a href="/docs/providers/azurerm/d/user_assigned_identity.html">azurerm_user_assigned_identity</a> + </li> + + <li> <a href="/docs/providers/azurerm/d/virtual_machine.html">azurerm_virtual_machine</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-virtual-network-x") %>> + <li> <a href="/docs/providers/azurerm/d/virtual_network.html">azurerm_virtual_network</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-virtual-network-gateway") %>> + <li> <a href="/docs/providers/azurerm/d/virtual_network_gateway.html">azurerm_virtual_network_gateway</a> </li> + <li<%= sidebar_current("docs-azurerm-datasource-virtual-network-gateway-connection") %>> + <a href="/docs/providers/azurerm/d/virtual_network_gateway_connection.html">azurerm_virtual_network_gateway_connection</a> + </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-resource") %>> + <li> <a href="#">Base Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-resource-group") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/resource_group.html">azurerm_resource_group</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-api-management") %>> + <li> + <a href="#">Analysis Services Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/analysis_services_server.html">azurerm_analysis_services_server</a> + </li> + </ul> + </li> + + <li> <a href="#">API Management Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-api-management-x") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/api_management.html">azurerm_api_management</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-api-management-api-x") %>> + <li> <a href="/docs/providers/azurerm/r/api_management_api.html">azurerm_api_management_api</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-api-management-group-x") %>> + <li> + <a href="/docs/providers/azurerm/r/api_management_api_operation.html">azurerm_api_management_api_operation</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_api_operation_policy.html">azurerm_api_management_api_operation_policy</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_api_policy.html">azurerm_api_management_api_policy</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_api_schema.html">azurerm_api_management_api_schema</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_subscription.html">azurerm_api_management_subscription</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_api_version_set.html">azurerm_api_management_version_set</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_authorization_server.html">azurerm_api_management_authorization_server</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_backend.html">azurerm_api_management_backend</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_certificate.html">azurerm_api_management_certificate</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/api_management_group.html">azurerm_api_management_group</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-api-management-group-user") %>> + <li> <a href="/docs/providers/azurerm/r/api_management_group_user.html">azurerm_api_management_group_user</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-api-management-product-x") %>> + <li> + <a href="/docs/providers/azurerm/r/api_management_logger.html">azurerm_api_management_logger</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_openid_connect_provider.html">azurerm_api_management_openid_connect_provider</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/api_management_product.html">azurerm_api_management_product</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-api-management-product-api") %>> + <li> <a href="/docs/providers/azurerm/r/api_management_product_api.html">azurerm_api_management_product_api</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-api-management-product-group") %>> + <li> <a href="/docs/providers/azurerm/r/api_management_product_group.html">azurerm_api_management_product_group</a> </li> - <li<%= sidebar_current("docs-azurerm-datasource-api-management-property-x") %>> + <li> + <a href="/docs/providers/azurerm/r/api_management_product_policy.html">azurerm_api_management_product_policy</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/api_management_property.html">azurerm_api_management_property</a> </li> + + <li> + <a href="/docs/providers/azurerm/r/api_management_user.html">azurerm_api_management_user</a> + </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-app-service") %>> + <li> <a href="#">App Service (Web Apps) Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-app-service-x") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/app_service.html">azurerm_app_service</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-app-service-active-slot") %>> + <li> <a href="/docs/providers/azurerm/r/app_service_active_slot.html">azurerm_app_service_active_slot</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-app-service-custom-hostname-binding") %>> + <li> + <a href="/docs/providers/azurerm/r/app_service_certificate.html">azurerm_app_service_certificate</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/app_service_custom_hostname_binding.html">azurerm_app_service_custom_hostname_binding</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-app-service-plan") %>> + <li> <a href="/docs/providers/azurerm/r/app_service_plan.html">azurerm_app_service_plan</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-app-service-slot") %>> + <li> <a href="/docs/providers/azurerm/r/app_service_slot.html">azurerm_app_service_slot</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-app-service-function-app") %>> + <li> <a href="/docs/providers/azurerm/r/function_app.html">azurerm_function_app</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-authorization") %>> - <a href="#">Authorization Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-authorization-role-assignment") %>> - <a href="/docs/providers/azurerm/r/role_assignment.html">azurerm_role_assignment</a> + <li> + <a href="#">Application Insights Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/application_insights.html">azurerm_application_insights</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-authorization-role-definition") %>> - <a href="/docs/providers/azurerm/r/role_definition.html">azurerm_role_definition</a> + <li> + <a href="/docs/providers/azurerm/r/application_insights_api_key.html">azurerm_application_insights_api_key</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-authorization-user-assigned-identity") %>> - <a href="/docs/providers/azurerm/r/user_assigned_identity.html">azurerm_user_assigned_identity</a> + <li> + <a href="/docs/providers/azurerm/r/application_insights_web_tests.html">azurerm_application_insights_web_test</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-azuread") %>> - <a href="#">Azure Active Directory Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-azuread-application") %>> - <a href="/docs/providers/azurerm/r/azuread_application.html">azurerm_azuread_application</a> + <li> + <a href="#">Authorization Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/role_assignment.html">azurerm_role_assignment</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-azuread-service-principal-x") %>> - <a href="/docs/providers/azurerm/r/azuread_service_principal.html">azurerm_azuread_service_principal</a> + <li> + <a href="/docs/providers/azurerm/r/role_definition.html">azurerm_role_definition</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-azuread-service-principal-password") %>> - <a href="/docs/providers/azurerm/r/azuread_service_principal_password.html">azurerm_azuread_service_principal_password</a> + <li> + <a href="/docs/providers/azurerm/r/user_assigned_identity.html">azurerm_user_assigned_identity</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-automation") %>> + <li> <a href="#">Automation Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-automation-account") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/automation_account.html">azurerm_automation_account</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-automation-credential") %>> + <li> <a href="/docs/providers/azurerm/r/automation_credential.html">azurerm_automation_credential</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-automation-dsc-configuration") %>> + <li> <a href="/docs/providers/azurerm/r/automation_dsc_configuration.html">azurerm_automation_dsc_configuration</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-automation-dsc-nodeconfiguration") %>> + <li> <a href="/docs/providers/azurerm/r/automation_dsc_nodeconfiguration.html">azurerm_automation_dsc_nodeconfiguration</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-automation-module") %>> + <li> <a href="/docs/providers/azurerm/r/automation_module.html">azurerm_automation_module</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-automation-runbook") %>> + <li> <a href="/docs/providers/azurerm/r/automation_runbook.html">azurerm_automation_runbook</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-automation-schedule") %>> + <li> <a href="/docs/providers/azurerm/r/automation_schedule.html">azurerm_automation_schedule</a> </li> + + <li> + <a href="/docs/providers/azurerm/r/automation_variable_bool.html">azurerm_automation_variable_bool</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/automation_variable_datetime.html">azurerm_automation_variable_datetime</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/automation_variable_int.html">azurerm_automation_variable_int</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/automation_variable_string.html">azurerm_automation_variable_string</a> + </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-application-insights") %>> - <a href="#">Application Insights Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-application-insights-x") %>> - <a href="/docs/providers/azurerm/r/application_insights.html">azurerm_application_insights</a> + <li> + <a href="#">Azure Active Directory Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/azuread_application.html">azurerm_azuread_application</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-application-insights-api-key") %>> - <a href="/docs/providers/azurerm/r/application_insights_api_key.html">azurerm_application_insights_api_key</a> + <li> + <a href="/docs/providers/azurerm/r/azuread_service_principal.html">azurerm_azuread_service_principal</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/azuread_service_principal_password.html">azurerm_azuread_service_principal_password</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-batch") %>> + <li> <a href="#">Batch Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-batch-account") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/batch_account.html">azurerm_batch_account</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-batch-pool") %>> + <li> + <a href="/docs/providers/azurerm/r/batch_application.html">azurerm_batch_application</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/batch_certificate.html">azurerm_batch_certificate</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/batch_pool.html">azurerm_batch_pool</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-cdn") %>> + <li> <a href="#">CDN Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-cdn-endpoint") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/cdn_endpoint.html">azurerm_cdn_endpoint</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-cdn-profile") %>> + <li> <a href="/docs/providers/azurerm/r/cdn_profile.html">azurerm_cdn_profile</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute") %>> + <li> + <a href="#">Cognitive Services Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/cognitive_account.html">azurerm_cognitive_account</a> + </li> + </ul> + </li> + + <li> <a href="#">Compute Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-compute-availability-set") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/availability_set.html">azurerm_availability_set</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-image") %>> + <li> <a href="/docs/providers/azurerm/r/image.html">azurerm_image</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-managed-disk") %>> + <li> <a href="/docs/providers/azurerm/r/managed_disk.html">azurerm_managed_disk</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-snapshot") %>> + <li> <a href="/docs/providers/azurerm/r/snapshot.html">azurerm_snapshot</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-shared-image-x") %>> + <li> <a href="/docs/providers/azurerm/r/shared_image.html">azurerm_shared_image</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-shared-image-gallery") %>> + <li> <a href="/docs/providers/azurerm/r/shared_image_gallery.html">azurerm_shared_image_gallery</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-shared-image-version") %>> + <li> <a href="/docs/providers/azurerm/r/shared_image_version.html">azurerm_shared_image_version</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-virtual-machine-x") %>> + <li> <a href="/docs/providers/azurerm/r/virtual_machine.html">azurerm_virtual_machine</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-virtual-machine-data-disk-attachment") %>> + <li> <a href="/docs/providers/azurerm/r/virtual_machine_data_disk_attachment.html">azurerm_virtual_machine_data_disk_attachment</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-virtualmachine-extension") %>> + <li> <a href="/docs/providers/azurerm/r/virtual_machine_extension.html">azurerm_virtual_machine_extension</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-compute-virtualmachine-scale-set") %>> + <li> <a href="/docs/providers/azurerm/r/virtual_machine_scale_set.html">azurerm_virtual_machine_scale_set</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-container") %>> + <li> <a href="#">Container Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-container-group") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/container_group.html">azurerm_container_group</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-container-registry") %>> + <li> <a href="/docs/providers/azurerm/r/container_registry.html">azurerm_container_registry</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-container-service") %>> - <a href="/docs/providers/azurerm/r/container_service.html">azurerm_container_service</a> + <li> + <a href="/docs/providers/azurerm/r/container_registry_webhook.html">azurerm_container_registry_webhook</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-container-kubernetes-cluster") %>> - <a href="/docs/providers/azurerm/r/kubernetes_cluster.html">azurerm_kubernetes_cluster</a> + <li> + <a href="/docs/providers/azurerm/r/container_service.html">azurerm_container_service</a> </li> - </ul> - </li> - <li<%= sidebar_current("docs-azurerm-resource-cognitive") %>> - <a href="#">Cognitive Services Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-cognitive-account") %>> - <a href="/docs/providers/azurerm/r/cognitive_account.html">azurerm_cognitive_account</a> + <li> + <a href="/docs/providers/azurerm/r/kubernetes_cluster.html">azurerm_kubernetes_cluster</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-cosmosdb") %>> + <li> <a href="#">CosmosDB (DocumentDB) Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-cosmosdb-account") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/cosmosdb_account.html">azurerm_cosmosdb_account</a> </li> + <li> + <a href="/docs/providers/azurerm/r/cosmosdb_cassandra_keyspace.html">azurerm_cosmosdb_cassandra_keyspace</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/cosmosdb_mongo_collection.html">azurerm_cosmosdb_mongo_collection</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/cosmosdb_mongo_database.html">azurerm_cosmosdb_mongo_database</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/cosmosdb_sql_database.html">azurerm_cosmosdb_sql_database</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/cosmosdb_table.html">azurerm_cosmosdb_table</a> + </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-database") %>> + <li> <a href="#">Database Resources</a> - <ul class="nav nav-visible"> + <ul class="nav"> - <li<%= sidebar_current("docs-azurerm-resource-database-mariadb-database") %>> + <li> <a href="/docs/providers/azurerm/r/mariadb_database.html">azurerm_mariadb_database</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-mariadb-server") %>> + <li> + <a href="/docs/providers/azurerm/r/mariadb_firewall_rule.html">azurerm_mariadb_firewall_rule</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/mariadb_server.html">azurerm_mariadb_server</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-mysql-configuration") %>> + <li> <a href="/docs/providers/azurerm/r/mysql_configuration.html">azurerm_mysql_configuration</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-mysql-database") %>> + <li> <a href="/docs/providers/azurerm/r/mysql_database.html">azurerm_mysql_database</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-mysql-firewall-rule") %>> + <li> <a href="/docs/providers/azurerm/r/mysql_firewall_rule.html">azurerm_mysql_firewall_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-mysql-server") %>> + <li> <a href="/docs/providers/azurerm/r/mysql_server.html">azurerm_mysql_server</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-mysql-virtual-network-rule") %>> + <li> <a href="/docs/providers/azurerm/r/mysql_virtual_network_rule.html">azurerm_mysql_virtual_network_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-postgresql-configuration") %>> + <li> <a href="/docs/providers/azurerm/r/postgresql_configuration.html">azurerm_postgresql_configuration</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-postgresql-database") %>> + <li> <a href="/docs/providers/azurerm/r/postgresql_database.html">azurerm_postgresql_database</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-postgresql-firewall-rule") %>> + <li> <a href="/docs/providers/azurerm/r/postgresql_firewall_rule.html">azurerm_postgresql_firewall_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-postgresql-server") %>> + <li> <a href="/docs/providers/azurerm/r/postgresql_server.html">azurerm_postgresql_server</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-postgresql-virtual-network-rule") %>> + <li> <a href="/docs/providers/azurerm/r/postgresql_virtual_network_rule.html">azurerm_postgresql_virtual_network_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-sql-database") %>> + <li> <a href="/docs/providers/azurerm/r/sql_database.html">azurerm_sql_database</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-sql-administrator") %>> + <li> <a href="/docs/providers/azurerm/r/sql_active_directory_administrator.html">azurerm_sql_active_directory_administrator</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-sql-elasticpool") %>> + <li> <a href="/docs/providers/azurerm/r/sql_elasticpool.html">azurerm_sql_elasticpool</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-mssql-elasticpool") %>> + <li> <a href="/docs/providers/azurerm/r/mssql_elasticpool.html">azurerm_mssql_elasticpool</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-sql-firewall-rule") %>> + <li> + <a href="/docs/providers/azurerm/r/sql_failover_group.html">azurerm_sql_failover_group</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/sql_firewall_rule.html">azurerm_sql_firewall_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-sql-server") %>> + <li> <a href="/docs/providers/azurerm/r/sql_server.html">azurerm_sql_server</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-database-sql-virtual-network-rule") %>> + <li> <a href="/docs/providers/azurerm/r/sql_virtual_network_rule.html">azurerm_sql_virtual_network_rule</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-databricks") %>> + <li> <a href="#">Databricks Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-databricks-workspace") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/databricks_workspace.html">azurerm_databricks_workspace</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-data-lake") %>> + <li> + <a href="#">Data Factory Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/data_factory.html">azurerm_data_factory</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/data_factory_dataset_mysql.html">azurerm_data_factory_dataset_mysql</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/data_factory_dataset_postgresql.html">azurerm_data_factory_dataset_postgresql</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/data_factory_dataset_sql_server_table.html">azurerm_data_factory_dataset_sql_server_table</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/data_factory_pipeline.html">azurerm_data_factory_pipeline</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/data_factory_linked_service_data_lake_storage_gen2.html">azurerm_data_factory_linked_service_data_lake_storage_gen2</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/data_factory_linked_service_mysql.html">azurerm_data_factory_linked_service_mysql</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/data_factory_linked_service_postgresql.html">azurerm_data_factory_linked_service_postgresql</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/data_factory_linked_service_sql_server.html">azurerm_data_factory_linked_service_sql_server</a> + </li> + </ul> + </li> + + <li> <a href="#">Data Lake Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-data-lake-analytics-account") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/data_lake_analytics_account.html">azurerm_data_lake_analytics_account</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-data-lake-analytics-firewall-rule") %>> + <li> <a href="/docs/providers/azurerm/r/data_lake_analytics_firewall_rule.html">azurerm_data_lake_analytics_firewall_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-data-lake-store-x") %>> + <li> <a href="/docs/providers/azurerm/r/data_lake_store.html">azurerm_data_lake_store</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-data-lake-store-firewall-rule") %>> + <li> <a href="/docs/providers/azurerm/r/data_lake_store_firewall_rule.html">azurerm_data_lake_store_firewall_rule</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-devspace") %>> + <li> <a href="#">DevSpace Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-devspace-controller") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/devspace_controller.html">azurerm_devspace_controller</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-dev-test") %>> + <li> <a href="#">Dev Test Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-dev-test-lab") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/dev_test_lab.html">azurerm_dev_test_lab</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dev-test-linux-virtual-machine") %>> + <li> <a href="/docs/providers/azurerm/r/dev_test_linux_virtual_machine.html">azurerm_dev_test_linux_virtual_machine</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dev-test-policy") %>> + <li> <a href="/docs/providers/azurerm/r/dev_test_policy.html">azurerm_dev_test_policy</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dev-test-virtual-network") %>> + <li> <a href="/docs/providers/azurerm/r/dev_test_virtual_network.html">azurerm_dev_test_virtual_network</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dev-test-windows-virtual-machine") %>> + <li> <a href="/docs/providers/azurerm/r/dev_test_windows_virtual_machine.html">azurerm_dev_test_windows_virtual_machine</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns") %>> + <li> <a href="#">DNS Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-dns-a-record") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/dns_a_record.html">azurerm_dns_a_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-aaaa-record") %>> + <li> <a href="/docs/providers/azurerm/r/dns_aaaa_record.html">azurerm_dns_aaaa_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-caa-record") %>> + <li> <a href="/docs/providers/azurerm/r/dns_caa_record.html">azurerm_dns_caa_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-cname-record") %>> + <li> <a href="/docs/providers/azurerm/r/dns_cname_record.html">azurerm_dns_cname_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-mx-record") %>> + <li> <a href="/docs/providers/azurerm/r/dns_mx_record.html">azurerm_dns_mx_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-ns-record") %>> + <li> <a href="/docs/providers/azurerm/r/dns_ns_record.html">azurerm_dns_ns_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-ptr-record") %>> + <li> <a href="/docs/providers/azurerm/r/dns_ptr_record.html">azurerm_dns_ptr_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-srv-record") %>> + <li> <a href="/docs/providers/azurerm/r/dns_srv_record.html">azurerm_dns_srv_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-txt-record") %>> + <li> <a href="/docs/providers/azurerm/r/dns_txt_record.html">azurerm_dns_txt_record</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-dns-zone") %>> + <li> <a href="/docs/providers/azurerm/r/dns_zone.html">azurerm_dns_zone</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-key-vault") %>> + <li> + <a href="#">HDInsight Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/hdinsight_hadoop_cluster.html">azurerm_hdinsight_hadoop_cluster</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/hdinsight_hbase_cluster.html">azurerm_hdinsight_hbase_cluster</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/hdinsight_kafka_cluster.html">azurerm_hdinsight_kafka_cluster</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/hdinsight_interactive_query_cluster.html">azurerm_hdinsight_interactive_query_cluster</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/hdinsight_ml_services_cluster.html">azurerm_hdinsight_ml_services_cluster</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/hdinsight_rserver_cluster.html">azurerm_hdinsight_rserver_cluster</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/hdinsight_spark_cluster.html">azurerm_hdinsight_spark_cluster</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/hdinsight_storm_cluster.html">azurerm_hdinsight_storm_cluster</a> + </li> + </ul> + </li> + + <li> <a href="#">Key Vault Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-key-vault-x") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/key_vault.html">azurerm_key_vault</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-key-vault-access-policy") %>> + <li> <a href="/docs/providers/azurerm/r/key_vault_access_policy.html">azurerm_key_vault_access_policy</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-key-vault-certificate") %>> + <li> <a href="/docs/providers/azurerm/r/key_vault_certificate.html">azurerm_key_vault_certificate</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-key-vault-key") %>> + <li> <a href="/docs/providers/azurerm/r/key_vault_key.html">azurerm_key_vault_key</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-key-vault-secret") %>> + <li> <a href="/docs/providers/azurerm/r/key_vault_secret.html">azurerm_key_vault_secret</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-loadbalancer") %>> + <li> + <a href="#">Data Explorer Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/kusto_cluster.html">azurerm_kusto_cluster</a> + </li> + </ul> + </li> + + <li> <a href="#">Load Balancer Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-loadbalancer-x") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/loadbalancer.html">azurerm_lb</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-loadbalancer-backend-address-pool") %>> + <li> <a href="/docs/providers/azurerm/r/loadbalancer_backend_address_pool.html">azurerm_lb_backend_address_pool</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-loadbalancer-rule") %>> + <li> <a href="/docs/providers/azurerm/r/loadbalancer_rule.html">azurerm_lb_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-loadbalancer-outbound-rule") %>> + <li> <a href="/docs/providers/azurerm/r/loadbalancer_outbound_rule.html">azurerm_lb_outbound_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-loadbalancer-nat-rule") %>> + <li> <a href="/docs/providers/azurerm/r/loadbalancer_nat_rule.html">azurerm_lb_nat_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-loadbalancer-nat-pool") %>> + <li> <a href="/docs/providers/azurerm/r/loadbalancer_nat_pool.html">azurerm_lb_nat_pool</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-loadbalancer-probe") %>> + <li> <a href="/docs/providers/azurerm/r/loadbalancer_probe.html">azurerm_lb_probe</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-logic") %>> + <li> + <a href="#">Log Analytics Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/log_analytics_linked_service.html">azurerm_log_analytics_linked_service</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/log_analytics_solution.html">azurerm_log_analytics_solution</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/log_analytics_workspace.html">azurerm_log_analytics_workspace</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/log_analytics_workspace_linked_service.html">azurerm_log_analytics_workspace_linked_service</a> + </li> + </ul> + </li> + + <li> <a href="#">Logic App Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-logic-app-action-custom") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/logic_app_action_custom.html">azurerm_logic_app_action_custom</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-logic-app-action-http") %>> + <li> <a href="/docs/providers/azurerm/r/logic_app_action_http.html">azurerm_logic_app_action_http</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-logic-app-trigger-custom") %>> + <li> <a href="/docs/providers/azurerm/r/logic_app_trigger_custom.html">azurerm_logic_app_trigger_custom</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-logic-app-trigger-http-request") %>> + <li> <a href="/docs/providers/azurerm/r/logic_app_trigger_http_request.html">azurerm_logic_app_trigger_http_request</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-logic-app-trigger-recurrence") %>> + <li> <a href="/docs/providers/azurerm/r/logic_app_trigger_recurrence.html">azurerm_logic_app_trigger_recurrence</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-logic-app-workflow") %>> + <li> <a href="/docs/providers/azurerm/r/logic_app_workflow.html">azurerm_logic_app_workflow</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-management") %>> + <li> <a href="#">Management Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-management-lock") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/management_lock.html">azurerm_management_lock</a> </li> + <li> + <a href="/docs/providers/azurerm/r/management_group.html">azurerm_management_group</a> + </li> + </ul> + </li> + + <li> + <a href="#">Maps Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/maps_account.html">azurerm_maps_account</a> + </li> + </ul> + </li> + + <li> + <a href="#">Media Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/media_services_account.html">azurerm_media_services_account</a> + </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging") %>> + <li> <a href="#">Messaging Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-messaging-eventgrid-domain") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/eventgrid_domain.html">azurerm_eventgrid_domain</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-eventgrid-event-subscription") %>> + <li> <a href="/docs/providers/azurerm/r/eventgrid_event_subscription.html">azurerm_eventgrid_event_subscription</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-eventgrid-topic") %>> + <li> <a href="/docs/providers/azurerm/r/eventgrid_topic.html">azurerm_eventgrid_topic</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-eventhub-x") %>> + <li> <a href="/docs/providers/azurerm/r/eventhub.html">azurerm_eventhub</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-eventhub-authorization-rule") %>> + <li> <a href="/docs/providers/azurerm/r/eventhub_authorization_rule.html">azurerm_eventhub_authorization_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-eventhub-consumer-group") %>> + <li> <a href="/docs/providers/azurerm/r/eventhub_consumer_group.html">azurerm_eventhub_consumer_group</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-eventhub-namespace-x") %>> + <li> <a href="/docs/providers/azurerm/r/eventhub_namespace.html">azurerm_eventhub_namespace</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-eventhub-namespace-authorization-rule") %>> + <li> <a href="/docs/providers/azurerm/r/eventhub_namespace_authorization_rule.html">azurerm_eventhub_namespace_authorization_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-iothub-x") %>> + <li> + <a href="/docs/providers/azurerm/r/iot_dps.html">azurerm_iot_dps</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/iot_dps_certificate.html">azurerm_iot_dps_certificate</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/iothub.html">azurerm_iothub</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-iothub-consumer-group") %>> + <li> <a href="/docs/providers/azurerm/r/iothub_consumer_group.html">azurerm_iothub_consumer_group</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-notification-hub-x") %>> + <li> + <a href="/docs/providers/azurerm/r/iothub_shared_access_policy.html">azurerm_iothub_shared_access_policy</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/notification_hub.html">azurerm_notification_hub</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-notification-hub-authorization-rule") %>> + <li> <a href="/docs/providers/azurerm/r/notification_hub_authorization_rule.html">azurerm_notification_hub_authorization_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-notification-hub-namespace") %>> + <li> <a href="/docs/providers/azurerm/r/notification_hub_namespace.html">azurerm_notification_hub_namespace</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-relay-namespace") %>> + <li> <a href="/docs/providers/azurerm/r/relay_namespace.html">azurerm_relay_namespace</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-servicebus-namespace-x") %>> + <li> <a href="/docs/providers/azurerm/r/servicebus_namespace.html">azurerm_servicebus_namespace</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-servicebus-namespace-authorization-rule") %>> + <li> <a href="/docs/providers/azurerm/r/servicebus_namespace_authorization_rule.html">azurerm_servicebus_namespace_authorization_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-servicebus-queue-x") %>> + <li> <a href="/docs/providers/azurerm/r/servicebus_queue.html">azurerm_servicebus_queue</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-servicebus-queue-authorization-rule") %>> + <li> <a href="/docs/providers/azurerm/r/servicebus_queue_authorization_rule.html">azurerm_servicebus_queue_authorization_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-servicebus-subscription-x") %>> + <li> <a href="/docs/providers/azurerm/r/servicebus_subscription.html">azurerm_servicebus_subscription</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-servicebus-subscription-rule") %>> + <li> <a href="/docs/providers/azurerm/r/servicebus_subscription_rule.html">azurerm_servicebus_subscription_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-servicebus-topic-x") %>> + <li> <a href="/docs/providers/azurerm/r/servicebus_topic.html">azurerm_servicebus_topic</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-servicebus-topic-authorization-rule") %>> + <li> <a href="/docs/providers/azurerm/r/servicebus_topic_authorization_rule.html">azurerm_servicebus_topic_authorization_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-messaging-signalr-service") %>> + <li> <a href="/docs/providers/azurerm/r/signalr_service.html">azurerm_signalr_service</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-monitor") %>> + <li> <a href="#">Monitor Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-autoscale-setting") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/autoscale_setting.html">azurerm_autoscale_setting</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-monitor-action-group") %>> + <li> <a href="/docs/providers/azurerm/r/monitor_action_group.html">azurerm_monitor_action_group</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-monitor-activity-log-alert") %>> + <li> <a href="/docs/providers/azurerm/r/monitor_activity_log_alert.html">azurerm_monitor_activity_log_alert</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-monitor-autoscale-setting") %>> + <li> <a href="/docs/providers/azurerm/r/monitor_autoscale_setting.html">azurerm_monitor_autoscale_setting</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-monitor-diagnostic-setting") %>> + <li> <a href="/docs/providers/azurerm/r/monitor_diagnostic_setting.html">azurerm_monitor_diagnostic_setting</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-monitor-log-profile") %>> + <li> <a href="/docs/providers/azurerm/r/monitor_log_profile.html">azurerm_monitor_log_profile</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-monitor-metric-alert-x") %>> + <li> <a href="/docs/providers/azurerm/r/monitor_metric_alert.html">azurerm_monitor_metric_alert</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-monitor-metric-alertrule") %>> + <li> <a href="/docs/providers/azurerm/r/monitor_metric_alertrule.html">azurerm_monitor_metric_alertrule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-metric-alertrule") %>> + <li> <a href="/docs/providers/azurerm/r/metric_alertrule.html">azurerm_metric_alertrule</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-network") %>> + <li> <a href="#">Network Resources</a> - <ul class="nav nav-visible"> + <ul class="nav"> - <li<%= sidebar_current("docs-azurerm-resource-network-application-gateway") %>> + <li> <a href="/docs/providers/azurerm/r/application_gateway.html">azurerm_application_gateway</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-application-security-group") %>> + <li> <a href="/docs/providers/azurerm/r/application_security_group.html">azurerm_application_security_group</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-connection-monitor") %>> + <li> <a href="/docs/providers/azurerm/r/connection_monitor.html">azurerm_connection_monitor</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-ddos-protection-plan") %>> + <li> + <a href="/docs/providers/azurerm/r/network_connection_monitor.html">azurerm_network_connection_monitor</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/ddos_protection_plan.html">azurerm_ddos_protection_plan</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-express-route-circuit-x") %>> + <li> + <a href="/docs/providers/azurerm/r/network_ddos_protection_plan.html">azurerm_network_ddos_protection_plan</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/express_route_circuit.html">azurerm_express_route_circuit</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-express-route-circuit-authorization") %>> + <li> <a href="/docs/providers/azurerm/r/express_route_circuit_authorization.html">azurerm_express_route_circuit_authorization</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-express-route-circuit-peering") %>> + <li> <a href="/docs/providers/azurerm/r/express_route_circuit_peering.html">azurerm_express_route_circuit_peering</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-firewall-x") %>> + <li> <a href="/docs/providers/azurerm/r/firewall.html">azurerm_firewall</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-firewall-application-rule-collection") %>> + <li> <a href="/docs/providers/azurerm/r/firewall_application_rule_collection.html">azurerm_firewall_application_rule_collection</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-firewall-network-rule-collection") %>> + <li> + <a href="/docs/providers/azurerm/r/firewall_nat_rule_collection.html">azurerm_firewall_nat_rule_collection</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/firewall_network_rule_collection.html">azurerm_firewall_network_rule_collection</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-local-network-gateway") %>> + <li> <a href="/docs/providers/azurerm/r/local_network_gateway.html">azurerm_local_network_gateway</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-interface-x") %>> + <li> <a href="/docs/providers/azurerm/r/network_interface.html">azurerm_network_interface</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-interface-application-gateway-backend-address-pool-association") %>> + <li> <a href="/docs/providers/azurerm/r/network_interface_application_gateway_backend_address_pool_association.html">azurerm_network_interface_application_gateway_backend_address_pool_association</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-interface-application-security-group-association") %>> + <li> <a href="/docs/providers/azurerm/r/network_interface_application_security_group_association.html">azurerm_network_interface_application_security_group_association</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-interface-backend-address-pool-association") %>> + <li> <a href="/docs/providers/azurerm/r/network_interface_backend_address_pool_association.html">azurerm_network_interface_backend_address_pool_association</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-interface-nat-rule-association") %>> + <li> <a href="/docs/providers/azurerm/r/network_interface_nat_rule_association.html">azurerm_network_interface_nat_rule_association</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-security-group") %>> + <li> + <a href="/docs/providers/azurerm/r/network_profile.html">azurerm_network_profile</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/network_security_group.html">azurerm_network_security_group</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-security-rule") %>> + <li> <a href="/docs/providers/azurerm/r/network_security_rule.html">azurerm_network_security_rule</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-watcher") %>> + <li> <a href="/docs/providers/azurerm/r/network_watcher.html">azurerm_network_watcher</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-packet-capture") %>> + <li> <a href="/docs/providers/azurerm/r/packet_capture.html">azurerm_packet_capture</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-public-ip") %>> + <li> + <a href="/docs/providers/azurerm/r/network_packet_capture.html">azurerm_network_packet_capture</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/public_ip.html">azurerm_public_ip</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-route-x") %>> + <li> + <a href="/docs/providers/azurerm/r/public_ip_prefix.html">azurerm_public_ip_prefix</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/route.html">azurerm_route</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-route-table") %>> + <li> <a href="/docs/providers/azurerm/r/route_table.html">azurerm_route_table</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-subnet-x") %>> + <li> <a href="/docs/providers/azurerm/r/subnet.html">azurerm_subnet</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-subnet-network-security-group-association") %>> + <li> <a href="/docs/providers/azurerm/r/subnet_network_security_group_association.html">azurerm_subnet_network_security_group_association</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-subnet-route-table-association") %>> + <li> <a href="/docs/providers/azurerm/r/subnet_route_table_association.html">azurerm_subnet_route_table_association</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-traffic-manager-endpoint") %>> + <li> <a href="/docs/providers/azurerm/r/traffic_manager_endpoint.html">azurerm_traffic_manager_endpoint</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-traffic-manager-profile") %>> + <li> <a href="/docs/providers/azurerm/r/traffic_manager_profile.html">azurerm_traffic_manager_profile</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-virtual-network-x") %>> + <li> <a href="/docs/providers/azurerm/r/virtual_network.html">azurerm_virtual_network</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-virtual-network-gateway-x") %>> + <li> <a href="/docs/providers/azurerm/r/virtual_network_gateway.html">azurerm_virtual_network_gateway</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-virtual-network-gateway-connection") %>> + <li> <a href="/docs/providers/azurerm/r/virtual_network_gateway_connection.html">azurerm_virtual_network_gateway_connection</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-network-virtual-network-peering") %>> + <li> <a href="/docs/providers/azurerm/r/virtual_network_peering.html">azurerm_virtual_network_peering</a> </li> - </ul> - </li> - - <li<%= sidebar_current("docs-azurerm-management-group") %>> - <a href="#">Management Group Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-management-group") %>> - <a href="/docs/providers/azurerm/r/management_group.html">azurerm_management_group</a> - </li> - </ul> - </li> - - <li<%= sidebar_current("docs-azurerm-log-analytics") %>> - <a href="#">Log Analytics Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-log-analytics-linked-service") %>> - <a href="/docs/providers/azurerm/r/log_analytics_linked_service.html">azurerm_log_analytics_linked_service</a> - </li> - <li<%= sidebar_current("docs-azurerm-log-analytics-solution") %>> - <a href="/docs/providers/azurerm/r/log_analytics_solution.html">azurerm_log_analytics_solution</a> + <li> + <a href="/docs/providers/azurerm/r/web_application_firewall_policy.html">azurerm_web_application_firewall_policy</a> </li> - <li<%= sidebar_current("docs-azurerm-log-analytics-workspace-x") %>> - <a href="/docs/providers/azurerm/r/log_analytics_workspace.html">azurerm_log_analytics_workspace</a> - </li> - - <li<%= sidebar_current("docs-azurerm-log-analytics-workspace-linked-service") %>> - <a href="/docs/providers/azurerm/r/log_analytics_workspace_linked_service.html">azurerm_log_analytics_workspace_linked_service</a> + <li<%= sidebar_current("docs-azurerm-resource-network-virtual-wan") %>> + <a href="/docs/providers/azurerm/r/virtual_wan.html">azurerm_virtual_wan</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-policy") %>> + <li> <a href="#">Policy Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-policy-assignment") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/policy_assignment.html">azurerm_policy_assignment</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-policy-definition") %>> + <li> <a href="/docs/providers/azurerm/r/policy_definition.html">azurerm_policy_definition</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-policy-set-definition") %>> + <li> <a href="/docs/providers/azurerm/r/policy_set_definition.html">azurerm_policy_set_definition</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-recovery-services") %>> + <li> + <a href="#">Private DNS Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/private_dns_zone.html">azurerm_private_dns_zone</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/private_dns_a_record.html">azurerm_private_dns_a_record</a> + </li> + <li> + <a href="/docs/providers/azurerm/r/private_dns_cname_record.html">azurerm_private_dns_cname_record</a> + </li> + </ul> + </li> + + <li> <a href="#">Recovery Services</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-recovery-services-protection-policy-vm") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/recovery_services_protection_policy_vm.html">azurerm_recovery_services_protection_policy_vm</a> </li> - <li<%= sidebar_current("docs-azurerm-recovery-services-protected-vm") %>> + <li> <a href="/docs/providers/azurerm/r/recovery_services_protected_vm.html">azurerm_recovery_services_protected_vm</a> </li> - <li<%= sidebar_current("docs-azurerm-recovery-services-vault") %>> + <li> <a href="/docs/providers/azurerm/r/recovery_services_vault.html">azurerm_recovery_services_vault</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-redis") %>> + <li> <a href="#">Redis Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-redis-cache") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/redis_cache.html">azurerm_redis_cache</a> </li> - <li<%= sidebar_current("docs-azurerm-redis-firewall-rule") %>> + <li> <a href="/docs/providers/azurerm/r/redis_firewall_rule.html">azurerm_redis_firewall_rule</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-search") %>> + <li> + <a href="#">Scheduler Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/scheduler_job_collection.html">azurerm_scheduler_job_collection</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/scheduler_job.html">azurerm_scheduler_job</a> + </li> + </ul> + </li> + + <li> <a href="#">Search Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-search-service") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/search_service.html">azurerm_search_service</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-security-center") %>> + <li> <a href="#">Security Center Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-security-center-contact") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/security_center_contact.html">azurerm_security_center_contact</a> </li> - <li<%= sidebar_current("docs-azurerm-security-center-subscription-pricing") %>> + <li> <a href="/docs/providers/azurerm/r/security_center_subscription_pricing.html">azurerm_security_center_subscription_pricing</a> </li> - <li<%= sidebar_current("docs-azurerm-security-center-workspace") %>> + <li> <a href="/docs/providers/azurerm/r/security_center_workspace.html">azurerm_security_center_workspace</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-scheduler") %>> - <a href="#">Scheduler Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-scheduler-job-collection") %>> - <a href="/docs/providers/azurerm/r/scheduler_job_collection.html">azurerm_scheduler_job_collection</a> - </li> - - <li<%= sidebar_current("docs-azurerm-resource-scheduler-job-x") %>> - <a href="/docs/providers/azurerm/r/scheduler_job.html">azurerm_scheduler_job</a> + <li> + <a href="#">Service Fabric Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/service_fabric_cluster.html">azurerm_service_fabric_cluster</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-service-fabric") %>> - <a href="#">Service Fabric Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-service-fabric-cluster") %>> - <a href="/docs/providers/azurerm/r/service_fabric_cluster.html">azurerm_service_fabric_cluster</a> + <li> + <a href="#">Stream Analytics Resources</a> + <ul class="nav"> + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_job.html">azurerm_stream_analytics_job</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_function_javascript_udf.html">azurerm_stream_analytics_function_javascript_udf</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_output_blob.html">azurerm_stream_analytics_output_blob</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_output_mssql.html">azurerm_stream_analytics_output_mssql</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_output_eventhub.html">azurerm_stream_analytics_output_eventhub</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_output_servicebus_queue.html">azurerm_stream_analytics_output_servicebus_queue</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_stream_input_blob.html">azurerm_stream_analytics_stream_input_blob</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_stream_input_eventhub.html">azurerm_stream_analytics_stream_input_eventhub</a> + </li> + + <li> + <a href="/docs/providers/azurerm/r/stream_analytics_stream_input_iothub.html">azurerm_stream_analytics_stream_input_iothub</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-storage") %>> + <li> <a href="#">Storage Resources</a> - <ul class="nav nav-visible"> + <ul class="nav"> - <li<%= sidebar_current("docs-azurerm-resource-storage-account") %>> + <li> <a href="/docs/providers/azurerm/r/storage_account.html">azurerm_storage_account</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-storage-blob") %>> + <li> <a href="/docs/providers/azurerm/r/storage_blob.html">azurerm_storage_blob</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-storage-container") %>> + <li> <a href="/docs/providers/azurerm/r/storage_container.html">azurerm_storage_container</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-storage-queue") %>> + <li> <a href="/docs/providers/azurerm/r/storage_queue.html">azurerm_storage_queue</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-storage-share") %>> + <li> <a href="/docs/providers/azurerm/r/storage_share.html">azurerm_storage_share</a> </li> - <li<%= sidebar_current("docs-azurerm-resource-storage-table") %>> + <li> + <a href="/docs/providers/azurerm/r/storage_share_directory.html">azurerm_storage_share_directory</a> + </li> + + <li> <a href="/docs/providers/azurerm/r/storage_table.html">azurerm_storage_table</a> </li> + <li> + <a href="/docs/providers/azurerm/r/storage_table_entity.html">azurerm_storage_table_entity</a> + </li> + </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-template") %>> + <li> <a href="#">Template Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-template-deployment") %>> + <ul class="nav"> + <li> <a href="/docs/providers/azurerm/r/template_deployment.html">azurerm_template_deployment</a> </li> </ul> </li> - <li<%= sidebar_current("docs-azurerm-resource-media") %>> - <a href="#">Media Resources</a> - <ul class="nav nav-visible"> - <li<%= sidebar_current("docs-azurerm-resource-media-media-services-account") %>> - <a href="/docs/providers/azurerm/r/media_services_account.html">azurerm_media_services_account</a> - </li> - </ul> - </li> - </ul> </div> <% end %> diff --git a/website/docs/auth/azure_cli.html.markdown b/website/docs/auth/azure_cli.html.markdown index 3d6471901e1e..a4aa1e22c0fe 100644 --- a/website/docs/auth/azure_cli.html.markdown +++ b/website/docs/auth/azure_cli.html.markdown @@ -86,7 +86,7 @@ To configure Terraform to use the Default Subscription defined in the Azure CLI ```hcl provider "azurerm" { # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" + version = "=1.28.0" } ``` @@ -101,7 +101,7 @@ It's also possible to configure Terraform to use a specific Subscription - for e ```hcl provider "azurerm" { # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" + version = "=1.28.0" subscription_id = "00000000-0000-0000-0000-000000000000" } @@ -118,7 +118,7 @@ If you're looking to use Terraform across Tenants - it's possible to do this by ```hcl provider "azurerm" { # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" + version = "=1.28.0" subscription_id = "00000000-0000-0000-0000-000000000000" tenant_id = "11111111-1111-1111-1111-111111111111" diff --git a/website/docs/auth/managed_service_identity.html.markdown b/website/docs/auth/managed_service_identity.html.markdown index 3674769bea1c..52b37d3d5626 100644 --- a/website/docs/auth/managed_service_identity.html.markdown +++ b/website/docs/auth/managed_service_identity.html.markdown @@ -1,34 +1,45 @@ --- layout: "azurerm" -page_title: "Azure Provider: Authenticating via Managed Service Identity" +page_title: "Azure Provider: Authenticating via Managed Identity" sidebar_current: "docs-azurerm-guide-authentication-managed-service-identity" description: |- - This guide will cover how to use Managed Service Identity as authentication for the Azure Provider. + This guide will cover how to use managed identity for Azure resources as authentication for the Azure Provider. --- -# Azure Provider: Authenticating using Managed Service Identity +# Azure Provider: Authenticating using managed identities for Azure resources Terraform supports a number of different methods for authenticating to Azure: * [Authenticating to Azure using the Azure CLI](azure_cli.html) -* Authenticating to Azure using Managed Service Identity (which is covered in this guide) +* Authenticating to Azure using Managed Identity (covered in this guide) * [Authenticating to Azure using a Service Principal and a Client Certificate](service_principal_client_certificate.html) * [Authenticating to Azure using a Service Principal and a Client Secret](service_principal_client_secret.html) --- -We recommend using either a Service Principal or Managed Service Identity when running Terraform non-interactively (such as when running Terraform in a CI server) - and authenticating using the Azure CLI when running Terraform locally. +We recommend using a service principal or a managed identity when running Terraform non-interactively (such as when running Terraform in a CI/CD pipeline), and authenticating using the Azure CLI when running Terraform locally. -## What is Managed Service Identity? +## What is a managed identity? -Certain services within Azure (for example Virtual Machines and Virtual Machine Scale Sets) can be assigned an Azure Active Directory identity which can be used to access the Azure Subscription. This identity can then be assigned permissions to a Subscription, Resource Group or other resources using the Azure Identity and Access Management functionality - however by default no permissions are assigned. +[Managed identities for Azure resources](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) can be used to authenticate to services that support Azure Active Directory (Azure AD) authentication. There are two types of managed identities: system-assigned and user-assigned. This article is based on system-assigned managed identities. -Once a resource is configured with an identity, a local metadata service exposes credentials which can be used by applications such as Terraform. +Managed identities work in conjunction with Azure Resource Manager (ARM), Azure AD, and the Azure Instance Metadata Service (IMDS). Azure resources that support managed identities expose an internal IMDS endpoint that the client can use to request an access token. No credentials are stored on the VM, and the only additional information needed to bootstrap the Terraform connection to Azure is the subscription ID and tenant ID. -## Configuring Managed Service Identity +Azure AD creates an AD identity when you configure an Azure resource to use a system-assigned managed identity. The configuration process is described in more detail, below. Azure AD then creates a service principal to represent the resource for role-based access control (RBAC) and access control (IAM). The lifecycle of a system-assigned identity is tied to the resource it is enabled for: it is created when the resource is created and it is automatically removed when the resource is deleted. -The (simplified) Terraform Configuration below configures a Virtual Machine with Managed Service Identity, and then grants it Contributor access to the Subscription: +Before you can use the managed identity, it has to be configured. There are two steps: + +1. Assign a role for the identity, associating it with the subscription that will be used to run Terraform. This step gives the identity permission to access Azure Resource Manager (ARM) resources. +1. Configure access control for one or more Azure resources. For example, if you use a key vault and a storage account, you will need to configure the vault and container separately. + +Before you can create a resource with a managed identity and then assign an RBAC role, your account needs sufficient permissions. You need to be a member of the account **Owner** role, or have **Contributor** plus **User Access Administrator** roles. + +Not all Azure services support managed identities, and availability varies by region. Configuration details vary slightly among services. For more information, see [Services that support managed identities for Azure resources](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities). + +## Configuring a VM to use a system-assigned managed identity + +The (simplified) Terraform configuration below provisions a virtual machine with a system-assigned managed identity, and then grants the Contributor role to the identity. ```hcl data "azurerm_subscription" "current" {} @@ -53,48 +64,72 @@ resource "azurerm_role_assignment" "test" { } ``` -## Configuring Managed Service Identity in Terraform +## Configuring Terraform to use a managed identity + +At this point we assume that managed idenity is configured on the resource (e.g. virtual machine) being used - and that permissions have been assigned via Azure's Identity and Access Management system. -At this point we assume that Managed Service Identity is configured on the resource (e.g. Virtual Machine) being used - and that permissions have been assigned via Azure's Identity and Access Management system. +Terraform can be configured to use managed identity for authentication in one of two ways: using environment variables, or by defining the fields within the provider block. -Terraform can be configured to use Managed Service Identity for authentication in one of two ways: using Environment Variables or by defining the fields within the Provider block. +### Configuring with environment variables -You can configure Terraform to use Managed Service Identity by setting the Environment Variable `ARM_USE_MSI` to `true`; as shown below: +Setting the `ARM_USE_MSI` environment variable to `true` tells Terraform to use a managed identity. In addition to a properly-configured management identity, Terraform needs to know the subscription ID and tenant ID to identify the full context for the Azure provider. ```shell $ export ARM_USE_MSI=true +$ export ARM_SUBSCRIPTION_ID=159f2485-xxxx-xxxx-xxxx-xxxxxxxxxxxx +$ export ARM_TENANT_ID=72f988bf-xxxx-xxxx-xxxx-xxxxxxxxxxxx ``` --> **Using a Custom MSI Endpoint?** In the unlikely event you're using a custom endpoint for Managed Service Identity - this can be configured using the `ARM_MSI_ENDPOINT` Environment Variable - however this shouldn't need to be configured in regular use. - -Whilst a Provider block is _technically_ optional when using Environment Variables - we'd strongly recommend defining one to be able to pin the version of the Provider being used: +A provider block is _technically_ optional when using environment variables. Even so, we recommend defining a provider block so that you can pin or constrain the version of the provider being used: ```hcl provider "azurerm" { - # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" + version = "~> 1.23" } ``` -More information on [the fields supported in the Provider block can be found here](../index.html#argument-reference). +### Configuring with the provider block -At this point running either `terraform plan` or `terraform apply` should allow Terraform to run using Managed Service Identity. +It's also possible to configure a managed identity within the provider block: ---- +```hcl +provider "azurerm" { + version = "~> 1.23" + + use_msi = true + + #... +} +``` -It's also possible to configure Managed Service Identity within the Provider Block: +If you intend to configure a remote backend in the provider block, put `use_msi` outside of the backend block: ```hcl provider "azurerm" { - # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" - + version = "~> 1.23" use_msi = true + + backend "azurerm" { + storage_account_name = "abcd1234" + container_name = "tfstate" + key = "prod.terraform.tfstate" + subscription_id = "00000000-0000-0000-0000-000000000000" + tenant_id = "00000000-0000-0000-0000-000000000000" + } } ``` --> **Using a Custom MSI Endpoint?** In the unlikely event you're using a custom endpoint for Managed Service Identity - this can be configured using the `msi_endpoint` field - however this shouldn't need to be configured in regular use. +More information on [the fields supported in the provider block can be found here](../index.html#argument-reference). + +<!-- it's not clear to me that we even need this info; it seems like this is the sort of thing you'd know about if you needed it. + +### Custom MSI endpoints + +Developers who are using a custom MSI endpoint can specify the endpoint in one of two ways: + +- In the provider block using the `msi_endpoint` field +- Using the `ARM_MSI_ENDPOINT` environment variable. -More information on [the fields supported in the Provider block can be found here](../index.html#argument-reference). +You don't normally need to set the endpoint, because Terraform and the Azure Provider will automatically locate the appropriate endpoint. -At this point running either `terraform plan` or `terraform apply` should allow Terraform to run using Managed Service Identity. +--> diff --git a/website/docs/auth/service_principal_client_certificate.html.markdown b/website/docs/auth/service_principal_client_certificate.html.markdown index c8564a09597d..fe9a6770e228 100644 --- a/website/docs/auth/service_principal_client_certificate.html.markdown +++ b/website/docs/auth/service_principal_client_certificate.html.markdown @@ -105,7 +105,7 @@ The following Provider block can be specified - where `1.21.0` is the version of ```hcl provider "azurerm" { # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" + version = "=1.28.0" } ``` @@ -125,7 +125,7 @@ variable "client_certificate_password" {} provider "azurerm" { # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" + version = "=1.28.0" subscription_id = "00000000-0000-0000-0000-000000000000" client_id = "00000000-0000-0000-0000-000000000000" diff --git a/website/docs/auth/service_principal_client_secret.html.markdown b/website/docs/auth/service_principal_client_secret.html.markdown index d6e60bb946fb..73e1c5b2370e 100644 --- a/website/docs/auth/service_principal_client_secret.html.markdown +++ b/website/docs/auth/service_principal_client_secret.html.markdown @@ -181,7 +181,7 @@ The following Provider block can be specified - where `1.21.0` is the version of ```hcl provider "azurerm" { # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" + version = "=1.28.0" } ``` @@ -200,7 +200,7 @@ variable "client_secret" {} provider "azurerm" { # Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used - version = "=1.22.0" + version = "=1.28.0" subscription_id = "00000000-0000-0000-0000-000000000000" client_id = "00000000-0000-0000-0000-000000000000" diff --git a/website/docs/d/api_management_group.html.markdown b/website/docs/d/api_management_group.html.markdown index 5ca86744e677..da3c915eea54 100644 --- a/website/docs/d/api_management_group.html.markdown +++ b/website/docs/d/api_management_group.html.markdown @@ -42,4 +42,4 @@ output "group_type" { * `external_id` - The identifier of the external Group. -* `type` - The type of this API Management Group, such as `custom` or `external`. \ No newline at end of file +* `type` - The type of this API Management Group, such as `custom` or `external`. diff --git a/website/docs/d/api_management_user.html.markdown b/website/docs/d/api_management_user.html.markdown index 2cc134a96f86..5f4f689be320 100644 --- a/website/docs/d/api_management_user.html.markdown +++ b/website/docs/d/api_management_user.html.markdown @@ -44,4 +44,4 @@ output "notes" { * `note` - Any notes about this User. -* `state` - The current state of this User, for example `active`, `blocked` or `pending`. \ No newline at end of file +* `state` - The current state of this User, for example `active`, `blocked` or `pending`. diff --git a/website/docs/d/app_service.html.markdown b/website/docs/d/app_service.html.markdown index 1c771a698874..0f79842d6421 100644 --- a/website/docs/d/app_service.html.markdown +++ b/website/docs/d/app_service.html.markdown @@ -69,12 +69,30 @@ output "app_service_id" { --- +A `cors` block exports the following: + +* `allowed_origins` - A list of origins which are able to make cross-origin calls. + +* `support_credentials` - Are credentials supported? + +--- + +A `ip_restriction` block exports the following: + +* `ip_address` - The IP Address used for this IP Restriction. + +* `subnet_mask` - The Subnet mask used for this IP Restriction. + +--- + `site_config` supports the following: * `always_on` - Is the app be loaded at all times? * `app_command_line` - App command line to launch. +* `cors` - A `cors` block as defined above. + * `default_documents` - The ordering of default documents to load, if an address isn't specified. * `dotnet_framework_version` - The version of the .net framework's CLR used in this App Service. @@ -83,7 +101,7 @@ output "app_service_id" { * `ftps_state` - State of FTP / FTPS service for this AppService. -* `ip_restriction` - One or more `ip_restriction` blocks as defined below. +* `ip_restriction` - One or more `ip_restriction` blocks as defined above. * `java_version` - The version of Java in use. @@ -93,6 +111,8 @@ output "app_service_id" { * `linux_fx_version` - Linux App Framework and version for the AppService. +* `windows_fx_version` - Windows Container Docker Image for the AppService. + * `local_mysql_enabled` - Is "MySQL In App" Enabled? This runs a local MySQL instance with your app and shares resources from the App Service plan. * `managed_pipeline_mode` - The Managed Pipeline Mode used in this App Service. @@ -114,11 +134,3 @@ output "app_service_id" { * `websockets_enabled` - Are WebSockets enabled for this App Service? * `virtual_network_name` - The name of the Virtual Network which this App Service is attached to. - ---- - -`ip_restriction` exports the following: - -* `ip_address` - The IP Address used for this IP Restriction. - -* `subnet_mask` - The Subnet mask used for this IP Restriction. diff --git a/website/docs/d/app_service_plan.html.markdown b/website/docs/d/app_service_plan.html.markdown index 120987c21afb..8e77a0e6bd8c 100644 --- a/website/docs/d/app_service_plan.html.markdown +++ b/website/docs/d/app_service_plan.html.markdown @@ -42,6 +42,10 @@ output "app_service_plan_id" { * `tags` - A mapping of tags assigned to the resource. +* `maximum_elastic_worker_count` - The maximum number of total workers allowed for this ElasticScaleEnabled App Service Plan. + +* `is_xenon` - A flag that indicates if it's a xenon plan (support for Windows Container) + * `maximum_number_of_workers` - The maximum number of workers supported with the App Service Plan's sku. --- diff --git a/website/docs/d/automation_variable_bool.html.markdown b/website/docs/d/automation_variable_bool.html.markdown new file mode 100644 index 000000000000..5821d3da741a --- /dev/null +++ b/website/docs/d/automation_variable_bool.html.markdown @@ -0,0 +1,50 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_automation_variable_bool" +sidebar_current: "docs-azurerm-datasource-automation-variable-bool" +description: |- + Gets information about an existing Automation Bool Variable +--- + +# Data Source: azurerm_automation_variable_bool + +Use this data source to access information about an existing Automation Bool Variable. + + +## Example Usage + +```hcl +data "azurerm_automation_variable_bool" "example" { + name = "tfex-example-var" + resource_group_name = "tfex-example-rg" + automation_account_name = "tfex-example-account" +} + +output "variable_id" { + value = "${data.azurerm_automation_variable_bool.example.id}" +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Automation Variable. + +* `resource_group_name` - (Required) The Name of the Resource Group where the automation account exists. + +* `automation_account_name` - (Required) The name of the automation account in which the Automation Variable exists. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Automation Variable. + +* `description` - The description of the Automation Variable. + +* `encrypted` - Specifies if the Automation Variable is encrypted. Defaults to `false`. + +* `value` - The value of the Automation Variable as a `boolean`. diff --git a/website/docs/d/automation_variable_datetime.html.markdown b/website/docs/d/automation_variable_datetime.html.markdown new file mode 100644 index 000000000000..b56726739e59 --- /dev/null +++ b/website/docs/d/automation_variable_datetime.html.markdown @@ -0,0 +1,50 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_automation_variable_datetime" +sidebar_current: "docs-azurerm-datasource-automation-variable-datetime" +description: |- + Gets information about an existing Automation Datetime Variable +--- + +# Data Source: azurerm_automation_variable_datetime + +Use this data source to access information about an existing Automation Datetime Variable. + + +## Example Usage + +```hcl +data "azurerm_automation_variable_datetime" "example" { + name = "tfex-example-var" + resource_group_name = "tfex-example-rg" + automation_account_name = "tfex-example-account" +} + +output "variable_id" { + value = "${data.azurerm_automation_variable_datetime.example.id}" +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Automation Variable. + +* `resource_group_name` - (Required) The Name of the Resource Group where the automation account exists. + +* `automation_account_name` - (Required) The name of the automation account in which the Automation Variable exists. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Automation Variable. + +* `description` - The description of the Automation Variable. + +* `encrypted` - Specifies if the Automation Variable is encrypted. Defaults to `false`. + +* `value` - The value of the Automation Variable in the [RFC3339 Section 5.6 Internet Date/Time Format](https://tools.ietf.org/html/rfc3339#section-5.6). diff --git a/website/docs/d/automation_variable_int.html.markdown b/website/docs/d/automation_variable_int.html.markdown new file mode 100644 index 000000000000..bcaf530303bc --- /dev/null +++ b/website/docs/d/automation_variable_int.html.markdown @@ -0,0 +1,50 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_automation_variable_int" +sidebar_current: "docs-azurerm-datasource-automation-variable-int" +description: |- + Gets information about an existing Automation Int Variable +--- + +# Data Source: azurerm_automation_variable_int + +Use this data source to access information about an existing Automation Int Variable. + + +## Example Usage + +```hcl +data "azurerm_automation_variable_int" "example" { + name = "tfex-example-var" + resource_group_name = "tfex-example-rg" + automation_account_name = "tfex-example-account" +} + +output "variable_id" { + value = "${data.azurerm_automation_variable_int.example.id}" +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Automation Variable. + +* `resource_group_name` - (Required) The Name of the Resource Group where the automation account exists. + +* `automation_account_name` - (Required) The name of the automation account in which the Automation Variable exists. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Automation Variable. + +* `description` - The description of the Automation Variable. + +* `encrypted` - Specifies if the Automation Variable is encrypted. Defaults to `false`. + +* `value` - The value of the Automation Variable as a `integer`. diff --git a/website/docs/d/automation_variable_string.html.markdown b/website/docs/d/automation_variable_string.html.markdown new file mode 100644 index 000000000000..e14aed9d18a5 --- /dev/null +++ b/website/docs/d/automation_variable_string.html.markdown @@ -0,0 +1,50 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_automation_variable_string" +sidebar_current: "docs-azurerm-datasource-automation-variable-string" +description: |- + Gets information about an existing Automation String Variable +--- + +# Data Source: azurerm_automation_variable_string + +Use this data source to access information about an existing Automation String Variable. + + +## Example Usage + +```hcl +data "azurerm_automation_variable_string" "example" { + name = "tfex-example-var" + resource_group_name = "tfex-example-rg" + automation_account_name = "tfex-example-account" +} + +output "variable_id" { + value = "${data.azurerm_automation_variable_string.example.id}" +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Automation Variable. + +* `resource_group_name` - (Required) The Name of the Resource Group where the automation account exists. + +* `automation_account_name` - (Required) The name of the automation account in which the Automation Variable exists. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Automation Variable. + +* `description` - The description of the Automation Variable. + +* `encrypted` - Specifies if the Automation Variable is encrypted. Defaults to `false`. + +* `value` - The value of the Automation Variable as a `string`. diff --git a/website/docs/d/batch_account.html.markdown b/website/docs/d/batch_account.html.markdown index 917037879ab4..cefcf91ade6b 100644 --- a/website/docs/d/batch_account.html.markdown +++ b/website/docs/d/batch_account.html.markdown @@ -50,6 +50,18 @@ The following attributes are exported: * `account_endpoint` - The account endpoint used to interact with the Batch service. +* `key_vault_reference` - The `key_vault_reference` block that describes the Azure KeyVault reference to use when deploying the Azure Batch account using the `UserSubscription` pool allocation mode. + * `tags` - A map of tags assigned to the Batch account. -~> **NOTE:** Primary and secondary access keys are only available when `pool_allocation_mode` is set to `BatchService`. See [documentation](https://docs.microsoft.com/en-us/azure/batch/batch-api-basics) for more information. \ No newline at end of file +~> **NOTE:** Primary and secondary access keys are only available when `pool_allocation_mode` is set to `BatchService`. See [documentation](https://docs.microsoft.com/en-us/azure/batch/batch-api-basics) for more information. + +--- + +A `key_vault_reference` block have the following properties: + +* `id` - The Azure identifier of the Azure KeyVault reference. + +* `url` - The HTTPS URL of the Azure KeyVault reference. + +--- diff --git a/website/docs/d/batch_certificate.html.markdown b/website/docs/d/batch_certificate.html.markdown new file mode 100644 index 000000000000..b45017b65e30 --- /dev/null +++ b/website/docs/d/batch_certificate.html.markdown @@ -0,0 +1,48 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_batch_certificate" +sidebar_current: "docs-azurerm-datasource-batch-certificate" +description: |- + Get information about an existing certificate in a Batch Account + +--- + +# Data Source: azurerm_batch_certificate + +Use this data source to access information about an existing certificate in a Batch Account. + +## Example Usage + +```hcl +data "azurerm_batch_certificate" "example" { + name = "SHA1-42C107874FD0E4A9583292A2F1098E8FE4B2EDDA" + account_name = "examplebatchaccount" + resource_group_name = "example" +} + +output "thumbprint" { + value = "${data.azurerm_batch_certificate.example.thumbprint}" +} +``` + +## Argument Reference + +* `name` - (Required) The name of the Batch certificate. + +* `account_name` - (Required) The name of the Batch account. + +* `resource_group_name` - (Required) The Name of the Resource Group where this Batch account exists. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Batch certificate ID. + +* `public_data` - The public key of the certificate. + +* `format` - The format of the certificate, such as `Cer` or `Pfx`. + +* `thumbprint` - The thumbprint of the certificate. + +* `thumbprint_algorithm` - The algorithm of the certificate thumbprint. diff --git a/website/docs/d/batch_pool.html.markdown b/website/docs/d/batch_pool.html.markdown index 8d3a40ce3d4c..21eb6fd31cda 100644 --- a/website/docs/d/batch_pool.html.markdown +++ b/website/docs/d/batch_pool.html.markdown @@ -14,7 +14,7 @@ Use this data source to access information about an existing Batch pool ## Example Usage ```hcl -data "azurerm_batch_pool "test" { +data "azurerm_batch_pool" "test" { name = "testbatchpool" account_name = "testbatchaccount" resource_group_name = "test" @@ -45,6 +45,10 @@ The following attributes are exported: * `max_tasks_per_node` - The maximum number of tasks that can run concurrently on a single compute node in the pool. +* `certificate` - One or more `certificate` blocks that describe the certificates installed on each compute node in the pool. + +* `container_configuration` - The container configuration used in the pool's VMs. + --- A `fixed_scale` block exports the following: @@ -55,7 +59,7 @@ A `fixed_scale` block exports the following: * `resize_timeout` - The timeout for resize operations. ---- +--- A `auto_scale` block exports the following: @@ -77,6 +81,8 @@ A `start_task` block exports the following: * `user_identity` - A `user_identity` block that describes the user identity under which the start task runs. +* `resource_file` - (Optional) One or more `resource_file` blocks that describe the files to be downloaded to a compute node. + --- A `user_identity` block exports the following: @@ -92,3 +98,53 @@ A `auto_user` block exports the following: * `elevation_level` - The elevation level of the user identity under which the start task runs. * `scope` - The scope of the user identity under which the start task runs. + +--- + +A `certificate` block exports the following: + +* `id` - The fully qualified ID of the certificate installed on the pool. + +* `store_location` - The location of the certificate store on the compute node into which the certificate is installed, either `CurrentUser` or `LocalMachine`. + +-> **NOTE:** This property is applicable only for pools configured with Windows nodes (that is, created with cloudServiceConfiguration, or with virtualMachineConfiguration using a Windows image reference). For Linux compute nodes, the certificates are stored in a directory inside the task working directory and an environment variable `AZ_BATCH_CERTIFICATES_DIR` is supplied to the task to query for this location. For certificates with visibility of 'remoteUser', a 'certs' directory is created in the user's home directory (e.g., `/home/{user-name}/certs`) and certificates are placed in that directory. + +* `store_name` - The name of the certificate store on the compute node into which the certificate is installed. + +-> **NOTE:** This property is applicable only for pools configured with Windows nodes (that is, created with cloudServiceConfiguration, or with virtualMachineConfiguration using a Windows image reference). + +* `visibility` - Which user accounts on the compute node have access to the private data of the certificate. + +--- + +A `resource_file` block exports the following: + +* `auto_storage_container_name` - The storage container name in the auto storage account. + +* `blob_prefix` - The blob prefix used when downloading blobs from an Azure Storage container. + +* `file_mode` - The file permission mode attribute represented as a string in octal format (e.g. `"0644"`). + +* `file_path` - The location on the compute node to which to download the file, relative to the task's working directory. If the `http_url` property is specified, the `file_path` is required and describes the path which the file will be downloaded to, including the filename. Otherwise, if the `auto_storage_container_name` or `storage_container_url` property is specified. + +* `http_url` - The URL of the file to download. If the URL is Azure Blob Storage, it must be readable using anonymous access. + +* `storage_container_url` - The URL of the blob container within Azure Blob Storage. + +--- + +A `container_configuration` block exports the following: + +* `type` - The type of container configuration. + +* `container_registries` - Additional container registries from which container images can be pulled by the pool's VMs. + +--- + +A `container_registries` block exports the following: + +* `registry_server` - The container registry URL. The default is "docker.io". + +* `user_name` - The user name to log into the registry server. + +* `password` - The password to log into the registry server. diff --git a/website/docs/d/dev_test_virtual_network.html.markdown b/website/docs/d/dev_test_virtual_network.html.markdown new file mode 100644 index 000000000000..81029b2f5e51 --- /dev/null +++ b/website/docs/d/dev_test_virtual_network.html.markdown @@ -0,0 +1,61 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_dev_test_virtual_network" +sidebar_current: "docs-azurerm-datasource-dev-test-virtual-network" +description: |- + Gets information about an existing Dev Test Lab Virtual Network. +--- + +# Data Source: azurerm_dev_test_virtual_network + +Use this data source to access information about an existing Dev Test Lab Virtual Network. + +## Example Usage + +```hcl +data "azurerm_dev_test_virtual_network" "test" { + name = "example-network" + lab_name = "examplelab" + resource_group_name = "example-resource" +} + +output "lab_subnet_name" { + value = "${data.azurerm_dev_test_virtual_network.test.allowed_subnets.0.lab_subnet_name} +} +``` + +## Argument Reference + +* `name` - (Required) Specifies the name of the Virtual Network. +* `lab_name` - (Required) Specifies the name of the Dev Test Lab. +* `resource_group_name` - (Required) Specifies the name of the resource group that contains the Virtual Network. + +## Attributes Reference + +* `allowed_subnets` - The list of subnets enabled for the virtual network as defined below. +* `subnet_overrides` - The list of permission overrides for the subnets as defined below. +* `unique_identifier` - The unique immutable identifier of the virtual network. + +--- + +An `allowed_subnets` block supports the following: + +* `allow_public_ip` - Indicates if this subnet allows public IP addresses. Possible values are `Allow`, `Default` and `Deny`. + +* `lab_subnet_name` - The name of the subnet. + +* `resource_id` - The resource identifier for the subnet. + +--- + +An `subnets_override` block supports the following: + +* `lab_subnet_name` - The name of the subnet. + +* `resource_id` - The resource identifier for the subnet. + +* `use_in_vm_creation_permission` - Indicates if the subnet can be used for VM creation. Possible values are `Allow`, `Default` and `Deny`. + +* `use_public_ip_permission` - Indicates if the subnet can be assigned public IP addresses. Possible values are `Allow`, `Default` and `Deny`. + +* `virtual_network_pool_name` - The virtual network pool associated with this subnet. diff --git a/website/docs/d/dns_zone.html.markdown b/website/docs/d/dns_zone.html.markdown index cc23b4e466af..5345bfdc0581 100644 --- a/website/docs/d/dns_zone.html.markdown +++ b/website/docs/d/dns_zone.html.markdown @@ -38,7 +38,9 @@ in your subscription that matches `name` will be returned. * `max_number_of_record_sets` - Maximum number of Records in the zone. * `number_of_record_sets` - The number of records already in the zone. * `name_servers` - A list of values that make up the NS record for the zone. -* `zone_type` - The type of this DNS zone, such as `Public` or `Private`. * `registration_virtual_network_ids` - A list of Virtual Network ID's that register hostnames in this DNS zone. * `resolution_virtual_network_ids` - A list of Virtual Network ID's that resolve records in this DNS zone. * `tags` - A mapping of tags to assign to the EventHub Namespace. +* `zone_type` - (**Deprecated**) The type of this DNS zone, such as `Public` or `Private`. + +~> **NOTE:** This field is deprecated since Private DNS is now a separate resource and will be removed in 2.0 of the Azure Provider. diff --git a/website/docs/d/express_route_circuit.html.markdown b/website/docs/d/express_route_circuit.html.markdown new file mode 100644 index 000000000000..add01b0c6f4d --- /dev/null +++ b/website/docs/d/express_route_circuit.html.markdown @@ -0,0 +1,73 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_express_route_circuit" +sidebar_current: "docs-azurerm-datasource-express-route-circuit" +description: |- + Gets information about an existing ExpressRoute circuit. +--- + +# Data Source: azurerm_express_route_circuit + +Use this data source to access information about an existing ExpressRoute circuit. + +## Example Usage + +```hcl +data "azurerm_express_route_circuit" test { + resource_group_name = "${azurerm_resource_group.test.name}" + name = "${azurerm_express_route_circuit.test.name}" +} + +output "express_route_circuit_id" { + value = "${data.azurerm_express_route_circuit.test.id}" +} + +output "service_key" { + value = "${data.azurerm_express_route_circuit.test.service_key}" +} +``` + +## Argument Reference + +* `name` - (Required) The name of the ExpressRoute circuit. +* `resource_group_name` - (Required) The Name of the Resource Group where the ExpressRoute circuit exists. + +## Attributes Reference + +* `id` - The ID of the ExpressRoute circuit. + +* `location` - The Azure location where the ExpressRoute circuit exists + +* `peerings` - A `peerings` block for the ExpressRoute circuit as documented below + +* `service_provider_provisioning_state` - The ExpressRoute circuit provisioning state from your chosen service provider. Possible values are "NotProvisioned", "Provisioning", "Provisioned", and "Deprovisioning". + +* `service_key` - The string needed by the service provider to provision the ExpressRoute circuit. + +* `service_provider_properties` - A `service_provider_properties` block for the ExpressRoute circuit as documented below + +* `sku` - A `sku` block for the ExpressRoute circuit as documented below. + +--- + +`service_provider_properties` supports the following: + +* `service_provider_name` - The name of the ExpressRoute Service Provider. +* `peering_location` - The name of the peering location and **not** the Azure resource location. +* `bandwidth_in_mbps` - The bandwidth in Mbps of the ExpressRoute circuit. + +`peerings` supports the following: + +* `peering_type` - The type of the ExpressRoute Circuit Peering. Acceptable values include `AzurePrivatePeering`, `AzurePublicPeering` and `MicrosoftPeering`. Changing this forces a new resource to be created. +~> **NOTE:** only one Peering of each Type can be created per ExpressRoute circuit. +* `primary_peer_address_prefix` - A `/30` subnet for the primary link. +* `secondary_peer_address_prefix` - A `/30` subnet for the secondary link. +* `vlan_id` - A valid VLAN ID to establish this peering on. +* `shared_key` - The shared key. Can be a maximum of 25 characters. +* `azure_asn` - The Either a 16-bit or a 32-bit ASN for Azure. +* `peer_asn` - The Either a 16-bit or a 32-bit ASN. Can either be public or private. + +`sku` supports the following: + +* `tier` - The service tier. Possible values are `Standard` or `Premium`. +* `family` - The billing mode for bandwidth. Possible values are `MeteredData` or `UnlimitedData`. diff --git a/website/docs/d/firewall.html.markdown b/website/docs/d/firewall.html.markdown new file mode 100644 index 000000000000..960cbaca3af8 --- /dev/null +++ b/website/docs/d/firewall.html.markdown @@ -0,0 +1,49 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_firewall" +sidebar_current: "docs-azurerm-datasource-firewall" +description: |- + Gets information about an existing Azure Firewall. + +--- + +# Data Source: azurerm_firewall + +Use this data source to access information about an existing Azure Firewall. + +## Example Usage + +```hcl +data "azurerm_firewall" "test" { + name = "firewall1" + resource_group_name = "firewall-RG" +} + +output "firewall_private_ip" { + value = "${data.azurerm_firewall.test.ip_configuration.0.private_ip_address}" +} +``` + +## Argument Reference + +* `name` - (Required) The name of the Azure Firewall. + +* `resource_group_name` - (Required) The name of the Resource Group in which the Azure Firewall exists. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Resource ID of the Azure Firewall. + +* `ip_configuration` - A `ip_configuration` block as defined below. + +--- + +A `ip_configuration` block exports the following: + +* `subnet_id` - The Resource ID of the subnet where the Azure Firewall is deployed. + +* `private_ip_address` - The private IP address of the Azure Firewall. + +* `public_ip_address_id`- The Resource ID of the public IP address of the Azure Firewall. diff --git a/website/docs/d/hdinsight_cluster.html.markdown b/website/docs/d/hdinsight_cluster.html.markdown new file mode 100644 index 000000000000..50a1c6a87376 --- /dev/null +++ b/website/docs/d/hdinsight_cluster.html.markdown @@ -0,0 +1,63 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_cluster" +sidebar_current: "docs-azurerm-datasource-hdinsight-cluster" +description: |- + Gets information about an existing HDInsight Cluster. + +--- + +# Data Source: azurerm_hdinsight_cluster + +Use this data source to access information about an existing HDInsight Cluster. + +## Example Usage + +```hcl +data "azurerm_hdinsight_cluster" "example" { + name = "example" + resource_group_name = "example-resources" +} + +output "https_endpoint" { + value = "${data.azurerm_hdinsight_cluster.example.https_endpoint}" +} +``` + +## Argument Reference + +* `name` - (Required) Specifies the name of this HDInsight Cluster. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight Cluster exists. + +## Attributes Reference + +* `location` - The Azure Region in which this HDInsight Cluster exists. + +* `cluster_version` - The version of HDInsights which is used on this HDInsight Cluster. + +* `component_versions` - A map of versions of software used on this HDInsights Cluster. + +* `gateway` - A `gateway` block as defined below. + +* `edge_ssh_endpoint` - The SSH Endpoint of the Edge Node for this HDInsight Cluster, if an Edge Node exists. + +* `https_endpoint` - The HTTPS Endpoint for this HDInsight Cluster. + +* `kind` - The kind of HDInsight Cluster this is, such as a Spark or Storm cluster. + +* `tier` - The SKU / Tier of this HDInsight Cluster. + +* `ssh_endpoint` - The SSH Endpoint for this HDInsight Cluster. + +* `tags` - A map of tags assigned to the HDInsight Cluster. + +--- + +A `gateway` block exports the following: + +* `enabled` - Is the Ambari Portal enabled? + +* `username` - The username used for the Ambari Portal. + +* `password` - The password used for the Ambari Portal. diff --git a/website/docs/d/image.html.markdown b/website/docs/d/image.html.markdown index 609a25d0a634..0b8f43c89981 100644 --- a/website/docs/d/image.html.markdown +++ b/website/docs/d/image.html.markdown @@ -33,11 +33,12 @@ output "image_id" { ## Attributes Reference +* `data_disk` - a collection of `data_disk` blocks as defined below. * `name` - the name of the Image. * `location` - the Azure Location where this Image exists. * `os_disk` - a `os_disk` block as defined below. -* `data_disk` - a collection of `data_disk` blocks as defined below. * `tags` - a mapping of tags to assigned to the resource. +* `zone_resilient` - is zone resiliency enabled? `os_disk` supports the following: diff --git a/website/docs/d/key_vault.html.markdown b/website/docs/d/key_vault.html.markdown index badfb50756ea..fc447511634a 100644 --- a/website/docs/d/key_vault.html.markdown +++ b/website/docs/d/key_vault.html.markdown @@ -72,3 +72,5 @@ A `sku` block exports the following: * `key_permissions` - A list of key permissions applicable to this Access Policy. * `secret_permissions` - A list of secret permissions applicable to this Access Policy. + +* `storage_permissions` - A list of storage permissions applicable to this Access Policy. diff --git a/website/docs/d/key_vault_secret.html.markdown b/website/docs/d/key_vault_secret.html.markdown index fee5997351fe..d02955d183f5 100644 --- a/website/docs/d/key_vault_secret.html.markdown +++ b/website/docs/d/key_vault_secret.html.markdown @@ -18,8 +18,8 @@ Use this data source to access information about an existing Key Vault Secret. ```hcl data "azurerm_key_vault_secret" "test" { - name = "secret-sauce" - vault_uri = "https://rickslab.vault.azure.net/" + name = "secret-sauce" + key_vault_id = "${data.azurerm_key_vault.existing.id}" } output "secret_value" { @@ -33,7 +33,7 @@ The following arguments are supported: * `name` - (Required) Specifies the name of the Key Vault Secret. -* `vault_uri` - (Required) Specifies the ID of the Key Vault Key Vault instance where the Secret resides, available on the `azurerm_key_vault` Data Source / Resource. +* `key_vault_id` - (Required) Specifies the ID of the Key Vault Key Vault instance where the Secret resides, available on the `azurerm_key_vault` Data Source / Resource. ## Attributes Reference diff --git a/website/docs/d/kubernetes_cluster.html.markdown b/website/docs/d/kubernetes_cluster.html.markdown index 8a7e81ec9a9d..19b45f9100d5 100644 --- a/website/docs/d/kubernetes_cluster.html.markdown +++ b/website/docs/d/kubernetes_cluster.html.markdown @@ -38,7 +38,7 @@ The following attributes are exported: * `addon_profile` - A `addon_profile` block as documented below. -* `agent_pool_profile` - One or more `agent_profile_pool` blocks as documented below. +* `agent_pool_profile` - An `agent_pool_profile` block as documented below. * `dns_prefix` - The DNS Prefix of the managed Kubernetes cluster. @@ -58,6 +58,8 @@ The following attributes are exported: * `linux_profile` - A `linux_profile` block as documented below. +* `windows_profile` - A `windows_profile` block as documented below. + * `network_profile` - A `network_profile` block as documented below. * `node_resource_group` - Auto-generated Resource Group containing AKS Cluster resources. @@ -76,14 +78,26 @@ A `addon_profile` block exports the following: * `oms_agent` - A `oms_agent` block. +* `kube_dashboard` - A `kube_dashboard` block. + --- A `agent_pool_profile` block exports the following: +* `type` - The type of the Agent Pool. + * `count` - The number of Agents (VM's) in the Pool. * `max_pods` - The maximum number of pods that can run on each agent. +* `availability_zones` - The availability zones used for the nodes. + +* `enable_auto_scaling` - If the auto-scaler is enabled. + +* `min_count` - Minimum number of nodes for auto-scaling + +* `max_count` - Maximum number of nodes for auto-scaling + * `name` - The name assigned to this pool of agents. * `os_disk_size_gb` - The size of the Agent VM's Operating System Disk in GB. @@ -94,6 +108,8 @@ A `agent_pool_profile` block exports the following: * `vnet_subnet_id` - The ID of the Subnet where the Agents in the Pool are provisioned. +* `node_taints` - The list of Kubernetes taints which are applied to nodes in the agent pool + --- A `azure_active_directory` block exports the following: @@ -147,7 +163,13 @@ A `linux_profile` block exports the following: * `admin_username` - The username associated with the administrator account of the managed Kubernetes Cluster. -* `ssh_key` - One or more `ssh_key` blocks as defined below. +* `ssh_key` - An `ssh_key` block as defined below. + +--- + +A `windows_profile` block exports the following: + +* `admin_username` - The username associated with the administrator account of the Windows VMs. --- @@ -159,6 +181,8 @@ A `network_profile` block exports the following: * `network_plugin` - Network plugin used such as `azure` or `kubenet`. +* `network_policy` - Network policy to be used with Azure CNI. Eg: `calico` or `azure` + * `pod_cidr` - The CIDR used for pod IP addresses. * `service_cidr` - Network range used by the Kubernetes service. @@ -173,6 +197,12 @@ A `oms_agent` block exports the following: --- +A `kube_dashboard` block supports the following: + +* `enabled` - (Required) Is the Kubernetes Dashboard enabled? + +--- + A `role_based_access_control` block exports the following: * `azure_active_directory` - A `azure_active_directory` block as documented above. diff --git a/website/docs/d/kubernetes_service_versions.html.markdown b/website/docs/d/kubernetes_service_versions.html.markdown new file mode 100644 index 000000000000..23382ebf0c3c --- /dev/null +++ b/website/docs/d/kubernetes_service_versions.html.markdown @@ -0,0 +1,39 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_kubernetes_service_versions" +sidebar_current: "docs-azurerm-datasource-kubernetes-service-versions" +description: |- + Gets the available versions of Kubernetes supported by Azure Kubernetes Service. +--- + +# Data Source: azurerm_kubernetes_service_versions + +Use this data source to retrieve the version of Kubernetes supported by Azure Kubernetes Service. + +## Example Usage + +```hcl +data "azurerm_kubernetes_service_versions" "current" { + location = "West Europe" +} + +output "versions" { + value = "${data.azurerm_kubernetes_service_versions.current.versions}" +} + +output "latest_version" { + value = "${data.azurerm_kubernetes_service_versions.current.latest_version}" +} +``` + +## Argument Reference + +* `location` - (Required) Specifies the location in which to query for versions. + +* `version_prefix` - (Optional) A prefix filter for the versions of Kubernetes which should be returned; for example `1.` will return `1.9` to `1.14`, whereas `1.12` will return `1.12.2`. + +## Attributes Reference + +* `versions` - The list of all supported versions. + +* `latest_version` - The most recent version available. diff --git a/website/docs/d/maps_account.html.markdown b/website/docs/d/maps_account.html.markdown new file mode 100644 index 000000000000..6b75bf5639fb --- /dev/null +++ b/website/docs/d/maps_account.html.markdown @@ -0,0 +1,43 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_maps_account" +sidebar_current: "docs-azurerm-datasource-maps-account" +description: |- + Gets information about an existing Azure Maps Account. +--- + +# Data Source: azurerm_maps_account + +Use this data source to access information about an existing Azure Maps Account. + +## Example Usage + +```hcl +data "azurerm_maps_account" "test" { + name = "production" + resource_group_name = "maps" +} + +output "maps_account_id" { + value = "${data.azurerm_maps_account.test.id}" +} +``` + +## Argument Reference + +* `name` - (Required) Specifies the name of the Maps Account. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which the Maps Account is located. + +## Attributes Reference + +* `id` - The ID of the Maps Account. + +* `sku_name` - The sku of the Azure Maps Account. + +* `primary_access_key` - The primary key used to authenticate and authorize access to the Maps REST APIs. + +* `secondary_access_key` - The primary key used to authenticate and authorize access to the Maps REST APIs. The second key is given to provide seamless key regeneration. + +* `x_ms_client_id` - A unique identifier for the Maps Account. + diff --git a/website/docs/d/monitor_diagnostic_categories.html.markdown b/website/docs/d/monitor_diagnostic_categories.html.markdown index 168b3d729314..954fa8423a32 100644 --- a/website/docs/d/monitor_diagnostic_categories.html.markdown +++ b/website/docs/d/monitor_diagnostic_categories.html.markdown @@ -20,7 +20,7 @@ data "azurerm_key_vault" "test" { } data "azurerm_monitor_diagnostic_categories" "test" { - resource_id = "${azurerm_key_vault.test.id}" + resource_id = "${data.azurerm_key_vault.test.id}" } ``` diff --git a/website/docs/d/mssql_elasticpool.html.markdown b/website/docs/d/mssql_elasticpool.html.markdown new file mode 100644 index 000000000000..9111ef85f618 --- /dev/null +++ b/website/docs/d/mssql_elasticpool.html.markdown @@ -0,0 +1,49 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_mssql_elasticpool" +sidebar_current: "docs-azurerm-datasource-mssql-elasticpool" +description: |- + Gets information about an existing SQL elastic pool. +--- + +# Data Source: azurerm_mssql_elasticpool + +Use this data source to access information about an existing SQL elastic pool. + +## Example Usage + +```hcl +data "azurerm_mssql_elasticpool" "example" { + name = "mssqlelasticpoolname" + resource_group_name = "example-resources" + server_name = "example-sql-server" +} + +output "elasticpool_id" { + value = "${data.azurerm_mssql_elasticpool.example.id}" +} +``` + +## Argument Reference + +* `name` - (Required) The name of the elastic pool. + +* `resource_group_name` - (Required) The name of the resource group which contains the elastic pool. + +* `server_name` - (Required) The name of the SQL Server which contains the elastic pool. + +## Attributes Reference + +* `location` - Specifies the supported Azure location where the resource exists. + +* `max_size_gb` - The max data size of the elastic pool in gigabytes. + +* `max_size_bytes` - The max data size of the elastic pool in bytes. + +* `per_db_min_capacity` - The minimum capacity all databases are guaranteed. + +* `per_db_max_capacity` - The maximum capacity any one database can consume. + +* `tags` - A mapping of tags to assign to the resource. + +* `zone_redundant` - Whether or not this elastic pool is zone redundant. diff --git a/website/docs/d/network_security_group.html.markdown b/website/docs/d/network_security_group.html.markdown index 01c1e14bdf01..fa544bc03bb2 100644 --- a/website/docs/d/network_security_group.html.markdown +++ b/website/docs/d/network_security_group.html.markdown @@ -54,8 +54,12 @@ The `security_rule` block supports: * `source_address_prefix` - CIDR or source IP range or * to match any IP. +* `source_address_prefixes` - A list of CIDRs or source IP ranges. + * `destination_address_prefix` - CIDR or destination IP range or * to match any IP. +* `destination_address_prefixes` - A list of CIDRs or destination IP ranges. + * `source_application_security_group_ids` - A List of source Application Security Group ID's * `destination_application_security_group_ids` - A List of destination Application Security Group ID's diff --git a/website/docs/d/redis_cache.html.markdown b/website/docs/d/redis_cache.html.markdown new file mode 100644 index 000000000000..46ecfef56329 --- /dev/null +++ b/website/docs/d/redis_cache.html.markdown @@ -0,0 +1,100 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_redis_cache" +sidebar_current: "docs-azurerm-datasource-redis-cache" +description: |- + Gets information about an existing Azure Redis Cache. + +--- + +# Data Source: azurerm_redis_cache + +Use this data source to access information about an existing Redis Cache + +# Example Usage +```hcl +data "azurerm_redis_cache" "example" { + name = "myrediscache" + resource_group_name = "redis-cache" +} + +output "primary_access_key" { + value = "${data.azurerm_redis_cache.example.primary_access_key}" +} + +output "hostname" { + value = "${data.azurerm_redis_cache.example.hostname}" +} +``` + +## Argument Reference + +* `name` - The name of the Redis cache + +* `resource_group_name` - The name of the resource group the Redis cache instance is located in. + +## Attribute Reference + +* `id` - The Cache ID. + +* `location` - The location of the Redis Cache. + +* `capacity` - The size of the Redis Cache deployed. + +* `family` - The SKU family/pricing group used. Possible values are `C` (for Basic/Standard SKU family) and `P` (for `Premium`) + +* `sku_name` - The SKU of Redis used. Possible values are `Basic`, `Standard` and `Premium`. + +* `enable_non_ssl_port` - Whether the SSL port is enabled. + +* `minimum_tls_version` - The minimum TLS version. + +* `patch_schedule` - A list of `patch_schedule` blocks as defined below - only available for Premium SKU's. + +* `private_static_ip_address` The Static IP Address assigned to the Redis Cache when hosted inside the Virtual Network. + +* `hostname` - The Hostname of the Redis Instance + +* `ssl_port` - The SSL Port of the Redis Instance + +* `port` - The non-SSL Port of the Redis Instance + +* `primary_access_key` - The Primary Access Key for the Redis Instance + +* `secondary_access_key` - The Secondary Access Key for the Redis Instance + +* `redis_configuration` - A `redis_configuration` block as defined below. + +--- + +A `patch_schedule` block supports the following (Requires Premium SKU's, attempting to access this value on Basic or Standard SKU's will result in an error): + +* `day_of_week` - the Weekday name for the patch item + +* `start_hour_utc` - The Start Hour for maintenance in UTC + +~> **Note:** The Patch Window lasts for `5` hours from the `start_hour_utc`. + +--- + +A `redis_configuration` block exports the following: + +* `enable_authentication` - Specifies if authentication is enabled + +* `maxmemory_reserved` - The value in megabytes reserved for non-cache usage e.g. failover + +* `maxmemory_delta` - The max-memory delta for this Redis instance. + +* `maxmemory_policy` - How Redis will select what to remove when `maxmemory` is reached. + +* `maxfragmentationmemory_reserved` - Value in megabytes reserved to accommodate for memory fragmentation. + +* `rdb_backup_enabled` - Is Backup Enabled? Only supported on Premium SKU's. + +* `rdb_backup_frequency` - The Backup Frequency in Minutes. Only supported on Premium SKU's. + +* `rdb_backup_max_snapshot_count` - The maximum number of snapshots that can be created as a backup. + +* `rdb_storage_connection_string` - The Connection String to the Storage Account. Only supported for Premium SKU's. + +~> **NOTE:** There's a bug in the Redis API where the original storage connection string isn't being returned, which [is being tracked in this issue](https://github.com/Azure/azure-rest-api-specs/issues/3037). In the interim you can use [the `ignore_changes` attribute to ignore changes to this field](https://www.terraform.io/docs/configuration/resources.html#ignore_changes) e.g.: diff --git a/website/docs/d/role_definition.markdown b/website/docs/d/role_definition.markdown index e81f1aeff167..235dde67de56 100644 --- a/website/docs/d/role_definition.markdown +++ b/website/docs/d/role_definition.markdown @@ -25,7 +25,7 @@ resource "azurerm_role_definition" "custom" { data "azurerm_role_definition" "custom" { role_definition_id = "${azurerm_role_definition.custom.role_definition_id}" - scope = "${data.azurerm_subscription.primary.id}" # /subscriptions/00000000-0000-0000-0000-000000000000 + scope = "${data.azurerm_subscription.primary.id}" # /subscriptions/00000000-0000-0000-0000-000000000000 } data "azurerm_role_definition" "custom-byname" { @@ -40,6 +40,7 @@ data "azurerm_builtin_role_definition" "builtin" { output "custom_role_definition_id" { value = "${data.azurerm_role_definition.custom.id}" } + output "contributor_role_definition_id" { value = "${data.azurerm_role_definition.builtin.id}" } diff --git a/website/docs/d/shared_image.html.markdown b/website/docs/d/shared_image.html.markdown index 506df038280d..a57febb15144 100644 --- a/website/docs/d/shared_image.html.markdown +++ b/website/docs/d/shared_image.html.markdown @@ -45,7 +45,7 @@ The following attributes are exported: * `location` - The supported Azure location where the Shared Image Gallery exists. -* `identity` - An `identity` block as defined below. +* `identifier` - An `identifier` block as defined below. * `os_type` - The type of Operating System present in this Shared Image. @@ -57,7 +57,7 @@ The following attributes are exported: --- -A `identity` block exports the following: +A `identifier` block exports the following: * `offer` - The Offer Name for this Shared Image. diff --git a/website/docs/d/sql_server.html.markdown b/website/docs/d/sql_server.html.markdown new file mode 100644 index 000000000000..a3bfffc0f469 --- /dev/null +++ b/website/docs/d/sql_server.html.markdown @@ -0,0 +1,42 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_sql_server" +sidebar_current: "docs-azurerm-datasource-sql-server" +description: |- + Gets information about an existing SQL Azure Database Server. +--- + +# Data Source: azurerm_sql_server + +Use this data source to access information about an existing SQL Azure Database Server. + +## Example Usage + +```hcl +data "azurerm_sql_server" "example" { + name = "examplesqlservername" + resource_group_name = "example-resources" +} + +output "sql_server_id" { + value = "${data.azurerm_sql_server.test.id}" +} +``` + +## Argument Reference + +* `name` - (Required) The name of the SQL Server. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group where the SQL Server exists. + +## Attributes Reference + +* `location` - The location of the Resource Group in which the SQL Server exists. + +* `fqdn` - The fully qualified domain name of the SQL Server. + +* `version` - The version of the SQL Server. + +* `administrator_login` - The administrator username of the SQL Server. + +* `tags` - A mapping of tags assigned to the resource. diff --git a/website/docs/d/storage_account.html.markdown b/website/docs/d/storage_account.html.markdown index b8f43966c7d9..697aa8278438 100644 --- a/website/docs/d/storage_account.html.markdown +++ b/website/docs/d/storage_account.html.markdown @@ -92,6 +92,26 @@ output "storage_account_tier" { * `primary_file_host` - The hostname with port if applicable for file storage in the primary location. +* `secondary_file_endpoint` - The endpoint URL for file storage in the secondary location. + +* `secondary_file_host` - The hostname with port if applicable for file storage in the secondary location. + +* `primary_dfs_endpoint` - The endpoint URL for DFS storage in the primary location. + +* `primary_dfs_host` - The hostname with port if applicable for DFS storage in the primary location. + +* `secondary_dfs_endpoint` - The endpoint URL for DFS storage in the secondary location. + +* `secondary_dfs_host` - The hostname with port if applicable for DFS storage in the secondary location. + +* `primary_web_endpoint` - The endpoint URL for web storage in the primary location. + +* `primary_web_host` - The hostname with port if applicable for web storage in the primary location. + +* `secondary_web_endpoint` - The endpoint URL for web storage in the secondary location. + +* `secondary_web_host` - The hostname with port if applicable for web storage in the secondary location. + * `primary_access_key` - The primary access key for the Storage Account. * `secondary_access_key` - The secondary access key for the Storage Account. diff --git a/website/docs/d/stream_analytics_job.html.markdown b/website/docs/d/stream_analytics_job.html.markdown new file mode 100644 index 000000000000..079159bfa7d6 --- /dev/null +++ b/website/docs/d/stream_analytics_job.html.markdown @@ -0,0 +1,56 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_job" +sidebar_current: "docs-azurerm-datasource-stream-analytics-job" +description: |- + Gets information about an existing Stream Analytics Job. + +--- + +# Data Source: azurerm_stream_analytics_job + +Use this data source to access information about an existing Stream Analytics Job. + +## Example Usage + +```hcl +data "azurerm_stream_analytics_job" "test" { + name = "example-job" + resource_group_name = "example-resources" +} + +output "job_id" { + value = "${data.azurerm_stream_analytics_job.test.job_id}" +} +``` + +## Argument Reference + +* `name` - (Required) Specifies the name of the Stream Analytics Job. + +* `resource_group_name` - (Required) Specifies the name of the resource group the Stream Analytics Job is located in. + +## Attributes Reference + +* `id` - The ID of the Stream Analytics Job. + +* `compatibility_level` - The compatibility level for this job. + +* `data_locale` - The Data Locale of the Job. + +* `events_late_arrival_max_delay_in_seconds` - The maximum tolerable delay in seconds where events arriving late could be included. + +* `events_out_of_order_max_delay_in_seconds` - The maximum tolerable delay in seconds where out-of-order events can be adjusted to be back in order. + +* `events_out_of_order_policy` - The policy which should be applied to events which arrive out of order in the input event stream. + +* `job_id` - The Job ID assigned by the Stream Analytics Job. + +* `location` - The Azure location where the Stream Analytics Job exists. + +* `output_error_policy` - The policy which should be applied to events which arrive at the output and cannot be written to the external storage due to being malformed (such as missing column values, column values of wrong type or size). + +* `streaming_units` - The number of streaming units that the streaming job uses. + +* `transformation_query` - The query that will be run in the streaming job, [written in Stream Analytics Query Language (SAQL)](https://msdn.microsoft.com/library/azure/dn834998). + diff --git a/website/docs/d/subnet.html.markdown b/website/docs/d/subnet.html.markdown index d4d0c1626fee..913ea9a6d705 100644 --- a/website/docs/d/subnet.html.markdown +++ b/website/docs/d/subnet.html.markdown @@ -37,3 +37,4 @@ output "subnet_id" { * `network_security_group_id` - The ID of the Network Security Group associated with the subnet. * `route_table_id` - The ID of the Route Table associated with this subnet. * `ip_configurations` - The collection of IP Configurations with IPs within this subnet. +* `service_endpoints` - A list of Service Endpoints within this subnet. diff --git a/website/docs/d/subscription.html.markdown b/website/docs/d/subscription.html.markdown index 6766343409bf..013b6cdc3442 100644 --- a/website/docs/d/subscription.html.markdown +++ b/website/docs/d/subscription.html.markdown @@ -26,8 +26,10 @@ output "current_subscription_display_name" { ## Attributes Reference -* `id` - The ID of the Subscription. +* `id` - The ID of the subscription. +* `subscription_id` - The subscription GUID. * `display_name` - The subscription display name. +* `tenant_id` - The subscription tenant ID. * `state` - The subscription state. Possible values are Enabled, Warned, PastDue, Disabled, and Deleted. * `location_placement_id` - The subscription location placement ID. * `quota_id` - The subscription quota ID. diff --git a/website/docs/d/subscriptions.html.markdown b/website/docs/d/subscriptions.html.markdown index 5bad02b43726..f8c12b0c52f0 100644 --- a/website/docs/d/subscriptions.html.markdown +++ b/website/docs/d/subscriptions.html.markdown @@ -35,7 +35,9 @@ output "first_available_subscription_display_name" { The `subscription` block contains: +* `subscription_id` - The subscription GUID. * `display_name` - The subscription display name. +* `tenant_id` - The subscription tenant ID. * `state` - The subscription state. Possible values are Enabled, Warned, PastDue, Disabled, and Deleted. * `location_placement_id` - The subscription location placement ID. * `quota_id` - The subscription quota ID. diff --git a/website/docs/d/user_assigned_identity.html.markdown b/website/docs/d/user_assigned_identity.html.markdown new file mode 100644 index 000000000000..a5bdca7428e5 --- /dev/null +++ b/website/docs/d/user_assigned_identity.html.markdown @@ -0,0 +1,44 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azure_user_assigned_identity" +sidebar_current: "docs-azurerm-datasource-user-assigned-identity" +description: |- + Gets information about an existing User Assigned Identity. + +--- + +# Data Source: azurerm_user_assigned_identity + +Use this data source to access information about an existing User Assigned Identity. + +## Example Usage (reference an existing) + +```hcl +data "azurerm_user_assigned_identity" "example" { + name = "name_of_user_assigned_identity" + resource_group_name = "name_of_resource_group" +} + +output "uai_client_id" { + value = "${data.azurerm_user_assigned_identity.example.client_id}" +} + +output "uai_principal_id" { + value = "${data.azurerm_user_assigned_identity.example.principal_id}" +} +``` + +## Argument Reference + +* `name` - (Required) The name of the User Assigned Identity. +* `resource_group_name` - (Required) The name of the Resource Group in which the User Assigned Identity exists. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Resource ID of the User Assigned Identity. +* `location` - The Azure location where the User Assigned Identity exists. +* `principal_id` - The Service Principal ID of the User Assigned Identity. +* `client_id` - The Client ID of the User Assigned Identity. +* `tags` - A mapping of tags assigned to the User Assigned Identity. diff --git a/website/docs/d/virtual_network.html.markdown b/website/docs/d/virtual_network.html.markdown index cc296340185b..277366f38855 100644 --- a/website/docs/d/virtual_network.html.markdown +++ b/website/docs/d/virtual_network.html.markdown @@ -31,7 +31,7 @@ output "virtual_network_id" { ## Attributes Reference * `id` - The ID of the virtual network. -* `address_spaces` - The list of address spaces used by the virtual network. +* `address_space` - The list of address spaces used by the virtual network. * `dns_servers` - The list of DNS servers used by the virtual network. * `subnets` - The list of name of the subnets that are attached to this virtual network. * `vnet_peerings` - A mapping of name - virtual network id of the virtual network peerings. diff --git a/website/docs/d/virtual_network_gateway_connection.html.markdown b/website/docs/d/virtual_network_gateway_connection.html.markdown new file mode 100644 index 000000000000..117dd41fef9c --- /dev/null +++ b/website/docs/d/virtual_network_gateway_connection.html.markdown @@ -0,0 +1,103 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_virtual_network_gateway_connection" +sidebar_current: "docs-azurerm-datasource-virtual-network-gateway-connection" +description: |- + Gets information about an existing Virtual Network Gateway Connection. +--- + +# Data Source: azurerm_virtual_network_gateway_connection + +Use this data source to access information about an existing Virtual Network Gateway Connection. + +## Example Usage + +```hcl +data "azurerm_virtual_network_gateway_connection" "test" { + name = "production" + resource_group_name = "networking" +} + +output "virtual_network_gateway_connection_id" { + value = "${data.azurerm_virtual_network_gateway_connection.test.id}" +} +``` + +## Argument Reference + +* `name` - (Required) Specifies the name of the Virtual Network Gateway Connection. +* `resource_group_name` - (Required) Specifies the name of the resource group the Virtual Network Gateway Connection is located in. + +## Attributes Reference + +* `id` - The ID of the Virtual Network Gateway Connection. + +* `location` - The location/region where the connection is + located. + +* `type` - The type of connection. Valid options are `IPsec` + (Site-to-Site), `ExpressRoute` (ExpressRoute), and `Vnet2Vnet` (VNet-to-VNet). + +* `virtual_network_gateway_id` - The ID of the Virtual Network Gateway + in which the connection is created. + +* `authorization_key` - The authorization key associated with the + Express Route Circuit. This field is present only if the type is an + ExpressRoute connection. + +* `express_route_circuit_id` - The ID of the Express Route Circuit + (i.e. when `type` is `ExpressRoute`). + +* `peer_virtual_network_gateway_id` - The ID of the peer virtual + network gateway when a VNet-to-VNet connection (i.e. when `type` + is `Vnet2Vnet`). + +* `local_network_gateway_id` - The ID of the local network gateway + when a Site-to-Site connection (i.e. when `type` is `IPsec`). + +* `routing_weight` - The routing weight. + +* `shared_key` - The shared IPSec key. + +* `enable_bgp` - If `true`, BGP (Border Gateway Protocol) is enabled + for this connection. + +* `express_route_gateway_bypass` - If `true`, data packets will bypass ExpressRoute Gateway for data forwarding. This is only valid for ExpressRoute connections. + +* `use_policy_based_traffic_selectors` - If `true`, policy-based traffic + selectors are enabled for this connection. Enabling policy-based traffic + selectors requires an `ipsec_policy` block. + +* `ipsec_policy` (Optional) A `ipsec_policy` block which is documented below. + Only a single policy can be defined for a connection. For details on + custom policies refer to [the relevant section in the Azure documentation](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-ipsecikepolicy-rm-powershell). + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +The `ipsec_policy` block supports: + +* `dh_group` - The DH group used in IKE phase 1 for initial SA. Valid + options are `DHGroup1`, `DHGroup14`, `DHGroup2`, `DHGroup2048`, `DHGroup24`, + `ECP256`, `ECP384`, or `None`. + +* `ike_encryption` - The IKE encryption algorithm. Valid + options are `AES128`, `AES192`, `AES256`, `DES`, or `DES3`. + +* `ike_integrity` - The IKE integrity algorithm. Valid + options are `MD5`, `SHA1`, `SHA256`, or `SHA384`. + +* `ipsec_encryption` - The IPSec encryption algorithm. Valid + options are `AES128`, `AES192`, `AES256`, `DES`, `DES3`, `GCMAES128`, `GCMAES192`, `GCMAES256`, or `None`. + +* `ipsec_integrity` - The IPSec integrity algorithm. Valid + options are `GCMAES128`, `GCMAES192`, `GCMAES256`, `MD5`, `SHA1`, or `SHA256`. + +* `pfs_group` - The DH group used in IKE phase 2 for new child SA. + Valid options are `ECP256`, `ECP384`, `PFS1`, `PFS2`, `PFS2048`, `PFS24`, + or `None`. + +* `sa_datasize` - The IPSec SA payload size in KB. Must be at least + `1024` KB. + +* `sa_lifetime` - The IPSec SA lifetime in seconds. Must be at least + `300` seconds. diff --git a/website/docs/guides/2.0-upgrade-guide.html.markdown b/website/docs/guides/2.0-upgrade-guide.html.markdown index 165accb50ba0..a8e0ed69dccc 100644 --- a/website/docs/guides/2.0-upgrade-guide.html.markdown +++ b/website/docs/guides/2.0-upgrade-guide.html.markdown @@ -23,7 +23,7 @@ We recommend pinning the version of each Provider you use in Terraform - you can ```hcl provider "azurerm" { - version = "=1.22.0" + version = "=1.28.0" } ``` @@ -145,6 +145,10 @@ The AzureAD Data Sources and Resources have been moved to [the new AzureAD Provi A guide on how to migrate to using the new Provider [can be found here](https://www.terraform.io/docs/providers/azurerm/guides/migrating-to-azuread.html). +### Data Source: `azurerm_dns_zone` + +The deprecated field `zone_type` will be removed. Private DNS Zones are now a separate resource in both Azure and Terraform. + ### Data Source: `azurerm_kubernetes_cluster` The deprecated field `dns_prefix` within the `agent_pool_profile` block will be removed. @@ -157,6 +161,10 @@ The deprecated field `internal_fqdn` will be removed. Azure Scheduler is being retired in favour of Logic Apps ([more information can be found here](https://docs.microsoft.com/en-us/azure/scheduler/migrate-from-scheduler-to-logic-apps)) - as such this Data Source will be removed. +### Data Source: `azurerm_virtual_network` + +The deprecated field `address_space` will be removed. + ### Resource: `azurerm_app_service_plan` The fields in the `properties` block (`app_service_environment_id`, `reserved` and `per_site_scaling`) have been moved to the top level - as such the `properties` block will be removed. @@ -189,11 +197,15 @@ The AzureAD Data Sources and Resources have been moved to [the new AzureAD Provi A guide on how to migrate to using the new Provider [can be found here](https://www.terraform.io/docs/providers/azurerm/guides/migrating-to-azuread.html). +### Resource: `azurerm_connection_monitor` + +The `azurerm_connection_monitor` resource will be deprecated in favour of a new resources `azurerm_network_connection_monitor`. + ### Resource: `azurerm_container_group` The deprecated `port` and `protocol` fields in the `container` block will be removed. These fields have been moved into the `ports` block within the `ports` field. -The deprecated `command` field in the `container` block will be removed. This has been replaced by the `commands` field in the container` block. +The deprecated `command` field in the `container` block will be removed. This has been replaced by the `commands` field in the `container` block. ### Resource: `azurerm_container_registry` @@ -207,6 +219,10 @@ Azure Container Service (ACS) is being Deprecated in favour of Azure Kubernetes The deprecated `failover_policy` block will be removed. This has been replaced by the `geo_location` block. +### Resource: `azurerm_ddos_protection_plan` + +The `azurerm_ddos_protection_planr` resource will be deprecated in favour of a new resources `azurerm_network_ddos_protection_plan`. + ### Resource: `azurerm_dns_mx_record` The `preference` field in the `record` block will change from a String to an Integer to better reflect the API. @@ -215,6 +231,10 @@ The `preference` field in the `record` block will change from a String to an Int The deprecated `record` field will be removed. This has been replaced by the `records` field which accepts multiple values. +### Resource: `azurerm_dns_zone` + +The deprecated `zone_type` field will be removed. This has been replaced by the `azurerm_private_dns_zone` resource. + ### Resource: `azurerm_eventhub` The deprecated `location` field will be removed, since this is no longer used. @@ -287,6 +307,10 @@ The `load_balancer_backend_address_pools_ids` field in the `ip_configuration` bl The `load_balancer_inbound_nat_rules_ids` field in the `ip_configuration` block will been removed. This has been replaced by the `azurerm_network_interface_nat_rule_association` resource. +### Resource: `azurerm_packet_capture` + +The `azurerm_packet_capture` resource will be deprecated in favour of a new resources `azurerm_network_packet_capture`. + ### Resource: `azurerm_public_ip` The deprecated `public_ip_address_allocation` field will be removed. This field has been replaced by `allocation_method`. @@ -323,6 +347,30 @@ The deprecated `enable_filtering_messages_before_publishing` field will be remov The deprecated `account_type` field will be removed. This has been split into the fields `account_tier` and `account_replication_type`. +### Resource: `azurerm_storage_blob` + +The deprecated `attempts` field will be removed, since Terraform now handles retries automatically. + +The deprecated `resource_group_name` field will be removed, since this is no longer used. + +### Resource: `azurerm_storage_container` + +The deprecated `resource_group_name` field will be removed, since this is no longer used. + +The deprecated `properties` block will be removed. + +### Resource: `azurerm_storage_queue` + +The deprecated `resource_group_name` field will be removed, since this is no longer used. + +### Resource: `azurerm_storage_share` + +The deprecated `resource_group_name` field will be removed, since this is no longer used. + +### Resource: `azurerm_storage_table` + +The deprecated `resource_group_name` field will be removed, since this is no longer used. + ### Resource: `azurerm_subnet` The deprecated field `network_security_group_id` will be removed. This has been replaced by the `azurerm_subnet_network_security_group_association` resource. @@ -345,6 +393,15 @@ Splitting the Virtual Machine Scale Set resource in two allows us to both provid The existing `azurerm_virtual_machine_scale_set` Resource will continue to be available in it's current form, however it will eventually be deprecated and we recommend using the new resources going forward. +### Resource: `azurerm_log_analytics_linked_service` + +The deprecated field `linked_service_properties` will be removed. This has been replaced by the `resource_id` resource. + +### Resource: `azurerm_log_analytics_workspace_linked_service` + +The deprecated field `linked_service_properties` will be removed. This has been replaced by the `resource_id` resource. + + --- We've spent the past few months laying the groundwork for these changes - and whilst we appreciate that your Terraform Configurations may require code changes to upgrade to 2.0 - we take Semantic Versioning seriously and so try our best to limit these changes to major versions. diff --git a/website/docs/guides/migrating-between-renamed-resources.html.markdown b/website/docs/guides/migrating-between-renamed-resources.html.markdown index 950559b2adf1..0cb1a5d37298 100644 --- a/website/docs/guides/migrating-between-renamed-resources.html.markdown +++ b/website/docs/guides/migrating-between-renamed-resources.html.markdown @@ -15,7 +15,10 @@ In v1.22 of the AzureRM Provider several resources have been deprecated in favou | ---------------------------------------------- | ------------------------------------ | | azurerm_log_analytics_workspace_linked_service | azurerm_log_analytics_linked_service | | azurerm_autoscale_setting | azurerm_monitor_autoscale_setting | -| azurerm_metric_alertrule | azurerm_monitor_metric_alertrule | +| azurerm_metric_alertrule | azurerm_monitor_metric_alert | +| azurerm_connection_monitor | azurerm_network_connection_monitor | +| azurerm_ddos_protection_plan | azurerm_network_ddos_protection_plan | +| azurerm_packet_capture | azurerm_network_packet_capture | As the Schema's for each resource are the same at this time - it's possible to migrate between the resources by updating your Terraform Configuration and updating the Statefile. diff --git a/website/docs/guides/migrating-to-azuread.html.markdown b/website/docs/guides/migrating-to-azuread.html.markdown index 62b66e392ec7..94a21c6540ad 100644 --- a/website/docs/guides/migrating-to-azuread.html.markdown +++ b/website/docs/guides/migrating-to-azuread.html.markdown @@ -25,7 +25,7 @@ As the AzureAD and AzureRM Provider support the same authentication methods - it ```hcl provider "azurerm" { - version = "=1.22.0" + version = "=1.28.0" } ``` diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 219bec156389..5a815f97d5f3 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -32,7 +32,7 @@ We recommend using either a Service Principal or Managed Service Identity when r # Configure the Azure Provider provider "azurerm" { # whilst the `version` attribute is optional, we recommend pinning to a given version of the Provider - version = "=1.22.0" + version = "=1.28.0" } # Create a resource group @@ -88,7 +88,7 @@ The following arguments are supported: * `client_id` - (Optional) The Client ID which should be used. This can also be sourced from the `ARM_CLIENT_ID` Environment Variable. -* `environment` - (Optional) The Cloud Environment which should be used. Possible values are `public`, `usgovernment`, `german` and `china`. Defaults to `public`. This can also be sourced from the `ARM_ENVIRONMENT` environment variable. +* `environment` - (Optional) The Cloud Environment which should be used. Possible values are `public`, `usgovernment`, `german`, and `china`. Defaults to `public`. This can also be sourced from the `ARM_ENVIRONMENT` environment variable. * `subscription_id` - (Optional) The Subscription ID which should be used. This can also be sourced from the `ARM_SUBSCRIPTION_ID` Environment Variable. @@ -130,6 +130,8 @@ For some advanced scenarios, such as where more granular permissions are necessa * `skip_credentials_validation` - (Optional) Should the AzureRM Provider skip verifying the credentials being used are valid? This can also be sourced from the `ARM_SKIP_CREDENTIALS_VALIDATION` Environment Variable. Defaults to `false`. -* `skip_provider_registration` - (Optional) Should the AzureRM Provider skip registering any required Resource Providers? This can also be sourced from the `ARM_SKIP_PROVIDER_REGISTRATION` Environment Variable. Defaults to `false`. +* `skip_provider_registration` - (Optional) Should the AzureRM Provider skip registering the Resource Providers it supports? This can also be sourced from the `ARM_SKIP_PROVIDER_REGISTRATION` Environment Variable. Defaults to `false`. + +-> By default, Terraform will attempt to register any Resource Providers that it supports, even if they're not used in your configurations to be able to display more helpful error messages. If you're running in an environment with restricted permissions, or wish to manage Resource Provider Registration outside of Terraform you may wish to disable this flag; however please note that the error messages returned from Azure may be confusing as a result (example: `API version 2019-01-01 was not found for Microsoft.Foo`). It's also possible to use multiple Provider blocks within a single Terraform configuration, for example to work with resources across multiple Subscriptions - more information can be found [in the documentation for Providers](https://www.terraform.io/docs/configuration/providers.html#multiple-provider-instances). diff --git a/website/docs/r/analysis_services_server.html.markdown b/website/docs/r/analysis_services_server.html.markdown new file mode 100644 index 000000000000..a705212c917d --- /dev/null +++ b/website/docs/r/analysis_services_server.html.markdown @@ -0,0 +1,84 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_analysis_services_server" +sidebar_current: "docs-azurerm-resource-analysis_services_server-x" +description: |- + Manages an Analysis Services Server. +--- + +# azurerm_analysis_services_server + +Manages an Analysis Services Server. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "rg" { + name = "analysis-services-server-test" + location = "northeurope" +} + +resource "azurerm_analysis_services_server" "server" { + name = "analysisservicesserver" + location = "northeurope" + resource_group_name = "${azurerm_resource_group.rg.name}" + sku = "S0" + admin_users = ["myuser@domain.tld"] + enable_power_bi_service = true + + ipv4_firewall_rule { + name = "myRule1" + range_start = "210.117.252.0" + range_end = "210.117.252.255" + } + + tags = { + abc = 123 + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Analysis Services Server. Changing this forces a new resource to be created. + +* `location` - (Required) The Azure location where the Analysis Services Server exists. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group in which the Analysis Services Server should be exist. Changing this forces a new resource to be created. + +* `sku` - (Required) SKU for the Analysis Services Server. Possible values are: `D1`, `B1`, `B2`, `S0`, `S1`, `S2`, `S4`, `S8` and `S9` + +* `admin_users` - (Optional) List of email addresses of admin users. + +* `querypool_connection_mode` - (Optional) Controls how the read-write server is used in the query pool. If this values is set to `All` then read-write servers are also used for queries. Otherwise with `ReadOnly` these servers do not participate in query operations. + +* `enable_power_bi_service` - (Optional) Indicates if the Power BI service is allowed to access or not. + +* `ipv4_firewall_rule` - (Optional) One or more `ipv4_firewall_rule` block(s) as defined below. + +--- + +A `ipv4_firewall_rule` block supports the following: + +* `name` - (Required) Specifies the name of the firewall rule. + +* `range_start` - (Required) Start of the firewall rule range as IPv4 address. + +* `range_end` - (Required) End of the firewall rule range as IPv4 address. + + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the Analysis Services Server. + +## Import + +Analysis Services Server can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_analysis_services_server.server /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourcegroup1/providers/Microsoft.AnalysisServices/servers/server1 +``` diff --git a/website/docs/r/api_management.html.markdown b/website/docs/r/api_management.html.markdown index be6f2b5cd59f..13c1fde22afa 100644 --- a/website/docs/r/api_management.html.markdown +++ b/website/docs/r/api_management.html.markdown @@ -60,8 +60,14 @@ The following arguments are supported: * `notification_sender_email` - (Optional) Email address from which the notification will be sent. +* `policy` - (Optional) A `policy` block as defined below. + * `security` - (Optional) A `security` block as defined below. +* `sign_in` - (Optional) A `sign_in` block as defined below. + +* `sign_up` - (Optional) A `sign_up` block as defined below. + * `tags` - (Optional) A mapping of tags assigned to the resource. --- @@ -80,6 +86,19 @@ A `certificate` block supports the following: * `store_name` - (Required) The name of the Certificate Store where this certificate should be stored. Possible values are `CertificateAuthority` and `Root`. + +--- + +A `hostname_configuration` block supports the following: + +* `management` - (Optional) One or more `management` blocks as documented below. + +* `portal` - (Optional) One or more `portal` blocks as documented below. + +* `proxy` - (Optional) One or more `proxy` blocks as documented below. + +* `scm` - (Optional) One or more `scm` blocks as documented below. + --- A `identity` block supports the following: @@ -88,6 +107,52 @@ A `identity` block supports the following: --- +A `management`, `portal` and `scm` block supports the following: + +* `host_name` - (Required) The Hostname to use for the Management API. + +* `key_vault_id` - (Optional) The ID of the Key Vault Secret containing the SSL Certificate, which must be should be of the type `application/x-pkcs12`. + +-> **NOTE:** Setting this field requires the `identity` block to be specified, since this identity is used for to retrieve the Key Vault Certificate. Auto-updating the Certificate from the Key Vault requires the Secret version isn't specified. + +* `certificate` - (Optional) The Base64 Encoded Certificate. + +* `certificate_password` - (Optional) The password associated with the certificate provided above. + +-> **NOTE:** Either `key_vault_id` or `certificate` and `certificate_password` must be specified. + +* `negotiate_client_certificate` - (Optional) Should Client Certificate Negotiation be enabled for this Hostname? Defaults to `false`. + +--- + +A `policy` block supports the following: + +* `xml_content` - (Optional) The XML Content for this Policy. + +* `xml_link` - (Optional) A link to an API Management Policy XML Document, which must be publicly available. + +--- + +A `proxy` block supports the following: + +* `default_ssl_binding` - (Optional) Is the certificate associated with this Hostname the Default SSL Certificate? This is used when an SNI header isn't specified by a client. Defaults to `false`. + +* `host_name` - (Required) The Hostname to use for the Management API. + +* `key_vault_id` - (Optional) The ID of the Key Vault Secret containing the SSL Certificate, which must be should be of the type `application/x-pkcs12`. + +-> **NOTE:** Setting this field requires the `identity` block to be specified, since this identity is used for to retrieve the Key Vault Certificate. Auto-updating the Certificate from the Key Vault requires the Secret version isn't specified. + +* `certificate` - (Optional) The Base64 Encoded Certificate. + +* `certificate_password` - (Optional) The password associated with the certificate provided above. + +-> **NOTE:** Either `key_vault_id` or `certificate` and `certificate_password` must be specified. + +* `negotiate_client_certificate` - (Optional) Should Client Certificate Negotiation be enabled for this Hostname? Defaults to `false`. + +--- + A `security` block supports the following: * `disable_backend_ssl30` - (Optional) Should SSL 3.0 be disabled on the backend of the gateway? Defaults to `false`. @@ -114,7 +179,7 @@ A `security` block supports the following: -> **info:** This maps to the `Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11` field -* `disable_triple_des_chipers` - (Optional) Should the `TLS_RSA_WITH_3DES_EDE_CBC_SHA` cipher be disabled for alL TLS versions (1.0, 1.1 and 1.2)? Defaults to `false`. +* `disable_triple_des_ciphers` - (Optional) Should the `TLS_RSA_WITH_3DES_EDE_CBC_SHA` cipher be disabled for alL TLS versions (1.0, 1.1 and 1.2)? Defaults to `false`. -> **info:** This maps to the `Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TripleDes168` field @@ -128,54 +193,27 @@ A `sku` block supports the following: --- -A `hostname_configuration` block supports the following: - -* `management` - (Optional) One or more `management` blocks as documented below. - -* `portal` - (Optional) One or more `portal` blocks as documented below. +A `sign_in` block supports the following: -* `proxy` - (Optional) One or more `proxy` blocks as documented below. - -* `scm` - (Optional) One or more `scm` blocks as documented below. +* `enabled` - (Required) Should anonymous users be redirected to the sign in page? --- -A `management`, `portal` and `scm` block supports the following: +A `sign_up` block supports the following: -* `host_name` - (Required) The Hostname to use for the Management API. +* `enabled` - (Required) Can users sign up on the development portal? -* `key_vault_id` - (Optional) The ID of the Key Vault Secret containing the SSL Certificate, which must be should be of the type `application/x-pkcs12`. - --> **NOTE:** Setting this field requires the `identity` block to be specified, since this identity is used for to retrieve the Key Vault Certificate. Auto-updating the Certificate from the Key Vault requires the Secret version isn't specified. - -* `certificate` - (Optional) The Base64 Encoded Certificate. - -* `certificate_password` - (Optional) The password associated with the certificate provided above. - --> **NOTE:** Either `key_vault_id` or `certificate` and `certificate_password` must be specified. - -* `negotiate_client_certificate` - (Optional) Should Client Certificate Negotiation be enabled for this Hostname? Defaults to `false`. +* `terms_of_service` - (Optional) A `terms_of_service` block as defined below. --- -A `proxy` block supports the following: +A `terms_of_service` block supports the following: -* `default_ssl_binding` - (Optional) Is the certificate associated with this Hostname the Default SSL Certificate? This is used when an SNI header isn't specified by a client. Defaults to `false`. +* `consent_required` - (Required) Should the user be asked for consent during sign up? -* `host_name` - (Required) The Hostname to use for the Management API. - -* `key_vault_id` - (Optional) The ID of the Key Vault Secret containing the SSL Certificate, which must be should be of the type `application/x-pkcs12`. - --> **NOTE:** Setting this field requires the `identity` block to be specified, since this identity is used for to retrieve the Key Vault Certificate. Auto-updating the Certificate from the Key Vault requires the Secret version isn't specified. - -* `certificate` - (Optional) The Base64 Encoded Certificate. - -* `certificate_password` - (Optional) The password associated with the certificate provided above. - --> **NOTE:** Either `key_vault_id` or `certificate` and `certificate_password` must be specified. - -* `negotiate_client_certificate` - (Optional) Should Client Certificate Negotiation be enabled for this Hostname? Defaults to `false`. +* `enabled` - (Required) Should Terms of Service be displayed during sign up?. +* `text` - (Required) The Terms of Service which users are required to agree to in order to sign up. ## Attributes Reference @@ -184,10 +222,14 @@ In addition to all arguments above, the following attributes are exported: * `id` - The ID of the API Management Service. +* `additional_location` - One or more `additional_location` blocks as documented below. + * `gateway_url` - The URL of the Gateway for the API Management Service. * `gateway_regional_url` - The Region URL for the Gateway of the API Management Service. +* `identity` - An `identity` block as defined below. + * `management_api_url` - The URL for the Management API associated with this API Management service. * `portal_url` - The URL for the Publisher Portal associated with this API Management service. @@ -196,25 +238,21 @@ In addition to all arguments above, the following attributes are exported: * `scm_url` - The URL for the SCM (Source Code Management) Endpoint associated with this API Management service. -* `identity` - An `identity` block as defined below. - -* `additional_location` - One or more `additional_location` blocks as documented below. - --- -An `identity` block exports the following: +An `additional_location` block exports the following: -* `principal_id` - The Principal ID associated with this Managed Service Identity. +* `gateway_regional_url` - The URL of the Regional Gateway for the API Management Service in the specified region. -* `tenant_id` - The Tenant ID associated with this Managed Service Identity. +* `public_ip_addresses` - Public Static Load Balanced IP addresses of the API Management service in the additional location. Available only for Basic, Standard and Premium SKU. --- -An `additional_location` block exports the following: +An `identity` block exports the following: -* `gateway_regional_url` - The URL of the Regional Gateway for the API Management Service in the specified region. +* `principal_id` - The Principal ID associated with this Managed Service Identity. -* `public_ip_addresses` - Public Static Load Balanced IP addresses of the API Management service in the additional location. Available only for Basic, Standard and Premium SKU. +* `tenant_id` - The Tenant ID associated with this Managed Service Identity. ## Import diff --git a/website/docs/r/api_management_api_operation.html.markdown b/website/docs/r/api_management_api_operation.html.markdown new file mode 100644 index 000000000000..c5f8dfd1325b --- /dev/null +++ b/website/docs/r/api_management_api_operation.html.markdown @@ -0,0 +1,190 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_api_operation" +sidebar_current: "docs-azurerm-resource-api-management-api-operation" +description: |- + Manages an API Operation within an API Management Service. +--- + +# azurerm_api_management_api_operation + +Manages an API Operation within an API Management Service. + +## Example Usage + +```hcl +data "azurerm_api_management_api" "example" { + name = "search-api" + api_management_name = "search-api-management" + resource_group_name = "search-service" + revision = "2" +} + +resource "azurerm_api_management_api_operation" "example" { + operation_id = "user-delete" + api_name = "${data.azurerm_api_management_api.example.name}" + api_management_name = "${data.azurerm_api_management_api.example.api_management_name}" + resource_group_name = "${data.azurerm_api_management_api.example.resource_group_name}" + display_name = "Delete User Operation" + method = "DELETE" + url_template = "/users/{id}/delete" + description = "This can only be done by the logged in user." + + response { + status_code = 200 + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `operation_id` - (Required) A unique identifier for this API Operation. Changing this forces a new resource to be created. + +* `api_name` - (Required) The name of the API within the API Management Service where this API Operation should be created. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The Name of the API Management Service where the API exists. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The Name of the Resource Group in which the API Management Service exists. Changing this forces a new resource to be created. + +* `display_name` - (Required) The Display Name for this API Management Operation. + +* `method` - (Required) The HTTP Method used for this API Management Operation, like `GET`, `DELETE`, `PUT` or `POST` - but not limited to these values. + +* `url_template` - (Required) The relative URL Template identifying the target resource for this operation, which may include parameters. + +--- + +* `description` - (Optional) A description for this API Operation, which may include HTML formatting tags. + +* `request` - (Optional) A `request` block as defined below. + +* `response` - (Optional) One or more `response` blocks as defined below. + +* `template_parameter` - (Optional) One or more `template_parameter` blocks as defined below. + + +--- + +A `form_parameter` block supports the following: + +* `name` - (Required) The Name of this Form Parameter. + +* `required` - (Required) Is this Form Parameter Required? + +* `type` - (Required) The Type of this Form Parameter, such as a `string`. + +* `description` - (Optional) A description of this Form Parameter. + +* `default_value` - (Optional) The default value for this Form Parameter. + +* `values` - (Optional) One or more acceptable values for this Form Parameter. + +--- + +A `header` block supports the following: + +* `name` - (Required) The Name of this Header. + +* `required` - (Required) Is this Header Required? + +* `type` - (Required) The Type of this Header, such as a `string`. + +* `description` - (Optional) A description of this Header. + +* `default_value` - (Optional) The default value for this Header. + +* `values` - (Optional) One or more acceptable values for this Header. + +--- + +A `query_parameter` block supports the following: + +* `name` - (Required) The Name of this Query Parameter. + +* `required` - (Required) Is this Query Parameter Required? + +* `type` - (Required) The Type of this Query Parameter, such as a `string`. + +* `description` - (Optional) A description of this Query Parameter. + +* `default_value` - (Optional) The default value for this Query Parameter. + +* `values` - (Optional) One or more acceptable values for this Query Parameter. + +--- + +A `request` block supports the following: + +* `description` - (Required) A description of the HTTP Request, which may include HTML tags. + +* `header` - (Optional) One or more `header` blocks as defined above. + +* `query_parameter` - (Optional) One or more `query_parameter` blocks as defined above. + +* `representation` - (Optional) One or more `representation` blocks as defined below. + +--- + +A `representation` block supports the following: + +* `content_type` - (Required) The Content Type of this representation, such as `application/json`. + +* `form_parameter` - (Optional) One or more `form_parameter` block as defined above. + +-> **NOTE:** This is Required when `content_type` is set to `application/x-www-form-urlencoded` or `multipart/form-data`. + +* `sample` - (Optional) An example of this representation. + +* `schema_id` - (Optional) The ID of an API Management Schema which represents this Response. + +-> **NOTE:** This can only be specified when `content_type` is not set to `application/x-www-form-urlencoded` or `multipart/form-data`. + +* `type_name` - (Optional) The Type Name defined by the Schema. + +-> **NOTE:** This can only be specified when `content_type` is not set to `application/x-www-form-urlencoded` or `multipart/form-data`. + +--- + +A `response` block supports the following: + +* `status_code` - (Required) The HTTP Status Code. + +* `description` - (Required) A description of the HTTP Response, which may include HTML tags. + +* `header` - (Optional) One or more `header` blocks as defined above. + +* `representation` - (Optional) One or more `representation` blocks as defined below. + +--- + +A `template_parameter` block supports the following: + +* `name` - (Required) The Name of this Template Parameter. + +* `required` - (Required) Is this Template Parameter Required? + +* `type` - (Required) The Type of this Template Parameter, such as a `string`. + +* `description` - (Optional) A description of this Template Parameter. + +* `default_value` - (Optional) The default value for this Template Parameter. + +* `values` - (Optional) One or more acceptable values for this Template Parameter. + +--- + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management API Operation. + +## Import + +API Management API Operation's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_api_operation.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.ApiManagement/service/instance1/apis/api1/operations/operation1 +``` diff --git a/website/docs/r/api_management_api_operation_policy.html.markdown b/website/docs/r/api_management_api_operation_policy.html.markdown new file mode 100644 index 000000000000..4f4b3bb6fb58 --- /dev/null +++ b/website/docs/r/api_management_api_operation_policy.html.markdown @@ -0,0 +1,64 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_api_operation_policy" +sidebar_current: "docs-azurerm-resource-api-management-api-operation-policy" +description: |- + Manages an API Management API Operation Policy +--- + +# azurerm_api_management_api_operation_policy + +Manages an API Management API Operation Policy + + +## Example Usage + +```hcl +resource "azurerm_api_management_api_operation" "example" { + #... +} + +resource "azurerm_api_management_api_operation_policy" "example" { + api_name = "${azurerm_api_management_api_operation.example.api_name}" + api_management_name = "${azurerm_api_management_api_operation.example.api_management_name}" + resource_group_name = "${azurerm_api_management_api_operation.example.resource_group_name}" + operation_id = "${azurerm_api_management_api_operation.example.operation_id}" + + xml_content = <<XML +<policies> + <inbound> + <find-and-replace from="xyz" to="abc" /> + </inbound> +</policies> +XML +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `api_name` - (Required) The ID of the API Management API Operation within the API Management Service. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The name of the API Management Service. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group in which the API Management Service exists. Changing this forces a new resource to be created. + +* `xml_content` - (Optional) The XML Content for this Policy. + +* `xml_link` - (Optional) A link to a Policy XML Document, which must be publicly available. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management API Operation Policy. + +## Import + +API Management API Operation Policy can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_api_operation_policy.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.ApiManagement/service/instance1/apis/api1/operations/operation1/policies/policy +``` diff --git a/website/docs/r/api_management_api_policy.html.markdown b/website/docs/r/api_management_api_policy.html.markdown new file mode 100644 index 000000000000..3646200f3e2d --- /dev/null +++ b/website/docs/r/api_management_api_policy.html.markdown @@ -0,0 +1,65 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_api_policy" +sidebar_current: "docs-azurerm-resource-api-management-api-policy" +description: |- + Manages an API Management API Policy +--- + +# azurerm_api_management_api_policy + +Manages an API Management API Policy + + +## Example Usage + +```hcl +data "azurerm_api_management_api" "example" { + api_name = "my-api" + api_management_name = "example-apim" + resource_group_name = "search-service" +} + +resource "azurerm_api_management_api_policy" "example" { + api_name = "${data.azurerm_api_management_api.example.name}" + api_management_name = "${data.azurerm_api_management_api.example.api_management_name}" + resource_group_name = "${data.azurerm_api_management_api.example.resource_group_name}" + + xml_content = <<XML +<policies> + <inbound> + <find-and-replace from="xyz" to="abc" /> + </inbound> +</policies> +XML +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `api_name` - (Required) The ID of the API Management API within the API Management Service. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The name of the API Management Service. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group in which the API Management Service exists. Changing this forces a new resource to be created. + +* `xml_content` - (Optional) The XML Content for this Policy as a string. An XML file can be used here with Terraform's [file function](https://www.terraform.io/docs/configuration/functions/file.html) that is similar to Microsoft's `PolicyFilePath` option. + +* `xml_link` - (Optional) A link to a Policy XML Document, which must be publicly available. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management API Policy. + +## Import + +API Management API Policy can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_api_policy.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.ApiManagement/service/service1/apis/exampleId/policies/policy +``` diff --git a/website/docs/r/api_management_api_schema.html.markdown b/website/docs/r/api_management_api_schema.html.markdown new file mode 100644 index 000000000000..a9fabcee63e0 --- /dev/null +++ b/website/docs/r/api_management_api_schema.html.markdown @@ -0,0 +1,61 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_api_schema" +sidebar_current: "docs-azurerm-resource-api-management-api-schema" +description: |- + Manages an API Schema within an API Management Service. +--- + +# azurerm_api_management_api_schema + +Manages an API Schema within an API Management Service. + +## Example Usage + +```hcl +data "azurerm_api_management_api" "example" { + name = "search-api" + api_management_name = "search-api-management" + resource_group_name = "search-service" + revision = "2" +} + +resource "azurerm_api_management_api_schema" "example" { + api_name = "${data.azurerm_api_management_api.example.name}" + api_management_name = "${data.azurerm_api_management_api.example.api_management_name}" + resource_group_name = "${data.azurerm_api_management_api.example.resource_group_name}" + schema_id = "example-sche,a" + content_type = "application/vnd.ms-azure-apim.xsd+xml" + value = "${file("api_management_api_schema.xml")}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `schema_id` - (Required) A unique identifier for this API Schema. Changing this forces a new resource to be created. + +* `api_name` - (Required) The name of the API within the API Management Service where this API Schema should be created. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The Name of the API Management Service where the API exists. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The Name of the Resource Group in which the API Management Service exists. Changing this forces a new resource to be created. + +* `content_type` - (Required) The content type of the API Schema. + +* `value` - (Required) The JSON escaped string defining the document representing the Schema. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management API Schema. + +## Import + +API Management API Schema's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_api_schema.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.ApiManagement/service/instance1/schemas/schema1 +``` diff --git a/website/docs/r/api_management_api_version_set.html.markdown b/website/docs/r/api_management_api_version_set.html.markdown new file mode 100644 index 000000000000..49eb2e18c5a4 --- /dev/null +++ b/website/docs/r/api_management_api_version_set.html.markdown @@ -0,0 +1,82 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_version_set" +sidebar_current: "docs-azurerm-resource-api-management-api-version-set" +description: |- + Manages an API Version Set within a API Management Service. +--- + +# azurerm_api_management_version_set + +Manages an API Version Set within a API Management Service. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West US" +} + +resource "azurerm_api_management" "example" { + name = "example-apim" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + publisher_name = "pub1" + publisher_email = "pub1@email.com" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_version_set" "example" { + name = "example-apimapi-1.0.0" + resource_group_name = "${azurerm_resource_group.example.name}" + api_management_name = "${azurerm_api_management.example.name}" + display_name = "ExampleAPIVersionSet" + versioning_scheme = "Segment" +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the API Version Set. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The name of the [API Management Service](api_management.html) in which the API Version Set should exist. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group in which the parent API Management Service exists. Changing this forces a new resource to be created. + +* `display_name` - (Required) The display name of this API Version Set. + +* `versioning_scheme` - (Required) Specifies where in an Inbound HTTP Request that the API Version should be read from. Possible values are `Header`, `Query` and `Segment`. + +--- + +* `description` - (Optional) The description of API Version Set. + +* `version_header_name` - (Optional) The name of the Header which should be read from Inbound Requests which defines the API Version. + +-> **NOTE:** This must be specified when `versioning_scheme` is set to `Header`. + +* `version_query_name` - (Optional) The name of the Query String which should be read from Inbound Requests which defines the API Version. + +-> **NOTE:** This must be specified when `versioning_scheme` is set to `Query`. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Version Set. + +## Import + +API Version Set can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_version_set.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-resources/providers/Microsoft.ApiManagement/service/example-apim/api-version-sets/example-apimp +``` diff --git a/website/docs/r/api_management_authorization_server.html.markdown b/website/docs/r/api_management_authorization_server.html.markdown new file mode 100644 index 000000000000..8321d61a8562 --- /dev/null +++ b/website/docs/r/api_management_authorization_server.html.markdown @@ -0,0 +1,109 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_authorization_server" +sidebar_current: "docs-azurerm-resource-api-management-authorization-server" +description: |- + Manages an Authorization Server within an API Management Service. +--- + +# azurerm_api_management_authorization_server + +Manages an Authorization Server within an API Management Service. + + +## Example Usage + +```hcl +data "azurerm_api_management_api" "example" { + name = "search-api" + api_management_name = "search-api-management" + resource_group_name = "search-service" + revision = "2" +} + +resource "azurerm_api_management_authorization_server" "example" { + name = "test-server" + api_management_name = "${data.azurerm_api_management.example.name}" + resource_group_name = "${data.azurerm_api_management.example.resource_group_name}" + display_name = "Test Server" + authorization_endpoint = "https://example.mydomain.com/client/authorize" + client_id = "42424242-4242-4242-4242-424242424242" + client_registration_endpoint = "https://example.mydomain.com/client/register" + + grant_types = [ + "authorizationCode", + ] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `api_management_name` - (Required) The name of the API Management Service in which this Authorization Server should be created. Changing this forces a new resource to be created. + +* `authorization_methods` - (Required) The HTTP Verbs supported by the Authorization Endpoint. Possible values are `DELETE`, `GET`, `HEAD`, `OPTIONS`, `PATCH`, `POST`, `PUT` and `TRACE`. + +-> **NOTE:** `GET` must always be present. + +* `authorization_endpoint` - (Required) The OAUTH Authorization Endpoint. + +* `client_id` - (Required) The Client/App ID registered with this Authorization Server. + +* `client_registration_endpoint` - (Required) The URI of page where Client/App Registration is performed for this Authorization Server. + +* `display_name` - (Required) The user-friendly name of this Authorization Server. + +* `grant_types` - (Required) Form of Authorization Grants required when requesting an Access Token. Possible values are `authorizationCode`, `clientCredentials`, `implicit` and `resourceOwnerPassword`. + +* `name` - (Required) The name of this Authorization Server. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group in which the API Management Service exists. Changing this forces a new resource to be created. + +--- + +* `bearer_token_sending_methods` - (Optional) The mechanism by which Access Tokens are passed to the API. Possible values are `authorizationHeader` and `query`. + +* `client_authentication_method` - (Optional) The Authentication Methods supported by the Token endpoint of this Authorization Server.. Possible values are `Basic` and `Body`. + +* `client_secret` - (Optional) The Client/App Secret registered with this Authorization Server. + +* `default_scope` - (Optional) The Default Scope used when requesting an Access Token, specified as a string containing space-delimited values. + +* `description` - (Optional) A description of the Authorization Server, which may contain HTML formatting tags. + +* `resource_owner_password` - (Optional) The password associated with the Resource Owner. + +-> **NOTE:** This can only be specified when `grant_type` includes `resourceOwnerPassword`. + +* `resource_owner_username` - (Optional) The username associated with the Resource Owner. + +-> **NOTE:** This can only be specified when `grant_type` includes `resourceOwnerPassword`. + +* `support_state` - (Optional) Does this Authorization Server support State? If this is set to `true` the client may use the state parameter to raise protocol security. + +* `token_body_parameters` - (Optional) A `token_body_parameters` block as defined below. + +* `token_endpoint` - (Optional) The OAUTH Token Endpoint. + +--- + +A `token_body_parameter` block supports the following: + +* `name` - (Required) The Name of the Parameter. + +* `value` - (Required) The Value of the Parameter. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management Authorization Server. + +## Import + +API Management Authorization Servers can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_authorization_server.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.ApiManagement/service/service1/authorizationServers/server1 +``` diff --git a/website/docs/r/api_management_backend.html.markdown b/website/docs/r/api_management_backend.html.markdown new file mode 100644 index 000000000000..41c2c1d828f1 --- /dev/null +++ b/website/docs/r/api_management_backend.html.markdown @@ -0,0 +1,146 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_backend" +sidebar_current: "docs-azurerm-resource-api-management-backend-x" +description: |- + Manages a backend within an API Management Service. +--- + +# azurerm_api_management_backend + +Manages a backend within an API Management Service. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_api_management" "test" { + name = "example-apim" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "My Company" + publisher_email = "company@terraform.io" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_backend" "test" { + name = "example-backend" + resource_group_name = "${azurerm_resource_group.test.name}" + api_management_name = "${azurerm_api_management.test.name}" + protocol = "http" + url = "https://backend" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the API Management backend. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The Name of the API Management Service where this backend should be created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The Name of the Resource Group where the API Management Service exists. Changing this forces a new resource to be created. + +* `protocol` - (Required) The protocol used by the backend host. Possible values are `http` or `soap`. + +* `url` - (Required) The URL of the backend host. + +--- + +* `credentials` - (Optional) A `credentials` block as documented below. + +* `description` - (Optional) The description of the backend. + +* `proxy` - (Optional) A `proxy` block as documented below. + +* `resource_id` - (Optional) The management URI of the backend host in an external system. This URI can be the ARM Resource ID of Logic Apps, Function Apps or API Apps, or the management endpoint of a Service Fabric cluster. + +* `service_fabric_cluster` - (Optional) A `service_fabric_cluster` block as documented below. + +* `title` - (Optional) The title of the backend. + +* `tls` - (Optional) A `tls` block as documented below. + +--- + +A `credentials` block supports the following: + +* `authorization` - (Optional) An `authorization` block as defined below. + +* `certificate` - (Optional) A list of client certificate thumbprints to present to the backend host. The certificates must exist within the API Management Service. + +* `header` - (Optional) A mapping of header parameters to pass to the backend host. The keys are the header names and the values are a comma separated string of header values. This is converted to a list before being passed to the API. + +* `query` - (Optional) A mapping of query parameters to pass to the backend host. The keys are the query names and the values are a comma separated string of query values. This is converted to a list before being passed to the API. + +--- + +An `authorization` block supports the following: + +* `parameter` - (Optional) The authentication Parameter value. + +* `scheme` - (Optional) The authentication Scheme name. + +--- + +A `proxy` block supports the following: + +* `password` - (Optional) The password to connect to the proxy server. + +* `url` - (Optional) The URL of the proxy server. + +* `username` - (Optional) The username to connect to the proxy server. + +--- + +A `service_fabric_cluster` block supports the following: + +* `client_certificate_thumbprint` - (Required) The client certificate thumbprint for the management endpoint. + +* `management_endpoints` - (Required) A list of cluster management endpoints. + +* `max_partition_resolution_retries` - (Required) The maximum number of retries when attempting resolve the partition. + +* `server_certificate_thumbprints` - (Optional) A list of thumbprints of the server certificates of the Service Fabric cluster. + +* `server_x509_name` - (Optional) One or more `server_x509_name` blocks as documented below. + +--- + +A `server_x509_name` block supports the following: + +* `issuer_certificate_thumbprint` - (Required) The thumbprint for the issuer of the certificate. + +* `name` - (Required) The common name of the certificate. + +--- + +A `tls` block supports the following: + +* `validate_certificate_chain` - (Optional) Flag indicating whether SSL certificate chain validation should be done when using self-signed certificates for the backend host. + +* `validate_certificate_name` - (Optional) Flag indicating whether SSL certificate name validation should be done when using self-signed certificates for the backend host. +--- + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management API. + +## Import + +API Management backends can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_backend.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.ApiManagement/service/instance1/backends/backend1 +``` diff --git a/website/docs/r/api_management_certificate.html.markdown b/website/docs/r/api_management_certificate.html.markdown new file mode 100644 index 000000000000..f98a15dd9220 --- /dev/null +++ b/website/docs/r/api_management_certificate.html.markdown @@ -0,0 +1,76 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_certificate" +sidebar_current: "docs-azurerm-resource-api-management-certificate" +description: |- + Manages an Certificate within an API Management Service. +--- + +# azurerm_api_management_certificate + +Manages an Certificate within an API Management Service. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_api_management" "test" { + name = "example-apim" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "My Company" + publisher_email = "company@terraform.io" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_certificate" "test" { + name = "example-cert" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + data = "${filebase64("example.pfx")}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the API Management Certificate. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The Name of the API Management Service where this Service should be created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The Name of the Resource Group where the API Management Service exists. Changing this forces a new resource to be created. + +* `data` - (Required) The base-64 encoded certificate data, which must be a PFX file. Changing this forces a new resource to be created. + +* `password` - (Optional) The password used for this certificate. Changing this forces a new resource to be created. + +--- + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management Certificate. + +* `expiration` - The Expiration Date of this Certificate, formatted as an RFC3339 string. + +* `subject` - The Subject of this Certificate. + +* `thumbprint` - The Thumbprint of this Certificate. + +## Import + +API Management Certificates can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_certificate.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.ApiManagement/service/instance1/certificates/certificate1 +``` diff --git a/website/docs/r/api_management_logger.html.markdown b/website/docs/r/api_management_logger.html.markdown new file mode 100644 index 000000000000..c35c07ac8ff1 --- /dev/null +++ b/website/docs/r/api_management_logger.html.markdown @@ -0,0 +1,100 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_logger" +sidebar_current: "docs-azurerm-resource-api-management-logger" +description: |- + Manages a Logger within an API Management Service. +--- + +# azurerm_api_management_logger + +Manages a Logger within an API Management Service. + + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West US" +} + +resource "azurerm_application_insights" "example" { + name = "example-appinsights" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + application_type = "Other" +} + +resource "azurerm_api_management" "example" { + name = "example-apim" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + publisher_name = "My Company" + publisher_email = "company@terraform.io" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_logger" "example" { + name = "example-logger" + api_management_name = "${azurerm_api_management.example.name}" + resource_group_name = "${azurerm_resource_group.example.name}" + + application_insights { + instrumentation_key = "${azurerm_application_insights.example.instrumentation_key}" + } +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of this Logger, which must be unique within the API Management Service. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group in which the API Management Service exists. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The name of the API Management Service. Changing this forces a new resource to be created. + +* `application_insights` - (Optional) An `application_insights` block as documented below. + +* `buffered` - (Optional) Specifies whether records should be buffered in the Logger prior to publishing. Defaults to `true`. + +* `description` - (Optional) A description of this Logger. + +* `eventhub` - (Optional) An `eventhub` block as documented below. + +--- + +An `application_insights` block supports the following: + +* `instrumentation_key` - (Required) The instrumentation key used to push data to Application Insights. + +--- + +An `eventhub` block supports the following: + +* `name` - (Required) The name of an EventHub. + +* `connection_string` - (Required) The connection string of an EventHub Namespace. + + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management Logger. + + +## Import + +API Management Loggers can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_api_management_logger.example /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-rg/Microsoft.ApiManagement/service/example-apim/loggers/example-logger +``` diff --git a/website/docs/r/api_management_openid_connect_provider.html.markdown b/website/docs/r/api_management_openid_connect_provider.html.markdown new file mode 100644 index 000000000000..edce139ba05c --- /dev/null +++ b/website/docs/r/api_management_openid_connect_provider.html.markdown @@ -0,0 +1,78 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_openid_connect_provider" +sidebar_current: "docs-azurerm-resource-api-management-openid-connect-provider" +description: |- + Manages an OpenID Connect Provider within a API Management Service. +--- + +# azurerm_api_management_openid_connect_provider + +Manages an OpenID Connect Provider within a API Management Service. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_api_management" "test" { + name = "example-apim" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + publisher_name = "My Company" + publisher_email = "company@terraform.io" + + sku { + name = "Developer" + capacity = 1 + } +} + +resource "azurerm_api_management_openid_connect_provider" "test" { + name = "example-provider" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + client_id = "00001111-2222-3333-4444-555566667777" + display_name = "Example Provider" + metadata_endpoint = "https://example.com/example" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) the Name of the OpenID Connect Provider which should be created within the API Management Service. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The name of the API Management Service in which this OpenID Connect Provider should be created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the API Management Service exists. Changing this forces a new resource to be created. + +* `client_id` - (Required) The Client ID used for the Client Application. + +* `client_secret` - (Required) The Client Secret used for the Client Application. + +* `display_name` - (Required) A user-friendly name for this OpenID Connect Provider. + +* `metadata_endpoint` - (Required) The URI of the Metadata endpoint. + +--- + +* `description` - (Optional) A description of this OpenID Connect Provider. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management OpenID Connect Provider. + +## Import + +API Management OpenID Connect Providers can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_openid_connect_provider.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.ApiManagement/service/instance1/openidConnectProviders/provider1 +``` diff --git a/website/docs/r/api_management_product_api.html.markdown b/website/docs/r/api_management_product_api.html.markdown index 6960745796b1..598b1703b8e6 100644 --- a/website/docs/r/api_management_product_api.html.markdown +++ b/website/docs/r/api_management_product_api.html.markdown @@ -18,13 +18,13 @@ data "azurerm_api_management" "example" { resource_group_name = "example-resources" } - data "azurerm_api_management_api" "example" { name = "search-api" api_management_name = "${data.azurerm_api_management.example.name}" resource_group_name = "${data.azurerm_api_management.example.resource_group_name}" revision = "2" } + data "azurerm_api_management_product" "test" { product_id = "my-product" api_management_name = "${data.azurerm_api_management.example.name}" diff --git a/website/docs/r/api_management_product_policy.html.markdown b/website/docs/r/api_management_product_policy.html.markdown new file mode 100644 index 000000000000..3777ad771163 --- /dev/null +++ b/website/docs/r/api_management_product_policy.html.markdown @@ -0,0 +1,65 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_product_policy" +sidebar_current: "docs-azurerm-resource-api-management-product-policy" +description: |- + Manages an API Management Product Policy +--- + +# azurerm_api_management_product_policy + +Manages an API Management Product Policy + + +## Example Usage + +```hcl +data "azurerm_api_management_product" "example" { + product_id = "my-product" + api_management_name = "example-apim" + resource_group_name = "search-service" +} + +resource "azurerm_api_management_product_policy" "example" { + product_id = "${data.azurerm_api_management_product.example.product_id}" + api_management_name = "${data.azurerm_api_management_product.example.api_management_name}" + resource_group_name = "${data.azurerm_api_management_product.example.resource_group_name}" + + xml_content = <<XML +<policies> + <inbound> + <find-and-replace from="xyz" to="abc" /> + </inbound> +</policies> +XML +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `product_id` - (Required) The ID of the API Management Product within the API Management Service. Changing this forces a new resource to be created. + +* `api_management_name` - (Required) The name of the API Management Service. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group in which the API Management Service exists. Changing this forces a new resource to be created. + +* `xml_content` - (Optional) The XML Content for this Policy. + +* `xml_link` - (Optional) A link to a Policy XML Document, which must be publicly available. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management Product Policy. + +## Import + +API Management Product Policy can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_product_policy.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.ApiManagement/service/service1/products/exampleId/policies/policy +``` diff --git a/website/docs/r/api_management_subscription.html.markdown b/website/docs/r/api_management_subscription.html.markdown new file mode 100644 index 000000000000..3a8911d13da6 --- /dev/null +++ b/website/docs/r/api_management_subscription.html.markdown @@ -0,0 +1,76 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_api_management_subscription" +sidebar_current: "docs-azurerm-resource-api-management-subscription" +description: |- + Manages a Subscription within a API Management Service. +--- + +# azurerm_api_management_subscription + +Manages a Subscription within a API Management Service. + + +## Example Usage + +```hcl +data "azurerm_api_management" "test" { + name = "example-apim" + resource_group_name = "example-resources" +} + +data "azurerm_api_management_product" "test" { + product_id = "00000000-0000-0000-0000-000000000000" + api_management_name = "${data.azurerm_api_management.test.name}" + resource_group_name = "${data.azurerm_api_management.test.resource_group_name}" +} + +data "azurerm_api_management_user" "test" { + user_id = "11111111-1111-1111-1111-111111111111" + api_management_name = "${data.azurerm_api_management.test.name}" + resource_group_name = "${data.azurerm_api_management.test.resource_group_name}" +} + +resource "azurerm_api_management_subscription" "test" { + api_management_name = "${data.azurerm_api_management.test.name}" + resource_group_name = "${data.azurerm_api_management.test.resource_group_name}" + user_id = "${data.azurerm_api_management_user.test.id}" + product_id = "${data.azurerm_api_management_product.test.id}" + display_name = "Parser API" +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `api_management_name` - (Required) The name of the API Management Service where this Subscription should be created. Changing this forces a new resource to be created. + +* `display_name` - (Required) The display name of this Subscription. + +* `resource_group_name` - (Required) The name of the Resource Group in which the API Management Service exists. Changing this forces a new resource to be created. + +* `product_id` - (Required) The ID of the Product which should be assigned to this Subscription. Changing this forces a new resource to be created. + +* `user_id` - (Required) The ID of the User which should be assigned to this Subscription. Changing this forces a new resource to be created. + +--- + +* `state` - (Optional) The state of this Subscription. Possible values are `Active`, `Cancelled`, `Expired`, `Rejected`, `Submitted` and `Suspended`. Defaults to `Submitted`. + +* `subscription_id` - (Optional) An Identifier which should used as the ID of this Subscription. If not specified a new Subscription ID will be generated. Changing this forces a new resource to be created. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the API Management Subscription. + +## Import + +API Management Subscriptions can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_api_management_subscription.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-resources/providers/Microsoft.ApiManagement/service/example-apim/properties/example-apimp +``` diff --git a/website/docs/r/api_management_user.html.markdown b/website/docs/r/api_management_user.html.markdown index 09c5a638e499..94d9663386bc 100644 --- a/website/docs/r/api_management_user.html.markdown +++ b/website/docs/r/api_management_user.html.markdown @@ -32,13 +32,13 @@ resource "azurerm_api_management" "test" { } resource "azurerm_api_management_user" "test" { - user_id = "5931a75ae4bbd512288c680b" - api_management_name = "${azurerm_api_management.test.name}" - resource_group_name = "${azurerm_resource_group.test.name}" - first_name = "Example" - last_name = "User" - email = "tom+tfdev@hashicorp.com" - state = "active" + user_id = "5931a75ae4bbd512288c680b" + api_management_name = "${azurerm_api_management.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + first_name = "Example" + last_name = "User" + email = "tom+tfdev@hashicorp.com" + state = "active" } ``` diff --git a/website/docs/r/app_service.html.markdown b/website/docs/r/app_service.html.markdown index d7cae64de733..4714782c2bea 100644 --- a/website/docs/r/app_service.html.markdown +++ b/website/docs/r/app_service.html.markdown @@ -71,16 +71,22 @@ The following arguments are supported: * `app_settings` - (Optional) A key-value pair of App Settings. +* `auth_settings` - (Optional) A `auth_settings` block as defined below. + +* `storage_account` - (Optional) One or more `storage_account` blocks as defined below. + * `connection_string` - (Optional) One or more `connection_string` blocks as defined below. * `client_affinity_enabled` - (Optional) Should the App Service send session affinity cookies, which route client requests in the same session to the same instance? * `client_cert_enabled` - (Optional) Does the App Service require client certificates for incoming requests? Defaults to `false`. -* `enabled` - (Optional) Is the App Service Enabled? Changing this forces a new resource to be created. +* `enabled` - (Optional) Is the App Service Enabled? * `https_only` - (Optional) Can the App Service only be accessed via HTTPS? Defaults to `false`. +* `logs` - (Optional) A `logs` block as defined below. + * `site_config` - (Optional) A `site_config` block as defined below. * `tags` - (Optional) A mapping of tags to assign to the resource. @@ -89,6 +95,22 @@ The following arguments are supported: --- +A `storage_account` block supports the following: + +* `name` - (Required) The name of the storage account identifier. + +* `type` - (Required) The type of storage. Possible values are `AzureBlob` and `AzureFiles`. + +* `account_name` - (Required) The name of the storage account. + +* `share_name` - (Required) The name of the file share (container name, for Blob storage). + +* `access_key` - (Required) The access key for the storage account. + +* `mount_path` - (Optional) The path to mount the storage within the site's runtime environment. + +--- + A `connection_string` block supports the following: * `name` - (Required) The name of the Connection String. @@ -101,9 +123,49 @@ A `connection_string` block supports the following: A `identity` block supports the following: -* `type` - (Required) Specifies the identity type of the App Service. At this time the only allowed value is `SystemAssigned`. +* `type` - (Required) Specifies the identity type of the App Service. Possible values are `SystemAssigned` (where Azure will generate a Service Principal for you), `UserAssigned` where you can specify the Service Principal IDs in the `identity_ids` field, and `SystemAssigned, UserAssigned` which assigns both a system managed identity as well as the specified user assigned identities. + +~> **NOTE:** When `type` is set to `SystemAssigned`, The assigned `principal_id` and `tenant_id` can be retrieved after the App Service has been created. More details are available below. + +* `identity_ids` - (Optional) Specifies a list of user managed identity ids to be assigned. Required if `type` is `UserAssigned`. + +--- + +A `logs` block supports the following: + +* `application_logs` - (Optional) An `application_logs` block as defined below. + +* `http_logs` - (Optional) An `http_logs` block as defined below. + +--- + +An `application_logs` block supports the following: + +* `azure_blob_storage` - (Optional) An `azure_blob_storage` block as defined below. + +--- + +An `azure_blob_storage` block supports the following: -~> The assigned `principal_id` and `tenant_id` can be retrieved after the App Service has been created. More details are available below. +* `level` - (Required) The level at which to log. Possible values include `Error`, `Warning`, `Information`, `Verbose` and `Off`. + +* `sas_url` - (Required) The URL to the storage container, with a Service SAS token appended. **NOTE:** there is currently no means of generating Service SAS tokens with the `azurerm` provider. + +* `retention_in_days` - (Required) The number of days to retain logs for. + +--- + +An `http_logs` block supports the following: + +* `file_system` - (Optional) A `file_system` block as defined below. + +--- + +A `file_system` block supports the following: + +* `retention_in_days` - (Required) The number of days to retain logs for. + +* `retention_in_mb` - (Required) The maximum size in megabytes that http log files can use before being removed. --- @@ -113,6 +175,8 @@ A `site_config` block supports the following: * `app_command_line` - (Optional) App command line to launch, e.g. `/sbin/myserver -b 0.0.0.0`. +* `cors` - (Optional) A `cors` block as defined below. + * `default_documents` - (Optional) The ordering of default documents to load, if an address isn't specified. * `dotnet_framework_version` - (Optional) The version of the .net framework's CLR used in this App Service. Possible values are `v2.0` (which will use the latest version of the .net framework for the .net CLR v2 - currently `.net 3.5`) and `v4.0` (which corresponds to the latest version of the .net CLR v4 - which at the time of writing is `.net 4.7.1`). [For more information on which .net CLR version to use based on the .net framework you're targeting - please see this table](https://en.wikipedia.org/wiki/.NET_Framework_version_history#Overview). Defaults to `v4.0`. @@ -121,9 +185,9 @@ A `site_config` block supports the following: * `http2_enabled` - (Optional) Is HTTP2 Enabled on this App Service? Defaults to `false`. -* `ip_restriction` - (Optional) One or more `ip_restriction` blocks as defined below. +* `ip_restriction` - (Optional) A [List of objects](/docs/configuration/attr-as-blocks.html) representing ip restrictions as defined below. -* `java_version` - (Optional) The version of Java to use. If specified `java_container` and `java_container_version` must also be specified. Possible values are `1.7` and `1.8`. +* `java_version` - (Optional) The version of Java to use. If specified `java_container` and `java_container_version` must also be specified. Possible values are `1.7`, `1.8` and `11`. * `java_container` - (Optional) The Java Container to use. If specified `java_version` and `java_container_version` must also be specified. Possible values are `JETTY` and `TOMCAT`. @@ -133,7 +197,9 @@ A `site_config` block supports the following: ~> **NOTE:** MySQL In App is not intended for production environments and will not scale beyond a single instance. Instead you may wish [to use Azure Database for MySQL](/docs/providers/azurerm/r/mysql_database.html). -* `linux_fx_version` - (Optional) Linux App Framework and version for the App Service. Possible options are a Docker container (`DOCKER|<user/image:tag>`), a base-64 encoded Docker Compose file (`COMPOSE|${base64encode(file("compose.yml"))}`) or a base-64 encoded Kubernetes Manifest (`KUBE|${base64encode(file("kubernetes.yml"))}`). +* `linux_fx_version` - (Optional) Linux App Framework and version for the App Service. Possible options are a Docker container (`DOCKER|<user/image:tag>`), a base-64 encoded Docker Compose file (`COMPOSE|${filebase64("compose.yml")}`) or a base-64 encoded Kubernetes Manifest (`KUBE|${filebase64("kubernetes.yml")}`). + +* `windows_fx_version` - (Optional) The Windows Docker container image (`DOCKER|<user/image:tag>`) Additional examples of how to run Containers via the `azurerm_app_service` resource can be found in [the `./examples/app-service` directory within the Github Repository](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples/app-service). @@ -161,12 +227,124 @@ Additional examples of how to run Containers via the `azurerm_app_service` resou --- +A `cors` block supports the following: + +* `allowed_origins` - (Optional) A list of origins which should be able to make cross-origin calls. `*` can be used to allow all calls. + +* `support_credentials` - (Optional) Are credentials supported? + +--- + +A `auth_settings` block supports the following: + +* `enabled` - (Required) Is Authentication enabled? + +* `active_directory` - (Optional) A `active_directory` block as defined below. + +* `additional_login_params` - (Optional) Login parameters to send to the OpenID Connect authorization endpoint when a user logs in. Each parameter must be in the form "key=value". + +* `allowed_external_redirect_urls` - (Optional) External URLs that can be redirected to as part of logging in or logging out of the app. + +* `default_provider` - (Optional) The default provider to use when multiple providers have been set up. Possible values are `AzureActiveDirectory`, `Facebook`, `Google`, `MicrosoftAccount` and `Twitter`. + +~> **NOTE:** When using multiple providers, the default provider must be set for settings like `unauthenticated_client_action` to work. + +* `facebook` - (Optional) A `facebook` block as defined below. + +* `google` - (Optional) A `google` block as defined below. + +* `issuer` - (Optional) Issuer URI. When using Azure Active Directory, this value is the URI of the directory tenant, e.g. https://sts.windows.net/{tenant-guid}/. + +* `microsoft` - (Optional) A `microsoft` block as defined below. + +* `runtime_version` - (Optional) The runtime version of the Authentication/Authorization module. + +* `token_refresh_extension_hours` - (Optional) The number of hours after session token expiration that a session token can be used to call the token refresh API. Defaults to 72. + +* `token_store_enabled` - (Optional) If enabled the module will durably store platform-specific security tokens that are obtained during login flows. Defaults to false. + +* `twitter` - (Optional) A `twitter` block as defined below. + +* `unauthenticated_client_action` - (Optional) The action to take when an unauthenticated client attempts to access the app. Possible values are `AllowAnonymous` and `RedirectToLoginPage`. + +--- + +A `active_directory` block supports the following: + +* `client_id` - (Required) The Client ID of this relying party application. Enables OpenIDConnection authentication with Azure Active Directory. + +* `client_secret` - (Optional) The Client Secret of this relying party application. If no secret is provided, implicit flow will be used. + +* `allowed_audiences` (Optional) Allowed audience values to consider when validating JWTs issued by Azure Active Directory. + +--- + +A `facebook` block supports the following: + +* `app_id` - (Required) The App ID of the Facebook app used for login + +* `app_secret` - (Required) The App Secret of the Facebook app used for Facebook Login. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Facebook Login authentication. https://developers.facebook.com/docs/facebook-login + +--- + +A `google` block supports the following: + +* `client_id` - (Required) The OpenID Connect Client ID for the Google web application. + +* `client_secret` - (Required) The client secret associated with the Google web application. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Google Sign-In authentication. https://developers.google.com/identity/sign-in/web/ + +--- + A `ip_restriction` block supports the following: -* `ip_address` - (Required) The IP Address used for this IP Restriction. +* `ip_address` - (Optional) The IP Address used for this IP Restriction. * `subnet_mask` - (Optional) The Subnet mask used for this IP Restriction. Defaults to `255.255.255.255`. +* `virtual_network_subnet_id` - (Optional.The Virtual Network Subnet ID used for this IP Restriction. + +-> **NOTE:** One of either `ip_address` or `virtual_network_subnet_id` must be specified + +--- + +A `microsoft` block supports the following: + +* `client_id` - (Required) The OAuth 2.0 client ID that was created for the app used for authentication. + +* `client_secret` - (Required) The OAuth 2.0 client secret that was created for the app used for authentication. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Microsoft Account authentication. https://msdn.microsoft.com/en-us/library/dn631845.aspx + +--- + +A `backup` block supports the following: + +* `backup_name` (Required) Specifies the name for this Backup. + +* `enabled` - (Required) Is this Backup enabled? + +* `storage_account_url` (Optional) The SAS URL to a Storage Container where Backups should be saved. + +* `schedule` - (Optional) A `schedule` block as defined below. + +--- + +A `schedule` block supports the following: + +* `frequency_interval` - (Required) Sets how often the backup should be executed. + +* `frequency_unit` - (Optional) Sets the unit of time for how often the backup should be executed. Possible values are `Day` or `Hour`. + +* `keep_at_least_one_backup` - (Optional) Should at least one backup always be kept in the Storage Account by the Retention Policy, regardless of how old it is? + +* `retention_period_in_days` - (Optional) Specifies the number of days after which Backups should be deleted. + +* `start_time` - (Optional) Sets when the schedule should start working. + ## Attributes Reference The following attributes are exported: @@ -187,7 +365,7 @@ The following attributes are exported: --- -`identity` exports the following: +A `identity` block exports the following: * `principal_id` - The Principal ID for the Service Principal associated with the Managed Service Identity of this App Service. @@ -197,7 +375,7 @@ The following attributes are exported: --- -`site_credential` exports the following: +A `site_credential` block exports the following: * `username` - The username which can be used to publish to this App Service * `password` - The password associated with the username, which can be used to publish to this App Service. @@ -206,7 +384,7 @@ The following attributes are exported: --- -`source_control` exports the following: +A `source_control` block exports the following: * `repo_url` - URL of the Git repository for this App Service. * `branch` - Branch name of the Git repository for this App Service. diff --git a/website/docs/r/app_service_certificate.html.markdown b/website/docs/r/app_service_certificate.html.markdown new file mode 100644 index 000000000000..84ce8a197c60 --- /dev/null +++ b/website/docs/r/app_service_certificate.html.markdown @@ -0,0 +1,75 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_app_service_certificate" +sidebar_current: "docs-azurerm-resource-app-service-certificate" +description: |- + Manages an App Service certificate. + +--- + +# azurerm_app_service_certificate + +Manages an App Service certificate. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_app_service_certificate" "example" { + name = "example-cert" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + pfx_blob = "${filebase64("certificate.pfx")}" + password = "terraform" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the certificate. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the certificate. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `pfx_blob` - (Optional) The base64-encoded contents of the certificate. Changing this forces a new resource to be created. + +-> **NOTE:** Either `pfx_blob` or `key_vault_secret_id` must be set - but not both. + +* `password` - (Optional) The password to access the certificate's private key. Changing this forces a new resource to be created. + +* `key_vault_secret_id` - (Optional) The ID of the Key Vault secret. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The App Service certificate ID. + +* `friendly_name` - The friendly name of the certificate. + +* `subject_name` - The subject name of the certificate. + +* `host_names` - List of host names the certificate applies to. + +* `issuer` - The name of the certificate issuer. + +* `issue_date` - The issue date for the certificate. + +* `expiration_date` - The expiration date for the certificate. + +* `thumbprint` - The thumbprint for the certificate. + +## Import + +App Service certificates can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_app_certificate.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Web/certificates/certificate1 +``` diff --git a/website/docs/r/app_service_plan.html.markdown b/website/docs/r/app_service_plan.html.markdown index 45e98d7e16b7..955fb1857c5e 100644 --- a/website/docs/r/app_service_plan.html.markdown +++ b/website/docs/r/app_service_plan.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_app_service_plan -Manage an App Service Plan component. +Manages an App Service Plan component. ## Example Usage (Dedicated) @@ -64,14 +64,33 @@ resource "azurerm_app_service_plan" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" kind = "Linux" + reserved = true sku { tier = "Standard" size = "S1" } +} +``` + +## Example Usage (Windows Container) + +```hcl +resource "azurerm_resource_group" "test" { + name = "api-rg-pro" + location = "West Europe" +} - properties { - reserved = true +resource "azurerm_app_service_plan" "test" { + name = "api-appserviceplan-pro" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + kind = "xenon" + is_xenon = true + + sku { + tier = "PremiumContainer" + size = "PC2" } } ``` @@ -86,7 +105,9 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `kind` - (Optional) The kind of the App Service Plan to create. Possible values are `Windows` (also available as `App`), `Linux` and `FunctionApp` (for a Consumption Plan). Defaults to `Windows`. Changing this forces a new resource to be created. +* `kind` - (Optional) The kind of the App Service Plan to create. Possible values are `Windows` (also available as `App`), `Linux`, `elastic` (for Premium Consumption) and `FunctionApp` (for a Consumption Plan). Defaults to `Windows`. Changing this forces a new resource to be created. + +* `maximum_elastic_worker_count` - The maximum number of total workers allowed for this ElasticScaleEnabled App Service Plan. ~> **NOTE:** When creating a `Linux` App Service Plan, the `reserved` field must be set to `true`. @@ -111,7 +132,6 @@ The following arguments are supported: * `capacity` - (Optional) Specifies the number of workers associated with this App Service Plan. - ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/app_service_slot.html.markdown b/website/docs/r/app_service_slot.html.markdown index bb629cc8e74c..eb026d6bf96d 100644 --- a/website/docs/r/app_service_slot.html.markdown +++ b/website/docs/r/app_service_slot.html.markdown @@ -156,6 +156,8 @@ The following arguments are supported: * `app_settings` - (Optional) A key-value pair of App Settings. +* `auth_settings` - (Optional) A `auth_settings` block as defined below. + * `connection_string` - (Optional) An `connection_string` block as defined below. * `client_affinity_enabled` - (Optional) Should the App Service Slot send session affinity cookies, which route client requests in the same session to the same instance? @@ -186,19 +188,21 @@ The following arguments are supported: * `always_on` - (Optional) Should the app be loaded at all times? Defaults to `false`. +* `cors` - (Optional) A `cors` block as defined below. + * `default_documents` - (Optional) The ordering of default documents to load, if an address isn't specified. * `dotnet_framework_version` - (Optional) The version of the .net framework's CLR used in this App Service Slot. Possible values are `v2.0` (which will use the latest version of the .net framework for the .net CLR v2 - currently `.net 3.5`) and `v4.0` (which corresponds to the latest version of the .net CLR v4 - which at the time of writing is `.net 4.7.1`). [For more information on which .net CLR version to use based on the .net framework you're targeting - please see this table](https://en.wikipedia.org/wiki/.NET_Framework_version_history#Overview). Defaults to `v4.0`. * `http2_enabled` - (Optional) Is HTTP2 Enabled on this App Service? Defaults to `false`. -* `ip_restriction` - (Optional) One or more `ip_restriction` blocks as defined below. +* `ip_restriction` - (Optional) A [List of objects](/docs/configuration/attr-as-blocks.html) representing ip restrictions as defined below. * `java_container` - (Optional) The Java Container to use. If specified `java_version` and `java_container_version` must also be specified. Possible values are `JETTY` and `TOMCAT`. * `java_container_version` - (Optional) The version of the Java Container to use. If specified `java_version` and `java_container` must also be specified. -* `java_version` - (Optional) The version of Java to use. If specified `java_container` and `java_container_version` must also be specified. Possible values are `1.7` and `1.8`. +* `java_version` - (Optional) The version of Java to use. If specified `java_container` and `java_container_version` must also be specified. Possible values are `1.7`, `1.8` and `11`. * `local_mysql_enabled` - (Optional) Is "MySQL In App" Enabled? This runs a local MySQL instance with your app and shares resources from the App Service plan. @@ -228,17 +232,116 @@ The following arguments are supported: --- -`ip_restriction` supports the following: +A `cors` block supports the following: -* `ip_address` - (Required) The IP Address used for this IP Restriction. +* `allowed_origins` - (Optional) A list of origins which should be able to make cross-origin calls. `*` can be used to allow all calls. + +* `support_credentials` - (Optional) Are credentials supported? + +--- + +A `auth_settings` block supports the following: + +* `enabled` - (Required) Is Authentication enabled? + +* `active_directory` - (Optional) A `active_directory` block as defined below. + +* `additional_login_params` - (Optional) Login parameters to send to the OpenID Connect authorization endpoint when a user logs in. Each parameter must be in the form "key=value". + +* `allowed_external_redirect_urls` - (Optional) External URLs that can be redirected to as part of logging in or logging out of the app. + +* `default_provider` - (Optional) The default provider to use when multiple providers have been set up. Possible values are `AzureActiveDirectory`, `Facebook`, `Google`, `MicrosoftAccount` and `Twitter`. + +~> **NOTE:** When using multiple providers, the default provider must be set for settings like `unauthenticated_client_action` to work. + +* `facebook` - (Optional) A `facebook` block as defined below. + +* `google` - (Optional) A `google` block as defined below. + +* `issuer` - (Optional) Issuer URI. When using Azure Active Directory, this value is the URI of the directory tenant, e.g. https://sts.windows.net/{tenant-guid}/. + +* `microsoft` - (Optional) A `microsoft` block as defined below. + +* `runtime_version` - (Optional) The runtime version of the Authentication/Authorization module. + +* `token_refresh_extension_hours` - (Optional) The number of hours after session token expiration that a session token can be used to call the token refresh API. Defaults to 72. + +* `token_store_enabled` - (Optional) If enabled the module will durably store platform-specific security tokens that are obtained during login flows. Defaults to false. + +* `twitter` - (Optional) A `twitter` block as defined below. + +* `unauthenticated_client_action` - (Optional) The action to take when an unauthenticated client attempts to access the app. Possible values are `AllowAnonymous` and `RedirectToLoginPage`. + +--- + +A `active_directory` block supports the following: + +* `client_id` - (Required) The Client ID of this relying party application. Enables OpenIDConnection authentication with Azure Active Directory. + +* `client_secret` - (Optional) The Client Secret of this relying party application. If no secret is provided, implicit flow will be used. + +* `allowed_audiences` (Optional) Allowed audience values to consider when validating JWTs issued by Azure Active Directory. + +--- + +A `facebook` block supports the following: + +* `app_id` - (Required) The App ID of the Facebook app used for login + +* `app_secret` - (Required) The App Secret of the Facebook app used for Facebook Login. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Facebook Login authentication. https://developers.facebook.com/docs/facebook-login + +--- + +A `google` block supports the following: + +* `client_id` - (Required) The OpenID Connect Client ID for the Google web application. + +* `client_secret` - (Required) The client secret associated with the Google web application. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Google Sign-In authentication. https://developers.google.com/identity/sign-in/web/ + +--- + +A `ip_restriction` block supports the following: + +* `ip_address` - (Optional) The IP Address used for this IP Restriction. * `subnet_mask` - (Optional) The Subnet mask used for this IP Restriction. Defaults to `255.255.255.255`. -`identity` supports the following: +* `virtual_network_subnet_id` - (Optional.The Virtual Network Subnet ID used for this IP Restriction. + +-> **NOTE:** One of either `ip_address` or `virtual_network_subnet_id` must be specified + + +--- + +A `microsoft` block supports the following: + +* `client_id` - (Required) The OAuth 2.0 client ID that was created for the app used for authentication. + +* `client_secret` - (Required) The OAuth 2.0 client secret that was created for the app used for authentication. -* `type` - (Required) Specifies the identity type of the App Service. At this time the only allowed value is `SystemAssigned`. +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Microsoft Account authentication. https://msdn.microsoft.com/en-us/library/dn631845.aspx -~> The assigned `principal_id` and `tenant_id` can be retrieved after the App Service Slot has been created. +--- + +A `identity` block supports the following: + +* `type` - (Required) Specifies the identity type of the App Service. Possible values are `SystemAssigned` (where Azure will generate a Service Principal for you), `UserAssigned` where you can specify the Service Principal IDs in the `identity_ids` field, and `SystemAssigned, UserAssigned` which assigns both a system managed identity as well as the specified user assigned identities. + +~> **NOTE:** When `type` is set to `SystemAssigned`, The assigned `principal_id` and `tenant_id` can be retrieved after the App Service has been created. More details are available below. + +* `identity_ids` - (Optional) Specifies a list of user managed identity ids to be assigned. Required if `type` is `UserAssigned`. + +--- + +Elements of `ip_restriction` [block](/docs/configuration/attr-as-blocks.html) support: + +* `ip_address` - (Required) The IP Address used for this IP Restriction. + +* `subnet_mask` - (Optional) The Subnet mask used for this IP Restriction. Defaults to `255.255.255.255`. ## Attributes Reference @@ -248,6 +351,15 @@ The following attributes are exported: * `default_site_hostname` - The Default Hostname associated with the App Service Slot - such as `mysite.azurewebsites.net` +* `site_credential` - A `site_credential` block as defined below, which contains the site-level credentials used to publish to this App Service. + +--- + +`site_credential` exports the following: + +* `username` - The username which can be used to publish to this App Service +* `password` - The password associated with the username, which can be used to publish to this App Service. + ## Import App Service Slots can be imported using the `resource id`, e.g. diff --git a/website/docs/r/application_gateway.html.markdown b/website/docs/r/application_gateway.html.markdown index 78f9ac82dcc2..7f4dd07fb13e 100644 --- a/website/docs/r/application_gateway.html.markdown +++ b/website/docs/r/application_gateway.html.markdown @@ -54,6 +54,7 @@ locals { http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" listener_name = "${azurerm_virtual_network.test.name}-httplstn" request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + redirect_configuration_name = "${azurerm_virtual_network.test.name}-rdrcfg" } resource "azurerm_application_gateway" "network" { @@ -89,7 +90,7 @@ resource "azurerm_application_gateway" "network" { backend_http_settings { name = "${local.http_setting_name}" cookie_based_affinity = "Disabled" - path = "/path1/" + path = "/path1/" port = 80 protocol = "Http" request_timeout = 1 @@ -134,17 +135,26 @@ The following arguments are supported: * `http_listener` - (Required) One or more `http_listener` blocks as defined below. +* `identity` - (Optional) A `identity` block. + * `request_routing_rule` - (Required) One or more `request_routing_rule` blocks as defined below. * `sku` - (Required) A `sku` block as defined below. +* `zones` - (Optional) A collection of availability zones to spread the Application Gateway over. + +-> **Please Note**: Availability Zones are [only supported in several regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview). They are also only supported for [v2 SKUs](https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-autoscaling-zone-redundant) + --- * `authentication_certificate` - (Optional) One or more `authentication_certificate` blocks as defined below. -* `disabled_ssl_protocols` - (Optional) A list of SSL Protocols which should be disabled on this Application Gateway. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. +* `disabled_ssl_protocols` - (Optional / **Deprecated**) A list of SSL Protocols which should be disabled on this Application Gateway. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. +~> **NOTE:** `disabled_ssl_protocols ` has been deprecated in favour of `disabled_protocols` in the `ssl_policy` block. + +* `ssl_policy` (Optional) a `ssl policy` block as defined below. -* `http2_enabled` - (Optional) Is HTTP2 enabled on the application gateway resource? Defaults to `false`. +* `enable_http2` - (Optional) Is HTTP2 enabled on the application gateway resource? Defaults to `false`. * `probe` - (Optional) One or more `probe` blocks as defined below. @@ -158,6 +168,12 @@ The following arguments are supported: * `custom_error_configuration` - (Optional) One or more `custom_error_configuration` blocks as defined below. +* `redirect_configuration` - (Optional) A `redirect_configuration` block as defined below. + +* `autoscale_configuration` - (Optional) A `autoscale_configuration` block as defined below. + +* `rewrite_rule_set` - (Optional) One or more `rewrite_rule_set` blocks as defined below. Only valid for v2 SKUs. + --- A `authentication_certificate` block supports the following: @@ -192,6 +208,8 @@ A `backend_http_settings` block supports the following: * `cookie_based_affinity` - (Required) Is Cookie-Based Affinity enabled? Possible values are `Enabled` and `Disabled`. +* `affinity_cookie_name` - (Optional) The name of the affinity cookie. + * `name` - (Required) The name of the Backend HTTP Settings Collection. * `path` - (Optional) The Path which should be used as a prefix for all HTTP requests. @@ -204,6 +222,8 @@ A `backend_http_settings` block supports the following: * `request_timeout` - (Required) The request timeout in seconds, which must be between 1 and 86400 seconds. +* `host_name` - (Optional) Host header to be sent to the backend servers. Cannot be set if `pick_host_name_from_backend_address` is set to `true`. + * `pick_host_name_from_backend_address` - (Optional) Whether host header should be picked from the host name of the backend server. Defaults to `false`. * `authentication_certificate` - (Optional) One or more `authentication_certificate` blocks. @@ -273,6 +293,14 @@ A `http_listener` block supports the following: --- +A `identity` block supports the following: + +* `type` - (Optional) The Managed Service Identity Type of this Application Gateway. The only possible value is `UserAssigned`. Defaults to `UserAssigned`. + +* `identity_ids` - (Required) Specifies a list with a single user managed identity id to be assigned to the Application Gateway. + +--- + A `match` block supports the following: * `body` - (Optional) A snippet from the Response Body which must be present in the Response. Defaults to `*`. @@ -287,9 +315,13 @@ A `path_rule` block supports the following: * `paths` - (Required) A list of Paths used in this Path Rule. -* `backend_address_pool_name` - (Required) The Name of the Backend Address Pool to use for this Path Rule. +* `backend_address_pool_name` - (Optional) The Name of the Backend Address Pool to use for this Path Rule. Cannot be set if `redirect_configuration_name` is set. -* `backend_http_settings_name` - (Required) The Name of the Backend HTTP Settings Collection to use for this Path Rule. +* `backend_http_settings_name` - (Optional) The Name of the Backend HTTP Settings Collection to use for this Path Rule. Cannot be set if `redirect_configuration_name` is set. + +* `redirect_configuration_name` - (Optional) The Name of a Redirect Configuration to use for this Path Rule. Cannot be set if `backend_address_pool_name` or `backend_http_settings_name` is set. + +* `rewrite_rule_set_name` - (Optional) The Name of the Rewrite Rule Set which should be used for this URL Path Map. Only valid for v2 SKUs. --- @@ -325,9 +357,13 @@ A `request_routing_rule` block supports the following: * `http_listener_name` - (Required) The Name of the HTTP Listener which should be used for this Routing Rule. -* `backend_address_pool_name` - (Optional) The Name of the Backend Address Pool which should be used for this Routing Rule. +* `backend_address_pool_name` - (Optional) The Name of the Backend Address Pool which should be used for this Routing Rule. Cannot be set if `redirect_configuration_name` is set. + +* `backend_http_settings_name` - (Optional) The Name of the Backend HTTP Settings Collection which should be used for this Routing Rule. Cannot be set if `redirect_configuration_name` is set. + +* `redirect_configuration_name` - (Optional) The Name of the Redirect Configuration which should be used for this Routing Rule. Cannot be set if either `backend_address_pool_name` or `backend_http_settings_name` is set. -* `backend_http_settings_name` - (Optional) The Name of the Backend HTTP Settings Collection which should be used for this Routing Rule. +* `rewrite_rule_set_name` - (Optional) The Name of the Rewrite Rule Set which should be used for this Routing Rule. Only valid for v2 SKUs. * `url_path_map_name` - (Optional) The Name of the URL Path Map which should be associated with this Routing Rule. @@ -339,7 +375,7 @@ A `sku` block supports the following: * `tier` - (Required) The Tier of the SKU to use for this Application Gateway. Possible values are `Standard`, `Standard_v2`, `WAF` and `WAF_v2`. -* `capacity` - (Required) The Capacity of the SKU to use for this Application Gateway - which must be between 1 and 10. +* `capacity` - (Required) The Capacity of the SKU to use for this Application Gateway - which must be between 1 and 10, optional if `autoscale_configuration` is set --- @@ -357,12 +393,41 @@ A `url_path_map` block supports the following: * `name` - (Required) The Name of the URL Path Map. -* `default_backend_address_pool_name` - (Required) The Name of the Default Backend Address Pool which should be used for this URL Path Map. +* `default_backend_address_pool_name` - (Optional) The Name of the Default Backend Address Pool which should be used for this URL Path Map. Cannot be set if `default_redirect_configuration_name` is set. -* `default_backend_http_settings_name` - (Required) The Name of the Default Backend HTTP Settings Collection which should be used for this URL Path Map. +* `default_backend_http_settings_name` - (Optional) The Name of the Default Backend HTTP Settings Collection which should be used for this URL Path Map. Cannot be set if `default_redirect_configuration_name` is set. + +* `default_redirect_configuration_name` - (Optional) The Name of the Default Redirect Configuration which should be used for this URL Path Map. Cannot be set if either `default_backend_address_pool_name` or `default_backend_http_settings_name` is set. + +* `default_rewrite_rule_set_name` - (Optional) The Name of the Default Rewrite Rule Set which should be used for this URL Path Map. Only valid for v2 SKUs. * `path_rule` - (Required) One or more `path_rule` blocks as defined above. +--- + +A `ssl_policy` block supports the following: + +* `disabled_protocols` - (Optional) A list of SSL Protocols which should be disabled on this Application Gateway. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. + +~> **NOTE:** `disabled_protocols` cannot be set when `policy_name` or `policy_type` are set. + +* `policy_type` - (Optional) The Type of the Policy. Possible values are `Predefined` and `Custom`. + +~> **NOTE:** `policy_type` is Required when `policy_name` is set - cannot be set if `disabled_protocols` is set. + +When using a `policy_type` of `Predefined` the following fields are supported: + +* `policy_name` - (Optional) The Name of the Policy e.g AppGwSslPolicy20170401S. Required if `policy_type` is set to `Predefined`. Possible values can change over time and +are published here https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-ssl-policy-overview. Not compatible with `disabled_protocols`. + +When using a `policy_type` of `Custom` the following fields are supported: + +* `cipher_suites` - (Required) A List of accepted cipher suites. Possible values are: `TLS_DHE_DSS_WITH_AES_128_CBC_SHA`, `TLS_DHE_DSS_WITH_AES_128_CBC_SHA256`, `TLS_DHE_DSS_WITH_AES_256_CBC_SHA`, `TLS_DHE_DSS_WITH_AES_256_CBC_SHA256`, `TLS_DHE_RSA_WITH_AES_128_CBC_SHA`, `TLS_DHE_RSA_WITH_AES_128_GCM_SHA256`, `TLS_DHE_RSA_WITH_AES_256_CBC_SHA`, `TLS_DHE_RSA_WITH_AES_256_GCM_SHA384`, `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA`, `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256`, `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`, `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA`, `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384`, `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384`, `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA`, `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256`, `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA`, `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384`, `TLS_RSA_WITH_3DES_EDE_CBC_SHA`, `TLS_RSA_WITH_AES_128_CBC_SHA`, `TLS_RSA_WITH_AES_128_CBC_SHA256`, `TLS_RSA_WITH_AES_128_GCM_SHA256`, `TLS_RSA_WITH_AES_256_CBC_SHA`, `TLS_RSA_WITH_AES_256_CBC_SHA256` and `TLS_RSA_WITH_AES_256_GCM_SHA384`. + +* `min_protocol_version` - (Required) The minimal TLS version. Possible values are `TLSv1_0`, `TLSv1_1` and `TLSv1_2`. + + + --- A `waf_configuration` block supports the following: @@ -375,8 +440,34 @@ A `waf_configuration` block supports the following: * `rule_set_version` - (Required) The Version of the Rule Set used for this Web Application Firewall. +* `disabled_rule_group` - (Optional) one or more `disabled_rule_group` blocks as defined below. + * `file_upload_limit_mb` - (Optional) The File Upload Limit in MB. Accepted values are in the range `1`MB to `500`MB. Defaults to `100`MB. +* `request_body_check` - (Optional) Is Request Body Inspection enabled? Defaults to `true`. + +* `max_request_body_size_kb` - (Optional) The Maximum Request Body Size in KB. Accepted values are in the range `1`KB to `128`KB. Defaults to `128`KB. + +* `exclusion` - (Optional) one or more `exclusion` blocks as defined below. + +--- + +A `disabled_rule_group` block supports the following: + +* `rule_group_name` - (Required) The rule group where specific rules should be disabled. Accepted values are: `crs_20_protocol_violations`, `crs_21_protocol_anomalies`, `crs_23_request_limits`, `crs_30_http_policy`, `crs_35_bad_robots`, `crs_40_generic_attacks`, `crs_41_sql_injection_attacks`, `crs_41_xss_attacks`, `crs_42_tight_security`, `crs_45_trojans`, `General`, `REQUEST-911-METHOD-ENFORCEMENT`, `REQUEST-913-SCANNER-DETECTION`, `REQUEST-920-PROTOCOL-ENFORCEMENT`, `REQUEST-921-PROTOCOL-ATTACK`, `REQUEST-930-APPLICATION-ATTACK-LFI`, `REQUEST-931-APPLICATION-ATTACK-RFI`, `REQUEST-932-APPLICATION-ATTACK-RCE`, `REQUEST-933-APPLICATION-ATTACK-PHP`, `REQUEST-941-APPLICATION-ATTACK-XSS`, `REQUEST-942-APPLICATION-ATTACK-SQLI`, `REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION` + +* `rules` - (Optional) A list of rules which should be disabled in that group. Disables all rules in the specified group if `rules` is not specified. + +--- + +A `exclusion` block supports the following: + +* `match_variable` - (Required) Match variable of the exclusion rule to exclude header, cookie or GET arguments. Possible values are `RequestHeaderNames`, `RequestArgNames` and `RequestCookieNames` + +* `selector_match_operator` - (Optional) Operator which will be used to search in the variable content. Possible values are `Equals`, `StartsWith`, `EndsWith`, `Contains`. If empty will exclude all traffic on this `match_variable` + +* `selector` - (Optional) String value which will be used for the filter operation. If empty will exclude all traffic on this `match_variable` + --- A `custom_error_configuration` block supports the following: @@ -385,6 +476,80 @@ A `custom_error_configuration` block supports the following: * `custom_error_page_url` - (Required) Error page URL of the application gateway customer error. +--- + +A `redirect_configuration` block supports the following: + +* `name` - (Required) Unique name of the redirect configuration block + +* `redirect_type` - (Required) The type of redirect. Possible values are `Permanent`, `Temporary`, `Found` and `SeeOther` + +* `target_listener_name` - (Optional) The name of the listener to redirect to. Cannot be set if `target_url` is set. + +* `target_url` - (Optional) The Url to redirect the request to. Cannot be set if `target_listener_name` is set. + +* `include_path` - (Optional) Whether or not to include the path in the redirected Url. Defaults to `false` + +* `include_query_string` - (Optional) Whether or not to include the query string in the redirected Url. Default to `false` + +--- + +A `autoscale_configuration` block supports the following: + +* `min_capacity` - (Required) Minimum capacity for autoscaling. + +* `max_capacity` - (Optional) Maximum capacity for autoscaling. + +--- + +A `rewrite_rule_set` block supports the following: + +* `name` - (Required) Unique name of the rewrite rule set block + +* `rewrite_rule` - (Required) One or more `rewrite_rule` blocks as defined above. + +--- + +A `rewrite_rule` block supports the following: + +* `name` - (Required) Unique name of the rewrite rule block + +* `rule_sequence` - (Required) Rule sequence of the rewrite rule that determines the order of execution in a set. + +* `condition` - (Optional) One or more `condition` blocks as defined above. + +* `request_header_configuration` - (Optional) One or more `request_header_configuration` blocks as defined above. + +* `response_header_configuration` - (Optional) One or more `response_header_configuration` blocks as defined above. + +--- + +A `condition` block supports the following: + +* `variable` - (Required) The [variable](https://docs.microsoft.com/en-us/azure/application-gateway/rewrite-http-headers#server-variables) of the condition. + +* `pattern` - (Required) The pattern, either fixed string or regular expression, that evaluates the truthfulness of the condition. + +* `ignore_case` - (Optional) Perform a case in-sensitive comparison. Defaults to `false` + +* `negate` - (Optional) Negate the result of the condition evaluation. Defaults to `false` + +--- + +A `request_header_configuration` block supports the following: + +* `header_name` - (Required) Header name of the header configuration. + +* `header_value` - (Required) Header value of the header configuration. + +--- + +A `response_header_configuration` block supports the following: + +* `header_name` - (Required) Header name of the header configuration. + +* `header_value` - (Required) Header value of the header configuration. + ## Attributes Reference The following attributes are exported: @@ -403,7 +568,7 @@ The following attributes are exported: * `gateway_ip_configuration` - A list of `gateway_ip_configuration` blocks as defined below. -* `http2_enabled` - (Optional) Is HTTP2 enabled on the application gateway resource? Defaults to `false`. +* `enable_http2` - (Optional) Is HTTP2 enabled on the application gateway resource? Defaults to `false`. * `http_listener` - A list of `http_listener` blocks as defined below. @@ -417,6 +582,8 @@ The following attributes are exported: * `custom_error_configuration` - A list of `custom_error_configuration` blocks as defined below. +* `redirect_configuration` - A list of `redirect_configuration` blocks as defined below. + --- A `authentication_certificate` block exports the following: @@ -483,6 +650,10 @@ A `path_rule` block exports the following: * `backend_http_settings_id` - The ID of the Backend HTTP Settings Collection used in this Path Rule. +* `redirect_configuration_id` - The ID of the Redirect Configuration used in this Path Rule. + +* `rewrite_rule_set_id` - The ID of the Rewrite Rule Set used in this Path Rule. + --- A `probe` block exports the following: @@ -501,6 +672,10 @@ A `request_routing_rule` block exports the following: * `backend_http_settings_id` - The ID of the associated Backend HTTP Settings Configuration. +* `redirect_configuration_id` - The ID of the associated Redirect Configuration. + +* `rewrite_rule_set_id` - The ID of the associated Rewrite Rule Set. + * `url_path_map_id` - The ID of the associated URL Path Map. --- @@ -521,6 +696,8 @@ A `url_path_map` block exports the following: * `default_backend_http_settings_id` - The ID of the Default Backend HTTP Settings Collection. +* `default_redirect_configuration_id` - The ID of the Default Redirect Configuration. + * `path_rule` - A list of `path_rule` blocks as defined above. --- @@ -529,6 +706,18 @@ A `custom_error_configuration` block exports the following: * `id` - The ID of the Custom Error Configuration. +--- + +A `redirect_configuration` block exports the following: + +* `id` - The ID of the Redirect Configuration. + +--- + +A `rewrite_rule_set` block exports the following: + +* `id` - The ID of the Rewrite Rule Set + ## Import Application Gateway's can be imported using the `resource id`, e.g. diff --git a/website/docs/r/application_insights.html.markdown b/website/docs/r/application_insights.html.markdown index ebfa9f5181d3..78eaac3a8dae 100644 --- a/website/docs/r/application_insights.html.markdown +++ b/website/docs/r/application_insights.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_application_insights -Manage an Application Insights component. +Manages an Application Insights component. ## Example Usage @@ -22,7 +22,7 @@ resource "azurerm_application_insights" "test" { name = "tf-test-appinsights" location = "West Europe" resource_group_name = "${azurerm_resource_group.test.name}" - application_type = "Web" + application_type = "web" } output "instrumentation_key" { @@ -46,7 +46,7 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `application_type` - (Required) Specifies the type of Application Insights to create. Valid values are `Java`, `iOS`, `MobileCenter`, `Other`, `Phone`, `Store`, `Web` and `Node.JS`. +* `application_type` - (Required) Specifies the type of Application Insights to create. Valid values are `ios` for _iOS_, `java` for _Java web_, `MobileCenter` for _App Center_, `Node.JS` for _Node.js_, `other` for _General_, `phone` for _Windows Phone_, `store` for _Windows Store_ and `web` for _ASP.NET_. Please note these values are case sensitive; unmatched values are treated as _ASP.NET_ by Azure. Changing this forces a new resource to be created. * `tags` - (Optional) A mapping of tags to assign to the resource. diff --git a/website/docs/r/application_insights_api_key.html.markdown b/website/docs/r/application_insights_api_key.html.markdown index 3550e5634449..d4622ce806d9 100644 --- a/website/docs/r/application_insights_api_key.html.markdown +++ b/website/docs/r/application_insights_api_key.html.markdown @@ -22,7 +22,7 @@ resource "azurerm_application_insights" "test" { name = "tf-test-appinsights" location = "West Europe" resource_group_name = "${azurerm_resource_group.test.name}" - application_type = "Web" + application_type = "web" } resource "azurerm_application_insights_api_key" "read_telemetry" { diff --git a/website/docs/r/application_insights_web_test.html.markdown b/website/docs/r/application_insights_web_test.html.markdown new file mode 100644 index 000000000000..a97e4d174c64 --- /dev/null +++ b/website/docs/r/application_insights_web_test.html.markdown @@ -0,0 +1,96 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_application_insights_web_test" +sidebar_current: "docs-azurerm-resource-application-insights-web-test" +description: |- + Manages an Application Insights WebTest. +--- + +# azurerm_application_insights_web_test + +Manages an Application Insights WebTest. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "tf-test" + location = "West Europe" +} + +resource "azurerm_application_insights" "test" { + name = "tf-test-appinsights" + location = "West Europe" + resource_group_name = "${azurerm_resource_group.test.name}" + application_type = "web" +} + +resource "azurerm_application_insights_web_test" "test" { + name = "tf-test-appinsights-webtest" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_insights_id = "${azurerm_application_insights.test.id}" + kind = "ping" + frequency = 300 + timeout = 60 + enabled = true + geo_locations = ["us-tx-sn1-azr", "us-il-ch1-azr"] + + configuration = <<XML +<WebTest Name="WebTest1" Id="ABD48585-0831-40CB-9069-682EA6BB3583" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="0" WorkItemIds="" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="default" StopOnError="False" RecordedResultFile="" ResultsLocale=""> + <Items> + <Request Method="GET" Guid="a5f10126-e4cd-570d-961c-cea43999a200" Version="1.1" Url="http://microsoft.com" ThinkTime="0" Timeout="300" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="200" ExpectedResponseUrl="" ReportingName="" IgnoreHttpStatusCode="False" /> + </Items> +</WebTest> +XML +} + +output "webtest_id" { + value = "${azurerm_application_insights_web_test.test.id}" +} + +output "webtest_provisioning_state" { + value = "${azurerm_application_insights_web_test.test.provisioning_state}" +} + +output "webtests_synthetic_id" { + value = "${azurerm_application_insights_web_test.test.synthetic_monitor_id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Application Insights WebTest. Changing this forces a + new resource to be created. + +* `application_insights_id` - (Required) The ID of the Application Insights component on which the WebTest operates. Changing this forces a new resource to be created. + +* `location` - (Required) The location of the resource group. + +* `kind` = (Required) The kind of web test that this web test watches. Choices are `ping` and `multistep`. + +* `geo_locations` - (Required) A list of where to physically run the tests from to give global coverage for accessibility of your application. + +* `configuration` - (Required) An XML configuration specification for a WebTest. + +* `frequency` - (Optional) Interval in seconds between test runs for this WebTest. Default is `300`. + +* `timeout` - (Optional) Seconds until this WebTest will timeout and fail. Default is `30`. + +* `enabled` - (Optional) Is the test actively being monitored. + +* `retry_enabled` - (Optional) Allow for retries should this WebTest fail. + +* `description` - (Optional) Purpose/user defined descriptive test for this WebTest. + +* `tags` - (Optional) Resource tags. + +## Import + +Application Insights Web Tests can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_application_insights_web_test.my_test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/microsoft.insights/webtests/my_test +``` diff --git a/website/docs/r/application_insights_web_tests.html.markdown b/website/docs/r/application_insights_web_tests.html.markdown new file mode 100644 index 000000000000..845ad58bf148 --- /dev/null +++ b/website/docs/r/application_insights_web_tests.html.markdown @@ -0,0 +1,96 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_application_insights_web_test" +sidebar_current: "docs-azurerm-resource-application-insights-webtests" +description: |- + Manages an Application Insights WebTest. +--- + +# azurerm_application_insights_web_test + +Manages an Application Insights WebTest. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "tf-test" + location = "West Europe" +} + +resource "azurerm_application_insights" "test" { + name = "tf-test-appinsights" + location = "West Europe" + resource_group_name = "${azurerm_resource_group.test.name}" + application_type = "web" +} + +resource "azurerm_application_insights_web_test" "test" { + name = "tf-test-appinsights-webtest" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + application_insights_id = "${azurerm_application_insights.test.id}" + kind = "ping" + frequency = 300 + timeout = 60 + enabled = true + geo_locations = ["us-tx-sn1-azr", "us-il-ch1-azr"] + + configuration = <<XML +<WebTest Name="WebTest1" Id="ABD48585-0831-40CB-9069-682EA6BB3583" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="0" WorkItemIds="" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="default" StopOnError="False" RecordedResultFile="" ResultsLocale=""> + <Items> + <Request Method="GET" Guid="a5f10126-e4cd-570d-961c-cea43999a200" Version="1.1" Url="http://microsoft.com" ThinkTime="0" Timeout="300" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="200" ExpectedResponseUrl="" ReportingName="" IgnoreHttpStatusCode="False" /> + </Items> +</WebTest> +XML +} + +output "webtest_id" { + value = "${azurerm_application_insights_web_test.test.id}" +} + +output "webtest_provisioning_state" { + value = "${azurerm_application_insights_web_test.test.provisioning_state}" +} + +output "webtests_synthetic_id" { + value = "${azurerm_application_insights_web_test.test.synthetic_monitor_id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Application Insights WebTest. Changing this forces a + new resource to be created. + +* `application_insights_id` - (Required) The ID of the Application Insights component on which the WebTest operates. Changing this forces a new resource to be created. + +* `location` - (Required) The location of the resource group. + +* `kind` = (Required) The kind of web test that this web test watches. Choices are `ping` and `multistep`. + +* `geo_locations` - (Required) A list of where to physically run the tests from to give global coverage for accessibility of your application. + +* `configuration` - (Required) An XML configuration specification for a WebTest. + +* `frequency` - (Optional) Interval in seconds between test runs for this WebTest. Default is `300`. + +* `timeout` - (Optional) Seconds until this WebTest will timeout and fail. Default is `30`. + +* `enabled` - (Optional) Is the test actively being monitored. + +* `retry_enabled` - (Optional) Allow for retries should this WebTest fail. + +* `description` - (Optional) Purpose/user defined descriptive test for this WebTest. + +* `tags` - (Optional) Resource tags. + +## Import + +Application Insights Web Tests can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_application_insights_web_test.my_test/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/microsoft.insights/webtests/my_test +``` diff --git a/website/docs/r/application_security_group.html.markdown b/website/docs/r/application_security_group.html.markdown index dd4cd5dd9894..b15c951d7b82 100644 --- a/website/docs/r/application_security_group.html.markdown +++ b/website/docs/r/application_security_group.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_application_security_group -Manage an Application Security Group. +Manages an Application Security Group. ## Example Usage @@ -24,7 +24,7 @@ resource "azurerm_application_security_group" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tags = { - "Hello" = "World" + Hello = "World" } } ``` diff --git a/website/docs/r/automation_account.html.markdown b/website/docs/r/automation_account.html.markdown index d3918d9bd194..a90d54630e86 100644 --- a/website/docs/r/automation_account.html.markdown +++ b/website/docs/r/automation_account.html.markdown @@ -23,10 +23,8 @@ resource "azurerm_automation_account" "example" { location = "${azurerm_resource_group.example.location}" resource_group_name = "${azurerm_resource_group.example.name}" - sku { - name = "Basic" - } - + sku_name = "Basic" + tags = { environment = "development" } @@ -43,13 +41,19 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `sku` - (Required) A `sku` block as defined below. +* `sku` - (Optional **Deprecated**)) A `sku` block as described below. + +* `sku_name` - (Optional) The SKU name of the account - only `Basic` is supported at this time. * `tags` - (Optional) A mapping of tags to assign to the resource. -`sku` supports the following: +---- + +A `sku` block supports the following: + +* `name` - (Required) The SKU name of the account - only `Basic` is supported at this time. -* `name` - (Optional) The SKU name of the account - only `Basic` is supported at this time. Defaults to `Basic`. +---- ## Attributes Reference diff --git a/website/docs/r/automation_schedule.html.markdown b/website/docs/r/automation_schedule.html.markdown index 0570d9e5bbb1..4e729df8c492 100644 --- a/website/docs/r/automation_schedule.html.markdown +++ b/website/docs/r/automation_schedule.html.markdown @@ -37,10 +37,7 @@ resource "azurerm_automation_schedule" "example" { timezone = "Central Europe Standard Time" start_time = "2014-04-15T18:00:15+02:00" description = "This is an example schedule" - - advanced_schedule { - week_days = ["Friday"] - } + week_days = ["Friday"] } ``` diff --git a/website/docs/r/automation_variable_bool.html.markdown b/website/docs/r/automation_variable_bool.html.markdown new file mode 100644 index 000000000000..f570eac73654 --- /dev/null +++ b/website/docs/r/automation_variable_bool.html.markdown @@ -0,0 +1,69 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_automation_variable_bool" +sidebar_current: "docs-azurerm-resource-automation-variable-bool" +description: |- + Manages a boolean variable in Azure Automation. +--- + +# azurerm_automation_variable_bool + +Manages a boolean variable in Azure Automation + + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "tfex-example-rg" + location = "West US" +} + +resource "azurerm_automation_account" "example" { + name = "tfex-example-account" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_bool" "example" { + name = "tfex-example-var" + resource_group_name = "${azurerm_resource_group.example.name}" + automation_account_name = "${azurerm_automation_account.example.name}" + value = false +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Automation Variable. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Automation Variable. Changing this forces a new resource to be created. + +* `automation_account_name` - (Required) The name of the automation account in which the Variable is created. Changing this forces a new resource to be created. + +* `description` - (Optional) The description of the Automation Variable. + +* `encrypted` - (Optional) Specifies if the Automation Variable is encrypted. Defaults to `false`. + +* `value` - (Optional) The value of the Automation Variable as a `boolean`. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Automation Variable. + + +## Import + +Automation Bool Variable can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_automation_variable_bool.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfex-example-rg/providers/Microsoft.Automation/automationAccounts/tfex-example-account/variables/tfex-example-var +``` diff --git a/website/docs/r/automation_variable_datetime.html.markdown b/website/docs/r/automation_variable_datetime.html.markdown new file mode 100644 index 000000000000..13d3ced0442d --- /dev/null +++ b/website/docs/r/automation_variable_datetime.html.markdown @@ -0,0 +1,69 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_automation_variable_datetime" +sidebar_current: "docs-azurerm-resource-automation-variable-datetime" +description: |- + Manages a date/time variable in Azure Automation. +--- + +# azurerm_automation_variable_datetime + +Manages a date/time variable in Azure Automation + + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "tfex-example-rg" + location = "West US" +} + +resource "azurerm_automation_account" "example" { + name = "tfex-example-account" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_datetime" "example" { + name = "tfex-example-var" + resource_group_name = "${azurerm_resource_group.example.name}" + automation_account_name = "${azurerm_automation_account.example.name}" + value = "2019-04-24T21:40:54.074Z" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Automation Variable. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Automation Variable. Changing this forces a new resource to be created. + +* `automation_account_name` - (Required) The name of the automation account in which the Variable is created. Changing this forces a new resource to be created. + +* `description` - (Optional) The description of the Automation Variable. + +* `encrypted` - (Optional) Specifies if the Automation Variable is encrypted. Defaults to `false`. + +* `value` - (Optional) The value of the Automation Variable in the [RFC3339 Section 5.6 Internet Date/Time Format](https://tools.ietf.org/html/rfc3339#section-5.6). + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Automation Variable. + + +## Import + +Automation Datetime Variable can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_automation_variable_datetime.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfex-example-rg/providers/Microsoft.Automation/automationAccounts/tfex-example-account/variables/tfex-example-var +``` diff --git a/website/docs/r/automation_variable_int.html.markdown b/website/docs/r/automation_variable_int.html.markdown new file mode 100644 index 000000000000..3b1a14bd974d --- /dev/null +++ b/website/docs/r/automation_variable_int.html.markdown @@ -0,0 +1,69 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_automation_variable_int" +sidebar_current: "docs-azurerm-resource-automation-variable-int" +description: |- + Manages a integer variable in Azure Automation. +--- + +# azurerm_automation_variable_int + +Manages a integer variable in Azure Automation + + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "tfex-example-rg" + location = "West US" +} + +resource "azurerm_automation_account" "example" { + name = "tfex-example-account" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_int" "example" { + name = "tfex-example-var" + resource_group_name = "${azurerm_resource_group.example.name}" + automation_account_name = "${azurerm_automation_account.example.name}" + value = 1234 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Automation Variable. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Automation Variable. Changing this forces a new resource to be created. + +* `automation_account_name` - (Required) The name of the automation account in which the Variable is created. Changing this forces a new resource to be created. + +* `description` - (Optional) The description of the Automation Variable. + +* `encrypted` - (Optional) Specifies if the Automation Variable is encrypted. Defaults to `false`. + +* `value` - (Optional) The value of the Automation Variable as a `integer`. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Automation Variable. + + +## Import + +Automation Int Variable can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_automation_variable_int.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfex-example-rg/providers/Microsoft.Automation/automationAccounts/tfex-example-account/variables/tfex-example-var +``` diff --git a/website/docs/r/automation_variable_string.html.markdown b/website/docs/r/automation_variable_string.html.markdown new file mode 100644 index 000000000000..f46d0dbc357d --- /dev/null +++ b/website/docs/r/automation_variable_string.html.markdown @@ -0,0 +1,69 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_automation_variable_string" +sidebar_current: "docs-azurerm-resource-automation-variable-string" +description: |- + Manages a string variable in Azure Automation. +--- + +# azurerm_automation_variable_string + +Manages a string variable in Azure Automation + + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "tfex-example-rg" + location = "West US" +} + +resource "azurerm_automation_account" "example" { + name = "tfex-example-account" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + + sku { + name = "Basic" + } +} + +resource "azurerm_automation_variable_string" "example" { + name = "tfex-example-var" + resource_group_name = "${azurerm_resource_group.example.name}" + automation_account_name = "${azurerm_automation_account.example.name}" + value = "Hello, Terraform Basic Test." +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Automation Variable. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Automation Variable. Changing this forces a new resource to be created. + +* `automation_account_name` - (Required) The name of the automation account in which the Variable is created. Changing this forces a new resource to be created. + +* `description` - (Optional) The description of the Automation Variable. + +* `encrypted` - (Optional) Specifies if the Automation Variable is encrypted. Defaults to `false`. + +* `value` - (Optional) The value of the Automation Variable as a `string`. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Automation Variable. + + +## Import + +Automation String Variable can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_automation_variable_string.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfex-example-rg/providers/Microsoft.Automation/automationAccounts/tfex-example-account/variables/tfex-example-var +``` diff --git a/website/docs/r/azuread_application.html.markdown b/website/docs/r/azuread_application.html.markdown index 848b57e16c98..a404a1b85eca 100644 --- a/website/docs/r/azuread_application.html.markdown +++ b/website/docs/r/azuread_application.html.markdown @@ -13,7 +13,7 @@ Manages an Application within Azure Active Directory. ~> **NOTE:** The Azure Active Directory resources have been split out into [a new AzureAD Provider](http://terraform.io/docs/providers/azuread/index.html) - as such the AzureAD resources within the AzureRM Provider are deprecated and will be removed in the next major version (2.0). Information on how to migrate from the existing resources to the new AzureAD Provider [can be found here](../guides/migrating-to-azuread.html). --> **NOTE:** If you're authenticating using a Service Principal then it must have permissions to both `Read and write all applications` and `Sign in and read user profile` within the `Windows Azure Active Directory` API. +-> **NOTE:** If you're authenticating using a Service Principal then it must have permissions to both `Read and write all applications` and `Sign in and read user profile` within the legacy `Windows Azure Active Directory` API. ## Example Usage diff --git a/website/docs/r/batch_account.html.markdown b/website/docs/r/batch_account.html.markdown index 749a61bd8533..7a8944b52881 100644 --- a/website/docs/r/batch_account.html.markdown +++ b/website/docs/r/batch_account.html.markdown @@ -48,14 +48,32 @@ The following arguments are supported: * `resource_group_name` - (Required) The name of the resource group in which to create the Batch account. Changing this forces a new resource to be created. +~> **NOTE:** To work around [a bug in the Azure API](https://github.com/Azure/azure-rest-api-specs/issues/5574) this property is currently treated as case-insensitive. A future version of Terraform will require that the casing is correct. + * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. * `pool_allocation_mode` - (Optional) Specifies the mode to use for pool allocation. Possible values are `BatchService` or `UserSubscription`. Defaults to `BatchService`. +~> **NOTE:** When using `UserSubscription` mode, an Azure KeyVault reference has to be specified. See `key_vault_reference` below. + +~> **NOTE:** When using `UserSubscription` mode, the `Microsoft Azure Batch` service principal has to have `Contributor` role on your subscription scope, as documented [here](https://docs.microsoft.com/en-us/azure/batch/batch-account-create-portal#additional-configuration-for-user-subscription-mode). + +* `key_vault_reference` - (Optional) A `key_vault_reference` block that describes the Azure KeyVault reference to use when deploying the Azure Batch account using the `UserSubscription` pool allocation mode. + * `storage_account_id` - (Optional) Specifies the storage account to use for the Batch account. If not specified, Azure Batch will manage the storage. * `tags` - (Optional) A mapping of tags to assign to the resource. +--- + +A `key_vault_reference` block supports the following: + +* `id` - (Required) The Azure identifier of the Azure KeyVault to use. + +* `url` - (Required) The HTTPS URL of the Azure KeyVault to use. + +--- + ## Attributes Reference The following attributes are exported: @@ -68,4 +86,4 @@ The following attributes are exported: * `account_endpoint` - The account endpoint used to interact with the Batch service. -~> **NOTE:** Primary and secondary access keys are only available when `pool_allocation_mode` is set to `BatchService`. See [documentation](https://docs.microsoft.com/en-us/azure/batch/batch-api-basics) for more information. \ No newline at end of file +~> **NOTE:** Primary and secondary access keys are only available when `pool_allocation_mode` is set to `BatchService`. See [documentation](https://docs.microsoft.com/en-us/azure/batch/batch-api-basics) for more information. diff --git a/website/docs/r/batch_application.html.markdown b/website/docs/r/batch_application.html.markdown new file mode 100644 index 000000000000..829e45e430ae --- /dev/null +++ b/website/docs/r/batch_application.html.markdown @@ -0,0 +1,73 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_batch_application" +sidebar_current: "docs-azurerm-resource-batch-application" +description: |- + Manages Azure Batch Application instance. +--- + +# azurerm_batch_application + +Manages Azure Batch Application instance. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-rg" + location = "West US" +} + +resource "azurerm_storage_account" "example" { + name = "examplesa" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_batch_account" "example" { + name = "exampleba" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + pool_allocation_mode = "BatchService" + storage_account_id = "${azurerm_storage_account.example.id}" +} + +resource "azurerm_batch_application" "example" { + name = "example-batch-application" + resource_group_name = "${azurerm_resource_group.example.name}" + account_name = "${azurerm_batch_account.example.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the application. This must be unique within the account. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group that contains the Batch account. Changing this forces a new resource to be created. + +* `account_name` - (Required) The name of the Batch account. Changing this forces a new resource to be created. + +* `allow_updates` - (Optional) A value indicating whether packages within the application may be overwritten using the same version string. Defaults to `true`. + +* `default_version` - (Optional) The package to use if a client requests the application but does not specify a version. This property can only be set to the name of an existing package. + +* `display_name` - (Optional) The display name for the application. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the resource. + + +## Import + +Batch Application can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_batch_application.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Batch/batchAccounts/exampleba/applications/example-batch-application +``` diff --git a/website/docs/r/batch_certificate.html.markdown b/website/docs/r/batch_certificate.html.markdown new file mode 100644 index 000000000000..9720f7418b39 --- /dev/null +++ b/website/docs/r/batch_certificate.html.markdown @@ -0,0 +1,77 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_batch_certificate" +sidebar_current: "docs-azurerm-resource-batch-certificate" +description: |- + Manages a certificate in an Azure Batch account. + +--- + +# azurerm_batch_certificate + +Manages a certificate in an Azure Batch account. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "testbatch" + location = "westeurope" +} + +resource "azurerm_storage_account" "test" { + name = "teststorage" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_batch_account" "test" { + name = "testbatchaccount" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + pool_allocation_mode = "BatchService" + storage_account_id = "${azurerm_storage_account.test.id}" + + tags = { + env = "test" + } +} + +resource "azurerm_batch_certificate" "test" { + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + certificate = "${filebase64("certificate.pfx")}" + format = "Pfx" + password = "terraform" + thumbprint = "42C107874FD0E4A9583292A2F1098E8FE4B2EDDA" + thumbprint_algorithm = "SHA1" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `account_name` - (Required) Specifies the name of the Batch account. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Batch account. Changing this forces a new resource to be created. + +* `certificate` - (Required) The base64-encoded contents of the certificate. + +* `format` - (Required) The format of the certificate. Possible values are `Cer` or `Pfx`. + +* `password` - (Optional) The password to access the certificate's private key. This must and can only be specified when `format` is `Pfx`. + +* `thumbprint` - (Required) The thumbprint of the certificate. At this time the only supported value is 'SHA1'. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Batch certificate ID. + +* `name` - The generated name of the certificate. + +* `public_data` - The public key of the certificate. diff --git a/website/docs/r/batch_pool.html.markdown b/website/docs/r/batch_pool.html.markdown index 052648ec4e9d..0c1cc07ecbd9 100644 --- a/website/docs/r/batch_pool.html.markdown +++ b/website/docs/r/batch_pool.html.markdown @@ -16,7 +16,7 @@ Manages an Azure Batch pool. ```hcl resource "azurerm_resource_group" "test" { name = "testaccbatch" - location = "%s" + location = "West Europe" } resource "azurerm_storage_account" "test" { @@ -39,6 +39,15 @@ resource "azurerm_batch_account" "test" { } } +resource "azurerm_batch_certificate" "testcer" { + resource_group_name = "${azurerm_resource_group.test.name}" + account_name = "${azurerm_batch_account.test.name}" + certificate = "${filebase64("certificate.cer")}" + format = "Cer" + thumbprint = "312d31a79fa0cef49c00f769afc2b73e9f4edf34" + thumbprint_algorithm = "SHA1" +} + resource "azurerm_batch_pool" "test" { name = "testaccpool" resource_group_name = "${azurerm_resource_group.test.name}" @@ -49,7 +58,8 @@ resource "azurerm_batch_pool" "test" { auto_scale { evaluation_interval = "PT15M" - formula = <<EOF + + formula = <<EOF startingNumberOfVMs = 1; maxNumberofVMs = 25; pendingTaskSamplePercent = $PendingTasks.GetSamplePercent(180 * TimeInterval_Second); @@ -59,12 +69,23 @@ EOF } storage_image_reference { - publisher = "Canonical" - offer = "UbuntuServer" - sku = "16.04.0-LTS" + publisher = "microsoft-azure-batch" + offer = "ubuntu-server-container" + sku = "16-04-lts" version = "latest" } + container_configuration { + type = "DockerCompatible" + container_registries = [ + { + registry_server = "docker.io" + user_name = "login" + password = "apassword" + }, + ] + } + start_task { command_line = "echo 'Hello World from $env'" max_task_retry_count = 1 @@ -81,6 +102,11 @@ EOF } } } + + certificate { + id = "${azurerm_batch_certificate.testcer.id}" + visibility = ["StartTask"] + } } ``` @@ -92,6 +118,8 @@ The following arguments are supported: * `resource_group_name` - (Required) The name of the resource group in which to create the Batch pool. Changing this forces a new resource to be created. +~> **NOTE:** To work around [a bug in the Azure API](https://github.com/Azure/azure-rest-api-specs/issues/5574) this property is currently treated as case-insensitive. A future version of Terraform will require that the casing is correct. + * `account_name` - (Required) Specifies the name of the Batch account in which the pool will be created. Changing this forces a new resource to be created. * `node_agent_sku_id` - (Required) Specifies the Sku of the node agents that will be created in the Batch pool. @@ -110,8 +138,32 @@ The following arguments are supported: * `start_task` - (Optional) A `start_task` block that describes the start task settings for the Batch pool. +* `certificate` - (Optional) One or more `certificate` blocks that describe the certificates to be installed on each compute node in the pool. + +* `container_configuration` - (Optional) The container configuration used in the pool's VMs. + +-> **NOTE:** For Windows compute nodes, the Batch service installs the certificates to the specified certificate store and location. For Linux compute nodes, the certificates are stored in a directory inside the task working directory and an environment variable `AZ_BATCH_CERTIFICATES_DIR` is supplied to the task to query for this location. For certificates with visibility of `remoteUser`, a `certs` directory is created in the user's home directory (e.g., `/home/{user-name}/certs`) and certificates are placed in that directory. + ~> **Please Note:** `fixed_scale` and `auto_scale` blocks cannot be used both at the same time. +--- +A `storage_image_reference` block supports the following: + +This block provisions virtual machines in the Batch Pool from one of two sources: an Azure Platform Image (e.g. Ubuntu/Windows Server) or a Custom Image. + +To provision from an Azure Platform Image, the following fields are applicable: + +* `publisher` - (Required) Specifies the publisher of the image used to create the virtual machines. Changing this forces a new resource to be created. + +* `offer` - (Required) Specifies the offer of the image used to create the virtual machines. Changing this forces a new resource to be created. + +* `sku` - (Required) Specifies the SKU of the image used to create the virtual machines. Changing this forces a new resource to be created. + +* `version` - (Optional) Specifies the version of the image used to create the virtual machines. Changing this forces a new resource to be created. + +To provision a Custom Image, the following fields are applicable: + +* `id` - (Required) Specifies the ID of the Custom Image which the virtual machines should be created from. Changing this forces a new resource to be created. See [official documentation](https://docs.microsoft.com/en-us/azure/batch/batch-custom-images) for more details. --- A `fixed_scale` block supports the following: @@ -132,7 +184,7 @@ A `auto_scale` block supports the following: --- -A `start_task` block exports the following: +A `start_task` block supports the following: * `command_line` - (Required) The command line executed by the start task. @@ -144,9 +196,11 @@ A `start_task` block exports the following: * `user_identity` - (Required) A `user_identity` block that describes the user identity under which the start task runs. +* `resource_file` - (Optional) One or more `resource_file` blocks that describe the files to be downloaded to a compute node. + --- -A `user_identity` block exports the following: +A `user_identity` block supports the following: * `user_name` - (Optional) The username to be used by the Batch pool start task. @@ -156,12 +210,62 @@ A `user_identity` block exports the following: --- -A `auto_user` block exports the following: +A `auto_user` block supports the following: * `elevation_level` - (Optional) The elevation level of the user identity under which the start task runs. Possible values are `Admin` or `NonAdmin`. Defaults to `NonAdmin`. * `scope` - (Optional) The scope of the user identity under which the start task runs. Possible values are `Task` or `Pool`. Defaults to `Task`. +--- + +A `certificate` block supports the following: + +* `id` - (Required) The ID of the Batch Certificate to install on the Batch Pool, which must be inside the same Batch Account. + +* `store_location` - (Required) The location of the certificate store on the compute node into which to install the certificate. Possible values are `CurrentUser` or `LocalMachine`. + + -> **NOTE:** This property is applicable only for pools configured with Windows nodes (that is, created with cloudServiceConfiguration, or with virtualMachineConfiguration using a Windows image reference). For Linux compute nodes, the certificates are stored in a directory inside the task working directory and an environment variable `AZ_BATCH_CERTIFICATES_DIR` is supplied to the task to query for this location. For certificates with visibility of `remoteUser`, a 'certs' directory is created in the user's home directory (e.g., `/home/{user-name}/certs`) and certificates are placed in that directory. + +* `store_name` - (Optional) The name of the certificate store on the compute node into which to install the certificate. This property is applicable only for pools configured with Windows nodes (that is, created with cloudServiceConfiguration, or with virtualMachineConfiguration using a Windows image reference). Common store names include: `My`, `Root`, `CA`, `Trust`, `Disallowed`, `TrustedPeople`, `TrustedPublisher`, `AuthRoot`, `AddressBook`, but any custom store name can also be used. The default value is `My`. + +* `visibility` - (Optional) Which user accounts on the compute node should have access to the private data of the certificate. + +--- + +A `container_configuration` block supports the following: + +* `type` - (Optional) The type of container configuration. Possible value is `DockerCompatible`. + +* `container_registries` - (Optional) Additional container registries from which container images can be pulled by the pool's VMs. + +--- + +A `resource_file` block supports the following: + +* `auto_storage_container_name` - (Optional) The storage container name in the auto storage account. + +* `blob_prefix` - (Optional) The blob prefix to use when downloading blobs from an Azure Storage container. Only the blobs whose names begin with the specified prefix will be downloaded. The property is valid only when `auto_storage_container_name` or `storage_container_url` is used. This prefix can be a partial filename or a subdirectory. If a prefix is not specified, all the files in the container will be downloaded. + +* `file_mode` - (Optional) The file permission mode represented as a string in octal format (e.g. `"0644"`). This property applies only to files being downloaded to Linux compute nodes. It will be ignored if it is specified for a `resource_file` which will be downloaded to a Windows node. If this property is not specified for a Linux node, then a default value of 0770 is applied to the file. + +* `file_path` - (Optional) The location on the compute node to which to download the file, relative to the task's working directory. If the `http_url` property is specified, the `file_path` is required and describes the path which the file will be downloaded to, including the filename. Otherwise, if the `auto_storage_container_name` or `storage_container_url` property is specified, `file_path` is optional and is the directory to download the files to. In the case where `file_path` is used as a directory, any directory structure already associated with the input data will be retained in full and appended to the specified filePath directory. The specified relative path cannot break out of the task's working directory (for example by using '..'). + +* `http_url` - (Optional) The URL of the file to download. If the URL is Azure Blob Storage, it must be readable using anonymous access; that is, the Batch service does not present any credentials when downloading the blob. There are two ways to get such a URL for a blob in Azure storage: include a Shared Access Signature (SAS) granting read permissions on the blob, or set the ACL for the blob or its container to allow public access. + +* `storage_container_url` - (Optional) The URL of the blob container within Azure Blob Storage. This URL must be readable and listable using anonymous access; that is, the Batch service does not present any credentials when downloading the blob. There are two ways to get such a URL for a blob in Azure storage: include a Shared Access Signature (SAS) granting read and list permissions on the blob, or set the ACL for the blob or its container to allow public access. + +~> **Please Note:** Exactly one of `auto_storage_container_name`, `storage_container_url` and `auto_user` must be specified. + +--- + +A `container_registries` block supports the following: + +* `registry_server` - (Optional) The container registry URL. The default is "docker.io". Changing this forces a new resource to be created. + +* `user_name` - (Optional) The user name to log into the registry server. Changing this forces a new resource to be created. + +* `password` - (Optional) The password to log into the registry server. Changing this forces a new resource to be created. + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/cdn_profile.html.markdown b/website/docs/r/cdn_profile.html.markdown index b5769998835b..8bc2e358955a 100644 --- a/website/docs/r/cdn_profile.html.markdown +++ b/website/docs/r/cdn_profile.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_cdn_profile -Manage a CDN Profile to create a collection of CDN Endpoints. +Manages a CDN Profile to create a collection of CDN Endpoints. ## Example Usage diff --git a/website/docs/r/cognitive_account.html.markdown b/website/docs/r/cognitive_account.html.markdown index d04af9b0c2a6..9cea8a61a5c2 100644 --- a/website/docs/r/cognitive_account.html.markdown +++ b/website/docs/r/cognitive_account.html.markdown @@ -45,7 +45,7 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `kind` - (Required) Specifies the type of Cognitive Service Account that should be created. Possible values are `Academic`, `Bing.Autosuggest`, `Bing.Autosuggest.v7`, `Bing.CustomSearch`, `Bing.Search`, `Bing.Search.v7`, `Bing.Speech`, `Bing.SpellCheck`, `Bing.SpellCheck.v7`, `ComputerVision`, `ContentModerator`, `CustomSpeech`, `Emotion`, `Face`, `LUIS`, `Recommendations`, `SpeakerRecognition`, `Speech`, `SpeechServices`, `SpeechTranslation`, `TextAnalytics`, `TextTranslation` and `WebLM`. Changing this forces a new resource to be created. +* `kind` - (Required) Specifies the type of Cognitive Service Account that should be created. Possible values are `Academic`, `Bing.Autosuggest`, `Bing.Autosuggest.v7`, `Bing.CustomSearch`, `Bing.Search`, `Bing.Search.v7`, `Bing.Speech`, `Bing.SpellCheck`, `Bing.SpellCheck.v7`, `ComputerVision`, `ContentModerator`, `CustomSpeech`, `CustomVision.Prediction`, `CustomVision.Training`, `Emotion`, `Face`, `LUIS`, `QnAMaker`, `Recommendations`, `SpeakerRecognition`, `Speech`, `SpeechServices`, `SpeechTranslation`, `TextAnalytics`, `TextTranslation` and `WebLM`. Changing this forces a new resource to be created. * `sku` - (Required) A `sku` block as defined below. diff --git a/website/docs/r/connection_monitor.html.markdown b/website/docs/r/connection_monitor.html.markdown index 22f347bd4e9b..9849b7e50ede 100644 --- a/website/docs/r/connection_monitor.html.markdown +++ b/website/docs/r/connection_monitor.html.markdown @@ -11,6 +11,8 @@ description: |- Configures a Connection Monitor to monitor communication between a Virtual Machine and an endpoint using a Network Watcher. +~> **NOTE:** This resource has been deprecated in favour of the `azurerm_network_connection_monitor` resource and will be removed in the next major version of the AzureRM Provider. The new resource shares the same fields as this one, and information on migrating across [can be found in this guide](../guides/migrating-between-renamed-resources.html). + ## Example Usage ```hcl diff --git a/website/docs/r/container_group.html.markdown b/website/docs/r/container_group.html.markdown index 47af628745d9..695d40256108 100644 --- a/website/docs/r/container_group.html.markdown +++ b/website/docs/r/container_group.html.markdown @@ -8,75 +8,36 @@ description: |- # azurerm_container_group -Manage as an Azure Container Group instance. +Manages as an Azure Container Group instance. ## Example Usage -```hcl -resource "azurerm_resource_group" "aci-rg" { - name = "aci-test" - location = "west us" -} - -resource "azurerm_storage_account" "aci-sa" { - name = "acistorageacct" - resource_group_name = "${azurerm_resource_group.aci-rg.name}" - location = "${azurerm_resource_group.aci-rg.location}" - account_tier = "Standard" - - account_replication_type = "LRS" -} - -resource "azurerm_storage_share" "aci-share" { - name = "aci-test-share" +This example provisions a Basic Container. Other examples of the `azurerm_container_group` resource can be found in [the `./examples/container-instance` directory within the Github Repository](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples/container-instance). - resource_group_name = "${azurerm_resource_group.aci-rg.name}" - storage_account_name = "${azurerm_storage_account.aci-sa.name}" - - quota = 50 +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" } -resource "azurerm_container_group" "aci-helloworld" { - name = "aci-hw" - location = "${azurerm_resource_group.aci-rg.location}" - resource_group_name = "${azurerm_resource_group.aci-rg.name}" +resource "azurerm_container_group" "example" { + name = "example-continst" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" ip_address_type = "public" dns_name_label = "aci-label" os_type = "Linux" container { - name = "hw" - image = "seanmckenna/aci-hellofiles" + name = "hello-world" + image = "microsoft/aci-helloworld:latest" cpu = "0.5" memory = "1.5" - ports = { - port = 80 - protocol = "TCP" - } + ports { port = 443 protocol = "TCP" } - - environment_variables = { - "NODE_ENV" = "testing" - } - - secure_environment_variables = { - "ACCESS_KEY" = "secure_testing" - } - - commands = ["/bin/bash", "-c", "'/path to/myscript.sh'"] - - volume { - name = "logs" - mount_path = "/aci/logs" - read_only = false - share_name = "${azurerm_storage_share.aci-share.name}" - - storage_account_name = "${azurerm_storage_account.aci-sa.name}" - storage_account_key = "${azurerm_storage_account.aci-sa.primary_access_key}" - } } container { @@ -102,25 +63,45 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `container` - (Required) The definition of a container that is part of the group as documented in the `container` block below. Changing this forces a new resource to be created. +* `identity` - (Optional) An `identity` block as defined below. + +~> **Note:** managed identities are not supported for containers in virtual networks. -~> **Note:** if `os_type` is set to `Windows` currently only a single `container` block is supported. +* `container` - (Required) The definition of a container that is part of the group as documented in the `container` block below. Changing this forces a new resource to be created. * `os_type` - (Required) The OS for the container group. Allowed values are `Linux` and `Windows`. Changing this forces a new resource to be created. +~> **Note:** if `os_type` is set to `Windows` currently only a single `container` block is supported. Windows containers are not supported in virtual networks. + --- * `diagnostics` - (Optional) A `diagnostics` block as documented below. -* `dns_name_label` - (Optional) The DNS label/name for the container groups IP. +* `dns_name_label` - (Optional) The DNS label/name for the container groups IP. Changing this forces a new resource to be created. + +~> **Note:** DNS label/name is not supported when deploying to virtual networks. + +* `ip_address_type` - (Optional) Specifies the ip address type of the container. `Public` or `Private`. Changing this forces a new resource to be created. If set to `Private`, `network_profile_id` also needs to be set. + +~> **Note:** `dns_name_label`, `identity` and `os_type` set to `windows` are not compatible with `Private` `ip_address_type` + +* `network_profile_id` - (Optional) Network profile ID for deploying to virtual network. + +* `image_registry_credential` - (Optional) A `image_registry_credential` block as documented below. Changing this forces a new resource to be created. + +* `restart_policy` - (Optional) Restart policy for the container group. Allowed values are `Always`, `Never`, `OnFailure`. Defaults to `Always`. Changing this forces a new resource to be created. + +* `tags` - (Optional) A mapping of tags to assign to the resource. Changing this forces a new resource to be created. -* `ip_address_type` - (Optional) Specifies the ip address type of the container. `Public` is the only acceptable value at this time. Changing this forces a new resource to be created. +--- + +An `identity` block supports the following: -* `image_registry_credential` - (Optional) A `image_registry_credential` block as documented below. +* `type` - (Required) The Managed Service Identity Type of this container group. Possible values are `SystemAssigned` (where Azure will generate a Service Principal for you), `UserAssigned` where you can specify the Service Principal IDs in the `identity_ids` field, and `SystemAssigned, UserAssigned` which assigns both a system managed identity as well as the specified user assigned identities. Changing this forces a new resource to be created. -* `restart_policy` - (Optional) Restart policy for the container group. Allowed values are `Always`, `Never`, `OnFailure`. Defaults to `Always`. +~> **NOTE:** When `type` is set to `SystemAssigned`, identity the Principal ID can be retrieved after the container group has been created. See [documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview) for more information. -* `tags` - (Optional) A mapping of tags to assign to the resource. +* `identity_ids` - (Optional) Specifies a list of user managed identity ids to be assigned. Required if `type` is `UserAssigned`. Changing this forces a new resource to be created. --- @@ -134,7 +115,7 @@ A `container` block supports: * `memory` - (Required) The required memory of the containers in GB. Changing this forces a new resource to be created. -* `gpu` - (Optional) A `gpu` block as defined below. +* `gpu` - (Optional) A `gpu` block as defined below. Changing this forces a new resource to be created. ~> **Note:** Gpu resources are currently only supported in Linux containers. @@ -144,11 +125,15 @@ A `container` block supports: * `secure_environment_variables` - (Optional) A list of sensitive environment variables to be set on the container. Specified as a map of name/value pairs. Changing this forces a new resource to be created. -* `command` - (Optional) A command line to be run on the container. +* `readiness_probe` - (Optional) The definition of a readiness probe for this container as documented in the `readiness_probe` block below. Changing this forces a new resource to be created. + +* `liveness_probe` - (Optional) The definition of a readiness probe for this container as documented in the `liveness_probe` block below. Changing this forces a new resource to be created. + +* `command` - (Optional) A command line to be run on the container. Changing this forces a new resource to be created. ~> **NOTE:** The field `command` has been deprecated in favor of `commands` to better match the API. -* `commands` - (Optional) A list of commands which should be run on the container. +* `commands` - (Optional) A list of commands which should be run on the container. Changing this forces a new resource to be created. * `volume` - (Optional) The definition of a volume mount for this container as documented in the `volume` block below. Changing this forces a new resource to be created. @@ -156,45 +141,45 @@ A `container` block supports: A `diagnostics` block supports: -* `log_analytics` - (Required) A `log_analytics` block as defined below. +* `log_analytics` - (Required) A `log_analytics` block as defined below. Changing this forces a new resource to be created. --- A `image_registry_credential` block supports: -* `username` - (Required) The username with which to connect to the registry. +* `username` - (Required) The username with which to connect to the registry. Changing this forces a new resource to be created. -* `password` - (Required) The password with which to connect to the registry. +* `password` - (Required) The password with which to connect to the registry. Changing this forces a new resource to be created. -* `server` - (Required) The address to use to connect to the registry without protocol ("https"/"http"). For example: "myacr.acr.io" +* `server` - (Required) The address to use to connect to the registry without protocol ("https"/"http"). For example: "myacr.acr.io". Changing this forces a new resource to be created. --- A `log_analytics` block supports: -* `log_type` - (Required) The log type which should be used. Possible values are `ContainerInsights` and `ContainerInstanceLogs`. +* `log_type` - (Optional) The log type which should be used. Possible values are `ContainerInsights` and `ContainerInstanceLogs`. Changing this forces a new resource to be created. -* `workspace_id` - (Required) The Workspace ID of the Log Analytics Workspace. +* `workspace_id` - (Required) The Workspace ID of the Log Analytics Workspace. Changing this forces a new resource to be created. -* `workspace_key` - (Required) The Workspace Key of the Log Analytics Workspace. +* `workspace_key` - (Required) The Workspace Key of the Log Analytics Workspace. Changing this forces a new resource to be created. -* `metadata` - (Optional) Any metadata required for Log Analytics. +* `metadata` - (Optional) Any metadata required for Log Analytics. Changing this forces a new resource to be created. --- A `ports` block supports: -* `port` - (Required) The port number the container will expose. +* `port` - (Required) The port number the container will expose. Changing this forces a new resource to be created. -* `protocol` - (Required) The network protocol associated with port. Possible values are `TCP` & `UDP`. +* `protocol` - (Required) The network protocol associated with port. Possible values are `TCP` & `UDP`. Changing this forces a new resource to be created. -- A `gpu` block supports: -* `count` - (Required) The number of GPUs which should be assigned to this container. Allowed values are `1`, `2`, or `4`. +* `count` - (Required) The number of GPUs which should be assigned to this container. Allowed values are `1`, `2`, or `4`. Changing this forces a new resource to be created. -* `sku` - (Required) The Sku which should be used for the GPU. Possible values are `K80`, `P100`, or `V100`. +* `sku` - (Required) The Sku which should be used for the GPU. Possible values are `K80`, `P100`, or `V100`. Changing this forces a new resource to be created. --- @@ -212,6 +197,52 @@ A `volume` block supports: * `share_name` - (Required) The Azure storage share that is to be mounted as a volume. This must be created on the storage account specified as above. Changing this forces a new resource to be created. +--- + +The `readiness_probe` block supports: + +* `exec` - (Optional) Commands to be run to validate container readiness. Changing this forces a new resource to be created. + +* `httpget` - (Optional) The definition of the httpget for this container as documented in the `httpget` block below. Changing this forces a new resource to be created. + +* `initial_delay_seconds` - (Optional) Number of seconds after the container has started before liveness or readiness probes are initiated. Changing this forces a new resource to be created. + +* `period_seconds` - (Optional) How often (in seconds) to perform the probe. The default value is `10` and the minimum value is `1`. Changing this forces a new resource to be created. + +* `failure_threshold` - (Optional) How many times to try the probe before restarting the container (liveness probe) or marking the container as unhealthy (readiness probe). The default value is `3` and the minimum value is `1`. Changing this forces a new resource to be created. + +* `success_threshold` - (Optional) Minimum consecutive successes for the probe to be considered successful after having failed. The default value is `1` and the minimum value is `1`. Changing this forces a new resource to be created. + +* `timeout_seconds` - (Optional) Number of seconds after which the probe times out. The default value is `1` and the minimum value is `1`. Changing this forces a new resource to be created. + +--- + +The `liveness_probe` block supports: + +* `exec` - (Optional) Commands to be run to validate container readiness. Changing this forces a new resource to be created. + +* `httpget` - (Optional) The definition of the httpget for this container as documented in the `httpget` block below. Changing this forces a new resource to be created. + +* `initial_delay_seconds` - (Optional) Number of seconds after the container has started before liveness or readiness probes are initiated. Changing this forces a new resource to be created. + +* `period_seconds` - (Optional) How often (in seconds) to perform the probe. The default value is `10` and the minimum value is `1`. Changing this forces a new resource to be created. + +* `failure_threshold` - (Optional) How many times to try the probe before restarting the container (liveness probe) or marking the container as unhealthy (readiness probe). The default value is `3` and the minimum value is `1`. Changing this forces a new resource to be created. + +* `success_threshold` - (Optional) Minimum consecutive successes for the probe to be considered successful after having failed. The default value is `1` and the minimum value is `1`. Changing this forces a new resource to be created. + +* `timeout_seconds` - (Optional) Number of seconds after which the probe times out. The default value is `1` and the minimum value is `1`. Changing this forces a new resource to be created. + +--- + +The `httpget` block supports: + +* `path` - (Optional) Path to access on the HTTP server. Changing this forces a new resource to be created. + +* `port` - (Optional) Number of the port to access on the container. Changing this forces a new resource to be created. + +* `scheme` - (Optional) Scheme to use for connecting to the host. Possible values are `Http` and `Https`. Changing this forces a new resource to be created. + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/container_registry.html.markdown b/website/docs/r/container_registry.html.markdown index edfa3a4da44e..0027a0f71f0e 100644 --- a/website/docs/r/container_registry.html.markdown +++ b/website/docs/r/container_registry.html.markdown @@ -44,7 +44,7 @@ The following arguments are supported: * `admin_enabled` - (Optional) Specifies whether the admin user is enabled. Defaults to `false`. -* `storage_account_id` - (Required for `Classic` Sku - Optional otherwise) The ID of a Storage Account which must be located in the same Azure Region as the Container Registry. +* `storage_account_id` - (Required for `Classic` Sku - Forbidden otherwise) The ID of a Storage Account which must be located in the same Azure Region as the Container Registry. * `sku` - (Optional) The SKU name of the the container registry. Possible values are `Classic` (which was previously `Basic`), `Basic`, `Standard` and `Premium`. @@ -54,6 +54,24 @@ The following arguments are supported: * `georeplication_locations` - (Optional) A list of Azure locations where the container registry should be geo-replicated. +* `network_rule_set` - (Optional) A `network_rule_set` block as documented below. + +`network_rule_set` supports the following: + +* `default_action` - (Optional) The behaviour for requests matching no rules. Either `Allow` or `Deny`. Defaults to `Allow` + +* `ip_rule` - (Optional) One or more `ip_rule` blocks as defined below. + +~> **NOTE:** `network_rule_set ` is only supported with the `Premium` SDK at this time. + +`ip_rule` supports the following: + +* `action` - (Required) The behaviour for requests matching this rule. At this time the only supported value is `Allow` + +* `ip_range` - (Required) The CIDR block from which requests will match the rule. + + +--- ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/container_registry_webhook.html.markdown b/website/docs/r/container_registry_webhook.html.markdown new file mode 100644 index 000000000000..21de13634afe --- /dev/null +++ b/website/docs/r/container_registry_webhook.html.markdown @@ -0,0 +1,79 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_container_registry_webhook" +sidebar_current: "docs-azurerm-resource-container-registry-webhook" +description: |- + Manages an Azure Container Registry Webhook. + +--- + +# azurerm_container_registry_webhook + +Manages an Azure Container Registry Webhook. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "rg" { + name = "resourceGroup1" + location = "West US" +} + +resource "azurerm_container_registry" "acr" { + name = "containerRegistry1" + resource_group_name = "${azurerm_resource_group.rg.name}" + location = "${azurerm_resource_group.rg.location}" + sku = "Standard" + admin_enabled = false +} + +resource "azurerm_container_registry_webhook" "webhook" { + name = "mywebhook" + resource_group_name = "${azurerm_resource_group.rg.name}" + registry_name = "${azurerm_container_registry.acr.name}" + location = "${azurerm_resource_group.rg.location}" + + service_uri = "https://mywebhookreceiver.example/mytag" + status = "enabled" + scope = "mytag:*" + actions = ["push"] + custom_headers = { "Content-Type" = "application/json" } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Container Registry Webhook. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Container Registry Webhook. Changing this forces a new resource to be created. + +* `registry_name` - (Required) The Name of Container registry this Webhook belongs to. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `service_uri` - (Required) Specifies the service URI for the Webhook to post notifications. + +* `actions` - (Required) A list of actions that trigger the Webhook to post notifications. At least one action needs to be specified. Valid values are: `push`, `delete`, `quarantine`, `chart_push`, `chart_delete` + +* `status` - (Optional) Specifies if this Webhook triggers notifications or not. Valid values: `enabled` and `disabled`. Default is `enabled`. + +* `scope` - (Optional) Specifies the scope of repositories that can trigger an event. For example, 'foo:*' means events for all tags under repository 'foo'. 'foo:bar' means events for 'foo:bar' only. 'foo' is equivalent to 'foo:latest'. Empty means all events. + +* `custom_headers` - (Optional) Custom headers that will be added to the webhook notifications request. + +--- +## Attributes Reference + +The following attributes are exported: + +* `id` - The Container Registry Webhook ID. + +## Import + +Container Registry Webhooks can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_container_registry_webhook.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/mygroup1/providers/Microsoft.ContainerRegistry/registries/myregistry1/webhooks/mywebhook1 +``` diff --git a/website/docs/r/cosmosdb_cassandra_keyspace.html.markdown b/website/docs/r/cosmosdb_cassandra_keyspace.html.markdown new file mode 100644 index 000000000000..a46024fa2be0 --- /dev/null +++ b/website/docs/r/cosmosdb_cassandra_keyspace.html.markdown @@ -0,0 +1,51 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_cassandra_keyspace" +sidebar_current: "docs-azurerm-resource-cosmosdb-cassandra-keyspace" +description: |- + Manages a Cassandra KeySpace within a Cosmos DB Account. +--- + +# azurerm_cosmosdb_cassandra_keyspace + +Manages a Cassandra KeySpace within a Cosmos DB Account. + +## Example Usage + +```hcl +data "azurerm_cosmosdb_account" "example" { + name = "tfex-cosmosdb-account" + resource_group_name = "tfex-cosmosdb-account-rg" +} + +resource "azurerm_cosmosdb_cassandra_keyspace" "example" { + name = "tfex-cosmos-cassandra-keyspace" + resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${data.azurerm_cosmosdb_account.example.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Cosmos DB Cassandra KeySpace. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Cosmos DB Cassandra KeySpace is created. Changing this forces a new resource to be created. + +* `account_name` - (Required) The name of the Cosmos DB Cassandra KeySpace to create the table within. Changing this forces a new resource to be created. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - the Cosmos DB Cassandra KeySpace ID. + +## Import + +Cosmos Cassandra KeySpace can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_cosmosdb_cassandra_keyspace.ks1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/cassandra/keyspaces/ks1 +``` diff --git a/website/docs/r/cosmosdb_mongo_collection.html.markdown b/website/docs/r/cosmosdb_mongo_collection.html.markdown new file mode 100644 index 000000000000..02ffc66b3d62 --- /dev/null +++ b/website/docs/r/cosmosdb_mongo_collection.html.markdown @@ -0,0 +1,78 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_mongo_collection" +sidebar_current: "docs-azurerm-resource-cosmosdb-mongo-collection" +description: |- + Manages a Mongo Collection within a Cosmos DB Account. +--- + +# azurerm_cosmosdb_mongo_collection + +Manages a Mongo Collection within a Cosmos DB Account. + +## Example Usage + +```hcl +data "azurerm_cosmosdb_account" "example" { + name = "tfex-cosmosdb-account" + resource_group_name = "tfex-cosmosdb-account-rg" +} + +resource "azurerm_cosmosdb_mongo_database" "example" { + name = "tfex-cosmos-mongo-db" + resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${data.azurerm_cosmosdb_account.example.name}" +} + +resource "azurerm_cosmosdb_mongo_collection" "example" { + name = "tfex-cosmos-mongo-db" + resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${data.azurerm_cosmosdb_account.example.name}" + database_name = "${azurerm_cosmosdb_mongo_database.example.name}" + + default_ttl_seconds = "777" + shard_key = "uniqueKey" + + indexes { + key = "aKey" + unique = false + } + + indexes { + key = "uniqueKey" + unique = true + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Cosmos DB Mongo Collection. Changing this forces a new resource to be created. +* `resource_group_name` - (Required) The name of the resource group in which the Cosmos DB Mongo Collection is created. Changing this forces a new resource to be created. +* `database_name` - (Required) The name of the Cosmos DB Mongo Database in which the Cosmos DB Mongo Collection is created. Changing this forces a new resource to be created. +* `default_ttl_seconds` - (Required) The default Time To Live in seconds. If the value is `-1` items are not automatically expired. +* `shard_key` - (Required) The name of the key to partition on for sharding. There must not be any other unique index keys. +* `indexes` - (Optional) One or more `indexes` blocks as defined below. + +--- + +An `indexes` block supports the following: + +* `key` - (Required) The name of the key to use for this index. +* `unique` - (Required) Whether the index key should be unique. + +## Attributes Reference + +The following attributes are exported: + +* `id` - the Cosmos DB Mongo Collection ID. + +## Import + +Cosmos DB Mongo Collection can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_cosmosdb_mongo_collection.collection1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/mongodb/databases/db1/collections/collection1 +``` diff --git a/website/docs/r/cosmosdb_mongo_database.html.markdown b/website/docs/r/cosmosdb_mongo_database.html.markdown new file mode 100644 index 000000000000..e9e8b5c744c4 --- /dev/null +++ b/website/docs/r/cosmosdb_mongo_database.html.markdown @@ -0,0 +1,51 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_mongo_database" +sidebar_current: "docs-azurerm-resource-cosmosdb-mongo-database" +description: |- + Manages a Mongo Database within a Cosmos DB Account. +--- + +# azurerm_cosmosdb_mongo_database + +Manages a Mongo Database within a Cosmos DB Account. + +## Example Usage + +```hcl +data "azurerm_cosmosdb_account" "example" { + name = "tfex-cosmosdb-account" + resource_group_name = "tfex-cosmosdb-account-rg" +} + +resource "azurerm_cosmosdb_mongo_database" "example" { + name = "tfex-cosmos-mongo-db" + resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${data.azurerm_cosmosdb_account.example.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Cosmos DB Mongo Database. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Cosmos DB Mongo Database is created. Changing this forces a new resource to be created. + +* `account_name` - (Required) The name of the Cosmos DB Mongo Database to create the table within. Changing this forces a new resource to be created. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - the Cosmos DB Mongo Database ID. + +## Import + +Cosmos Mongo Database can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_cosmosdb_mongo_database.db1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/mongodb/databases/db1 +``` diff --git a/website/docs/r/cosmosdb_sql_container.html.markdown b/website/docs/r/cosmosdb_sql_container.html.markdown new file mode 100644 index 000000000000..378282b030ba --- /dev/null +++ b/website/docs/r/cosmosdb_sql_container.html.markdown @@ -0,0 +1,66 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_sql_container" +sidebar_current: "docs-azurerm-resource-cosmosdb-sql-container" +description: |- + Manages a SQL Container within a Cosmos DB Account. +--- + +# azurerm_cosmosdb_sql_container + +Manages a SQL Container within a Cosmos DB Account. + +## Example Usage + +```hcl + +resource "azurerm_cosmosdb_sql_container" "example" { + name = "example-container" + resource_group_name = "${azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${azurerm_cosmosdb_account.example.name}" + database_name = "${azurerm_cosmosdb_sql_database.example.name}" + partition_key_path = "/definition/id" + + unique_key { + paths = ["/definition/idlong", "/definition/idshort"] + } +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Cosmos DB SQL Database. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Cosmos DB SQL Database is created. Changing this forces a new resource to be created. + +* `account_name` - (Required) The name of the Cosmos DB Account to create the container within. Changing this forces a new resource to be created. + +* `database_name` - (Required) The name of the Cosmos DB SQL Database to create the container within. Changing this forces a new resource to be created. + +* `partition_key_path` - (Optional) Define a partition key. Changing this forces a new resource to be created. + +* `unique_key` - (Optional) One or more `unique_key` blocks as defined below. Changing this forces a new resource to be created. + +--- +A `unique_key` block supports the following: + +* `paths` - (Required) A list of paths to use for this unique key. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - the Cosmos DB SQL Database ID. + +## Import + +Cosmos SQL Database can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_cosmosdb_sql_container.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/sql/databases/database1/containers/example +``` + diff --git a/website/docs/r/cosmosdb_sql_database.html.markdown b/website/docs/r/cosmosdb_sql_database.html.markdown new file mode 100644 index 000000000000..e71bdbd91aa0 --- /dev/null +++ b/website/docs/r/cosmosdb_sql_database.html.markdown @@ -0,0 +1,51 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_sql_database" +sidebar_current: "docs-azurerm-resource-cosmosdb-sql-database" +description: |- + Manages a SQL Database within a Cosmos DB Account. +--- + +# azurerm_cosmosdb_sql_database + +Manages a SQL Database within a Cosmos DB Account. + +## Example Usage + +```hcl +data "azurerm_cosmosdb_account" "example" { + name = "tfex-cosmosdb-account" + resource_group_name = "tfex-cosmosdb-account-rg" +} + +resource "azurerm_cosmosdb_sql_database" "example" { + name = "tfex-cosmos-mongo-db" + resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${data.azurerm_cosmosdb_account.example.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Cosmos DB SQL Database. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Cosmos DB SQL Database is created. Changing this forces a new resource to be created. + +* `account_name` - (Required) The name of the Cosmos DB SQL Database to create the table within. Changing this forces a new resource to be created. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - the Cosmos DB SQL Database ID. + +## Import + +Cosmos SQL Database can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_cosmosdb_sql_database.db1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/sql/databases/db1 +``` diff --git a/website/docs/r/cosmosdb_table.html.markdown b/website/docs/r/cosmosdb_table.html.markdown new file mode 100644 index 000000000000..ea40cc0963bf --- /dev/null +++ b/website/docs/r/cosmosdb_table.html.markdown @@ -0,0 +1,51 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_table" +sidebar_current: "docs-azurerm-resource-cosmosdb-table" +description: |- + Manages a Table within a Cosmos DB Account. +--- + +# azurerm_cosmosdb_table + +Manages a Table within a Cosmos DB Account. + +## Example Usage + +```hcl +data "azurerm_cosmosdb_account" "example" { + name = "tfex-cosmosdb-account" + resource_group_name = "tfex-cosmosdb-account-rg" +} + +resource "azurerm_cosmosdb_table" "example" { + name = "tfex-cosmos-table" + resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${data.azurerm_cosmosdb_account.example.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Cosmos DB Table. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Cosmos DB Table is created. Changing this forces a new resource to be created. + +* `account_name` - (Required) The name of the Cosmos DB Table to create the table within. Changing this forces a new resource to be created. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - the Cosmos DB Table ID. + +## Import + +Cosmos Tables can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_cosmosdb_table.t1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/table/tables/t1 +``` diff --git a/website/docs/r/data_factory.html.markdown b/website/docs/r/data_factory.html.markdown new file mode 100644 index 000000000000..b9ea5dcccf20 --- /dev/null +++ b/website/docs/r/data_factory.html.markdown @@ -0,0 +1,107 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory" +sidebar_current: "docs-azurerm-resource-data-factory-x" +description: |- + Manages an Azure Data Factory (Version 2). +--- + +# azurerm_data_factory + +Manages an Azure Data Factory (Version 2). + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `github_configuration` - (Optional) A `github_configuration` block as defined below. + +* `identity` - (Optional) An `identity` block as defined below. + +* `vsts_configuration` - (Optional) A `vsts_configuration` block as defined below. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +A `github_configuration` block supports the following: + +* `account_name` - (Required) Specifies the GitHub account name. + +* `branch_name` - (Required) Specifies the branch of the repository to get code from. + +* `git_url` - (Required) Specifies the GitHub Enterprise host name. For example: https://github.mydomain.com. Use https://github.com for open source repositories. + +* `repository_name` - (Required) Specifies the name of the git repository. + +* `root_folder` - (Required) Specifies the root folder within the repository. Set to `/` for the top level. + +-> **Note:** You must log in to the Data Factory management UI to complete the authentication to the GitHub repository. + +--- + +A `identity` block supports the following: + +* `type` - (Required) Specifies the identity type of the Data Factory. At this time the only allowed value is `SystemAssigned`. + +--- + +A `vsts_configuration` block supports the following: + +* `account_name` - (Required) Specifies the VSTS account name. + +* `branch_name` - (Required) Specifies the branch of the repository to get code from. + +* `project_name` - (Required) Specifies the name of the VSTS project. + +* `repository_name` - (Required) Specifies the name of the git repository. + +* `root_folder` - (Required) Specifies the root folder within the repository. Set to `/` for the top level. + +* `tenant_id` - (Required) Specifies the Tenant ID associated with the VSTS account. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Data Factory ID. + +* `identity` - An `identity` block as defined below. + +--- + +The `identity` block exports the following: + +* `principal_id` - The ID of the Principal (Client) in Azure Active Directory + +* `tenant_id` - The ID of the Azure Active Directory Tenant. + + +## Import + +Data Factory can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example +``` diff --git a/website/docs/r/data_factory_dataset_mysql.html.markdown b/website/docs/r/data_factory_dataset_mysql.html.markdown new file mode 100644 index 000000000000..af79ee1ff38b --- /dev/null +++ b/website/docs/r/data_factory_dataset_mysql.html.markdown @@ -0,0 +1,91 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory_dataset_mysql" +sidebar_current: "docs-azurerm-resource-data-factory-dataset-mysql" +description: |- + Manages a MySQL Dataset inside a Azure Data Factory. +--- + +# azurerm_data_factory_dataset_mysql + +Manages a MySQL Dataset inside a Azure Data Factory. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_data_factory_linked_service_mysql" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + data_factory_name = "${azurerm_data_factory.example.name}" + connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test" +} + +resource "azurerm_data_factory_dataset_mysql" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + data_factory_name = "${azurerm_data_factory.example.name}" + linked_service_name = "${azurerm_data_factory_linked_service_mysql.test.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory Dataset MySQL. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory Dataset MySQL. Changing this forces a new resource + +* `data_factory_name` - (Required) The Data Factory name in which to associate the Dataset with. Changing this forces a new resource. + +* `linked_service_name` - (Required) The Data Factory Linked Service name in which to associate the Dataset with. + +* `table_name` - (Optional) The table name of the Data Factory Dataset MySQL. + +* `folder` - (Optional) The folder that this Dataset is in. If not specified, the Dataset will appear at the root level. + +* `schema_column` - (Optional) A `schema_column` block as defined below. + +* `description` - (Optional) The description for the Data Factory Dataset MySQL. + +* `annotations` - (Optional) List of tags that can be used for describing the Data Factory Dataset MySQL. + +* `parameters` - (Optional) A map of parameters to associate with the Data Factory Dataset MySQL. + +* `additional_properties` - (Optional) A map of additional properties to associate with the Data Factory Dataset MySQL. + +--- + +A `schema_column` block supports the following: + +* `name` - (Required) The name of the column. + +* `type` - (Optional) Type of the column. Valid values are `Byte`, `Byte[]`, `Boolean`, `Date`, `DateTime`,`DateTimeOffset`, `Decimal`, `Double`, `Guid`, `Int16`, `Int32`, `Int64`, `Single`, `String`, `TimeSpan`. Please note these values are case sensitive. + +* `description` - (Optional) The description of the column. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Data Factory Dataset. + +## Import + +Data Factory Dataset MySQL can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory_dataset_mysql.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example/datasets/example +``` diff --git a/website/docs/r/data_factory_dataset_postgresql.html.markdown b/website/docs/r/data_factory_dataset_postgresql.html.markdown new file mode 100644 index 000000000000..0fd5b101b124 --- /dev/null +++ b/website/docs/r/data_factory_dataset_postgresql.html.markdown @@ -0,0 +1,91 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory_dataset_postgresql" +sidebar_current: "docs-azurerm-resource-data-factory-dataset-postgresql" +description: |- + Manages a PostgreSQL Dataset inside a Azure Data Factory. +--- + +# azurerm_data_factory_dataset_postgresql + +Manages a PostgreSQL Dataset inside a Azure Data Factory. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_data_factory_linked_service_postgresql" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + data_factory_name = "${azurerm_data_factory.example.name}" + connection_string = "Host=example;Port=5432;Database=example;UID=example;EncryptionMethod=0;Password=example" +} + +resource "azurerm_data_factory_dataset_postgresql" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + data_factory_name = "${azurerm_data_factory.example.name}" + linked_service_name = "${azurerm_data_factory_linked_service_postgresql.test.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory Dataset PostgreSQL. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory Dataset PostgreSQL. Changing this forces a new resource + +* `data_factory_name` - (Required) The Data Factory name in which to associate the Dataset with. Changing this forces a new resource. + +* `linked_service_name` - (Required) The Data Factory Linked Service name in which to associate the Dataset with. + +* `table_name` - (Optional) The table name of the Data Factory Dataset PostgreSQL. + +* `folder` - (Optional) The folder that this Dataset is in. If not specified, the Dataset will appear at the root level. + +* `schema_column` - (Optional) A `schema_column` block as defined below. + +* `description` - (Optional) The description for the Data Factory Dataset PostgreSQL. + +* `annotations` - (Optional) List of tags that can be used for describing the Data Factory Dataset PostgreSQL. + +* `parameters` - (Optional) A map of parameters to associate with the Data Factory Dataset PostgreSQL. + +* `additional_properties` - (Optional) A map of additional properties to associate with the Data Factory Dataset PostgreSQL. + +--- + +A `schema_column` block supports the following: + +* `name` - (Required) The name of the column. + +* `type` - (Optional) Type of the column. Valid values are `Byte`, `Byte[]`, `Boolean`, `Date`, `DateTime`,`DateTimeOffset`, `Decimal`, `Double`, `Guid`, `Int16`, `Int32`, `Int64`, `Single`, `String`, `TimeSpan`. Please note these values are case sensitive. + +* `description` - (Optional) The description of the column. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Data Factory Dataset. + +## Import + +Data Factory Dataset PostgreSQL can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory_dataset_postgresql.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example/datasets/example +``` diff --git a/website/docs/r/data_factory_dataset_sql_server_table.html.markdown b/website/docs/r/data_factory_dataset_sql_server_table.html.markdown new file mode 100644 index 000000000000..fa67a1d33958 --- /dev/null +++ b/website/docs/r/data_factory_dataset_sql_server_table.html.markdown @@ -0,0 +1,91 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory_dataset_sql_server_table" +sidebar_current: "docs-azurerm-resource-data-factory-dataset-sql-server-table" +description: |- + Manages a SQL Server Table Dataset inside a Azure Data Factory. +--- + +# azurerm_data_factory_dataset_sql_server + +Manages a SQL Server Table Dataset inside a Azure Data Factory. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_data_factory_linked_service_sql_server" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + data_factory_name = "${azurerm_data_factory.example.name}" + connection_string = "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test" +} + +resource "azurerm_data_factory_dataset_sql_server_table" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + data_factory_name = "${azurerm_data_factory.example.name}" + linked_service_name = "${azurerm_data_factory_linked_service_sql_server.test.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory Dataset SQL Server Table. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory Dataset SQL Server Table. Changing this forces a new resource + +* `data_factory_name` - (Required) The Data Factory name in which to associate the Dataset with. Changing this forces a new resource. + +* `linked_service_name` - (Required) The Data Factory Linked Service name in which to associate the Dataset with. + +* `table_name` - (Optional) The table name of the Data Factory Dataset SQL Server Table. + +* `folder` - (Optional) The folder that this Dataset is in. If not specified, the Dataset will appear at the root level. + +* `schema_column` - (Optional) A `schema_column` block as defined below. + +* `description` - (Optional) The description for the Data Factory Dataset SQL Server Table. + +* `annotations` - (Optional) List of tags that can be used for describing the Data Factory Dataset SQL Server Table. + +* `parameters` - (Optional) A map of parameters to associate with the Data Factory Dataset SQL Server Table. + +* `additional_properties` - (Optional) A map of additional properties to associate with the Data Factory Dataset SQL Server Table. + +--- + +A `schema_column` block supports the following: + +* `name` - (Required) The name of the column. + +* `type` - (Optional) Type of the column. Valid values are `Byte`, `Byte[]`, `Boolean`, `Date`, `DateTime`,`DateTimeOffset`, `Decimal`, `Double`, `Guid`, `Int16`, `Int32`, `Int64`, `Single`, `String`, `TimeSpan`. Please note these values are case sensitive. + +* `description` - (Optional) The description of the column. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Data Factory Dataset. + +## Import + +Data Factory Dataset SQL Server Table can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory_dataset_sql_server_table.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example/datasets/example +``` diff --git a/website/docs/r/data_factory_linked_service_data_lake_storage_gen2.html.markdown b/website/docs/r/data_factory_linked_service_data_lake_storage_gen2.html.markdown new file mode 100644 index 000000000000..cf1340d231a8 --- /dev/null +++ b/website/docs/r/data_factory_linked_service_data_lake_storage_gen2.html.markdown @@ -0,0 +1,82 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory_linked_service_data_lake_storage_gen2" +sidebar_current: "docs-azurerm-resource-data-factory-linked-service-data-lake-storage-gen2" +description: |- + Manages a Linked Service (connection) between Data Lake Storage Gen2 and Azure Data Factory. +--- + +# azurerm_data_factory_linked_service_data_lake_storage_gen2 + +Manages a Linked Service (connection) between Data Lake Storage Gen2 and Azure Data Factory. + +~> **Note:** All arguments including the `service_principal_key` will be stored in the raw state as plain-text. [Read more about sensitive data in state](/docs/state/sensitive-data.html). + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_data_factory_linked_service_data_lake_storage_gen2" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + service_principal_id = "${data.azurerm_client_config.current.client_id}" + service_principal_key = "exampleKey" + tenant = "11111111-1111-1111-1111-111111111111" + url = "https://datalakestoragegen2" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory Linked Service MySQL. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory Linked Service MySQL. Changing this forces a new resource + +* `data_factory_name` - (Required) The Data Factory name in which to associate the Linked Service with. Changing this forces a new resource. + +* `url` - (Required) The endpoint for the Azure Data Lake Storage Gen2 service. + +* `service_principal_id` - (Required) The service principal id in which to authenticate against the Azure Data Lake Storage Gen2 account. + +* `service_principal_key` - (Required) The service principal key in which to authenticate against the Azure Data Lake Storage Gen2 account. + +* `tenant` - (Required) The tenant id or name in which to authenticate against the Azure Data Lake Storage Gen2 account. + +* `description` - (Optional) The description for the Data Factory Linked Service MySQL. + +* `integration_runtime_name` - (Optional) The integration runtime reference to associate with the Data Factory Linked Service MySQL. + +* `annotations` - (Optional) List of tags that can be used for describing the Data Factory Linked Service MySQL. + +* `parameters` - (Optional) A map of parameters to associate with the Data Factory Linked Service MySQL. + +* `additional_properties` - (Optional) A map of additional properties to associate with the Data Factory Linked Service MySQL. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Data Factory Linked Service. + +## Import + +Data Factory Linked Service MySQL can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory_linked_service_mysql.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example/linkedservices/example +``` diff --git a/website/docs/r/data_factory_linked_service_mysql.html.markdown b/website/docs/r/data_factory_linked_service_mysql.html.markdown new file mode 100644 index 000000000000..456fc86f301b --- /dev/null +++ b/website/docs/r/data_factory_linked_service_mysql.html.markdown @@ -0,0 +1,71 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory_linked_service_mysql" +sidebar_current: "docs-azurerm-resource-data-factory-linked-service-mysql" +description: |- + Manages a Linked Service (connection) between MySQL and Azure Data Factory. +--- + +# azurerm_data_factory_linked_service_mysql + +Manages a Linked Service (connection) between MySQL and Azure Data Factory. + +~> **Note:** All arguments including the connection_string will be stored in the raw state as plain-text. [Read more about sensitive data in state](/docs/state/sensitive-data.html). + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_data_factory_linked_service_mysql" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory Linked Service MySQL. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory Linked Service MySQL. Changing this forces a new resource + +* `data_factory_name` - (Required) The Data Factory name in which to associate the Linked Service with. Changing this forces a new resource. + +* `connection_string` - (Required) The connection string in which to authenticate with MySQL. + +* `description` - (Optional) The description for the Data Factory Linked Service MySQL. + +* `integration_runtime_name` - (Optional) The integration runtime reference to associate with the Data Factory Linked Service MySQL. + +* `annotations` - (Optional) List of tags that can be used for describing the Data Factory Linked Service MySQL. + +* `parameters` - (Optional) A map of parameters to associate with the Data Factory Linked Service MySQL. + +* `additional_properties` - (Optional) A map of additional properties to associate with the Data Factory Linked Service MySQL. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Data Factory Linked Service. + +## Import + +Data Factory Linked Service MySQL can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory_linked_service_mysql.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example/linkedservices/example +``` diff --git a/website/docs/r/data_factory_linked_service_postgresql.html.markdown b/website/docs/r/data_factory_linked_service_postgresql.html.markdown new file mode 100644 index 000000000000..1616610b4309 --- /dev/null +++ b/website/docs/r/data_factory_linked_service_postgresql.html.markdown @@ -0,0 +1,71 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory_linked_service_postgresql" +sidebar_current: "docs-azurerm-resource-data-factory-linked-service-postgresql" +description: |- + Manages a Linked Service (connection) between PostgreSQL and Azure Data Factory. +--- + +# azurerm_data_factory_linked_service_postgresql + +Manages a Linked Service (connection) between PostgreSQL and Azure Data Factory. + +~> **Note:** All arguments including the connection_string will be stored in the raw state as plain-text. [Read more about sensitive data in state](/docs/state/sensitive-data.html). + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_data_factory_linked_service_postgresql" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Host=example;Port=5432;Database=example;UID=example;EncryptionMethod=0;Password=example" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory Linked Service PostgreSQL. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory Linked Service PostgreSQL. Changing this forces a new resource + +* `data_factory_name` - (Required) The Data Factory name in which to associate the Linked Service with. Changing this forces a new resource. + +* `connection_string` - (Required) The connection string in which to authenticate with PostgreSQL. + +* `description` - (Optional) The description for the Data Factory Linked Service PostgreSQL. + +* `integration_runtime_name` - (Optional) The integration runtime reference to associate with the Data Factory Linked Service PostgreSQL. + +* `annotations` - (Optional) List of tags that can be used for describing the Data Factory Linked Service PostgreSQL. + +* `parameters` - (Optional) A map of parameters to associate with the Data Factory Linked Service PostgreSQL. + +* `additional_properties` - (Optional) A map of additional properties to associate with the Data Factory Linked Service PostgreSQL. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Data Factory Linked Service. + +## Import + +Data Factory Linked Service PostgreSQL can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory_linked_service_postgresql.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example/linkedservices/example +``` diff --git a/website/docs/r/data_factory_linked_service_sql_server.html.markdown b/website/docs/r/data_factory_linked_service_sql_server.html.markdown new file mode 100644 index 000000000000..3838a5ee5eb9 --- /dev/null +++ b/website/docs/r/data_factory_linked_service_sql_server.html.markdown @@ -0,0 +1,71 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory_linked_service_sql_server" +sidebar_current: "docs-azurerm-resource-data-factory-linked-service-sql-server" +description: |- + Manages a Linked Service (connection) between a SQL Server and Azure Data Factory. +--- + +# azurerm_data_factory_linked_service_sql_server + +Manages a Linked Service (connection) between a SQL Server and Azure Data Factory. + +~> **Note:** All arguments including the client secret will be stored in the raw state as plain-text. [Read more about sensitive data in state](/docs/state/sensitive-data.html). + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_data_factory_linked_service_sql_server" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.test.name}" + data_factory_name = "${azurerm_data_factory.test.name}" + connection_string = "Integrated Security=False;Data Source=test;Initial Catalog=test;User ID=test;Password=test" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory Linked Service SQL Server. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory Linked Service SQL Server. Changing this forces a new resource + +* `data_factory_name` - (Required) The Data Factory name in which to associate the Linked Service with. Changing this forces a new resource. + +* `connection_string` - (Required) The connection string in which to authenticate with the SQL Server. + +* `description` - (Optional) The description for the Data Factory Linked Service SQL Server. + +* `integration_runtime_name` - (Optional) The integration runtime reference to associate with the Data Factory Linked Service SQL Server. + +* `annotations` - (Optional) List of tags that can be used for describing the Data Factory Linked Service SQL Server. + +* `parameters` - (Optional) A map of parameters to associate with the Data Factory Linked Service SQL Server. + +* `additional_properties` - (Optional) A map of additional properties to associate with the Data Factory Linked Service SQL Server. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Data Factory Linked Service. + +## Import + +Data Factory Linked Service SQL Server can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory_linked_service_sql_server.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example/linkedservices/example +``` diff --git a/website/docs/r/data_factory_pipeline.html.markdown b/website/docs/r/data_factory_pipeline.html.markdown new file mode 100644 index 000000000000..5041b03aeb39 --- /dev/null +++ b/website/docs/r/data_factory_pipeline.html.markdown @@ -0,0 +1,64 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_data_factory_pipeline" +sidebar_current: "docs-azurerm-resource-data-factory-pipeline" +description: |- + Manages a Pipeline inside a Azure Data Factory. +--- + +# azurerm_data_factory_pipeline + +Manages a Pipeline inside a Azure Data Factory. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "northeurope" +} + +resource "azurerm_data_factory" "example" { + name = "example" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_data_factory_pipeline" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + data_factory_name = "${azurerm_data_factory.example.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Data Factory Pipeline. Changing this forces a new resource to be created. Must be globally unique. See the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/data-factory/naming-rules) for all restrictions. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Data Factory Pipeline. Changing this forces a new resource + +* `data_factory_name` - (Required) The Data Factory name in which to associate the Pipeline with. Changing this forces a new resource. + +* `description` - (Optional) The description for the Data Factory Pipeline. + +* `annotations` - (Optional) List of tags that can be used for describing the Data Factory Pipeline. + +* `parameters` - (Optional) A map of parameters to associate with the Data Factory Pipeline. + +* `variables` - (Optional) A map of variables to associate with the Data Factory Pipeline. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Data Factory Pipeline. + +## Import + +Data Factory Pipeline can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_data_factory_pipeline.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example/providers/Microsoft.DataFactory/factories/example/pipelines/example +``` diff --git a/website/docs/r/data_lake_analytics_account.html.markdown b/website/docs/r/data_lake_analytics_account.html.markdown index 483d7d963f9d..e13dec825a36 100644 --- a/website/docs/r/data_lake_analytics_account.html.markdown +++ b/website/docs/r/data_lake_analytics_account.html.markdown @@ -3,12 +3,12 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_data_lake_analytics_account" sidebar_current: "docs-azurerm-resource-data-lake-analytics-account" description: |- - Manage an Azure Data Lake Analytics Account. + Manages an Azure Data Lake Analytics Account. --- # azurerm_data_lake_analytics_account -Manage an Azure Data Lake Analytics Account. +Manages an Azure Data Lake Analytics Account. ## Example Usage diff --git a/website/docs/r/data_lake_analytics_firewall_rule.html.markdown b/website/docs/r/data_lake_analytics_firewall_rule.html.markdown index 4d08ea9b3353..2cb98830eec8 100644 --- a/website/docs/r/data_lake_analytics_firewall_rule.html.markdown +++ b/website/docs/r/data_lake_analytics_firewall_rule.html.markdown @@ -3,12 +3,12 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_data_lake_analytics_firewall_rule" sidebar_current: "docs-azurerm-resource-data-lake-analytics-firewall-rule" description: |- - Manage a Azure Data Lake Analytics Firewall Rule. + Manages a Azure Data Lake Analytics Firewall Rule. --- # azurerm_data_lake_analytics_firewall_rule -Manage a Azure Data Lake Analytics Firewall Rule. +Manages a Azure Data Lake Analytics Firewall Rule. ## Example Usage diff --git a/website/docs/r/data_lake_store.html.markdown b/website/docs/r/data_lake_store.html.markdown index ebb1fefd5e9c..81612cef8b25 100644 --- a/website/docs/r/data_lake_store.html.markdown +++ b/website/docs/r/data_lake_store.html.markdown @@ -3,12 +3,12 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_data_lake_store" sidebar_current: "docs-azurerm-resource-data-lake-store-x" description: |- - Manage an Azure Data Lake Store. + Manages an Azure Data Lake Store. --- # azurerm_data_lake_store -Manage an Azure Data Lake Store. +Manages an Azure Data Lake Store. ## Example Usage diff --git a/website/docs/r/data_lake_store_file.html.markdown b/website/docs/r/data_lake_store_file.html.markdown index 660d55a65a48..eb374ad17c67 100644 --- a/website/docs/r/data_lake_store_file.html.markdown +++ b/website/docs/r/data_lake_store_file.html.markdown @@ -3,12 +3,12 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_data_lake_store_file" sidebar_current: "docs-azurerm-resource-data-lake-store-file" description: |- - Manage a Azure Data Lake Store File. + Manages a Azure Data Lake Store File. --- # azurerm_data_lake_store_file -Manage a Azure Data Lake Store File. +Manages a Azure Data Lake Store File. ~> **Note:** If you want to change the data in the remote file without changing the `local_file_path`, then taint the resource so the `azurerm_data_lake_store_file` gets recreated with the new data. diff --git a/website/docs/r/data_lake_store_firewall_rule.html.markdown b/website/docs/r/data_lake_store_firewall_rule.html.markdown index b25446e7c691..45e6d5ee8718 100644 --- a/website/docs/r/data_lake_store_firewall_rule.html.markdown +++ b/website/docs/r/data_lake_store_firewall_rule.html.markdown @@ -3,12 +3,12 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_data_lake_store_firewall_rule" sidebar_current: "docs-azurerm-resource-data-lake-store-firewall-rule" description: |- - Manage a Azure Data Lake Store Firewall Rule. + Manages a Azure Data Lake Store Firewall Rule. --- # azurerm_data_lake_store_firewall_rule -Manage a Azure Data Lake Store Firewall Rule. +Manages a Azure Data Lake Store Firewall Rule. ## Example Usage diff --git a/website/docs/r/ddos_protection_plan.html.markdown b/website/docs/r/ddos_protection_plan.html.markdown index 2e69f32ac93e..f0db90c712b9 100644 --- a/website/docs/r/ddos_protection_plan.html.markdown +++ b/website/docs/r/ddos_protection_plan.html.markdown @@ -1,7 +1,7 @@ --- layout: "azurerm" page_title: "Azure Resource Manager: azurerm_ddos_protection_plan" -sidebar_current: "docs-azurerm-resource-network-ddos-protection-plan-x" +sidebar_current: "docs-azurerm-resource-ddos-protection-plan-x" description: |- Manages an Azure DDoS Protection Plan. @@ -13,6 +13,8 @@ Manages an Azure DDoS Protection Plan. -> **NOTE** Azure only allow `one` DDoS Protection Plan per region. +~> **NOTE:** This resource has been deprecated in favour of the `azurerm_network_ddos_protection_plan` resource and will be removed in the next major version of the AzureRM Provider. The new resource shares the same fields as this one, and information on migrating across [can be found in this guide](../guides/migrating-between-renamed-resources.html). + ## Example Usage ```hcl @@ -54,4 +56,4 @@ Azure DDoS Protection Plan can be imported using the `resource id`, e.g. ```shell terraform import azurerm_ddos_protection_plan.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Network/ddosProtectionPlans/testddospplan -``` \ No newline at end of file +``` diff --git a/website/docs/r/dev_test_lab_schedule.html.markdown b/website/docs/r/dev_test_lab_schedule.html.markdown new file mode 100644 index 000000000000..80e4b2ed23ab --- /dev/null +++ b/website/docs/r/dev_test_lab_schedule.html.markdown @@ -0,0 +1,109 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_dev_test_schedule" +sidebar_current: "docs-azurerm-dev-test-lab-schedule" +description: |- + Manages automated startup and shutdown schedules for Azure Dev Test Lab. +--- + +# azurerm_dev_test_schedule + +Manages automated startup and shutdown schedules for Azure Dev Test Lab. + + +## Example Usage + +```hcl +resource "azurerm_resource_group" "sample" { + name = "acctestRG" + location = "West US" +} + +resource "azurerm_dev_test_lab" "sample" { + name = "YourDevTestLab" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + +} + +resource "azurerm_dev_test_schedule" "sample" { + name = "LabVmAutoStart" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + lab_name = "${azurerm_dev_test_lab.test.name}" + + weekly_recurrence { + time = "1100" + week_days = ["Monday", "Tuesday"] + } + + time_zone_id = "Pacific Standard Time" + task_type = "LabVmsStartupTask" + + notification_settings { + } + + tags = { + environment = "Production" + } +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the dev test lab schedule. Valid value for name depends on the `task_type`. For instance for task_type `LabVmsStartupTask` the name needs to be `LabVmAutoStart`. + +* `location` - (Required) The location where the schedule is created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the dev test lab schedule. Changing this forces a new resource to be created. + +* `lab_name` - (Required) The name of the dev test lab. Changing this forces a new resource to be created. + +* `status` - The status of this schedule. Possible values are `Enabled` and `Disabled`. Defaults to `Disabled`. + +* `task_type` - (Required) The task type of the schedule. Possible values include `LabVmsShutdownTask` and `LabVmAutoStart`. + +* `time_zone_id` - (Required) The time zone ID (e.g. Pacific Standard time). + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +A `weekly_recurrence` - block supports the following: + +* `time` - The time when the schedule takes effect. + +* `week_days` - A list of days that this schedule takes effect . Possible values include `Monday`, `Tuesday`, `Wednesday`, `Thursday`, `Friday`, `Saturday` and `Sunday`. + +--- + +A `daily_recurrence` - block supports the following: + +* `time` - The time each day when the schedule takes effect. + +--- + +A `notification_settings` - (Required) - block supports the following: + +* `status` - The status of the notification. Possible values are `Enabled` and `Disabled`. Defaults to `Disabled` + +* `time_in_minutes` - Time in minutes before event at which notification will be sent. + +* `webhook_url` - The webhook URL to which the notification will be sent. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Dev Test Lab Schedule ID. + +## Import + +Dev Test Schedule can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_dev_test_schedule.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.DevTestLab/labs/myDevTestLab/schedules/labvmautostart +``` diff --git a/website/docs/r/devspace_controller.html.markdown b/website/docs/r/devspace_controller.html.markdown index f161ca776150..2520f2d6d391 100644 --- a/website/docs/r/devspace_controller.html.markdown +++ b/website/docs/r/devspace_controller.html.markdown @@ -36,7 +36,7 @@ resource "azurerm_kubernetes_cluster" "test" { } } -resource "azurerm_devspace_controller" test { +resource "azurerm_devspace_controller" "test" { name = "acctestdsc1" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" diff --git a/website/docs/r/dns_caa_record.html.markdown b/website/docs/r/dns_caa_record.html.markdown index 0e8688921ed1..a66a7a7b43d5 100644 --- a/website/docs/r/dns_caa_record.html.markdown +++ b/website/docs/r/dns_caa_record.html.markdown @@ -3,7 +3,7 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_dns_caa_record" sidebar_current: "docs-azurerm-resource-dns-caa-record" description: |- - Manage a DNS CAA Record. + Manages a DNS CAA Record. --- # azurerm_dns_caa_record diff --git a/website/docs/r/dns_mx_record.html.markdown b/website/docs/r/dns_mx_record.html.markdown index aa5f86123490..1cb378d93408 100644 --- a/website/docs/r/dns_mx_record.html.markdown +++ b/website/docs/r/dns_mx_record.html.markdown @@ -3,7 +3,7 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_dns_mx_record" sidebar_current: "docs-azurerm-resource-dns-mx-record" description: |- - Manage a DNS MX Record. + Manages a DNS MX Record. --- # azurerm_dns_mx_record diff --git a/website/docs/r/dns_srv_record.html.markdown b/website/docs/r/dns_srv_record.html.markdown index 6c4388e65703..e46733682b9e 100644 --- a/website/docs/r/dns_srv_record.html.markdown +++ b/website/docs/r/dns_srv_record.html.markdown @@ -3,7 +3,7 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_dns_srv_record" sidebar_current: "docs-azurerm-resource-dns-srv-record" description: |- - Manage a DNS SRV Record. + Manages a DNS SRV Record. --- # azurerm_dns_srv_record diff --git a/website/docs/r/dns_zone.html.markdown b/website/docs/r/dns_zone.html.markdown index 7120d316eaa1..c9911a51c60e 100644 --- a/website/docs/r/dns_zone.html.markdown +++ b/website/docs/r/dns_zone.html.markdown @@ -38,14 +38,16 @@ The following arguments are supported: * `resource_group_name` - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created. -* `zone_type` - (Required) Specifies the type of this DNS zone. Possible values are `Public` or `Private` (Defaults to `Public`). - * `registration_virtual_network_ids` - (Optional) A list of Virtual Network ID's that register hostnames in this DNS zone. This field can only be set when `zone_type` is set to `Private`. * `resolution_virtual_network_ids` - (Optional) A list of Virtual Network ID's that resolve records in this DNS zone. This field can only be set when `zone_type` is set to `Private`. * `tags` - (Optional) A mapping of tags to assign to the resource. +* `zone_type` - (Optional / **Deprecated**) Specifies the type of this DNS zone. Possible values are `Public` or `Private` (Defaults to `Public`). + +~> **NOTE:** This field was part of the initial Preview for Private DNS Zones - which has been [replaced by the separate resource `azurerm_private_dns_zone`](private_dns_zone.html) and will be removed in v2.0 of the Azure Provider. + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/eventgrid_event_subscription.html.markdown b/website/docs/r/eventgrid_event_subscription.html.markdown index 676c4473bb1d..5b657810ff43 100644 --- a/website/docs/r/eventgrid_event_subscription.html.markdown +++ b/website/docs/r/eventgrid_event_subscription.html.markdown @@ -20,29 +20,30 @@ resource "azurerm_resource_group" "default" { } resource "azurerm_storage_account" "default" { - name = "defaultStorageAccount" - resource_group_name = "${azurerm_resource_group.default.name}" - location = "${azurerm_resource_group.default.location}" - account_tier = "Standard" - account_replication_type = "LRS" - - tags = { - environment = "staging" - } - } - - resource "azurerm_storage_queue" "default" { - name = "defaultStorageQueue" - resource_group_name = "${azurerm_resource_group.default.name}" - storage_account_name = "${azurerm_storage_account.default.name}" + name = "defaultStorageAccount" + resource_group_name = "${azurerm_resource_group.default.name}" + location = "${azurerm_resource_group.default.location}" + account_tier = "Standard" + account_replication_type = "LRS" + + tags = { + environment = "staging" } +} + +resource "azurerm_storage_queue" "default" { + name = "defaultStorageQueue" + resource_group_name = "${azurerm_resource_group.default.name}" + storage_account_name = "${azurerm_storage_account.default.name}" +} resource "azurerm_eventgrid_event_subscription" "default" { name = "defaultEventSubscription" scope = "${azurerm_resource_group.default.id}" + storage_queue_endpoint { - storage_account_id = "${azurerm_storage_account.default.id}" - queue_name = "${azurerm_storage_queue.default.name}" + storage_account_id = "${azurerm_storage_account.default.id}" + queue_name = "${azurerm_storage_queue.default.name}" } } ``` @@ -101,7 +102,7 @@ A `hybrid_connection_endpoint` supports the following: A `webhook_endpoint` supports the following: -* `url` - (Required) Specifies the url of the webhook where the Event Subscription will recieve events. +* `url` - (Required) Specifies the url of the webhook where the Event Subscription will receive events. --- diff --git a/website/docs/r/eventhub.html.markdown b/website/docs/r/eventhub.html.markdown index 402d5b5dd2fd..a05226d3bc9d 100644 --- a/website/docs/r/eventhub.html.markdown +++ b/website/docs/r/eventhub.html.markdown @@ -68,6 +68,8 @@ A `capture_description` block supports the following: * `size_limit_in_bytes` - (Optional) Specifies the amount of data built up in your EventHub before a Capture Operation occurs. Value should be between `10485760` and `524288000` bytes. Defaults to `314572800` bytes. +* `skip_empty_archives` - (Optional) Specifies if empty files should not be emitted if no events occur during the Capture time window. Defaults to `false`. + * `destination` - (Required) A `destination` block as defined below. A `destination` block supports the following: diff --git a/website/docs/r/eventhub_namespace.html.markdown b/website/docs/r/eventhub_namespace.html.markdown index 823e77ecd0a5..d37fec5d2bad 100644 --- a/website/docs/r/eventhub_namespace.html.markdown +++ b/website/docs/r/eventhub_namespace.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_eventhub_namespace -Manage an EventHub Namespace. +Manages an EventHub Namespace. ## Example Usage diff --git a/website/docs/r/firewall.html.markdown b/website/docs/r/firewall.html.markdown index bf6a3fed194f..78b258edeb94 100644 --- a/website/docs/r/firewall.html.markdown +++ b/website/docs/r/firewall.html.markdown @@ -76,7 +76,7 @@ A `ip_configuration` block supports the following: * `subnet_id` - (Required) Reference to the subnet associated with the IP Configuration. --> **NOTE** The Subnet used for the Firewall must have the name `AzureFirewallSubnet` and the subnet mask must be at least `/25`. +-> **NOTE** The Subnet used for the Firewall must have the name `AzureFirewallSubnet` and the subnet mask must be at least `/26`. * `public_ip_address_id` - (Required) The Resource ID of the Public IP Address associated with the firewall. diff --git a/website/docs/r/firewall_application_rule_collection.html.markdown b/website/docs/r/firewall_application_rule_collection.html.markdown index 6e9d5a49ce5f..c7be55eb1175 100644 --- a/website/docs/r/firewall_application_rule_collection.html.markdown +++ b/website/docs/r/firewall_application_rule_collection.html.markdown @@ -47,9 +47,9 @@ resource "azurerm_firewall" "test" { resource_group_name = "${azurerm_resource_group.test.name}" ip_configuration { - name = "configuration" - subnet_id = "${azurerm_subnet.test.id}" - public_ip_address_id = "${azurerm_public_ip.test.id}" + name = "configuration" + subnet_id = "${azurerm_subnet.test.id}" + public_ip_address_id = "${azurerm_public_ip.test.id}" } } @@ -72,8 +72,8 @@ resource "azurerm_firewall_application_rule_collection" "test" { ] protocol { - port = "443" - type = "Https" + port = "443" + type = "Https" } } } @@ -117,7 +117,7 @@ A `protocol` block supports the following: * `port` - (Optional) Specify a port for the connection. -* `type` - (Required) Specifies the type of conection. Possible values are `Http` or `Https`. +* `type` - (Required) Specifies the type of connection. Possible values are `Http` or `Https`. ## Import diff --git a/website/docs/r/firewall_nat_rule_collection.html.markdown b/website/docs/r/firewall_nat_rule_collection.html.markdown new file mode 100644 index 000000000000..3f14ec28fc31 --- /dev/null +++ b/website/docs/r/firewall_nat_rule_collection.html.markdown @@ -0,0 +1,129 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_firewall_nat_rule_collection" +sidebar_current: "docs-azurerm-resource-network-firewall-nat-rule-collection" +description: |- + Manages a NAT Rule Collection within an Azure Firewall. + +--- + +# azurerm_firewall_nat_rule_collection + +Manages a NAT Rule Collection within an Azure Firewall. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "North Europe" +} + +resource "azurerm_virtual_network" "test" { + name = "testvnet" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "AzureFirewallSubnet" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.1.0/24" +} + +resource "azurerm_public_ip" "test" { + name = "testpip" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_firewall" "test" { + name = "testfirewall" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "configuration" + subnet_id = "${azurerm_subnet.test.id}" + public_ip_address_id = "${azurerm_public_ip.test.id}" + } +} + +resource "azurerm_firewall_nat_rule_collection" "test" { + name = "testcollection" + azure_firewall_name = "${azurerm_firewall.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + priority = 100 + action = "Dnat" + + rule { + name = "testrule" + + source_addresses = [ + "10.0.0.0/16", + ] + + destination_ports = [ + "53", + ] + + destination_addresses = [ + "8.8.8.8", + "8.8.4.4", + ] + + protocols = [ + "TCP", + "UDP", + ] + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the NAT Rule Collection which must be unique within the Firewall. Changing this forces a new resource to be created. + +* `azure_firewall_name` - (Required) Specifies the name of the Firewall in which the NAT Rule Collection should be created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which the Firewall exists. Changing this forces a new resource to be created. + +* `priority` - (Required) Specifies the priority of the rule collection. Possible values are between `100` - `65000`. + +* `action` - (Required) Specifies the action the rule will apply to matching traffic. Possible values are `Dnat` and `Snat`. + +* `rule` - (Required) One or more `rule` blocks as defined below. + +--- + +A `rule` block supports the following: + +* `name` - (Required) Specifies the name of the rule. + +* `description` - (Optional) Specifies a description for the rule. + +* `destination_addresses` - (Required) A list of destination IP addresses and/or IP ranges. + +* `destination_ports` - (Required) A list of destination ports. + +* `protocols` - (Required) A list of protocols. Possible values are `Any`, `ICMP`, `TCP` and `UDP`. If `action` is `Dnat`, protocols can only be `TCP` and `UDP`. + +* `source_addresses` - (Required) A list of source IP addresses and/or IP ranges. + +* `translated_address` - (Required) The address of the service behind the Firewall. + +* `translated_port` - (Required) The port of the service behind the Firewall. + +## Import + +Azure Firewall NAT Rule Collections can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_firewall_nat_rule_collection.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/azureFirewalls/myfirewall/natRuleCollections/mycollection +``` diff --git a/website/docs/r/firewall_network_rule_collection.html.markdown b/website/docs/r/firewall_network_rule_collection.html.markdown index 9e279c508113..5a6c90a5bab1 100644 --- a/website/docs/r/firewall_network_rule_collection.html.markdown +++ b/website/docs/r/firewall_network_rule_collection.html.markdown @@ -34,11 +34,11 @@ resource "azurerm_subnet" "test" { } resource "azurerm_public_ip" "test" { - name = "testpip" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - allocation_method = "Static" - sku = "Standard" + name = "testpip" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" + sku = "Standard" } resource "azurerm_firewall" "test" { diff --git a/website/docs/r/function_app.html.markdown b/website/docs/r/function_app.html.markdown index 817d148a46c9..ffb2e8f8b8f6 100644 --- a/website/docs/r/function_app.html.markdown +++ b/website/docs/r/function_app.html.markdown @@ -99,6 +99,12 @@ The following arguments are supported: * `app_settings` - (Optional) A key-value pair of App Settings. +~> **Note:** When integrating a `CI/CD pipeline` and expecting to run from a deployed package in `Azure` you must seed your `app settings` as part of terraform code for function app to be successfully deployed. `Important Default key pairs`: (`"WEBSITE_RUN_FROM_PACKAGE" = ""`, `"FUNCTIONS_WORKER_RUNTIME" = "node"` (or python, etc), `"WEBSITE_NODE_DEFAULT_VERSION" = "10.14.1"`, `"APPINSIGHTS_INSTRUMENTATIONKEY" = ""`). + +~> **Note:** When using an App Service Plan in the `Free` or `Shared` Tiers `use_32_bit_worker_process` must be set to `true`. + +* `auth_settings` - (Optional) A `auth_settings` block as defined below. + * `enable_builtin_logging` - (Optional) Should the built-in logging of this Function App be enabled? Defaults to `true`. * `connection_string` - (Optional) An `connection_string` block as defined below. @@ -136,14 +142,99 @@ The following arguments are supported: * `websockets_enabled` - (Optional) Should WebSockets be enabled? +* `virtual_network_name` - (Optional) The name of the Virtual Network which this App Service should be attached to. + * `linux_fx_version` - (Optional) Linux App Framework and version for the AppService, e.g. `DOCKER|(golang:latest)`. +* `cors` - (Optional) A `cors` block as defined below. + +--- + +A `cors` block supports the following: + +* `allowed_origins` - (Optional) A list of origins which should be able to make cross-origin calls. `*` can be used to allow all calls. + +* `support_credentials` - (Optional) Are credentials supported? + --- `identity` supports the following: * `type` - (Required) Specifies the identity type of the App Service. At this time the only allowed value is `SystemAssigned`. +--- + +An `auth_settings` block supports the following: + +* `enabled` - (Required) Is Authentication enabled? + +* `active_directory` - (Optional) A `active_directory` block as defined below. + +* `additional_login_params` - (Optional) Login parameters to send to the OpenID Connect authorization endpoint when a user logs in. Each parameter must be in the form "key=value". + +* `allowed_external_redirect_urls` - (Optional) External URLs that can be redirected to as part of logging in or logging out of the app. + +* `default_provider` - (Optional) The default provider to use when multiple providers have been set up. Possible values are `AzureActiveDirectory`, `Facebook`, `Google`, `MicrosoftAccount` and `Twitter`. + +~> **NOTE:** When using multiple providers, the default provider must be set for settings like `unauthenticated_client_action` to work. + +* `facebook` - (Optional) A `facebook` block as defined below. + +* `google` - (Optional) A `google` block as defined below. + +* `issuer` - (Optional) Issuer URI. When using Azure Active Directory, this value is the URI of the directory tenant, e.g. https://sts.windows.net/{tenant-guid}/. + +* `microsoft` - (Optional) A `microsoft` block as defined below. + +* `runtime_version` - (Optional) The runtime version of the Authentication/Authorization module. + +* `token_refresh_extension_hours` - (Optional) The number of hours after session token expiration that a session token can be used to call the token refresh API. Defaults to 72. + +* `token_store_enabled` - (Optional) If enabled the module will durably store platform-specific security tokens that are obtained during login flows. Defaults to false. + +* `twitter` - (Optional) A `twitter` block as defined below. + +* `unauthenticated_client_action` - (Optional) The action to take when an unauthenticated client attempts to access the app. Possible values are `AllowAnonymous` and `RedirectToLoginPage`. + +--- + +An `active_directory` block supports the following: + +* `client_id` - (Required) The Client ID of this relying party application. Enables OpenIDConnection authentication with Azure Active Directory. + +* `client_secret` - (Optional) The Client Secret of this relying party application. If no secret is provided, implicit flow will be used. + +* `allowed_audiences` (Optional) Allowed audience values to consider when validating JWTs issued by Azure Active Directory. + +--- + +A `facebook` block supports the following: + +* `app_id` - (Required) The App ID of the Facebook app used for login + +* `app_secret` - (Required) The App Secret of the Facebook app used for Facebook Login. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Facebook Login authentication. https://developers.facebook.com/docs/facebook-login + +--- + +A `google` block supports the following: + +* `client_id` - (Required) The OpenID Connect Client ID for the Google web application. + +* `client_secret` - (Required) The client secret associated with the Google web application. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Google Sign-In authentication. https://developers.google.com/identity/sign-in/web/ + +--- + +A `microsoft` block supports the following: + +* `client_id` - (Required) The OAuth 2.0 client ID that was created for the app used for authentication. + +* `client_secret` - (Required) The OAuth 2.0 client secret that was created for the app used for authentication. + +* `oauth_scopes` (Optional) The OAuth 2.0 scopes that will be requested as part of Microsoft Account authentication. https://msdn.microsoft.com/en-us/library/dn631845.aspx ## Attributes Reference diff --git a/website/docs/r/hdinsight_hadoop_cluster.html.markdown b/website/docs/r/hdinsight_hadoop_cluster.html.markdown new file mode 100644 index 000000000000..c677ace1e5ab --- /dev/null +++ b/website/docs/r/hdinsight_hadoop_cluster.html.markdown @@ -0,0 +1,230 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_hadoop_cluster" +sidebar_current: "docs-azurerm-resource-hdinsight-hadoop-cluster" +description: |- + Manages a HDInsight Hadoop Cluster. +--- + +# azurerm_hdinsight_hadoop_cluster + +Manages a HDInsight Hadoop Cluster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "hdinsightstor" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "hdinsight" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_hdinsight_hadoop_cluster" "example" { + name = "example-hdicluster" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hadoop = "2.7" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.example.id}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name for this HDInsight Hadoop Cluster. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight Hadoop Cluster should exist. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the Azure Region which this HDInsight Hadoop Cluster should exist. Changing this forces a new resource to be created. + +* `cluster_version` - (Required) Specifies the Version of HDInsights which should be used for this Cluster. Changing this forces a new resource to be created. + +* `component_version` - (Required) A `component_version` block as defined below. + +* `gateway` - (Required) A `gateway` block as defined below. + +* `roles` - (Required) A `roles` block as defined below. + +* `storage_account` - (Required) One or more `storage_account` block as defined below. + +* `tier` - (Required) Specifies the Tier which should be used for this HDInsight Hadoop Cluster. Possible values are `Standard` or `Premium`. Changing this forces a new resource to be created. + +--- + +* `tags` - (Optional) A map of Tags which should be assigned to this HDInsight Hadoop Cluster. + +--- + +A `component_version` block supports the following: + +* `hadoop` - (Required) The version of Hadoop which should be used for this HDInsight Hadoop Cluster. Changing this forces a new resource to be created. + +--- + +A `gateway` block supports the following: + +* `enabled` - (Required) Is the Ambari portal enabled? Changing this forces a new resource to be created. + +* `password` - (Required) The password used for the Ambari Portal. Changing this forces a new resource to be created. + +-> **NOTE:** This password must be different from the one used for the `head_node`, `worker_node` and `zookeeper_node` roles. + +* `username` - (Required) The username used for the Ambari Portal. Changing this forces a new resource to be created. + +--- + +A `head_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Head Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `roles` block supports the following: + +* `head_node` - (Required) A `head_node` block as defined above. + +* `worker_node` - (Required) A `worker_node` block as defined below. + +* `zookeeper_node` - (Required) A `zookeeper_node` block as defined below. + +--- + +A `storage_account` block supports the following: + +* `is_default` - (Required) Is this the Default Storage Account for the HDInsight Hadoop Cluster? Changing this forces a new resource to be created. + +-> **NOTE:** One of the `storage_account` blocks must be marked as the default. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to the Storage Account. Changing this forces a new resource to be created. + +* `storage_container_id` - (Required) The ID of the Storage Container. Changing this forces a new resource to be created. + +-> **NOTE:** This can be obtained from the `id` of the `azurerm_storage_container` resource. + +--- + +A `worker_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Worker Nodes. Changing this forces a new resource to be created. + +* `min_instance_count` - (Optional) The minimum number of instances which should be run for the Worker Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `target_instance_count` - (Optional) The number of instances which should be run for the Worker Nodes. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `zookeeper_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the HDInsight Hadoop Cluster. + +* `https_endpoint` - The HTTPS Connectivity Endpoint for this HDInsight Hadoop Cluster. + +* `ssh_endpoint` - The SSH Connectivity Endpoint for this HDInsight Hadoop Cluster. + +## Import + +HDInsight Hadoop Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_hdinsight_hadoop_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.HDInsight/clusters/cluster1} +``` diff --git a/website/docs/r/hdinsight_hbase_cluster.html.markdown b/website/docs/r/hdinsight_hbase_cluster.html.markdown new file mode 100644 index 000000000000..d4efaf934f62 --- /dev/null +++ b/website/docs/r/hdinsight_hbase_cluster.html.markdown @@ -0,0 +1,230 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_hbase_cluster" +sidebar_current: "docs-azurerm-resource-hdinsight-hbase-cluster" +description: |- + Manages a HDInsight HBase Cluster. +--- + +# azurerm_hdinsight_hbase_cluster + +Manages a HDInsight HBase Cluster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "hdinsightstor" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "hdinsight" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_hdinsight_hbase_cluster" "example" { + name = "example-hdicluster" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + hbase = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.example.id}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name for this HDInsight HBase Cluster. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight HBase Cluster should exist. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the Azure Region which this HDInsight HBase Cluster should exist. Changing this forces a new resource to be created. + +* `cluster_version` - (Required) Specifies the Version of HDInsights which should be used for this Cluster. Changing this forces a new resource to be created. + +* `component_version` - (Required) A `component_version` block as defined below. + +* `gateway` - (Required) A `gateway` block as defined below. + +* `roles` - (Required) A `roles` block as defined below. + +* `storage_account` - (Required) One or more `storage_account` block as defined below. + +* `tier` - (Required) Specifies the Tier which should be used for this HDInsight HBase Cluster. Possible values are `Standard` or `Premium`. Changing this forces a new resource to be created. + +--- + +* `tags` - (Optional) A map of Tags which should be assigned to this HDInsight HBase Cluster. + +--- + +A `component_version` block supports the following: + +* `hbase` - (Required) The version of HBase which should be used for this HDInsight HBase Cluster. Changing this forces a new resource to be created. + +--- + +A `gateway` block supports the following: + +* `enabled` - (Required) Is the Ambari portal enabled? Changing this forces a new resource to be created. + +* `password` - (Required) The password used for the Ambari Portal. Changing this forces a new resource to be created. + +-> **NOTE:** This password must be different from the one used for the `head_node`, `worker_node` and `zookeeper_node` roles. + +* `username` - (Required) The username used for the Ambari Portal. Changing this forces a new resource to be created. + +--- + +A `head_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Head Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `roles` block supports the following: + +* `head_node` - (Required) A `head_node` block as defined above. + +* `worker_node` - (Required) A `worker_node` block as defined below. + +* `zookeeper_node` - (Required) A `zookeeper_node` block as defined below. + +--- + +A `storage_account` block supports the following: + +* `is_default` - (Required) Is this the Default Storage Account for the HDInsight HBase Cluster? Changing this forces a new resource to be created. + +-> **NOTE:** One of the `storage_account` blocks must be marked as the default. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to the Storage Account. Changing this forces a new resource to be created. + +* `storage_container_id` - (Required) The ID of the Storage Container. Changing this forces a new resource to be created. + +-> **NOTE:** This can be obtained from the `id` of the `azurerm_storage_container` resource. + +--- + +A `worker_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Worker Nodes. Changing this forces a new resource to be created. + +* `min_instance_count` - (Optional) The minimum number of instances which should be run for the Worker Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `target_instance_count` - (Optional) The number of instances which should be run for the Worker Nodes. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `zookeeper_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the HDInsight HBase Cluster. + +* `https_endpoint` - The HTTPS Connectivity Endpoint for this HDInsight HBase Cluster. + +* `ssh_endpoint` - The SSH Connectivity Endpoint for this HDInsight HBase Cluster. + +## Import + +HDInsight HBase Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_hdinsight_hbase_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.HDInsight/clusters/cluster1} +``` diff --git a/website/docs/r/hdinsight_interactive_query_cluster.html.markdown b/website/docs/r/hdinsight_interactive_query_cluster.html.markdown new file mode 100644 index 000000000000..42810fc0e46b --- /dev/null +++ b/website/docs/r/hdinsight_interactive_query_cluster.html.markdown @@ -0,0 +1,234 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_interactive_query_cluster" +sidebar_current: "docs-azurerm-resource-hdinsight-interactive-query-cluster" +description: |- + Manages a HDInsight Interactive Query Cluster. +--- + +# azurerm_hdinsight_interactive_query_cluster + +Manages a HDInsight Interactive Query Cluster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "hdinsightstor" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "hdinsight" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_hdinsight_interactive_query_cluster" "example" { + name = "example-hdicluster" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + interactive_hive = "2.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.example.id}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D13_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D14_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name for this HDInsight Interactive Query Cluster. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight Interactive Query Cluster should exist. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the Azure Region which this HDInsight Interactive Query Cluster should exist. Changing this forces a new resource to be created. + +* `cluster_version` - (Required) Specifies the Version of HDInsights which should be used for this Cluster. Changing this forces a new resource to be created. + +* `component_version` - (Required) A `component_version` block as defined below. + +* `gateway` - (Required) A `gateway` block as defined below. + +* `roles` - (Required) A `roles` block as defined below. + +* `storage_account` - (Required) One or more `storage_account` block as defined below. + +* `tier` - (Required) Specifies the Tier which should be used for this HDInsight Interactive Query Cluster. Possible values are `Standard` or `Premium`. Changing this forces a new resource to be created. + +--- + +* `tags` - (Optional) A map of Tags which should be assigned to this HDInsight Interactive Query Cluster. + +--- + +A `component_version` block supports the following: + +* `interactive_query` - (Required) The version of Interactive Query which should be used for this HDInsight Interactive Query Cluster. Changing this forces a new resource to be created. + +--- + +A `gateway` block supports the following: + +* `enabled` - (Required) Is the Ambari portal enabled? Changing this forces a new resource to be created. + +* `password` - (Required) The password used for the Ambari Portal. Changing this forces a new resource to be created. + +-> **NOTE:** This password must be different from the one used for the `head_node`, `worker_node` and `zookeeper_node` roles. + +* `username` - (Required) The username used for the Ambari Portal. Changing this forces a new resource to be created. + +--- + +A `head_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** High memory instances must be specified for the Head Node (Azure suggests a `Standard_D13_V2`). + +* `password` - (Optional) The Password associated with the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `roles` block supports the following: + +* `head_node` - (Required) A `head_node` block as defined above. + +* `worker_node` - (Required) A `worker_node` block as defined below. + +* `zookeeper_node` - (Required) A `zookeeper_node` block as defined below. + +--- + +A `storage_account` block supports the following: + +* `is_default` - (Required) Is this the Default Storage Account for the HDInsight Interactive Query Cluster? Changing this forces a new resource to be created. + +-> **NOTE:** One of the `storage_account` blocks must be marked as the default. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to the Storage Account. Changing this forces a new resource to be created. + +* `storage_container_id` - (Required) The ID of the Storage Container. Changing this forces a new resource to be created. + +-> **NOTE:** This can be obtained from the `id` of the `azurerm_storage_container` resource. + +--- + +A `worker_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** High memory instances must be specified for the Head Node (Azure suggests a `Standard_D14_V2`). + +* `min_instance_count` - (Optional) The minimum number of instances which should be run for the Worker Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `target_instance_count` - (Optional) The number of instances which should be run for the Worker Nodes. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `zookeeper_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the HDInsight Interactive Query Cluster. + +* `https_endpoint` - The HTTPS Connectivity Endpoint for this HDInsight Interactive Query Cluster. + +* `ssh_endpoint` - The SSH Connectivity Endpoint for this HDInsight Interactive Query Cluster. + +## Import + +HDInsight Interactive Query Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_hdinsight_interactive_query_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.HDInsight/clusters/cluster1} +``` diff --git a/website/docs/r/hdinsight_kafka_cluster.html.markdown b/website/docs/r/hdinsight_kafka_cluster.html.markdown new file mode 100644 index 000000000000..72bac9ef48d7 --- /dev/null +++ b/website/docs/r/hdinsight_kafka_cluster.html.markdown @@ -0,0 +1,233 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_kafka_cluster" +sidebar_current: "docs-azurerm-resource-hdinsight-kafka-cluster" +description: |- + Manages a HDInsight Kafka Cluster. +--- + +# azurerm_hdinsight_kafka_cluster + +Manages a HDInsight Kafka Cluster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "hdinsightstor" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "hdinsight" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_hdinsight_kafka_cluster" "example" { + name = "example-hdicluster" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + kafka = "2.3" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.example.id}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + number_of_disks_per_node = 3 + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name for this HDInsight Kafka Cluster. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight Kafka Cluster should exist. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the Azure Region which this HDInsight Kafka Cluster should exist. Changing this forces a new resource to be created. + +* `cluster_version` - (Required) Specifies the Version of HDInsights which should be used for this Cluster. Changing this forces a new resource to be created. + +* `component_version` - (Required) A `component_version` block as defined below. + +* `gateway` - (Required) A `gateway` block as defined below. + +* `roles` - (Required) A `roles` block as defined below. + +* `storage_account` - (Required) One or more `storage_account` block as defined below. + +* `tier` - (Required) Specifies the Tier which should be used for this HDInsight Kafka Cluster. Possible values are `Standard` or `Premium`. Changing this forces a new resource to be created. + +--- + +* `tags` - (Optional) A map of Tags which should be assigned to this HDInsight Kafka Cluster. + +--- + +A `component_version` block supports the following: + +* `kafka` - (Required) The version of Kafka which should be used for this HDInsight Kafka Cluster. Changing this forces a new resource to be created. + +--- + +A `gateway` block supports the following: + +* `enabled` - (Required) Is the Ambari portal enabled? Changing this forces a new resource to be created. + +* `password` - (Required) The password used for the Ambari Portal. Changing this forces a new resource to be created. + +-> **NOTE:** This password must be different from the one used for the `head_node`, `worker_node` and `zookeeper_node` roles. + +* `username` - (Required) The username used for the Ambari Portal. Changing this forces a new resource to be created. + +--- + +A `head_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Head Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `roles` block supports the following: + +* `head_node` - (Required) A `head_node` block as defined above. + +* `worker_node` - (Required) A `worker_node` block as defined below. + +* `zookeeper_node` - (Required) A `zookeeper_node` block as defined below. + +--- + +A `storage_account` block supports the following: + +* `is_default` - (Required) Is this the Default Storage Account for the HDInsight Kafka Cluster? Changing this forces a new resource to be created. + +-> **NOTE:** One of the `storage_account` blocks must be marked as the default. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to the Storage Account. Changing this forces a new resource to be created. + +* `storage_container_id` - (Required) The ID of the Storage Container. Changing this forces a new resource to be created. + +-> **NOTE:** This can be obtained from the `id` of the `azurerm_storage_container` resource. + +--- + +A `worker_node` block supports the following: + +* `number_of_disks_per_node` - (Required) The number of Data Disks which should be assigned to each Worker Node, which can be between 1 and 8. Changing this forces a new resource to be created. + +* `username` - (Required) The Username of the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Worker Nodes. Changing this forces a new resource to be created. + +* `min_instance_count` - (Optional) The minimum number of instances which should be run for the Worker Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `target_instance_count` - (Optional) The number of instances which should be run for the Worker Nodes. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `zookeeper_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the HDInsight Kafka Cluster. + +* `https_endpoint` - The HTTPS Connectivity Endpoint for this HDInsight Kafka Cluster. + +* `ssh_endpoint` - The SSH Connectivity Endpoint for this HDInsight Kafka Cluster. + +## Import + +HDInsight Kafka Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_hdinsight_kafka_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.HDInsight/clusters/cluster1} +``` diff --git a/website/docs/r/hdinsight_ml_services_cluster.html.markdown b/website/docs/r/hdinsight_ml_services_cluster.html.markdown new file mode 100644 index 000000000000..02615fc934fc --- /dev/null +++ b/website/docs/r/hdinsight_ml_services_cluster.html.markdown @@ -0,0 +1,249 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_ml_services_cluster" +sidebar_current: "docs-azurerm-resource-hdinsight-ml-services-cluster" +description: |- + Manages a HDInsight ML Services Cluster. +--- + +# azurerm_hdinsight_ml_services_cluster + +Manages a HDInsight ML Services Cluster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "hdinsightstor" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "hdinsight" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_hdinsight_ml_services_cluster" "example" { + name = "example-hdicluster" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.example.id}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + edge_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name for this HDInsight ML Services Cluster. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight ML Services Cluster should exist. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the Azure Region which this HDInsight ML Services Cluster should exist. Changing this forces a new resource to be created. + +* `cluster_version` - (Required) Specifies the Version of HDInsights which should be used for this Cluster. Changing this forces a new resource to be created. + +* `gateway` - (Required) A `gateway` block as defined below. + +* `roles` - (Required) A `roles` block as defined below. + +* `rstudio` - (Required) Should R Studio community edition for ML Services be installed? Changing this forces a new resource to be created. + +* `storage_account` - (Required) One or more `storage_account` block as defined below. + +* `tier` - (Required) Specifies the Tier which should be used for this HDInsight ML Services Cluster. Possible values are `Standard` or `Premium`. Changing this forces a new resource to be created. + +--- + +* `tags` - (Optional) A map of Tags which should be assigned to this HDInsight ML Services Cluster. + +--- + +A `gateway` block supports the following: + +* `enabled` - (Required) Is the Ambari portal enabled? Changing this forces a new resource to be created. + +* `password` - (Required) The password used for the Ambari Portal. Changing this forces a new resource to be created. + +-> **NOTE:** This password must be different from the one used for the `head_node`, `worker_node` and `zookeeper_node` roles. + +* `username` - (Required) The username used for the Ambari Portal. Changing this forces a new resource to be created. + +--- + +A `edge_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Edge Node. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Edge Node. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Edge Node. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Edge Node. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Edge Node should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Edge Node should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `head_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Head Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `roles` block supports the following: + +* `edge_node` - (Required) A `edge_node` block as defined above. + +* `head_node` - (Required) A `head_node` block as defined above. + +* `worker_node` - (Required) A `worker_node` block as defined below. + +* `zookeeper_node` - (Required) A `zookeeper_node` block as defined below. + +--- + +A `storage_account` block supports the following: + +* `is_default` - (Required) Is this the Default Storage Account for the HDInsight ML Services Cluster? Changing this forces a new resource to be created. + +-> **NOTE:** One of the `storage_account` blocks must be marked as the default. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to the Storage Account. Changing this forces a new resource to be created. + +* `storage_container_id` - (Required) The ID of the Storage Container. Changing this forces a new resource to be created. + +-> **NOTE:** This can be obtained from the `id` of the `azurerm_storage_container` resource. + +--- + +A `worker_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Worker Nodes. Changing this forces a new resource to be created. + +* `min_instance_count` - (Optional) The minimum number of instances which should be run for the Worker Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `target_instance_count` - (Optional) The number of instances which should be run for the Worker Nodes. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `zookeeper_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the HDInsight ML Services Cluster. + +* `edge_ssh_endpoint` - The SSH Connectivity Endpoint for the Edge Node of the HDInsight ML Cluster. + +* `https_endpoint` - The HTTPS Connectivity Endpoint for this HDInsight ML Services Cluster. + +* `ssh_endpoint` - The SSH Connectivity Endpoint for this HDInsight ML Services Cluster. + +## Import + +HDInsight ML Services Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_hdinsight_ml_services_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.HDInsight/clusters/cluster1} +``` diff --git a/website/docs/r/hdinsight_rserver_cluster.html.markdown b/website/docs/r/hdinsight_rserver_cluster.html.markdown new file mode 100644 index 000000000000..502f0fc7ad92 --- /dev/null +++ b/website/docs/r/hdinsight_rserver_cluster.html.markdown @@ -0,0 +1,249 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_rserver_cluster" +sidebar_current: "docs-azurerm-resource-hdinsight-rserver-cluster" +description: |- + Manages a HDInsight RServer Cluster. +--- + +# azurerm_hdinsight_rserver_cluster + +Manages a HDInsight RServer Cluster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "hdinsightstor" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "hdinsight" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_hdinsight_rserver_cluster" "example" { + name = "example-hdicluster" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + cluster_version = "3.6" + tier = "Standard" + rstudio = true + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.example.id}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + edge_node { + vm_size = "Standard_D3_v2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name for this HDInsight RServer Cluster. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight RServer Cluster should exist. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the Azure Region which this HDInsight RServer Cluster should exist. Changing this forces a new resource to be created. + +* `cluster_version` - (Required) Specifies the Version of HDInsights which should be used for this Cluster. Changing this forces a new resource to be created. + +* `gateway` - (Required) A `gateway` block as defined below. + +* `roles` - (Required) A `roles` block as defined below. + +* `rstudio` - (Required) Should R Studio community edition for RServer be installed? Changing this forces a new resource to be created. + +* `storage_account` - (Required) One or more `storage_account` block as defined below. + +* `tier` - (Required) Specifies the Tier which should be used for this HDInsight RServer Cluster. Possible values are `Standard` or `Premium`. Changing this forces a new resource to be created. + +--- + +* `tags` - (Optional) A map of Tags which should be assigned to this HDInsight RServer Cluster. + +--- + +A `gateway` block supports the following: + +* `enabled` - (Required) Is the Ambari portal enabled? Changing this forces a new resource to be created. + +* `password` - (Required) The password used for the Ambari Portal. Changing this forces a new resource to be created. + +-> **NOTE:** This password must be different from the one used for the `head_node`, `worker_node` and `zookeeper_node` roles. + +* `username` - (Required) The username used for the Ambari Portal. Changing this forces a new resource to be created. + +--- + +A `edge_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Edge Node. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Edge Node. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Edge Node. Changing this forces a new resource to be created. + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Edge Node. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Edge Node should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Edge Node should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `head_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Head Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `roles` block supports the following: + +* `edge_node` - (Required) A `edge_node` block as defined above. + +* `head_node` - (Required) A `head_node` block as defined above. + +* `worker_node` - (Required) A `worker_node` block as defined below. + +* `zookeeper_node` - (Required) A `zookeeper_node` block as defined below. + +--- + +A `storage_account` block supports the following: + +* `is_default` - (Required) Is this the Default Storage Account for the HDInsight RServer Cluster? Changing this forces a new resource to be created. + +-> **NOTE:** One of the `storage_account` blocks must be marked as the default. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to the Storage Account. Changing this forces a new resource to be created. + +* `storage_container_id` - (Required) The ID of the Storage Container. Changing this forces a new resource to be created. + +-> **NOTE:** This can be obtained from the `id` of the `azurerm_storage_container` resource. + +--- + +A `worker_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Worker Nodes. Changing this forces a new resource to be created. + +* `min_instance_count` - (Optional) The minimum number of instances which should be run for the Worker Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `target_instance_count` - (Optional) The number of instances which should be run for the Worker Nodes. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `zookeeper_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the HDInsight RServer Cluster. + +* `edge_ssh_endpoint` - The SSH Connectivity Endpoint for the Edge Node of the HDInsight RServer Cluster. + +* `https_endpoint` - The HTTPS Connectivity Endpoint for this HDInsight RServer Cluster. + +* `ssh_endpoint` - The SSH Connectivity Endpoint for this HDInsight RServer Cluster. + +## Import + +HDInsight RServer Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_hdinsight_rserver_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.HDInsight/clusters/cluster1} +``` diff --git a/website/docs/r/hdinsight_spark_cluster.html.markdown b/website/docs/r/hdinsight_spark_cluster.html.markdown new file mode 100644 index 000000000000..874a77bbf699 --- /dev/null +++ b/website/docs/r/hdinsight_spark_cluster.html.markdown @@ -0,0 +1,230 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_spark_cluster" +sidebar_current: "docs-azurerm-resource-hdinsight-spark-cluster" +description: |- + Manages a HDInsight Spark Cluster. +--- + +# azurerm_hdinsight_spark_cluster + +Manages a HDInsight Spark Cluster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "hdinsightstor" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "hdinsight" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_hdinsight_spark_cluster" "example" { + name = "example-hdicluster" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + spark = "2.3" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.example.id}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A3" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_A3" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Medium" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name for this HDInsight Spark Cluster. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight Spark Cluster should exist. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the Azure Region which this HDInsight Spark Cluster should exist. Changing this forces a new resource to be created. + +* `cluster_version` - (Required) Specifies the Version of HDInsights which should be used for this Cluster. Changing this forces a new resource to be created. + +* `component_version` - (Required) A `component_version` block as defined below. + +* `gateway` - (Required) A `gateway` block as defined below. + +* `roles` - (Required) A `roles` block as defined below. + +* `storage_account` - (Required) One or more `storage_account` block as defined below. + +* `tier` - (Required) Specifies the Tier which should be used for this HDInsight Spark Cluster. Possible values are `Standard` or `Premium`. Changing this forces a new resource to be created. + +--- + +* `tags` - (Optional) A map of Tags which should be assigned to this HDInsight Spark Cluster. + +--- + +A `component_version` block supports the following: + +* `spark` - (Required) The version of Spark which should be used for this HDInsight Spark Cluster. Changing this forces a new resource to be created. + +--- + +A `gateway` block supports the following: + +* `enabled` - (Required) Is the Ambari portal enabled? Changing this forces a new resource to be created. + +* `password` - (Required) The password used for the Ambari Portal. Changing this forces a new resource to be created. + +-> **NOTE:** This password must be different from the one used for the `head_node`, `worker_node` and `zookeeper_node` roles. + +* `username` - (Required) The username used for the Ambari Portal. Changing this forces a new resource to be created. + +--- + +A `head_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Head Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `roles` block supports the following: + +* `head_node` - (Required) A `head_node` block as defined above. + +* `worker_node` - (Required) A `worker_node` block as defined below. + +* `zookeeper_node` - (Required) A `zookeeper_node` block as defined below. + +--- + +A `storage_account` block supports the following: + +* `is_default` - (Required) Is this the Default Storage Account for the HDInsight Spark Cluster? Changing this forces a new resource to be created. + +-> **NOTE:** One of the `storage_account` blocks must be marked as the default. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to the Storage Account. Changing this forces a new resource to be created. + +* `storage_container_id` - (Required) The ID of the Storage Container. Changing this forces a new resource to be created. + +-> **NOTE:** This can be obtained from the `id` of the `azurerm_storage_container` resource. + +--- + +A `worker_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Worker Nodes. Changing this forces a new resource to be created. + +* `min_instance_count` - (Optional) The minimum number of instances which should be run for the Worker Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `target_instance_count` - (Optional) The number of instances which should be run for the Worker Nodes. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `zookeeper_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the HDInsight Spark Cluster. + +* `https_endpoint` - The HTTPS Connectivity Endpoint for this HDInsight Spark Cluster. + +* `ssh_endpoint` - The SSH Connectivity Endpoint for this HDInsight Spark Cluster. + +## Import + +HDInsight Spark Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_hdinsight_spark_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.HDInsight/clusters/cluster1} +``` diff --git a/website/docs/r/hdinsight_storm_cluster.html.markdown b/website/docs/r/hdinsight_storm_cluster.html.markdown new file mode 100644 index 000000000000..bd76bd256eb2 --- /dev/null +++ b/website/docs/r/hdinsight_storm_cluster.html.markdown @@ -0,0 +1,234 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_hdinsight_storm_cluster" +sidebar_current: "docs-azurerm-resource-hdinsight-storm-cluster" +description: |- + Manages a HDInsight Storm Cluster. +--- + +# azurerm_hdinsight_storm_cluster + +Manages a HDInsight Storm Cluster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_storage_account" "example" { + name = "hdinsightstor" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "hdinsight" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_hdinsight_storm_cluster" "example" { + name = "example-hdicluster" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + cluster_version = "3.6" + tier = "Standard" + + component_version { + storm = "1.1" + } + + gateway { + enabled = true + username = "acctestusrgw" + password = "TerrAform123!" + } + + storage_account { + storage_container_id = "${azurerm_storage_container.example.id}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + is_default = true + } + + roles { + head_node { + vm_size = "Standard_A3" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + + worker_node { + vm_size = "Standard_D3_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + target_instance_count = 3 + } + + zookeeper_node { + vm_size = "Standard_A4_V2" + username = "acctestusrvm" + password = "AccTestvdSC4daf986!" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name for this HDInsight Storm Cluster. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group in which this HDInsight Storm Cluster should exist. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the Azure Region which this HDInsight Storm Cluster should exist. Changing this forces a new resource to be created. + +* `cluster_version` - (Required) Specifies the Version of HDInsights which should be used for this Cluster. Changing this forces a new resource to be created. + +* `component_version` - (Required) A `component_version` block as defined below. + +* `gateway` - (Required) A `gateway` block as defined below. + +* `roles` - (Required) A `roles` block as defined below. + +* `storage_account` - (Required) One or more `storage_account` block as defined below. + +* `tier` - (Required) Specifies the Tier which should be used for this HDInsight Storm Cluster. Possible values are `Standard` or `Premium`. Changing this forces a new resource to be created. + +--- + +* `tags` - (Optional) A map of Tags which should be assigned to this HDInsight Storm Cluster. + +--- + +A `component_version` block supports the following: + +* `storm` - (Required) The version of Storm which should be used for this HDInsight Storm Cluster. Changing this forces a new resource to be created. + +--- + +A `gateway` block supports the following: + +* `enabled` - (Required) Is the Ambari portal enabled? Changing this forces a new resource to be created. + +* `password` - (Required) The password used for the Ambari Portal. Changing this forces a new resource to be created. + +-> **NOTE:** This password must be different from the one used for the `head_node`, `worker_node` and `zookeeper_node` roles. + +* `username` - (Required) The username used for the Ambari Portal. Changing this forces a new resource to be created. + +--- + +A `head_node` block supports the following: + +-> **NOTE:** This is also known as the `nimbus` node. + +* `username` - (Required) The Username of the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Head Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Head Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Head Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `roles` block supports the following: + +* `head_node` - (Required) A `head_node` block as defined above. + +* `worker_node` - (Required) A `worker_node` block as defined below. + +* `zookeeper_node` - (Required) A `zookeeper_node` block as defined below. + +--- + +A `storage_account` block supports the following: + +* `is_default` - (Required) Is this the Default Storage Account for the HDInsight Storm Cluster? Changing this forces a new resource to be created. + +-> **NOTE:** One of the `storage_account` blocks must be marked as the default. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to the Storage Account. Changing this forces a new resource to be created. + +* `storage_container_id` - (Required) The ID of the Storage Container. Changing this forces a new resource to be created. + +-> **NOTE:** This can be obtained from the `id` of the `azurerm_storage_container` resource. + +--- + +A `worker_node` block supports the following: + +-> **NOTE:** This is also known as the `supervisor` node. + +* `username` - (Required) The Username of the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Worker Nodes. Changing this forces a new resource to be created. + +* `min_instance_count` - (Optional) The minimum number of instances which should be run for the Worker Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Worker Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `target_instance_count` - (Optional) The number of instances which should be run for the Worker Nodes. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Worker Nodes should be provisioned within. Changing this forces a new resource to be created. + +--- + +A `zookeeper_node` block supports the following: + +* `username` - (Required) The Username of the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `vm_size` - (Required) The Size of the Virtual Machine which should be used as the Zookeeper Nodes. Changing this forces a new resource to be created. + +* `password` - (Optional) The Password associated with the local administrator for the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** If specified, this password must be at least 10 characters in length and must contain at least one digit, one uppercase and one lower case letter, one non-alphanumeric character (except characters ' " ` \). + +* `ssh_keys` - (Optional) A list of SSH Keys which should be used for the local administrator on the Zookeeper Nodes. Changing this forces a new resource to be created. + +-> **NOTE:** Either a `password` or one or more `ssh_keys` must be specified - but not both. + +* `subnet_id` - (Optional) The ID of the Subnet within the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +* `virtual_network_id` - (Optional) The ID of the Virtual Network where the Zookeeper Nodes should be provisioned within. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the HDInsight Storm Cluster. + +* `https_endpoint` - The HTTPS Connectivity Endpoint for this HDInsight Storm Cluster. + +* `ssh_endpoint` - The SSH Connectivity Endpoint for this HDInsight Storm Cluster. + +## Import + +HDInsight Storm Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_hdinsight_storm_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.HDInsight/clusters/cluster1} +``` diff --git a/website/docs/r/image.html.markdown b/website/docs/r/image.html.markdown index 799802930c25..1b01e0e891d1 100644 --- a/website/docs/r/image.html.markdown +++ b/website/docs/r/image.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_image -Manage a custom virtual machine image that can be used to create virtual machines. +Manages a custom virtual machine image that can be used to create virtual machines. ## Example Usage Creating from VHD @@ -62,6 +62,9 @@ The following arguments are supported: * `os_disk` - (Optional) One or more `os_disk` elements as defined below. * `data_disk` - (Optional) One or more `data_disk` elements as defined below. * `tags` - (Optional) A mapping of tags to assign to the resource. +* `zone_resilient` - (Optional) Is zone resiliency enabled? Defaults to `false`. Changing this forces a new resource to be created. + +~> **Note**: `zone_resilient` can only be set to `true` if the image is stored in a region that supports availability zones. `os_disk` supports the following: diff --git a/website/docs/r/iot_dps.html.markdown b/website/docs/r/iot_dps.html.markdown new file mode 100644 index 000000000000..6be2e507ba2b --- /dev/null +++ b/website/docs/r/iot_dps.html.markdown @@ -0,0 +1,86 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_iot_dps" +sidebar_current: "docs-azurerm-resource-messaging-iot-dps-x" +description: |- + Manages an IoT Device Provisioning Service. +--- + +# azurerm_iot_dps + +Manages an IoT Device Provisioning Service. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "resourceGroup1" + location = "West US" +} + +resource "azurerm_iot_dps" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Iot Device Provisioning Service resource. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group under which the Iot Device Provisioning Service resource has to be created. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource has to be createc. Changing this forces a new resource to be created. + +* `sku` - (Required) A `sku` block as defined below. + +* `linked_hub` - (Optional) A `linked_hub` block as defined below. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +A `sku` block supports the following: + +* `name` - (Required) The name of the sku. Possible values are `B1`, `B2`, `B3`, `F1`, `S1`, `S2`, and `S3`. + +* `tier` - (Required) The billing tier for the IoT Device Provisioning Service. Possible values are `Basic`, `Free` or `Standard`. + +* `capacity` - (Required) The number of provisioned IoT Device Provisioning Service units. + +--- + +A `linked_hub` block supports the following: + +* `connection_string` - (Required) The connection string to connect to the IoT Hub. Changing this forces a new resource. + +* `location` - (Required) The location of the IoT hub. Changing this forces a new resource. + +* `apply_application_policy` - (Optional) Determines whether to apply application policies to the IoT Hub. Defaults to false. + +* `allocation_weight` - (Optional) The weight applied to the IoT Hub. Defaults to 0. + +* `hostname` - (Computed) The IoT Hub hostname. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the IoT Device Provisioning Service. + +## Import + +IoT Device Provisioning Service can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_iot_dps.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Devices/provisioningServices/example +``` diff --git a/website/docs/r/iot_dps_certificate.html.markdown b/website/docs/r/iot_dps_certificate.html.markdown new file mode 100644 index 000000000000..0d22fdfc9c1d --- /dev/null +++ b/website/docs/r/iot_dps_certificate.html.markdown @@ -0,0 +1,66 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_iot_dps_certificate" +sidebar_current: "docs-azurerm-resource-messaging-iot-dps_certificate" +description: |- + Manages an IoT Device Provisioning Service Certificate. +--- + +# azurerm_iot_dps_certificate + +Manages an IoT Device Provisioning Service Certificate. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "resourceGroup1" + location = "West US" +} + +resource "azurerm_iot_dps" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} + +resource "azurerm_iot_dps_certificate" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + iot_dps_name = "${azurerm_iot_dps.example.name}" + + certificate_content = "${filebase64("example.cer")}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Iot Device Provisioning Service Certificate resource. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group under which the Iot Device Provisioning Service Certificate resource has to be created. Changing this forces a new resource to be created. + +* `iot_dps_name` - (Required) The name of the IoT Device Provisioning Service that this certificate will be attached to. Changing this forces a new resource to be created. + +* `certificate_content` - (Required) The Base-64 representation of the X509 leaf certificate .cer file or just a .pem file content. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the IoT Device Provisioning Service Certificate. + +## Import + +IoT Device Provisioning Service Certificate can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_iot_dps_certificate.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Devices/provisioningServices/example/certificates/example +``` diff --git a/website/docs/r/iothub.html.markdown b/website/docs/r/iothub.html.markdown index f3e99e327af6..b41347637c4c 100644 --- a/website/docs/r/iothub.html.markdown +++ b/website/docs/r/iothub.html.markdown @@ -64,11 +64,21 @@ resource "azurerm_iothub" "test" { } fallback_route { - enabled = true + enabled = true + } + + file_upload { + connection_string = "${azurerm_storage_account.test.primary_blob_connection_string}" + container_name = "${azurerm_storage_container.test.name}" + sas_ttl = "PT1H" + notifications = true + lock_duration = "PT1M" + default_ttl = "PT1H" + max_delivery_count = 10 } tags = { - "purpose" = "testing" + purpose = "testing" } } ``` @@ -87,10 +97,14 @@ The following arguments are supported: * `endpoint` - (Optional) An `endpoint` block as defined below. +* `ip_filter_rule` - (Optional) One or more `ip_filter_rule` blocks as defined below. + * `route` - (Optional) A `route` block as defined below. * `fallback_route` - (Optional) A `fallback_route` block as defined below. If the fallback route is enabled, messages that don't match any of the supplied routes are automatically sent to this route. Defaults to messages/events. +* `file_upload` - (Optional) A `file_upload` block as defined below. + * `tags` - (Optional) A mapping of tags to assign to the resource. --- @@ -127,6 +141,16 @@ An `endpoint` block supports the following: --- +An `ip_filter_rule` block supports the following: + +* `name` - (Required) The name of the filter. + +* `ip_mask` - (Required) The IP address range in CIDR notation for the rule. + +* `action` - (Required) The desired action for requests captured by this rule. Possible values are `Accept`, `Reject` + +--- + A `route` block supports the following: * `name` - (Required) The name of the route. @@ -151,6 +175,25 @@ A `fallback_route` block supports the following: * `enabled` - (Optional) Used to specify whether the fallback route is enabled. +--- + +A `file_upload` block supports the following: + +* `connection_string` - (Required) The connection string for the Azure Storage account to which files are uploaded. + +* `container_name` - (Required) The name of the root container where you upload files. The container need not exist but should be creatable using the connection_string specified. + +* `sas_ttl` - (Optional) The period of time for which the SAS URI generated by IoT Hub for file upload is valid, specified as an [ISO 8601 timespan duration](https://en.wikipedia.org/wiki/ISO_8601#Durations). This value must be between 1 minute and 24 hours, and evaluates to 'PT1H' by default. + +* `notifications` - (Optional) Used to specify whether file notifications are sent to IoT Hub on upload. It evaluates to false by default. + +* `lock_duration` - (Optional) The lock duration for the file upload notifications queue, specified as an [ISO 8601 timespan duration](https://en.wikipedia.org/wiki/ISO_8601#Durations). This value must be between 5 and 300 seconds, and evaluates to 'PT1M' by default. + +* `default_ttl` - (Optional) The period of time for which a file upload notification message is available to consume before it is expired by the IoT hub, specified as an [ISO 8601 timespan duration](https://en.wikipedia.org/wiki/ISO_8601#Durations). This value must be between 1 minute and 48 hours, and evaluates to 'PT1H' by default. + +* `max_delivery_count` - (Optional) The number of times the IoT hub attempts to deliver a file upload notification message. It evaluates to 10 by default. + + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/iothub_consumer_group.html.markdown b/website/docs/r/iothub_consumer_group.html.markdown index 2b8d86f365d5..c97c6784ae0d 100644 --- a/website/docs/r/iothub_consumer_group.html.markdown +++ b/website/docs/r/iothub_consumer_group.html.markdown @@ -30,7 +30,7 @@ resource "azurerm_iothub" "test" { } tags = { - "purpose" = "testing" + purpose = "testing" } } diff --git a/website/docs/r/iothub_shared_access_policy.html.markdown b/website/docs/r/iothub_shared_access_policy.html.markdown new file mode 100644 index 000000000000..83cac4b73908 --- /dev/null +++ b/website/docs/r/iothub_shared_access_policy.html.markdown @@ -0,0 +1,85 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_iothub_shared_access_policy" +sidebar_current: "docs-azurerm-resource-messaging-iothub-shared-access-policy-x" +description: |- + Manages an IotHub Shared Access Policy +--- + +# azurerm_iothub_shared_access_policy + +Manages an IotHub Shared Access Policy + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "resourceGroup1" + location = "West US" +} + +resource "azurerm_iothub" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} + +resource "azurerm_iothub_shared_access_policy" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + iothub_name = "${azurerm_iothub.example.name}" + + registry_read = true + registry_write = true +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the IotHub Shared Access Policy resource. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group under which the IotHub Shared Access Policy resource has to be created. Changing this forces a new resource to be created. + +* `iothub_name` - (Required) The name of the IoTHub to which this Shared Access Policy belongs. Changing this forces a new resource to be created. + +* `registry_read` - (Optional) Adds `RegistryRead` permission to this Shared Access Account. It allows read access to the identity registry. + +* `registry_write` - (Optional) Adds `RegistryWrite` permission to this Shared Access Account. It allows write access to the identity registry. + +-> **NOTE** When `registry_write` is set to `true`, `registry_read` must also be set to true. This is a limitation of the Azure REST API + +* `service_connect` - (Optional) Adds `ServiceConnect` permission to this Shared Access Account. It allows sending and receiving on the cloud-side endpoints. + +* `device_connect` - (Optional) Adds `DeviceConnect` permission to this Shared Access Account. It allows sending and receiving on the device-side endpoints. + +-> **NOTE** At least one of `registry_read`, `registry_write`, `service_connect`, `device_connect` permissions must be set to `true`. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the IoTHub Shared Access Policy. + +* `primary_key` - The primary key used to create the authentication token. + +* `primary_connection_string` - The primary connection string of the Shared Access Policy. + +* `secondary_key` - The secondary key used to create the authentication token. + +* `secondary_connection_string` - The secondary connection string of the Shared Access Policy. + +## Import + +IoTHub Shared Access Policies can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_iothub_shared_access_policy.shared_access_policy1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Devices/IotHubs/hub1/IotHubKeys/shared_access_policy1 +``` diff --git a/website/docs/r/key_vault.html.markdown b/website/docs/r/key_vault.html.markdown index b2b95b635fac..1133ddab59e8 100644 --- a/website/docs/r/key_vault.html.markdown +++ b/website/docs/r/key_vault.html.markdown @@ -27,9 +27,7 @@ resource "azurerm_key_vault" "test" { enabled_for_disk_encryption = true tenant_id = "d6e396d0-5584-41dc-9fc0-268df99bc610" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "d6e396d0-5584-41dc-9fc0-268df99bc610" @@ -42,6 +40,10 @@ resource "azurerm_key_vault" "test" { secret_permissions = [ "get", ] + + storage_permissions = [ + "get", + ] } network_acls { @@ -65,12 +67,14 @@ The following arguments are supported: * `resource_group_name` - (Required) The name of the resource group in which to create the Key Vault. Changing this forces a new resource to be created. -* `sku` - (Required) An SKU block as described below. +* `sku` - (Optional **Deprecated**)) A `sku` block as described below. + +* `sku_name` - (Optional) The Name of the SKU used for this Key Vault. Possible values are `standard` and `premium`. * `tenant_id` - (Required) The Azure Active Directory tenant ID that should be used for authenticating requests to the key vault. -* `access_policy` - (Optional) An access policy block as described below. A maximum of 16 may be declared. - +* `access_policy` - (Optional) [A list](/docs/configuration/attr-as-blocks.html) of up to 16 objects describing access policies, as described below. + ~> **NOTE:** It's possible to define Key Vault Access Policies both within [the `azurerm_key_vault` resource](key_vault.html) via the `access_policy` block and by using [the `azurerm_key_vault_access_policy` resource](key_vault_access_policy.html). However it's not possible to use both methods to manage Access Policies within a KeyVault, since there'll be conflicts. * `enabled_for_deployment` - (Optional) Boolean flag to specify whether Azure Virtual Machines are permitted to retrieve certificates stored as secrets from the key vault. Defaults to `false`. @@ -84,9 +88,15 @@ The following arguments are supported: * `tags` - (Optional) A mapping of tags to assign to the resource. --- +A `sku` block supports the following: + +* `name` - (Required) The Name of the SKU used for this Key Vault. Possible values are `standard` and `premium`. +--- A `access_policy` block supports the following: +Elements of `access_policy` support: + * `tenant_id` - (Required) The Azure Active Directory tenant ID that should be used for authenticating requests to the key vault. Must match the `tenant_id` used above. * `object_id` - (Required) The object ID of a user, service principal or security group in the Azure Active Directory tenant for the vault. The object ID must be unique for the list of access policies. @@ -95,10 +105,11 @@ A `access_policy` block supports the following: * `certificate_permissions` - (Optional) List of certificate permissions, must be one or more from the following: `backup`, `create`, `delete`, `deleteissuers`, `get`, `getissuers`, `import`, `list`, `listissuers`, `managecontacts`, `manageissuers`, `purge`, `recover`, `restore`, `setissuers` and `update`. -* `key_permissions` - (Required) List of key permissions, must be one or more from the following: `backup`, `create`, `decrypt`, `delete`, `encrypt`, `get`, `import`, `list`, `purge`, `recover`, `restore`, `sign`, `unwrapKey`, `update`, `verify` and `wrapKey`. +* `key_permissions` - (Optional) List of key permissions, must be one or more from the following: `backup`, `create`, `decrypt`, `delete`, `encrypt`, `get`, `import`, `list`, `purge`, `recover`, `restore`, `sign`, `unwrapKey`, `update`, `verify` and `wrapKey`. -* `secret_permissions` - (Required) List of secret permissions, must be one or more from the following: `backup`, `delete`, `get`, `list`, `purge`, `recover`, `restore` and `set`. +* `secret_permissions` - (Optional) List of secret permissions, must be one or more from the following: `backup`, `delete`, `get`, `list`, `purge`, `recover`, `restore` and `set`. +* `storage_permissions` - (Optional) List of storage permissions, must be one or more from the following: `backup`, `delete`, `deletesas`, `get`, `getsas`, `list`, `listsas`, `purge`, `recover`, `regeneratekey`, `restore`, `set`, `setsas` and `update`. --- @@ -108,17 +119,10 @@ A `network_acls` block supports the following: * `default_action` - (Required) The Default Action to use when no rules match from `ip_rules` / `virtual_network_subnet_ids`. Possible values are `Allow` and `Deny`. -* `ip_rules` - (Optional) One or more IP Addresses, or CIDR Blocks which should be able to access thie Key Vault. +* `ip_rules` - (Optional) One or more IP Addresses, or CIDR Blocks which should be able to access the Key Vault. * `virtual_network_subnet_ids` - (Optional) One or more Subnet ID's which should be able to access this Key Vault. ---- - -A `sku` block supports the following: - -* `name` - (Required) The Name of the SKU used for this Key Vault. Possible values are `standard` and `premium`. - - ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/key_vault_access_policy.html.markdown b/website/docs/r/key_vault_access_policy.html.markdown index 552e4316188d..23e53bfa1073 100644 --- a/website/docs/r/key_vault_access_policy.html.markdown +++ b/website/docs/r/key_vault_access_policy.html.markdown @@ -27,9 +27,7 @@ resource "azurerm_key_vault" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - sku { - name = "standard" - } + sku_name = "standard" tenant_id = "22222222-2222-2222-2222-222222222222" @@ -41,8 +39,7 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_access_policy" "test" { - vault_name = "${azurerm_key_vault.test.name}" - resource_group_name = "${azurerm_key_vault.test.resource_group_name}" + key_vault_id = "${azurerm_key_vault.test.id}" tenant_id = "00000000-0000-0000-0000-000000000000" object_id = "11111111-1111-1111-1111-111111111111" @@ -61,10 +58,15 @@ resource "azurerm_key_vault_access_policy" "test" { The following arguments are supported: -* `vault_name` - (Required) Specifies the name of the Key Vault resource. Changing this +* `key_vault_id` - (Required) Specifies the id of the Key Vault resource. Changing this forces a new resource to be created. -* `resource_group_name` - (Required) The name of the resource group in which to +-> **NOTE:** At this time the Key Vault `<->` Key Vault Access Policy associations need to be configured using the field `key_vault_id` or using both fields `vault_name` and `resource_group_name`. These fields are now deprecated and will be removed in favour of `key_vault_id` in the next major version (2.0) of the AzureRM Provider. + +* `vault_name` - (Required / **Deprecated**) Specifies the name of the Key Vault resource. Changing this + forces a new resource to be created. + +* `resource_group_name` - (Required / **Deprecated**) The name of the resource group in which to create the namespace. Changing this forces a new resource to be created. * `tenant_id` - (Required) The Azure Active Directory tenant ID that should be used @@ -89,6 +91,8 @@ The following arguments are supported: * `secret_permissions` - (Required) List of secret permissions, must be one or more from the following: `backup`, `delete`, `get`, `list`, `purge`, `recover`, `restore` and `set`. +* `storage_permissions` - (Optional) List of storage permissions, must be one or more from the following: `backup`, `delete`, `deletesas`, `get`, `getsas`, `list`, `listsas`, `purge`, `recover`, `regeneratekey`, `restore`, `set`, `setsas` and `update`. + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/key_vault_certificate.html.markdown b/website/docs/r/key_vault_certificate.html.markdown index a4453cec20dd..018629dc49de 100644 --- a/website/docs/r/key_vault_certificate.html.markdown +++ b/website/docs/r/key_vault_certificate.html.markdown @@ -29,9 +29,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -89,11 +87,11 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "imported-cert" + name = "imported-cert" key_vault_id = "${azurerm_key_vault.test.id}" certificate { - contents = "${base64encode(file("certificate-to-import.pfx"))}" + contents = "${filebase64("certificate-to-import.pfx")}" password = "" } @@ -132,29 +130,55 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "standard" - } + sku_name = "standard" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" object_id = "${data.azurerm_client_config.current.service_principal_object_id}" certificate_permissions = [ - "create","delete","deleteissuers", - "get","getissuers","import","list", - "listissuers","managecontacts","manageissuers", - "setissuers","update", + "create", + "delete", + "deleteissuers", + "get", + "getissuers", + "import", + "list", + "listissuers", + "managecontacts", + "manageissuers", + "setissuers", + "update", ] key_permissions = [ - "backup","create","decrypt","delete","encrypt","get", - "import","list","purge","recover","restore","sign", - "unwrapKey","update","verify","wrapKey", + "backup", + "create", + "decrypt", + "delete", + "encrypt", + "get", + "import", + "list", + "purge", + "recover", + "restore", + "sign", + "unwrapKey", + "update", + "verify", + "wrapKey", ] secret_permissions = [ - "backup","delete","get","list","purge","recover","restore","set", + "backup", + "delete", + "get", + "list", + "purge", + "recover", + "restore", + "set", ] } @@ -164,7 +188,7 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_certificate" "test" { - name = "generated-cert" + name = "generated-cert" key_vault_id = "${azurerm_key_vault.test.id}" certificate_policy { diff --git a/website/docs/r/key_vault_key.html.markdown b/website/docs/r/key_vault_key.html.markdown index 022ece97dcde..78169d4cace9 100644 --- a/website/docs/r/key_vault_key.html.markdown +++ b/website/docs/r/key_vault_key.html.markdown @@ -35,9 +35,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -59,10 +57,10 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_key" "generated" { - name = "generated-certificate" + name = "generated-certificate" key_vault_id = "${azurerm_key_vault.test.id}" - key_type = "RSA" - key_size = 2048 + key_type = "RSA" + key_size = 2048 key_opts = [ "decrypt", @@ -81,11 +79,13 @@ The following arguments are supported: * `name` - (Required) Specifies the name of the Key Vault Key. Changing this forces a new resource to be created. -* `key_vault_id` - (Required) The ID of the Key Vault where the Key should be created. +* `key_vault_id` - (Required) The ID of the Key Vault where the Key should be created. Changing this forces a new resource to be created. + +* `key_type` - (Required) Specifies the Key Type to use for this Key Vault Key. Possible values are `EC` (Elliptic Curve), `EC-HSM`, `Oct` (Octet), `RSA` and `RSA-HSM`. Changing this forces a new resource to be created. -* `key_type` - (Required) Specifies the Key Type to use for this Key Vault Key. Possible values are `EC` (Elliptic Curve), `Oct` (Octet), `RSA` and `RSA-HSM`. Changing this forces a new resource to be created. +* `key_size` - (Optional) Specifies the Size of the RSA key to create in bytes. For example, 1024 or 2048. *Note*: This field is required if `key_type` is `RSA` or `RSA-HSM`. Changing this forces a new resource to be created. -* `key_size` - (Required) Specifies the Size of the Key to create in bytes. For example, 1024 or 2048. Changing this forces a new resource to be created. +* `curve` - (Optional) Specifies the curve to use when creating an `EC` key. Possible values are `P-256`, `P-384`, `P-521`, and `SECP256K1`. This field will be required in a future release if `key_type` is `EC` or `EC-HSM`. The API will default to `P-256` if nothing is specified. Changing this forces a new resource to be created. * `key_opts` - (Required) A list of JSON web key operations. Possible values include: `decrypt`, `encrypt`, `sign`, `unwrapKey`, `verify` and `wrapKey`. Please note these values are case sensitive. @@ -99,6 +99,8 @@ The following attributes are exported: * `version` - The current version of the Key Vault Key. * `n` - The RSA modulus of this Key Vault Key. * `e` - The RSA public exponent of this Key Vault Key. +* `x` - The EC X component of this Key Vault Key. +* `y` - The EC Y component of this Key Vault Key. ## Import diff --git a/website/docs/r/key_vault_secret.html.markdown b/website/docs/r/key_vault_secret.html.markdown index 152e8163045b..6ce40377f845 100644 --- a/website/docs/r/key_vault_secret.html.markdown +++ b/website/docs/r/key_vault_secret.html.markdown @@ -38,9 +38,7 @@ resource "azurerm_key_vault" "test" { resource_group_name = "${azurerm_resource_group.test.name}" tenant_id = "${data.azurerm_client_config.current.tenant_id}" - sku { - name = "premium" - } + sku_name = "premium" access_policy { tenant_id = "${data.azurerm_client_config.current.tenant_id}" @@ -64,8 +62,8 @@ resource "azurerm_key_vault" "test" { } resource "azurerm_key_vault_secret" "test" { - name = "secret-sauce" - value = "szechuan" + name = "secret-sauce" + value = "szechuan" key_vault_id = "${azurerm_key_vault.test.id}" tags = { diff --git a/website/docs/r/kubernetes_cluster.html.markdown b/website/docs/r/kubernetes_cluster.html.markdown index 38be895ecf46..5b6b24d924e3 100644 --- a/website/docs/r/kubernetes_cluster.html.markdown +++ b/website/docs/r/kubernetes_cluster.html.markdown @@ -36,6 +36,14 @@ resource "azurerm_kubernetes_cluster" "test" { os_disk_size_gb = 30 } + agent_pool_profile { + name = "pool2" + count = 1 + vm_size = "Standard_D2_v2" + os_type = "Linux" + os_disk_size_gb = 30 + } + service_principal { client_id = "00000000-0000-0000-0000-000000000000" client_secret = "00000000000000000000000000000000" @@ -65,7 +73,7 @@ The following arguments are supported: * `resource_group_name` - (Required) Specifies the Resource Group where the Managed Kubernetes Cluster should exist. Changing this forces a new resource to be created. -* `agent_pool_profile` - (Required) One or more `agent_pool_profile` blocks as documented below. +* `agent_pool_profile` - (Required) One or more `agent_pool_profile` blocks as defined below. * `dns_prefix` - (Required) DNS prefix specified when creating the managed cluster. Changing this forces a new resource to be created. @@ -75,18 +83,57 @@ The following arguments are supported: --- +A `aci_connector_linux` block supports the following: + +* `enabled` - (Required) Is the virtual node addon enabled? + +* `subnet_name` - (Required) The subnet name for the virtual nodes to run. + +-> **Note:** AKS will add a delegation to the subnet named here. To prevent further runs from failing you should make sure that the subnet you create for virtual nodes has a delegation, like so. + +``` +resource "azurerm_subnet" "virtual" { + + ... + + delegation { + name = "aciDelegation" + service_delegation { + name = "Microsoft.ContainerInstance/containerGroups" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } +} +``` + +--- + * `addon_profile` - (Optional) A `addon_profile` block. +* `api_server_authorized_ip_ranges` - (Optional) The IP ranges to whitelist for incoming traffic to the masters. + +-> **NOTE:** `api_server_authorized_ip_ranges` Is currently in Preview on an opt-in basis. To use it, enable feature `APIServerSecurityPreview` for `namespace Microsoft.ContainerService`. For an example of how to enable a Preview feature, please visit [How to enable the Azure Firewall Public Preview](https://docs.microsoft.com/en-us/azure/firewall/public-preview) + * `kubernetes_version` - (Optional) Version of Kubernetes specified when creating the AKS managed cluster. If not specified, the latest recommended version will be used at provisioning time (but won't auto-upgrade). * `linux_profile` - (Optional) A `linux_profile` block. +* `windows_profile` - (Optional) A `windows_profile` block. + * `network_profile` - (Optional) A `network_profile` block. -> **NOTE:** If `network_profile` is not defined, `kubenet` profile will be used by default. * `role_based_access_control` - (Optional) A `role_based_access_control` block. Changing this forces a new resource to be created. +* `enable_pod_security_policy` - (Optional) Whether Pod Security Policies are enabled. Note that this also requires role based access control to be enabled. + +-> **NOTE:** Support for `enable_pod_security_policy` is currently in Preview on an opt-in basis. To use it, enable feature `PodSecurityPolicyPreview` for `namespace Microsoft.ContainerService`. For an example of how to enable a Preview feature, please visit [Register scale set feature provider](https://docs.microsoft.com/en-us/azure/aks/cluster-autoscaler#register-scale-set-feature-provider). + +* `node_resource_group` - (Optional) The name of the Resource Group where the the Kubernetes Nodes should exist. Changing this forces a new resource to be created. + +-> **NOTE:** Azure requires that a new, non-existent Resource Group is used, as otherwise the provisioning of the Kubernetes Service will fail. + * `tags` - (Optional) A mapping of tags to assign to the resource. --- @@ -96,22 +143,42 @@ A `addon_profile` block supports the following: * `aci_connector_linux` - (Optional) A `aci_connector_linux` block. For more details, please visit [Create and configure an AKS cluster to use virtual nodes](https://docs.microsoft.com/en-us/azure/aks/virtual-nodes-portal). * `http_application_routing` - (Optional) A `http_application_routing` block. * `oms_agent` - (Optional) A `oms_agent` block. For more details, please visit [How to onboard Azure Monitor for containers](https://docs.microsoft.com/en-us/azure/monitoring/monitoring-container-insights-onboard). +* `kube_dashboard` - (Optional) A `kube_dashboard` block. --- A `agent_pool_profile` block supports the following: * `name` - (Required) Unique name of the Agent Pool Profile in the context of the Subscription and Resource Group. Changing this forces a new resource to be created. + * `count` - (Required) Number of Agents (VMs) in the Pool. Possible values must be in the range of 1 to 100 (inclusive). Defaults to `1`. + * `vm_size` - (Required) The size of each VM in the Agent Pool (e.g. `Standard_F1`). Changing this forces a new resource to be created. -* `max_pods` - (Optional) The maximum number of pods that can run on each agent. +* `availability_zones` - (Optional) Availability zones for nodes. The property `type` of the `agent_pool_profile` must be set to `VirtualMachineScaleSets` in order to use availability zones. + +* `enable_auto_scaling` - (Optional) Whether to enable [auto-scaler](https://docs.microsoft.com/en-us/azure/aks/cluster-autoscaler). Note that auto scaling feature requires the that the `type` is set to `VirtualMachineScaleSets` + +* `min_count` - (Optional) Minimum number of nodes for auto-scaling + +* `max_count` - (Optional) Maximum number of nodes for auto-scaling + +* `max_pods` - (Optional) The maximum number of pods that can run on each agent. Changing this forces a new resource to be created. + * `os_disk_size_gb` - (Optional) The Agent Operating System disk size in GB. Changing this forces a new resource to be created. + * `os_type` - (Optional) The Operating System used for the Agents. Possible values are `Linux` and `Windows`. Changing this forces a new resource to be created. Defaults to `Linux`. + +* `type` - (Optional) Type of the Agent Pool. Possible values are `AvailabilitySet` and `VirtualMachineScaleSets`. Changing this forces a new resource to be created. Defaults to `AvailabilitySet`. + +~> **NOTE:** Support for the `type` of `VirtualMachineScaleSets` is currently in Public Preview on an opt-in basis. To use it, enable feature `VMSSPreview` for `namespace Microsoft.ContainerService`. For an example of how to enable a Preview feature, please visit [Register scale set feature provider](https://docs.microsoft.com/en-us/azure/aks/cluster-autoscaler#register-scale-set-feature-provider). + * `vnet_subnet_id` - (Optional) The ID of the Subnet where the Agents in the Pool should be provisioned. Changing this forces a new resource to be created. ~> **NOTE:** A route table should be configured on this Subnet. +* `node_taints` - (Optional) A list of Kubernetes taints which should be applied to nodes in the agent pool (e.g `key=value:NoSchedule`) + --- A `azure_active_directory` block supports the following: @@ -120,7 +187,7 @@ A `azure_active_directory` block supports the following: * `server_app_id` - (Required) The Server ID of an Azure Active Directory Application. Changing this forces a new resource to be created. -* `server_app_secret` - (Required) The Client Secret of an Azure Active Directory Application. Changing this forces a new resource to be created. +* `server_app_secret` - (Required) The Server Secret of an Azure Active Directory Application. Changing this forces a new resource to be created. * `tenant_id` - (Optional) The Tenant ID used for Azure Active Directory Application. If this isn't specified the Tenant ID of the current Subscription is used. Changing this forces a new resource to be created. @@ -136,7 +203,15 @@ A `linux_profile` block supports the following: * `admin_username` - (Required) The Admin Username for the Cluster. Changing this forces a new resource to be created. -* `ssh_key` - (Required) One or more `ssh_key` blocks. Changing this forces a new resource to be created. +* `ssh_key` - (Required) An `ssh_key` block. Only one is currently allowed. Changing this forces a new resource to be created. + +--- + +A `windows_profile` block supports the following: + +* `admin_username` - (Required) The Admin Username for Windows VMs. + +* `admin_password` - (Required) The Admin Password for Windows VMs. --- @@ -146,6 +221,8 @@ A `network_profile` block supports the following: -> **NOTE:** When `network_plugin` is set to `azure` - the `vnet_subnet_id` field in the `agent_pool_profile` block must be set. +* `network_policy` - (Optional) Sets up network policy to be used with Azure CNI. [Network policy allows us to control the traffic flow between pods](https://docs.microsoft.com/en-us/azure/aks/use-network-policies). This field can only be set when `network_plugin` is set to `azure`. Currently supported values are `calico` and `azure`. Changing this forces a new resource to be created. + * `dns_service_ip` - (Optional) IP address within the Kubernetes service address range that will be used by cluster service discovery (kube-dns). This is required when `network_plugin` is set to `azure`. Changing this forces a new resource to be created. * `docker_bridge_cidr` - (Optional) IP address (in CIDR notation) used as the Docker bridge IP address on nodes. This is required when `network_plugin` is set to `azure`. Changing this forces a new resource to be created. @@ -158,6 +235,10 @@ A `network_profile` block supports the following: Examples of how to use [AKS with Advanced Networking](https://docs.microsoft.com/en-us/azure/aks/networking-overview#advanced-networking) can be [found in the `./examples/kubernetes/` directory in the Github repository](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples/kubernetes). +* `load_balancer_sku` - (Optional) Specifies the SKU of the Load Balancer used for this Kubernetes Cluster. Possible values are `basic` and `standard`. Defaults to `basic`. + +~> **NOTE:** Support for using a `standard` load balancer is currently in Public Preview on an opt-in basis. To use it, enable feature `VMSSPreview` and `AKSAzureStandardLoadBalancer` for `namespace Microsoft.ContainerService`. For additional information please visit [Standard SKU LoadBalancer](https://docs.microsoft.com/en-us/azure/aks/load-balancer-standard). + --- A `oms_agent` block supports the following: @@ -168,11 +249,9 @@ A `oms_agent` block supports the following: --- -A `aci_connector_linux` block supports the following: - -* `enabled` - (Required) Is the virtual node addon enabled? +A `kube_dashboard` block supports the following: -* `subnet_name` - (Required) The subnet name for the virtual nodes to run. +* `enabled` - (Required) Is the Kubernetes Dashboard enabled? --- diff --git a/website/docs/r/kusto_cluster.html.markdown b/website/docs/r/kusto_cluster.html.markdown new file mode 100644 index 000000000000..4c328f4acddd --- /dev/null +++ b/website/docs/r/kusto_cluster.html.markdown @@ -0,0 +1,78 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_kusto_cluster" +sidebar_current: "docs-azurerm-resource-kusto-cluster" +description: |- + Manages Kusto (also known as Azure Data Explorer) Cluster +--- + +# azurerm_kusto_cluster + +Manages a Kusto (also known as Azure Data Explorer) Cluster + +## Example Usage + +```hcl +resource "azurerm_resource_group" "rg" { + name = "my-kusto-cluster-rg" + location = "East US" +} + +resource "azurerm_kusto_cluster" "test" { + name = "kustocluster" + location = "${azurerm_resource_group.rg.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + + sku { + name = "Standard_D13_v2" + capacity = 2 + } + + tags = { + Environment = "Production" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Kusto Cluster to create. Changing this forces a new resource to be created. + +* `location` - (Required) The location where the Kusto Cluster should be created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) Specifies the Resource Group where the Kusto Cluster should exist. Changing this forces a new resource to be created. + +* `sku` - (Required) A `sku` block as defined below. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +A `sku` block supports the following: + +* `name` - (Required) The name of the SKU. Valid values are: `Dev(No SLA)_Standard_D11_v2`, `Standard_D11_v2`, `Standard_D12_v2`, `Standard_D13_v2`, `Standard_D14_v2`, `Standard_DS13_v2+1TB_PS`, `Standard_DS13_v2+2TB_PS`, `Standard_DS14_v2+3TB_PS`, `Standard_DS14_v2+4TB_PS`, `Standard_L16s`, `Standard_L4s` and `Standard_L8s` + +* `capacity` - (Required) Specifies the node count for the cluster. Boundaries depend on the sku name. + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Kusto Cluster ID. + +* `uri` - The FQDN of the Azure Kusto Cluster. + +* `data_ingestion_uri` - The Kusto Cluster URI to be used for data ingestion. + +--- + +## Import + +Kusto Clusters can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_kusto_cluster.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Kusto/Clusters/cluster1 +``` diff --git a/website/docs/r/loadbalancer.html.markdown b/website/docs/r/loadbalancer.html.markdown index b74f448c2550..129031a8bb91 100644 --- a/website/docs/r/loadbalancer.html.markdown +++ b/website/docs/r/loadbalancer.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_lb -Manage a Load Balancer Resource. +Manages a Load Balancer Resource. ## Example Usage @@ -44,7 +44,7 @@ The following arguments are supported: * `name` - (Required) Specifies the name of the Load Balancer. * `resource_group_name` - (Required) The name of the Resource Group in which to create the Load Balancer. * `location` - (Required) Specifies the supported Azure Region where the Load Balancer should be created. -* `frontend_ip_configuration` - (Optional) A `frontend_ip_configuration` block as documented below. +* `frontend_ip_configuration` - (Optional) One or multiple `frontend_ip_configuration` blocks as documented below. * `sku` - (Optional) The SKU of the Azure Load Balancer. Accepted values are `Basic` and `Standard`. Defaults to `Basic`. * `tags` - (Optional) A mapping of tags to assign to the resource. @@ -55,7 +55,8 @@ The following arguments are supported: * `subnet_id` - The ID of the Subnet which should be associated with the IP Configuration. * `private_ip_address` - (Optional) Private IP Address to assign to the Load Balancer. The last one and first four IPs in any range are reserved and cannot be manually assigned. * `private_ip_address_allocation` - (Optional) The allocation method for the Private IP Address used by this Load Balancer. Possible values as `Dynamic` and `Static`. -* `public_ip_address_id` - (Optional) Th ID of a Public IP Address which should be associated with the Load Balancer. +* `public_ip_address_id` - (Optional) The ID of a Public IP Address which should be associated with the Load Balancer. +* `public_ip_prefix_id` - (Optional) The ID of a Public IP Prefix which should be associated with the Load Balancer. Public IP Prefix can only be used with outbound rules. * `zones` - (Optional) A list of Availability Zones which the Load Balancer's IP Addresses should be created in. -> **Please Note**: Availability Zones are [only supported in several regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview). diff --git a/website/docs/r/loadbalancer_backend_address_pool.html.markdown b/website/docs/r/loadbalancer_backend_address_pool.html.markdown index bc68dff334d8..a94f83e48560 100644 --- a/website/docs/r/loadbalancer_backend_address_pool.html.markdown +++ b/website/docs/r/loadbalancer_backend_address_pool.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_lb_backend_address_pool -Manage a Load Balancer Backend Address Pool. +Manages a Load Balancer Backend Address Pool. ~> **NOTE:** When using this resource, the Load Balancer needs to have a FrontEnd IP Configuration Attached @@ -21,10 +21,10 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_public_ip" "test" { - name = "PublicIPForLB" - location = "West US" - resource_group_name = "${azurerm_resource_group.test.name}" - allocation_method = "Static" + name = "PublicIPForLB" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" } resource "azurerm_lb" "test" { diff --git a/website/docs/r/loadbalancer_nat_pool.html.markdown b/website/docs/r/loadbalancer_nat_pool.html.markdown index bb253806d145..10bef32e0bec 100644 --- a/website/docs/r/loadbalancer_nat_pool.html.markdown +++ b/website/docs/r/loadbalancer_nat_pool.html.markdown @@ -21,10 +21,10 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_public_ip" "test" { - name = "PublicIPForLB" - location = "West US" - resource_group_name = "${azurerm_resource_group.test.name}" - allocation_method = "Static" + name = "PublicIPForLB" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" } resource "azurerm_lb" "test" { diff --git a/website/docs/r/loadbalancer_nat_rule.html.markdown b/website/docs/r/loadbalancer_nat_rule.html.markdown index 40b289591c60..dbd7af7b9be1 100644 --- a/website/docs/r/loadbalancer_nat_rule.html.markdown +++ b/website/docs/r/loadbalancer_nat_rule.html.markdown @@ -21,10 +21,10 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_public_ip" "test" { - name = "PublicIPForLB" - location = "West US" - resource_group_name = "${azurerm_resource_group.test.name}" - allocation_method = "Static" + name = "PublicIPForLB" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" } resource "azurerm_lb" "test" { diff --git a/website/docs/r/loadbalancer_outbound_rule.html.markdown b/website/docs/r/loadbalancer_outbound_rule.html.markdown index 6052cf127f80..2a08b29e791a 100644 --- a/website/docs/r/loadbalancer_outbound_rule.html.markdown +++ b/website/docs/r/loadbalancer_outbound_rule.html.markdown @@ -21,10 +21,10 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_public_ip" "test" { - name = "PublicIPForLB" - location = "West US" - resource_group_name = "${azurerm_resource_group.test.name}" - allocation_method = "Static" + name = "PublicIPForLB" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" } resource "azurerm_lb" "test" { @@ -45,11 +45,11 @@ resource "azurerm_lb_backend_address_pool" "test" { } resource "azurerm_lb_outbound_rule" "test" { - resource_group_name = "${azurerm_resource_group.test.name}" - loadbalancer_id = "${azurerm_lb.test.id}" - name = "OutboundRule" - protocol = "Tcp" - backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + name = "OutboundRule" + protocol = "Tcp" + backend_address_pool_id = "${azurerm_lb_backend_address_pool.test.id}" frontend_ip_configuration { name = "PublicIPAddress" diff --git a/website/docs/r/loadbalancer_probe.html.markdown b/website/docs/r/loadbalancer_probe.html.markdown index d028fc748f93..99ca484b867d 100644 --- a/website/docs/r/loadbalancer_probe.html.markdown +++ b/website/docs/r/loadbalancer_probe.html.markdown @@ -21,10 +21,10 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_public_ip" "test" { - name = "PublicIPForLB" - location = "West US" - resource_group_name = "${azurerm_resource_group.test.name}" - allocation_method = "Static" + name = "PublicIPForLB" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" } resource "azurerm_lb" "test" { diff --git a/website/docs/r/loadbalancer_rule.html.markdown b/website/docs/r/loadbalancer_rule.html.markdown index ddfa14691198..2b412c7092fd 100644 --- a/website/docs/r/loadbalancer_rule.html.markdown +++ b/website/docs/r/loadbalancer_rule.html.markdown @@ -21,10 +21,10 @@ resource "azurerm_resource_group" "test" { } resource "azurerm_public_ip" "test" { - name = "PublicIPForLB" - location = "West US" - resource_group_name = "${azurerm_resource_group.test.name}" - allocation_method = "Static" + name = "PublicIPForLB" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + allocation_method = "Static" } resource "azurerm_lb" "test" { @@ -65,7 +65,7 @@ The following arguments are supported: * `enable_floating_ip` - (Optional) Floating IP is pertinent to failover scenarios: a "floating” IP is reassigned to a secondary server in case the primary server fails. Floating IP is required for SQL AlwaysOn. * `idle_timeout_in_minutes` - (Optional) Specifies the timeout for the Tcp idle connection. The value can be set between 4 and 30 minutes. The default value is 4 minutes. This element is only used when the protocol is set to Tcp. * `load_distribution` - (Optional) Specifies the load balancing distribution type to be used by the Load Balancer. Possible values are: `Default` – The load balancer is configured to use a 5 tuple hash to map traffic to available servers. `SourceIP` – The load balancer is configured to use a 2 tuple hash to map traffic to available servers. `SourceIPProtocol` – The load balancer is configured to use a 3 tuple hash to map traffic to available servers. Also known as Session Persistence, where the options are called `None`, `Client IP` and `Client IP and Protocol` respectively. - +* `disable_outbound_snat` - (Optional) Indicates whether outbound snat is disabled or enabled. Default false. ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/managed_disk.html.markdown b/website/docs/r/managed_disk.html.markdown index 9b235d3b260f..2ba174c831f5 100644 --- a/website/docs/r/managed_disk.html.markdown +++ b/website/docs/r/managed_disk.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_managed_disk -Manage a managed disk. +Manages a managed disk. ## Example Usage with Create Empty @@ -89,10 +89,12 @@ The following arguments are supported: * `Empty` - Create an empty managed disk. * `Copy` - Copy an existing managed disk or snapshot (specified with `source_resource_id`). * `FromImage` - Copy a Platform Image (specified with `image_reference_id`) + * `Restore` - Set by Azure Backup or Site Recovery on a restored disk (specified with `source_resource_id`). * `source_uri` - (Optional) URI to a valid VHD file to be used when `create_option` is `Import`. -* `source_resource_id` - (Optional) ID of an existing managed disk to copy when `create_option` is `Copy`. +* `source_resource_id` - (Optional) ID of an existing managed disk to copy `create_option` is `Copy` + or the recovery point to restore when `create_option` is `Restore` * `image_reference_id` - (Optional) ID of an existing platform/marketplace disk image to copy when `create_option` is `FromImage`. diff --git a/website/docs/r/management_group.html.markdown b/website/docs/r/management_group.html.markdown index db1433c02a07..c93e71461070 100644 --- a/website/docs/r/management_group.html.markdown +++ b/website/docs/r/management_group.html.markdown @@ -16,20 +16,22 @@ Manages a Management Group. data "azurerm_subscription" "current" {} resource "azurerm_management_group" "example_parent" { - display_name = "ParentGroup" + display_name = "ParentGroup" + subscription_ids = [ - "${data.azurerm_subscription.current.id}", + "${data.azurerm_subscription.current.subscription_id}", ] } resource "azurerm_management_group" "example_child" { display_name = "ChildGroup" parent_management_group_id = "${azurerm_management_group.example_parent.id}" - + subscription_ids = [ - "${data.azurerm_subscription.current.id}", - # other subscription IDs can go here + "${data.azurerm_subscription.current.subscription_id}", ] + + # other subscription IDs can go here } ``` @@ -43,7 +45,7 @@ The following arguments are supported: * `parent_management_group_id` - (Optional) The ID of the Parent Management Group. Changing this forces a new resource to be created. -* `subscription_ids` - (Optional) A list of Subscription ID's which should be assigned to the Management Group. +* `subscription_ids` - (Optional) A list of Subscription GUIDs which should be assigned to the Management Group. ## Attributes Reference diff --git a/website/docs/r/maps_account.html.markdown b/website/docs/r/maps_account.html.markdown new file mode 100644 index 000000000000..f9b59046d651 --- /dev/null +++ b/website/docs/r/maps_account.html.markdown @@ -0,0 +1,64 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_maps_account" +sidebar_current: "docs-azurerm-resource-maps-account" +description: |- + Manages an Azure Maps Account. +--- + +# azurerm_maps_account + +Manages an Azure Maps Account. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_maps_account" "test" { + name = "example-maps-account" + resource_group_name = "${azurerm_resource_group.test.name}" + sku_name = "s1" + + tags = { + environment = "Test" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Azure Maps Account. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group in which the Azure Maps Account should exist. Changing this forces a new resource to be created. + +* `sku_name` - (Required) The sku of the Azure Maps Account. Possible values are `s0` and `s1`. + +* `tags` - (Optional) A mapping of tags to assign to the Azure Maps Account. + + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The ID of the Azure Maps Account. + +* `primary_access_key` - The primary key used to authenticate and authorize access to the Maps REST APIs. + +* `secondary_access_key` - The secondary key used to authenticate and authorize access to the Maps REST APIs. + +* `x_ms_client_id` - A unique identifier for the Maps Account. + +## Import + +A Maps Account can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_maps_account.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Maps/accounts/my-maps-account +``` + diff --git a/website/docs/r/mariadb_configuration.html.markdown b/website/docs/r/mariadb_configuration.html.markdown new file mode 100644 index 000000000000..47067dddeec4 --- /dev/null +++ b/website/docs/r/mariadb_configuration.html.markdown @@ -0,0 +1,79 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_mariadb_configuration" +sidebar_current: "docs-azurerm-resource-database-mariadb-configuration" +description: |- + Sets a MariaDB Configuration value on a MariaDB Server. +--- + +# azurerm_mariadb_configuration + +Sets a MariaDB Configuration value on a MariaDB Server. + +-> **NOTE** MariaDB Server is currently in Public Preview. You can find more information, including [how to register for the Public Preview here](https://azure.microsoft.com/en-us/updates/mariadb-public-preview/). + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "api-rg-pro" + location = "West Europe" +} + +resource "azurerm_mariadb_server" "example" { + name = "mariadb-server-1" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + + sku { + name = "B_Gen5_2" + capacity = 2 + tier = "Basic" + family = "Gen5" + } + + storage_profile { + storage_mb = 5120 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } + + administrator_login = "mariadbadmin" + administrator_login_password = "H@Sh1CoR3!" + version = "10.2" + ssl_enforcement = "Enabled" +} + +resource "azurerm_mariadb_configuration" "example" { + name = "interactive_timeout" + resource_group_name = "${azurerm_resource_group.example.name}" + server_name = "${azurerm_mariadb_server.example.name}" + value = "600" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the MariaDB Configuration, which needs [to be a valid MariaDB configuration name](https://mariadb.com/kb/en/library/server-system-variables/). Changing this forces a new resource to be created. + +* `server_name` - (Required) Specifies the name of the MariaDB Server. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the MariaDB Server exists. Changing this forces a new resource to be created. + +* `value` - (Required) Specifies the value of the MariaDB Configuration. See the MariaDB documentation for valid values. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the MariaDB Configuration. + +## Import + +MariaDB Configurations can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_mariadb_configuration.interactive_timeout /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.DBforMariaDB/servers/server1/configurations/interactive_timeout +``` diff --git a/website/docs/r/mariadb_firewall_rule.html.markdown b/website/docs/r/mariadb_firewall_rule.html.markdown new file mode 100644 index 000000000000..128c538b50ac --- /dev/null +++ b/website/docs/r/mariadb_firewall_rule.html.markdown @@ -0,0 +1,63 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_mariadb_firewall_rule" +sidebar_current: "docs-azurerm-resource-database-mariadb-firewall-rule" +description: |- + Manages a Firewall Rule for a MariaDB Server. +--- + +# azurerm_mariadb_firewall_rule + +Manages a Firewall Rule for a MariaDB Server + +## Example Usage (Single IP Address) + +```hcl +resource "azurerm_mariadb_firewall_rule" "test" { + name = "test-rule" + resource_group_name = "test-rg" + server_name = "test-server" + start_ip_address = "40.112.8.12" + end_ip_address = "40.112.8.12" +} +``` + +## Example Usage (IP Range) + +```hcl +resource "azurerm_mariadb_firewall_rule" "test" { + name = "test-rule" + resource_group_name = "test-rg" + server_name = "test-server" + start_ip_address = "40.112.0.0" + end_ip_address = "40.112.255.255" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the MariaDB Firewall Rule. Changing this forces a new resource to be created. + +* `server_name` - (Required) Specifies the name of the MariaDB Server. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the MariaDB Server exists. Changing this forces a new resource to be created. + +* `start_ip_address` - (Required) Specifies the Start IP Address associated with this Firewall Rule. Changing this forces a new resource to be created. + +* `end_ip_address` - (Required) Specifies the End IP Address associated with this Firewall Rule. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the MariaDB Firewall Rule. + +## Import + +MariaDB Firewall rules can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_mariadb_firewall_rule.rule1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.DBforMariaDB/servers/server1/firewallRules/rule1 +``` diff --git a/website/docs/r/mariadb_server.html.markdown b/website/docs/r/mariadb_server.html.markdown index 1f8061ef896e..ecdeb8d5c1db 100644 --- a/website/docs/r/mariadb_server.html.markdown +++ b/website/docs/r/mariadb_server.html.markdown @@ -63,7 +63,7 @@ The following arguments are supported: * `administrator_login_password` - (Required) The Password associated with the `administrator_login` for the MariaDB Server. -* `version` - (Required) Specifies the version of MariaDB to use. The valid value is `10.2`. Changing this forces a new resource to be created. +* `version` - (Required) Specifies the version of MariaDB to use. Possible values are `10.2` and `10.3`. Changing this forces a new resource to be created. * `ssl_enforcement` - (Required) Specifies if SSL should be enforced on connections. Possible values are `Enabled` and `Disabled`. diff --git a/website/docs/r/mariadb_virtual_network_rule.html.markdown b/website/docs/r/mariadb_virtual_network_rule.html.markdown new file mode 100644 index 000000000000..563e171545f6 --- /dev/null +++ b/website/docs/r/mariadb_virtual_network_rule.html.markdown @@ -0,0 +1,100 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_mariadb_virtual_network_rule" +sidebar_current: "docs-azurerm-resource-database-mariadb-virtual-network-rule" +description: |- + Manages a MariaDB Virtual Network Rule. +--- + +# azurerm_mariadb_virtual_network_rule + +Manages a MariaDB Virtual Network Rule. + +-> **NOTE:** MariaDB Virtual Network Rules [can only be used with SKU Tiers of `GeneralPurpose` or `MemoryOptimized`](https://docs.microsoft.com/en-us/azure/mariadb/concepts-data-access-security-vnet) + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_virtual_network" "test" { + name = "example-vnet" + address_space = ["10.7.29.0/29"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "internal" { + name = "internal" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.0/29" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "mariadb-server-1" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "mariadbadminun" + administrator_login_password = "H@Sh1CoR3!" + version = "5.7" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 5120 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "test" { + name = "mariadb-vnet-rule" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.internal.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the MariaDB Virtual Network Rule. Cannot be empty and must only contain alphanumeric characters and hyphens. Cannot start with a number, and cannot start or end with a hyphen. Changing this forces a new resource to be created. + +~> **NOTE:** `name` must be between 1-128 characters long and must satisfy all of the requirements below: +1. Contains only alphanumeric and hyphen characters +2. Cannot start with a number or hyphen +3. Cannot end with a hyphen + +* `resource_group_name` - (Required) The name of the resource group where the MariaDB server resides. Changing this forces a new resource to be created. + +* `server_name` - (Required) The name of the SQL Server to which this MariaDB virtual network rule will be applied to. Changing this forces a new resource to be created. + +* `subnet_id` - (Required) The ID of the subnet that the MariaDB server will be connected to. + +~> **NOTE:** Due to [a bug in the Azure API](https://github.com/Azure/azure-rest-api-specs/issues/3719) this resource currently doesn't expose the `ignore_missing_vnet_service_endpoint` field and defaults this to `false`. Terraform will check during the provisioning of the Virtual Network Rule that the Subnet contains the Service Rule to verify that the Virtual Network Rule can be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the MariaDB Virtual Network Rule. + +## Import + +MariaDB Virtual Network Rules can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_mariadb_virtual_network_rule.rule1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/MariaDB/servers/myserver/virtualNetworkRules/vnetrulename +``` diff --git a/website/docs/r/media_services_account.html.markdown b/website/docs/r/media_services_account.html.markdown index 2da9b975e5eb..6e993b12db7e 100644 --- a/website/docs/r/media_services_account.html.markdown +++ b/website/docs/r/media_services_account.html.markdown @@ -72,4 +72,4 @@ Media Services Accounts can be imported using the `resource id`, e.g. ```shell terraform import azurerm_media_services_account.account /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Media/mediaservices/account1 -``` \ No newline at end of file +``` diff --git a/website/docs/r/metric_alertrule.html.markdown b/website/docs/r/metric_alertrule.html.markdown index 39ad24290b54..1e8d4714816f 100644 --- a/website/docs/r/metric_alertrule.html.markdown +++ b/website/docs/r/metric_alertrule.html.markdown @@ -11,7 +11,7 @@ description: |- Manages a [metric-based alert rule](https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitor-quick-resource-metric-alert-portal) in Azure Monitor. -~> **NOTE:** This resource has been deprecated in favour of the `azurerm_monitor_metric_alertrule` resource and will be removed in the next major version of the AzureRM Provider. The new resource shares the same fields as this one, and information on migrating across [can be found in this guide](../guides/migrating-between-renamed-resources.html). +~> **NOTE:** This resource has been [deprecated](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/monitoring-classic-retirement) in favour of the `azurerm_monitor_metric_alert` resource and will be removed in the next major version of the AzureRM Provider. The new resource shares the same fields as this one, and information on migrating across [can be found in this guide](../guides/migrating-between-renamed-resources.html). ## Example Usage (CPU Percentage of a virtual machine) diff --git a/website/docs/r/monitor_diagnostic_setting.html.markdown b/website/docs/r/monitor_diagnostic_setting.html.markdown index a5dd600012dd..99db90eacbd6 100644 --- a/website/docs/r/monitor_diagnostic_setting.html.markdown +++ b/website/docs/r/monitor_diagnostic_setting.html.markdown @@ -87,6 +87,10 @@ The following arguments are supported: -> **NOTE:** One of `eventhub_authorization_rule_id`, `log_analytics_workspace_id` and `storage_account_id` must be specified. +* `log_analytics_destination_type` - (Optional) When set to 'Dedicated' logs sent to a Log Analytics workspace will go into resource specific tables, instead of the legacy AzureDiagnostics table. + +-> **NOTE:** This setting will only have an effect if a `log_analytics_workspace_id` is provided, and the resource is available for resource-specific logs. As of July 2019, this only includes Azure Data Factory. Please [see the documentation](https://docs.microsoft.com/en-us/azure/azure-monitor/platform/diagnostic-logs-stream-log-store#azure-diagnostics-vs-resource-specific) for more information. + --- A `log` block supports the following: diff --git a/website/docs/r/mssql_elasticpool.html.markdown b/website/docs/r/mssql_elasticpool.html.markdown index 6c5ab9d20aaf..c124a9ec5d6b 100644 --- a/website/docs/r/mssql_elasticpool.html.markdown +++ b/website/docs/r/mssql_elasticpool.html.markdown @@ -70,6 +70,8 @@ The following arguments are supported: * `tags` - (Optional) A mapping of tags to assign to the resource. +* `zone_redundant` - (Optional) Whether or not this elastic pool is zone redundant. `tier` needs to be `Premium` for `DTU` based or `BusinessCritical` for `vCore` based `sku`. Defaults to `false`. + --- `sku` supports the following: @@ -98,8 +100,6 @@ The following attributes are exported: * `id` - The MsSQL Elastic Pool ID. -* `zone_redundant` - Whether or not this elastic pool is zone redundant. - ## Import SQL Elastic Pool can be imported using the `resource id`, e.g. diff --git a/website/docs/r/mysql_configuration.html.markdown b/website/docs/r/mysql_configuration.html.markdown index f4c95e09f849..19554c1f979d 100644 --- a/website/docs/r/mysql_configuration.html.markdown +++ b/website/docs/r/mysql_configuration.html.markdown @@ -24,7 +24,7 @@ resource "azurerm_mysql_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - name = "B_Gen4_2" + name = "B_Gen5_2" capacity = 2 tier = "Basic" family = "Gen4" diff --git a/website/docs/r/mysql_database.html.markdown b/website/docs/r/mysql_database.html.markdown index e5af26227938..5fa5ed2a3c09 100644 --- a/website/docs/r/mysql_database.html.markdown +++ b/website/docs/r/mysql_database.html.markdown @@ -24,10 +24,10 @@ resource "azurerm_mysql_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - name = "B_Gen4_2" + name = "B_Gen5_2" capacity = 2 tier = "Basic" - family = "Gen4" + family = "Gen5" } storage_profile { diff --git a/website/docs/r/mysql_server.html.markdown b/website/docs/r/mysql_server.html.markdown index 4d9c7b28345b..7a8c2b8cb9d7 100644 --- a/website/docs/r/mysql_server.html.markdown +++ b/website/docs/r/mysql_server.html.markdown @@ -25,10 +25,10 @@ resource "azurerm_mysql_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - name = "B_Gen4_2" + name = "B_Gen5_2" capacity = 2 tier = "Basic" - family = "Gen4" + family = "Gen5" } storage_profile { diff --git a/website/docs/r/network_connection_monitor.html.markdown b/website/docs/r/network_connection_monitor.html.markdown new file mode 100644 index 000000000000..e799cedb3608 --- /dev/null +++ b/website/docs/r/network_connection_monitor.html.markdown @@ -0,0 +1,170 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_network_connection_monitor" +sidebar_current: "docs-azurerm-resource-network-connection-monitor" +description: |- + Configures a Network Connection Monitor to monitor communication between a Virtual Machine and an endpoint using a Network Watcher. + +--- + +# azurerm_connection_monitor + +Configures a Network Connection Monitor to monitor communication between a Virtual Machine and an endpoint using a Network Watcher. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "connection-monitor-rg" + location = "West US" +} + +resource "azurerm_network_watcher" "test" { + name = "network-watcher" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_virtual_network" "test" { + name = "production-network" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "internal" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "cmtest-nic" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "cmtest-vm" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_F2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "osdisk" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "cmtest-vm" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } +} + +resource "azurerm_virtual_machine_extension" "test" { + name = "cmtest-vm-network-watcher" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_machine_name = "${azurerm_virtual_machine.test.name}" + publisher = "Microsoft.Azure.NetworkWatcher" + type = "NetworkWatcherAgentLinux" + type_handler_version = "1.4" + auto_upgrade_minor_version = true +} + +resource "azurerm_network_connection_monitor" "test" { + name = "cmtest-connectionmonitor" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + network_watcher_name = "${azurerm_network_watcher.test.name}" + + source { + virtual_machine_id = "${azurerm_virtual_machine.test.id}" + } + + destination { + address = "terraform.io" + port = 80 + } + + depends_on = ["azurerm_virtual_machine_extension.test"] +} +``` + +~> **NOTE:** This Resource requires that [the Network Watcher Agent Virtual Machine Extension](https://docs.microsoft.com/en-us/azure/network-watcher/connection-monitor) is installed on the Virtual Machine before monitoring can be started. The extension can be installed via [the `azurerm_virtual_machine_extension` resource](virtual_machine_extension.html). + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Network Connection Monitor. Changing this forces a new resource to be created. + +* `network_watcher_name` - (Required) The name of the Network Watcher. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Connection Monitor. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `auto_start` - (Optional) Specifies whether the connection monitor will start automatically once created. Defaults to `true`. Changing this forces a new resource to be created. + +* `interval_in_seconds` - (Optional) Monitoring interval in seconds. Defaults to `60`. + +* `source` - (Required) A `source` block as defined below. + +* `destination` - (Required) A `destination` block as defined below. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +A `source` block contains: + +* `virtual_machine_id` - (Required) The ID of the Virtual Machine to monitor connectivity from. + +* `port` - (Optional) The port on the Virtual Machine to monitor connectivity from. Defaults to `0` (Dynamic Port Assignment). + +A `destination` block contains: + +* `virtual_machine_id` - (Optional) The ID of the Virtual Machine to monitor connectivity to. + +* `address` - (Optional) IP address or domain name to monitor connectivity to. + +* `port` - (Required) The port on the destination to monitor connectivity to. + +~> **NOTE:** One of `virtual_machine_id` or `address` must be specified. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Connection Monitor ID. + +## Import + +Connection Monitors can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_network_connection_monitor.monitor1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/networkWatchers/watcher1/connectionMonitors/monitor1 +``` diff --git a/website/docs/r/network_ddos_protection_plan.html.markdown b/website/docs/r/network_ddos_protection_plan.html.markdown new file mode 100644 index 000000000000..b3d2cbf2304b --- /dev/null +++ b/website/docs/r/network_ddos_protection_plan.html.markdown @@ -0,0 +1,57 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_network_ddos_protection_plan" +sidebar_current: "docs-azurerm-resource-network-ddos-protection-plan-x" +description: |- + Manages an Azure Network DDoS Protection Plan. + +--- + +# azurerm_network_ddos_protection_plan + +Manages an AzureNetwork DDoS Protection Plan. + +-> **NOTE** Azure only allow `one` DDoS Protection Plan per region. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_network_ddos_protection_plan" "test" { + name = "example-protection-plan" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Network DDoS Protection Plan. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the resource. Changing this forces a new resource to be created. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Resource ID of the DDoS Protection Plan + +* `virtual_network_ids` - The Resource ID list of the Virtual Networks associated with DDoS Protection Plan. + +## Import + +Azure DDoS Protection Plan can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_network_ddos_protection_plan.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Network/ddosProtectionPlans/testddospplan +``` diff --git a/website/docs/r/network_interface_application_gateway_backend_address_pool_association.html.markdown b/website/docs/r/network_interface_application_gateway_backend_address_pool_association.html.markdown index cd8bb392841d..358c0fa7f835 100644 --- a/website/docs/r/network_interface_application_gateway_backend_address_pool_association.html.markdown +++ b/website/docs/r/network_interface_application_gateway_backend_address_pool_association.html.markdown @@ -126,7 +126,7 @@ resource "azurerm_network_interface" "test" { resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "test" { network_interface_id = "${azurerm_network_interface.test.id}" ip_configuration_name = "testconfiguration1" - backend_address_pool_id = "${azurerm_application_gateway.test.backend_address_pool.0.id}" + backend_address_pool_id = "${azurerm_application_gateway.network.backend_address_pool.0.id}" } ``` diff --git a/website/docs/r/network_interface_application_security_group_association.html.markdown b/website/docs/r/network_interface_application_security_group_association.html.markdown index 876718d64021..c3ec4a94594d 100644 --- a/website/docs/r/network_interface_application_security_group_association.html.markdown +++ b/website/docs/r/network_interface_application_security_group_association.html.markdown @@ -48,7 +48,7 @@ resource "azurerm_network_interface" "test" { name = "testconfiguration1" subnet_id = "${azurerm_subnet.test.id}" private_ip_address_allocation = "Dynamic" - application_security_group_ids = [ "${azurerm_application_security_group.test.id}" ] + application_security_group_ids = ["${azurerm_application_security_group.test.id}"] } } diff --git a/website/docs/r/network_packet_capture.html.markdown b/website/docs/r/network_packet_capture.html.markdown new file mode 100644 index 000000000000..071a12a45e61 --- /dev/null +++ b/website/docs/r/network_packet_capture.html.markdown @@ -0,0 +1,187 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_network_packet_capture" +sidebar_current: "docs-azurerm-resource-network-packet-capture" +description: |- + Configures Packet Capturing against a Virtual Machine using a Network Watcher. + +--- + +# azurerm_packet_capture + +Configures Network Packet Capturing against a Virtual Machine using a Network Watcher. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "packet-capture-rg" + location = "West Europe" +} + +resource "azurerm_network_watcher" "test" { + name = "network-watcher" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_virtual_network" "test" { + name = "production-network" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "internal" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "pctest-nic" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + ip_configuration { + name = "testconfiguration1" + subnet_id = "${azurerm_subnet.test.id}" + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_virtual_machine" "test" { + name = "pctest-vm" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + network_interface_ids = ["${azurerm_network_interface.test.id}"] + vm_size = "Standard_F2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "osdisk" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "pctest-vm" + admin_username = "testadmin" + admin_password = "Password1234!" + } + + os_profile_linux_config { + disable_password_authentication = false + } +} + +resource "azurerm_virtual_machine_extension" "test" { + name = "network-watcher" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_machine_name = "${azurerm_virtual_machine.test.name}" + publisher = "Microsoft.Azure.NetworkWatcher" + type = "NetworkWatcherAgentLinux" + type_handler_version = "1.4" + auto_upgrade_minor_version = true +} + +resource "azurerm_storage_account" "test" { + name = "pctestsa" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_network_packet_capture" "test" { + name = "pctestcapture" + network_watcher_name = "${azurerm_network_watcher.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + target_resource_id = "${azurerm_virtual_machine.test.id}" + + storage_location { + storage_account_id = "${azurerm_storage_account.test.id}" + } + + depends_on = ["azurerm_virtual_machine_extension.test"] +} +``` + +~> **NOTE:** This Resource requires that [the Network Watcher Virtual Machine Extension](https://docs.microsoft.com/azure/network-watcher/network-watcher-packet-capture-manage-portal#before-you-begin) is installed on the Virtual Machine before capturing can be enabled which can be installed via [the `azurerm_virtual_machine_extension` resource](virtual_machine_extension.html). + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name to use for this Network Packet Capture. Changing this forces a new resource to be created. + +* `network_watcher_name` - (Required) The name of the Network Watcher. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Network Watcher exists. Changing this forces a new resource to be created. + +* `target_resource_id` - (Required) The ID of the Resource to capture packets from. Changing this forces a new resource to be created. + +~> **NOTE:** Currently only Virtual Machines ID's are supported. + +* `maximum_bytes_per_packet` - (Optional) The number of bytes captured per packet. The remaining bytes are truncated. Defaults to `0` (Entire Packet Captured). Changing this forces a new resource to be created. + +* `maximum_bytes_per_session` - (Optional) Maximum size of the capture in Bytes. Defaults to `1073741824` (1GB). Changing this forces a new resource to be created. + +* `maximum_capture_duration` - (Optional) The maximum duration of the capture session in seconds. Defaults to `18000` (5 hours). Changing this forces a new resource to be created. + +* `storage_location` - (Required) A `storage_location` block as defined below. Changing this forces a new resource to be created. + +* `filter` - (Optional) One or more `filter` blocks as defined below. Changing this forces a new resource to be created. + +--- + +A `storage_location` block contains: + +* `file_path` - (Optional) A valid local path on the targeting VM. Must include the name of the capture file (*.cap). For linux virtual machine it must start with `/var/captures`. + +* `storage_account_id` - (Optional) The ID of the storage account to save the packet capture session + +~> **NOTE:** At least one of `file_path` or `storage_account_id` must be specified. + +A `filter` block contains: + +* `local_ip_address` - (Optional) The local IP Address to be filtered on. Notation: "127.0.0.1" for single address entry. "127.0.0.1-127.0.0.255" for range. "127.0.0.1;127.0.0.5" for multiple entries. Multiple ranges not currently supported. Mixing ranges with multiple entries not currently supported. Changing this forces a new resource to be created. + +* `local_port` - (Optional) The local port to be filtered on. Notation: "80" for single port entry."80-85" for range. "80;443;" for multiple entries. Multiple ranges not currently supported. Mixing ranges with multiple entries not currently supported. Changing this forces a new resource to be created. + +* `protocol` - (Required) The Protocol to be filtered on. Possible values include `Any`, `TCP` and `UDP`. Changing this forces a new resource to be created. + +* `remote_ip_address` - (Optional) The remote IP Address to be filtered on. Notation: "127.0.0.1" for single address entry. "127.0.0.1-127.0.0.255" for range. "127.0.0.1;127.0.0.5;" for multiple entries. Multiple ranges not currently supported. Mixing ranges with multiple entries not currently supported.. Changing this forces a new resource to be created. + +* `remote_port` - (Optional) The remote port to be filtered on. Notation: "80" for single port entry."80-85" for range. "80;443;" for multiple entries. Multiple ranges not currently supported. Mixing ranges with multiple entries not currently supported. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Packet Capture ID. + +* `storage_location` - (Required) A `storage_location` block as defined below. + +--- + +A `storage_location` block contains: + +* `storage_path` - The URI of the storage path to save the packet capture. + +## Import + +Packet Captures can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_network_packet_capture.capture1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/networkWatchers/watcher1/packetCaptures/capture1 +``` diff --git a/website/docs/r/network_profile.html.markdown b/website/docs/r/network_profile.html.markdown new file mode 100644 index 000000000000..431223b0d972 --- /dev/null +++ b/website/docs/r/network_profile.html.markdown @@ -0,0 +1,105 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_network_profile" +sidebar_current: "docs-azurerm-resource-network-profile-x" +description: |- + Manages an Azure Network Profile. + +--- + +# azurerm_network_profile + +Manages an Azure Network Profile. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "examplegroup" + location = "West Europe" +} + +resource "azurerm_virtual_network" "example" { + name = "examplevnet" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + address_space = ["10.1.0.0/16"] +} + +resource "azurerm_subnet" "example" { + name = "examplesubnet" + resource_group_name = "${azurerm_resource_group.example.name}" + virtual_network_name = "${azurerm_virtual_network.example.name}" + address_prefix = "10.1.0.0/24" + + delegation { + name = "delegation" + + service_delegation { + name = "Microsoft.ContainerInstance/containerGroups" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } +} + +resource "azurerm_network_profile" "example" { + name = "examplenetprofile" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + + container_network_interface_configuration { + name = "examplecnic" + + ip_configuration { + name = "exampleipconfig" + subnet_id = "${azurerm_subnet.example.id}" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Network Profile. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the resource. Changing this forces a new resource to be created. + +* `container_network_interface_configuration` - (Required) A `container_network_interface_configuration` block as documented below. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +A `container_network_interface_configuration` block supports the following: + +* `name` - (Required) Specifies the name of the IP Configuration. + +* `ip_configuration` - (Required) One or more `ip_configuration` blocks as documented below. + +--- + +A `ip_configuration` block supports the following: + +* `name` - (Required) Specifies the name of the IP Configuration. + +* `subnet_id` - (Required) Reference to the subnet associated with the IP Configuration. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Resource ID of the Azure Network Profile. + +* `container_network_interface_ids` - One or more Resource IDs of Azure Container Network Interfaces. + +## Import + +Azure Network Profile can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_network_profile.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Network/networkProfiles/examplenetprofile +``` diff --git a/website/docs/r/network_security_group.html.markdown b/website/docs/r/network_security_group.html.markdown index 4dace31b1538..6e5dbc1c9c6a 100644 --- a/website/docs/r/network_security_group.html.markdown +++ b/website/docs/r/network_security_group.html.markdown @@ -56,12 +56,12 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `security_rule` - (Optional) One or more `security_rule` blocks as defined below. +* `security_rule` - (Optional) [List of objects](/docs/configuration/attr-as-blocks.html) representing security rules, as defined below. * `tags` - (Optional) A mapping of tags to assign to the resource. -The `security_rule` block supports: +Elements of `security_rule` support: * `name` - (Required) The name of the security rule. diff --git a/website/docs/r/notification_hub.html.markdown b/website/docs/r/notification_hub.html.markdown index 5d367661e3f1..2a6f34104f07 100644 --- a/website/docs/r/notification_hub.html.markdown +++ b/website/docs/r/notification_hub.html.markdown @@ -25,9 +25,7 @@ resource "azurerm_notification_hub_namespace" "test" { location = "${azurerm_resource_group.test.location}" namespace_type = "NotificationHub" - sku { - name = "Free" - } + sku_name = "Free" } resource "azurerm_notification_hub" "test" { diff --git a/website/docs/r/notification_hub_authorization_rule.html.markdown b/website/docs/r/notification_hub_authorization_rule.html.markdown index 52dfae364eef..1657908eeb03 100644 --- a/website/docs/r/notification_hub_authorization_rule.html.markdown +++ b/website/docs/r/notification_hub_authorization_rule.html.markdown @@ -25,9 +25,7 @@ resource "azurerm_notification_hub_namespace" "test" { location = "${azurerm_resource_group.test.location}" namespace_type = "NotificationHub" - sku { - name = "Free" - } + sku_name = "Free" } resource "azurerm_notification_hub" "test" { diff --git a/website/docs/r/notification_hub_namespace.html.markdown b/website/docs/r/notification_hub_namespace.html.markdown index 9b763182a662..45b99d64dfc1 100644 --- a/website/docs/r/notification_hub_namespace.html.markdown +++ b/website/docs/r/notification_hub_namespace.html.markdown @@ -25,9 +25,7 @@ resource "azurerm_notification_hub_namespace" "test" { location = "${azurerm_resource_group.test.location}" namespace_type = "NotificationHub" - sku { - name = "Free" - } + sku_name = "Free" } ``` @@ -43,11 +41,13 @@ The following arguments are supported: * `namespace_type` - (Required) The Type of Namespace - possible values are `Messaging` or `NotificationHub`. Changing this forces a new resource to be created. -* `sku` - (Required) A `sku` block as defined below. +* `sku` - (Optional **Deprecated**)) A `sku` block as described below. + +* `sku_name` - (Optional) The name of the SKU to use for this Notification Hub Namespace. Possible values are `Free`, `Basic` or `Standard`. Changing this forces a new resource to be created. * `enabled` - (Optional) Is this Notification Hub Namespace enabled? Defaults to `true`. ---- +---- A `sku` block contains: diff --git a/website/docs/r/packet_capture.html.markdown b/website/docs/r/packet_capture.html.markdown index d8e260645856..95a1ce9be347 100644 --- a/website/docs/r/packet_capture.html.markdown +++ b/website/docs/r/packet_capture.html.markdown @@ -1,7 +1,7 @@ --- layout: "azurerm" page_title: "Azure Resource Manager: azurerm_packet_capture" -sidebar_current: "docs-azurerm-resource-network-packet-capture" +sidebar_current: "docs-azurerm-resource-packet-capture" description: |- Configures Packet Capturing against a Virtual Machine using a Network Watcher. @@ -11,6 +11,8 @@ description: |- Configures Packet Capturing against a Virtual Machine using a Network Watcher. +~> **NOTE:** This resource has been deprecated in favour of the `azurerm_network_connection_monitor` resource and will be removed in the next major version of the AzureRM Provider. The new resource shares the same fields as this one, and information on migrating across [can be found in this guide](../guides/migrating-between-renamed-resources.html). + ## Example Usage ```hcl diff --git a/website/docs/r/policy_definition.html.markdown b/website/docs/r/policy_definition.html.markdown index d3012599d88b..93f504263a30 100644 --- a/website/docs/r/policy_definition.html.markdown +++ b/website/docs/r/policy_definition.html.markdown @@ -21,6 +21,12 @@ resource "azurerm_policy_definition" "policy" { mode = "Indexed" display_name = "acceptance test policy definition" + metadata = <<METADATA + { + "category": "General" + } + METADATA + policy_rule = <<POLICY_RULE { "if": { diff --git a/website/docs/r/postgresql_configuration.html.markdown b/website/docs/r/postgresql_configuration.html.markdown index b3e391e8040d..1feab199287e 100644 --- a/website/docs/r/postgresql_configuration.html.markdown +++ b/website/docs/r/postgresql_configuration.html.markdown @@ -24,7 +24,7 @@ resource "azurerm_postgresql_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - name = "B_Gen4_2" + name = "B_Gen5_2" capacity = 2 tier = "Basic" family = "Gen4" diff --git a/website/docs/r/postgresql_database.html.markdown b/website/docs/r/postgresql_database.html.markdown index 3c890ec60506..0c9668d0ac31 100644 --- a/website/docs/r/postgresql_database.html.markdown +++ b/website/docs/r/postgresql_database.html.markdown @@ -24,7 +24,7 @@ resource "azurerm_postgresql_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - name = "B_Gen4_2" + name = "B_Gen5_2" capacity = 2 tier = "Basic" family = "Gen4" diff --git a/website/docs/r/postgresql_server.html.markdown b/website/docs/r/postgresql_server.html.markdown index a6661169bc7e..34318962e5f6 100644 --- a/website/docs/r/postgresql_server.html.markdown +++ b/website/docs/r/postgresql_server.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_postgresql_server -Manage a PostgreSQL Server. +Manages a PostgreSQL Server. ## Example Usage @@ -24,7 +24,7 @@ resource "azurerm_postgresql_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" sku { - name = "B_Gen4_2" + name = "B_Gen5_2" capacity = 2 tier = "Basic" family = "Gen4" @@ -61,7 +61,7 @@ The following arguments are supported: * `administrator_login_password` - (Required) The Password associated with the `administrator_login` for the PostgreSQL Server. -* `version` - (Required) Specifies the version of PostgreSQL to use. Valid values are `9.5`, `9.6`, `10`, `10.0`, and `10.2`. Changing this forces a new resource to be created. +* `version` - (Required) Specifies the version of PostgreSQL to use. Valid values are `9.5`, `9.6`, `10`, `10.0`, and `11`. Changing this forces a new resource to be created. * `ssl_enforcement` - (Required) Specifies if SSL should be enforced on connections. Possible values are `Enabled` and `Disabled`. @@ -87,7 +87,7 @@ The following arguments are supported: * `backup_retention_days` - (Optional) Backup retention days for the server, supported values are between `7` and `35` days. -* `geo_redundant_backup` - (Optional) Enable Geo-redundant or not for server backup. Valid values for this property are `Enabled` or `Disabled`, not supported for the `basic` tier. +* `geo_redundant_backup` - (Optional) Enable/Disable Geo-redundant for server backup. Valid values for this property are `Enabled` or `Disabled`, not supported for the `basic` tier. This allows you to choose between locally redundant or geo-redundant backup storage in the General Purpose and Memory Optimized tiers. When the backups are stored in geo-redundant backup storage, they are not only stored within the region in which your server is hosted, but are also replicated to a paired data center. This provides better protection and ability to restore your server in a different region in the event of a disaster. The Basic tier only offers locally redundant backup storage. ## Attributes Reference diff --git a/website/docs/r/private_dns_a_record.html.markdown b/website/docs/r/private_dns_a_record.html.markdown new file mode 100644 index 000000000000..807e35720fc1 --- /dev/null +++ b/website/docs/r/private_dns_a_record.html.markdown @@ -0,0 +1,63 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_private_dns_a_record" +sidebar_current: "docs-azurerm-resource-private-dns-a-record" +description: |- + Manages a Private DNS A Record. +--- + +# azurerm_private_dns_a_record + +Enables you to manage DNS A Records within Azure Private DNS. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} + +resource "azurerm_private_dns_zone" "test" { + name = "mydomain.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_a_record" "test" { + name = "test" + zone_name = "${azurerm_private_dns_zone.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + ttl = 300 + records = ["10.0.180.17"] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the DNS A Record. + +* `resource_group_name` - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created. + +* `zone_name` - (Required) Specifies the Private DNS Zone where the resource exists. Changing this forces a new resource to be created. + +* `TTL` - (Required) The Time To Live (TTL) of the DNS record in seconds. + +* `records` - (Required) List of IPv4 Addresses. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Private DNS A Record ID. + +## Import + +Private DNS A Records can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_private_dns_a_record.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/privateDnsZones/zone1/A/myrecord1 +``` diff --git a/website/docs/r/private_dns_cname_record.html.markdown b/website/docs/r/private_dns_cname_record.html.markdown new file mode 100644 index 000000000000..d24962e259a1 --- /dev/null +++ b/website/docs/r/private_dns_cname_record.html.markdown @@ -0,0 +1,63 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_private_dns_cname_record" +sidebar_current: "docs-azurerm-resource-private-dns-cname-record" +description: |- + Manages a Private DNS CNAME Record. +--- + +# azurerm_dns_a_record + +Enables you to manage DNS CNAME Records within Azure Private DNS. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} + +resource "azurerm_private_dns_zone" "test" { + name = "mydomain.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_private_dns_cname_record" "test" { + name = "test" + zone_name = "${azurerm_private_dns_zone.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + ttl = 300 + record = "contoso.com" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the DNS CNAME Record. + +* `resource_group_name` - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created. + +* `zone_name` - (Required) Specifies the Private DNS Zone where the resource exists. Changing this forces a new resource to be created. + +* `TTL` - (Required) The Time To Live (TTL) of the DNS record in seconds. + +* `record` - (Required) The target of the CNAME. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Private DNS CNAME Record ID. + +## Import + +Private DNS CName Records can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_private_dns_cname_record.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/privateDnsZones/zone1/CName/myrecord1 +``` diff --git a/website/docs/r/private_dns_zone.html.markdown b/website/docs/r/private_dns_zone.html.markdown new file mode 100644 index 000000000000..33bdc733197f --- /dev/null +++ b/website/docs/r/private_dns_zone.html.markdown @@ -0,0 +1,52 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_private_dns_zone" +sidebar_current: "docs-azurerm-resource-private-dns-zone" +description: |- + Manages a Private DNS Zone. +--- + +# azurerm_private_dns_zone + +Enables you to manage Private DNS zones within Azure DNS. These zones are hosted on Azure's name servers. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} + +resource "azurerm_private_dns_zone" "test" { + name = "mydomain.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} +``` +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Private DNS Zone. Must be a valid domain name. + +* `resource_group_name` - (Required) Specifies the resource group where the resource exists. Changing this forces a new resource to be created. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Prviate DNS Zone ID. +* `number_of_record_sets` - The current number of record sets in this Private DNS zone. +* `max_number_of_record_sets` - The maximum number of record sets that can be created in this Private DNS zone. +* `max_number_of_virtual_network_links` - The maximum number of virtual networks that can be linked to this Private DNS zone. +* `max_number_of_virtual_network_links_with_registration` - The maximum number of virtual networks that can be linked to this Private DNS zone with registration enabled. + +## Import + +Private DNS Zones can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_private_dns_zone.zone1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/privateDnsZones/zone1 +``` diff --git a/website/docs/r/public_ip.html.markdown b/website/docs/r/public_ip.html.markdown index 3e6c8bfbadf4..684fd49fc054 100644 --- a/website/docs/r/public_ip.html.markdown +++ b/website/docs/r/public_ip.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_public_ip -Manage a Public IP Address. +Manages a Public IP Address. ## Example Usage @@ -46,8 +46,6 @@ The following arguments are supported: -> **Note** Public IP Standard SKUs require `allocation_method` to be set to `Static`. --> **Note:** The `Standard` SKU is currently in Public Preview on an opt-in basis. [More information, including how you can register for the Preview, and which regions `Standard` SKU's are available in are available here](https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-standard-overview) - * `allocation_method` - (Required) Defines the allocation method for this IP address. Possible values are `Static` or `Dynamic`. ~> **Note** `Dynamic` Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure - [more information is available below](#ip_address). @@ -62,6 +60,10 @@ The following arguments are supported: * `reverse_fqdn` - (Optional) A fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN. +* `public_ip_prefix_id` - (Optional) If specified then public IP address allocated will be provided from the public IP prefix resource. + +-> **Please Note**: Public IP Prefix are currently in Public Preview. You can find more information about [Public IP Preifx Preview here](https://docs.microsoft.com/en-us/azure/virtual-network/public-ip-address-prefix). + * `tags` - (Optional) A mapping of tags to assign to the resource. * `zones` - (Optional) A collection containing the availability zone to allocate the Public IP in. @@ -77,7 +79,7 @@ The following attributes are exported: ~> **Note** `Dynamic` Public IP Addresses aren't allocated until they're attached to a device (e.g. a Virtual Machine/Load Balancer). Instead you can obtain the IP Address once the the Public IP has been assigned via the [`azurerm_public_ip` Data Source](../d/public_ip.html). -* `fqdn` - Fully qualified domain name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone +* `fqdn` - Fully qualified domain name of the A DNS record associated with the public IP. `domain_name_label` must be specified to get the `fqdn`. This is the concatenation of the `domain_name_label` and the regionalized DNS zone ## Import diff --git a/website/docs/r/public_ip_prefix.html.markdown b/website/docs/r/public_ip_prefix.html.markdown new file mode 100644 index 000000000000..f186dd25b8c9 --- /dev/null +++ b/website/docs/r/public_ip_prefix.html.markdown @@ -0,0 +1,73 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_public_ip_prefix" +sidebar_current: "docs-azurerm-resource-network-public-ip-prefix" +description: |- + Manages a Public IP Prefix. +--- + +# azurerm_public_ip_prefix + +Manages a Public IP Prefix. + +-> **NOTE** Public IP Prefix are currently in Public Preview. You can find more information about [Public IP Preifx Preview here](https://docs.microsoft.com/en-us/azure/virtual-network/public-ip-address-prefix). + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "resourceGroup1" + location = "West Europe" +} + +resource "azurerm_public_ip_prefix" "test" { + name = "acceptanceTestPublicIpPrefix1" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + prefix_length = 31 + + tags = { + environment = "Production" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Public IP resource . Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the public IP. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `sku` - (Optional) The SKU of the Public IP Prefix. Accepted values are `Standard`. Defaults to `Standard`. Changing this forces a new resource to be created. + +-> **Note** Public IP Prefix can only be created with Standard SKUs at this time. + +* `prefix_length` - (Optional) Specifies the number of bits of the prefix. The value can be set between 24 (256 addresses) and 31 (2 addresses). Changing this forces a new resource to be created. + +-> **Please Note:**: There may be Public IP address limits on the subscription . [More information available here](https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits?toc=%2fazure%2fvirtual-network%2ftoc.json#publicip-address) + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +* `zones` - (Optional) A collection containing the availability zone to allocate the Public IP in. + +-> **Please Note**: Availability Zones are [only supported in several regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview). + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Public IP Prefix ID. +* `ip_prefix` - The IP address prefix value that was allocated. + +## Import + +Public IP Prefixes can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_public_ip_prefix.myPublicIpPrefix /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/publicIPFixes/myPublicIpPrefix1 +``` diff --git a/website/docs/r/recovery_network_mapping.html.markdown b/website/docs/r/recovery_network_mapping.html.markdown new file mode 100644 index 000000000000..2acf8dccfd59 --- /dev/null +++ b/website/docs/r/recovery_network_mapping.html.markdown @@ -0,0 +1,103 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_recovery_network_mapping" +sidebar_current: "docs-azurerm-recovery-network-mapping" +description: |- + Manages a site recovery network mapping on Azure. +--- + +# azurerm_recovery_network_mapping + +Manages a site recovery network mapping on Azure. A network mapping decides how to translate connected netwroks when a VM is migrated from one region to another. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "primary" { + name = "tfex-network-mapping-primary" + location = "West US" +} + +resource "azurerm_resource_group" "secondary" { + name = "tfex-network-mapping-secondary" + location = "East US" +} + +resource "azurerm_recovery_services_vault" "vault" { + name = "example-recovery-vault" + location = "${azurerm_resource_group.secondary.location}" + resource_group_name = "${azurerm_resource_group.secondary.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "primary" { + name = "primary-fabric" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + location = "${azurerm_resource_group.primary.location}" +} + +resource "azurerm_recovery_services_fabric" "secondary" { + name = "secondary-fabric" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + location = "${azurerm_resource_group.secondary.location}" + depends_on = ["azurerm_recovery_services_fabric.primary"] # Avoids issues with crearing fabrics simultainusly +} + +resource "azurerm_virtual_network" "primary" { + name = "network1" + resource_group_name = "${azurerm_resource_group.primary.name}" + address_space = [ "192.168.1.0/24" ] + location = "${azurerm_resource_group.primary.location}" +} + +resource "azurerm_virtual_network" "secondary" { + name = "network2" + resource_group_name = "${azurerm_resource_group.secondary.name}" + address_space = [ "192.168.2.0/24" ] + location = "${azurerm_resource_group.secondary.location}" +} + +resource "azurerm_recovery_network_mapping" "recovery-mapping" { + name = "recovery-network-mapping-1" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + source_recovery_fabric_name = "primary-fabric" + target_recovery_fabric_name = "secondary-fabric" + source_network_id = "${azurerm_virtual_network.primary.id}" + target_network_id = "${azurerm_virtual_network.secondary.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the network mapping. + +* `resource_group_name` - (Required) Name of the resource group where the vault that should be updated is located. + +* `recovery_vault_name` - (Required) The name of the vault that should be updated. + +* `source_recovery_fabric_name` - (Required) Specifies the ASR fabric where mapping should be created. + +* `target_recovery_fabric_name` - (Required) The Azure Site Recovery fabric object corresponding to the recovery Azure region. + +* `source_network_id` - (Required) The id of the primary network. + +* `target_network_id` - (Required) The id of the recovery network. + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +* `id` - The resource ID. + +## Import + +Site recovery network mapping can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_recovery_network_mapping.mymapping /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resource-group-name/providers/Microsoft.RecoveryServices/vaults/recovery-vault-name/replicationFabrics/primary-fabric-name/replicationNetworks/azureNetwork/replicationNetworkMappings/mapping-name +``` diff --git a/website/docs/r/recovery_services_fabric.html.markdown b/website/docs/r/recovery_services_fabric.html.markdown new file mode 100644 index 000000000000..0e32c5c72f33 --- /dev/null +++ b/website/docs/r/recovery_services_fabric.html.markdown @@ -0,0 +1,65 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_recovery_services_fabric" +sidebar_current: "docs-azurerm-recovery-services-fabric" +description: |- + Manages a site recovery services fabric on Azure. +--- + +# azurerm_recovery_services_fabric + +Manages a Azure recovery vault fabric. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "primary" { + name = "tfex-network-mapping-primary" + location = "West US" +} + +resource "azurerm_resource_group" "secondary" { + name = "tfex-network-mapping-secondary" + location = "East US" +} + +resource "azurerm_recovery_services_vault" "vault" { + name = "example-recovery-vault" + location = "${azurerm_resource_group.secondary.location}" + resource_group_name = "${azurerm_resource_group.secondary.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "fabric" { + name = "primary-fabric" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + location = "${azurerm_resource_group.primary.location}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the network mapping. + +* `resource_group_name` - (Required) Name of the resource group where the vault that should be updated is located. + +* `recovery_vault_name` - (Required) The name of the vault that should be updated. + +* `location` - (Required) In what region should the fabric be located. + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +* `id` - The resource ID. + +## Import + +Site recovery recovery vault fabric can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_recovery_services_fabric.myfabric /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resource-group-name/providers/Microsoft.RecoveryServices/vaults/recovery-vault-name/replicationFabrics/fabric-name +``` diff --git a/website/docs/r/recovery_services_protected_vm.markdown b/website/docs/r/recovery_services_protected_vm.markdown index 737c314004cf..46622b5a7378 100644 --- a/website/docs/r/recovery_services_protected_vm.markdown +++ b/website/docs/r/recovery_services_protected_vm.markdown @@ -54,7 +54,7 @@ The following arguments are supported: * `source_vm_id` - (Required) Specifies the ID of the VM to backup. Changing this forces a new resource to be created. -* `backup_policy_id` - (Required) Specifies the id of the backup policy to use. Changing this forces a new resource to be created. +* `backup_policy_id` - (Required) Specifies the id of the backup policy to use. * `tags` - (Optional) A mapping of tags to assign to the resource. diff --git a/website/docs/r/recovery_services_protection_container.html.markdown b/website/docs/r/recovery_services_protection_container.html.markdown new file mode 100644 index 000000000000..b5f022667708 --- /dev/null +++ b/website/docs/r/recovery_services_protection_container.html.markdown @@ -0,0 +1,72 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_recovery_services_protection_container" +sidebar_current: "docs-azurerm-recovery-services-protection-container" +description: |- + Manages a site recovery services protection container on Azure. +--- + +# azurerm_recovery_services_protection_container + +Manages a Azure recovery vault protection container. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "primary" { + name = "tfex-network-mapping-primary" + location = "West US" +} + +resource "azurerm_resource_group" "secondary" { + name = "tfex-network-mapping-secondary" + location = "East US" +} + +resource "azurerm_recovery_services_vault" "vault" { + name = "example-recovery-vault" + location = "${azurerm_resource_group.secondary.location}" + resource_group_name = "${azurerm_resource_group.secondary.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "fabric" { + name = "primary-fabric" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + location = "${azurerm_resource_group.primary.location}" +} + +resource "azurerm_recovery_services_protection_container" "protection-container" { + name = "protection-container" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.fabric.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the network mapping. + +* `resource_group_name` - (Required) Name of the resource group where the vault that should be updated is located. + +* `recovery_vault_name` - (Required) The name of the vault that should be updated. + +* `recovery_fabric_name` - (Required) Name of fabric that should contain this protection container. + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +* `id` - The resource ID. + +## Import + +Site recovery recovery vault fabric can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_recovery_services_protection_container.mycontainer /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resource-group-name/providers/Microsoft.RecoveryServices/vaults/recovery-vault-name/replicationFabrics/fabric-name/replicationProtectionContainers/protection-container-name +``` diff --git a/website/docs/r/recovery_services_protection_container_mapping.html.markdown b/website/docs/r/recovery_services_protection_container_mapping.html.markdown new file mode 100644 index 000000000000..52c421400576 --- /dev/null +++ b/website/docs/r/recovery_services_protection_container_mapping.html.markdown @@ -0,0 +1,110 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_recovery_services_protection_container_mapping" +sidebar_current: "docs-azurerm-recovery-services-protection-container-mapping" +description: |- + Manages a site recovery services protection container mappings on Azure. +--- + +# azurerm_recovery_services_protection_container_mapping + +Manages a Azure recovery vault protection container mapping. A network protection container mapping decides how to translate the protection container when a VM is migrated from one region to another. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "primary" { + name = "tfex-network-mapping-primary" + location = "West US" +} + +resource "azurerm_resource_group" "secondary" { + name = "tfex-network-mapping-secondary" + location = "East US" +} + +resource "azurerm_recovery_services_vault" "vault" { + name = "example-recovery-vault" + location = "${azurerm_resource_group.secondary.location}" + resource_group_name = "${azurerm_resource_group.secondary.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "primary" { + name = "primary-fabric" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + location = "${azurerm_resource_group.primary.location}" +} + +resource "azurerm_recovery_services_fabric" "secondary" { + name = "secondary-fabric" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + location = "${azurerm_resource_group.secondary.location}" +} + +resource "azurerm_recovery_services_protection_container" "primary" { + name = "primary-protection-container" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.primary.name}" +} + +resource "azurerm_recovery_services_protection_container" "secondary" { + name = "secondary-protection-container" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.secondary.name}" +} + +resource "azurerm_recovery_services_replication_policy" "policy" { + name = "policy" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_point_retention_in_minutes = "${24 * 60}" + application_consistent_snapshot_frequency_in_minutes = "${4 * 60}" +} + +resource "azurerm_recovery_services_protection_container_mapping" "container-mapping" { + name = "container-mapping" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.primary.name}" + recovery_source_protection_container_name = "${azurerm_recovery_services_protection_container.primary.name}" + recovery_target_protection_container_id = "${azurerm_recovery_services_protection_container.secondary.id}" + recovery_replication_policy_id = "${azurerm_recovery_services_replication_policy.policy.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the network mapping. + +* `resource_group_name` - (Required) Name of the resource group where the vault that should be updated is located. + +* `recovery_vault_name` - (Required) The name of the vault that should be updated. + +* `recovery_fabric_name` - (Required) Name of fabric that should contains the protection container to map. + +* `recovery_source_protection_container_name` - (Required) Name of the protection container to map. + +* `recovery_target_protection_container_id` - (Required) Id of protection container to map to. + +* `recovery_replication_policy_id` - (Required) Id of the policy to use for this mapping. + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +* `id` - The resource ID. + +## Import + +Site recovery recovery vault fabric can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_recovery_services_protection_container_mapping.mymapping /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resource-group-name/providers/Microsoft.RecoveryServices/vaults/recovery-vault-name/ +``` diff --git a/website/docs/r/recovery_services_protection_policy_vm.markdown b/website/docs/r/recovery_services_protection_policy_vm.markdown index fd8ce5ea4a95..883e04875ef2 100644 --- a/website/docs/r/recovery_services_protection_policy_vm.markdown +++ b/website/docs/r/recovery_services_protection_policy_vm.markdown @@ -91,7 +91,7 @@ The `backup` block supports: * `frequency` - (Required) Sets the backup frequency. Must be either `Daily` or`Weekly`. -* `times` - (Required) The time of day to preform the backup in 24hour format. +* `times` - (Required) The time of day to perform the backup in 24hour format. * `weekdays` - (Optional) The days of the week to perform backups on. Must be one of `Sunday`, `Monday`, `Tuesday`, `Wednesday`, `Thursday`, `Friday` or `Saturday`. @@ -129,7 +129,7 @@ The `retention_yearly` block supports: * `weeks` - (Required) The weeks of the month to retain backups of. Must be one of `First`, `Second`, `Third`, `Fourth`, `Last`. -* `months` - (Required) The months of the year to retain backups of. Must be one of `January`, `Febuary`, `March`, `April`, `May`, `June`, `July`, `Augest`, `September`, `October`, `November` and `December`. +* `months` - (Required) The months of the year to retain backups of. Must be one of `January`, `February`, `March`, `April`, `May`, `June`, `July`, `Augest`, `September`, `October`, `November` and `December`. --- diff --git a/website/docs/r/recovery_services_replicated_vm.html.markdown b/website/docs/r/recovery_services_replicated_vm.html.markdown new file mode 100644 index 000000000000..5c8dedaccf66 --- /dev/null +++ b/website/docs/r/recovery_services_replicated_vm.html.markdown @@ -0,0 +1,220 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_recovery_replicated_vm" +sidebar_current: "docs-azurerm-recovery-replicated-vm" +description: |- + Manages a site recovery services protection container mappings on Azure. +--- + +# azurerm_recovery_replicated_vm + +Manages a Azure recovery replicated vms (Azure to Azure). An replicated VM keeps a copiously updated image of the vm in another region in order to be able to start the VM in that region in case of a disaster. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "primary" { + name = "tfex-replicated-vm-primary" + location = "West US" +} + +resource "azurerm_resource_group" "secondary" { + name = "tfex-replicated-vm-secondary" + location = "East US" +} + +resource "azurerm_virtual_machine" "vm" { + name = "vm" + location = "${azurerm_resource_group.primary.location}" + resource_group_name = "${azurerm_resource_group.primary.name}" + vm_size = "Standard_B1s" + network_interface_ids = ["${azurerm_network_interface.vm.id}"] + + storage_image_reference { + publisher = "OpenLogic" + offer = "CentOS" + sku = "7.5" + version = "latest" + } + + storage_os_disk { + name = "vm-os-disk" + os_type = "Linux" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Premium_LRS" + } + + os_profile { + admin_username = "test-admin-123" + admin_password = "test-pwd-123" + computer_name = "vm" + } + + os_profile_linux_config { + disable_password_authentication = false + } +} + +resource "azurerm_recovery_services_vault" "vault" { + name = "example-recovery-vault" + location = "${azurerm_resource_group.secondary.location}" + resource_group_name = "${azurerm_resource_group.secondary.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_fabric" "primary" { + name = "primary-fabric" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + location = "${azurerm_resource_group.primary.location}" +} + +resource "azurerm_recovery_services_fabric" "secondary" { + name = "secondary-fabric" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + location = "${azurerm_resource_group.secondary.location}" +} + +resource "azurerm_recovery_services_protection_container" "primary" { + name = "primary-protection-container" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.primary.name}" +} + +resource "azurerm_recovery_services_protection_container" "secondary" { + name = "secondary-protection-container" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.secondary.name}" +} + +resource "azurerm_recovery_services_replication_policy" "policy" { + name = "policy" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_point_retention_in_minutes = "${24 * 60}" + application_consistent_snapshot_frequency_in_minutes = "${4 * 60}" +} + +resource "azurerm_recovery_services_protection_container_mapping" "container-mapping" { + name = "container-mapping" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_fabric_name = "${azurerm_recovery_services_fabric.primary.name}" + recovery_source_protection_container_name = "${azurerm_recovery_services_protection_container.primary.name}" + recovery_target_protection_container_id = "${azurerm_recovery_services_protection_container.secondary.id}" + recovery_replication_policy_id = "${azurerm_recovery_services_replication_policy.policy.id}" +} + +resource "azurerm_storage_account" "primary" { + name = "primaryrecoverycache" + location = "${azurerm_resource_group.primary.location}" + resource_group_name = "${azurerm_resource_group.primary.name}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_virtual_network" "primary" { + name = "network1" + resource_group_name = "${azurerm_resource_group.primary.name}" + address_space = [ "192.168.1.0/24" ] + location = "${azurerm_resource_group.primary.location}" +} + +resource "azurerm_subnet" "primary" { + name = "network1-subnet" + resource_group_name = "${azurerm_resource_group.primary.name}" + virtual_network_name = "${azurerm_virtual_network.primary.name}" + address_prefix = "192.168.1.0/24" +} + +resource "azurerm_network_interface" "vm" { + name = "vm-nic" + location = "${azurerm_resource_group.primary.location}" + resource_group_name = "${azurerm_resource_group.primary.name}" + + ip_configuration { + name = "vm" + subnet_id = "${azurerm_subnet.primary.id}" + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_recovery_replicated_vm" "vm-replication" { + name = "vm-replication" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + source_recovery_fabric_name = "${azurerm_recovery_services_fabric.primary.name}" + source_vm_id = "${azurerm_virtual_machine.vm.id}" + recovery_replication_policy_id = "${azurerm_recovery_services_replication_policy.policy.id}" + source_recovery_protection_container_name = "${azurerm_recovery_services_protection_container.primary.name}" + + target_resource_group_id = "${azurerm_resource_group.secondary.id}" + target_recovery_fabric_id = "${azurerm_recovery_services_fabric.secondary.id}" + target_recovery_protection_container_id = "${azurerm_recovery_services_protection_container.secondary.id}" + + managed_disk { + disk_id = "${azurerm_virtual_machine.vm.storage_os_disk.0.managed_disk_id}" + staging_storage_account_id = "${azurerm_storage_account.primary.id}" + target_resource_group_id = "${azurerm_resource_group.secondary.id}" + target_disk_type = "Premium_LRS" + target_replica_disk_type = "Premium_LRS" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the network mapping. + +* `resource_group_name` - (Required) Name of the resource group where the vault that should be updated is located. + +* `recovery_vault_name` - (Required) The name of the vault that should be updated. + +* `source_recovery_fabric_name` - (Required) Name of fabric that should contains this replication. + +* `source_vm_id` - (Required) Id of the VM to replicate + +* `source_recovery_protection_container_name` - (Required) Name of the protection container to use. + +* `target_resource_group_id` - (Required) Id of resource group where the VM should be created when a failover is done. + +* `target_recovery_fabric_id` - (Required) Id of fabric where the VM replication should be handled when a failover is done. + +* `target_recovery_protection_container_id` - (Required) Id of protection container where the VM replication should be created when a failover is done. + +* `target_availability_set_id` - (Optional) Id of availability set that the new VM should belong to when a failover is done. + +* `managed_disk` - (Required) One or more `managed_disk` block. + +--- + +A `managed_disk` block supports the following: + +* `disk_id` - (Required) Id of disk that should be replicated. + +* `staging_storage_account_id` - (Required) Storage account that should be used for caching. + +* `target_resource_group_id` - (Required) Resource group disk should belong to when a failover is done. + +* `target_disk_type` - (Required) What type should the disk be when a failover is done. + +* `target_replica_disk_type` - (Required) What type should the disk be that holds the replication data. + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +* `id` - The resource ID. + +## Import + +Site recovery recovery vault fabric can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_recovery_replicated_vm.vmreplication /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resource-group-name/providers/Microsoft.RecoveryServices/vaults/recovery-vault-name/replicationFabrics/fabric-name/replicationProtectionContainers/protection-container-name/replicationProtectedItems/vm-replication-name diff --git a/website/docs/r/recovery_services_replication_policy.html.markdown b/website/docs/r/recovery_services_replication_policy.html.markdown new file mode 100644 index 000000000000..bfddf60f050c --- /dev/null +++ b/website/docs/r/recovery_services_replication_policy.html.markdown @@ -0,0 +1,63 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_recovery_services_replication_policy" +sidebar_current: "docs-azurerm-recovery-services-replication-policy" +description: |- + Manages a site recovery services replication policy on Azure. +--- + +# azurerm_recovery_services_replication_policy + +Manages a Azure recovery vault replication policy. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "secondary" { + name = "tfex-network-mapping-secondary" + location = "East US" +} + +resource "azurerm_recovery_services_vault" "vault" { + name = "example-recovery-vault" + location = "${azurerm_resource_group.secondary.location}" + resource_group_name = "${azurerm_resource_group.secondary.name}" + sku = "Standard" +} + +resource "azurerm_recovery_services_replication_policy" "policy" { + name = "policy" + resource_group_name = "${azurerm_resource_group.secondary.name}" + recovery_vault_name = "${azurerm_recovery_services_vault.vault.name}" + recovery_point_retention_in_minutes = "${24 * 60}" + application_consistent_snapshot_frequency_in_minutes = "${4 * 60}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the network mapping. + +* `resource_group_name` - (Required) Name of the resource group where the vault that should be updated is located. + +* `recovery_vault_name` - (Required) The name of the vault that should be updated. + +* `recovery_point_retention_in_minutes` - (Required) Retain the recovery points for given time in minutes. + +* `application_consistent_snapshot_frequency_in_minutes` - (Required) Specifies the frequency(in minutes) at which to create application consistent recovery points. + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +* `id` - The resource ID. + +## Import + +Site recovery recovery vault fabric can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_recovery_services_protection_container.mycontainer /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resource-group-name/providers/Microsoft.RecoveryServices/vaults/recovery-vault-name/replicationPolicies/policy-name +``` diff --git a/website/docs/r/recovery_services_vault.markdown b/website/docs/r/recovery_services_vault.markdown index 2438b1eb75cb..1c4c3d8c339e 100644 --- a/website/docs/r/recovery_services_vault.markdown +++ b/website/docs/r/recovery_services_vault.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_recovery_services_vault -Manage an Recovery Services Vault. +Manages an Recovery Services Vault. ## Example Usage diff --git a/website/docs/r/redis_cache.html.markdown b/website/docs/r/redis_cache.html.markdown index f9c785d76134..b4da57a39458 100644 --- a/website/docs/r/redis_cache.html.markdown +++ b/website/docs/r/redis_cache.html.markdown @@ -11,105 +11,28 @@ description: |- Manages a Redis Cache. -## Example Usage (Basic) +## Example Usage -```hcl -resource "azurerm_resource_group" "test" { - name = "redis-resources" - location = "West US" -} - -# NOTE: the Name used for Redis needs to be globally unique -resource "azurerm_redis_cache" "test" { - name = "tf-redis-basic" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - capacity = 0 - family = "C" - sku_name = "Basic" - enable_non_ssl_port = false -} -``` - -## Example Usage (Standard) +This example provisions a Standard Redis Cache. Other examples of the `azurerm_redis_cache` resource can be found in [the `./examples/redis-cache` directory within the Github Repository](https://github.com/terraform-providers/terraform-provider-azurerm/tree/master/examples/redis-cache) ```hcl -resource "azurerm_resource_group" "test" { - name = "redis-resources" - location = "West US" +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" } # NOTE: the Name used for Redis needs to be globally unique -resource "azurerm_redis_cache" "test" { - name = "tf-redis-standard" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" +resource "azurerm_redis_cache" "example" { + name = "example-cache" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" capacity = 2 family = "C" sku_name = "Standard" enable_non_ssl_port = false -} -``` - -## Example Usage (Premium with Clustering) + minimum_tls_version = "1.2" -```hcl -resource "azurerm_resource_group" "test" { - name = "redis-resources" - location = "West US" -} - -# NOTE: the Name used for Redis needs to be globally unique -resource "azurerm_redis_cache" "test" { - name = "tf-redis-premium" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - capacity = 1 - family = "P" - sku_name = "Premium" - enable_non_ssl_port = false - shard_count = 3 - - redis_configuration { - maxmemory_reserved = 2 - maxmemory_delta = 2 - maxmemory_policy = "allkeys-lru" - } -} -``` - -## Example Usage (Premium with Backup) - -```hcl -resource "azurerm_resource_group" "test" { - name = "redis-resources" - location = "West US" -} - -resource "azurerm_storage_account" "test" { - name = "redissa" - resource_group_name = "${azurerm_resource_group.test.name}" - location = "${azurerm_resource_group.test.location}" - account_tier = "Standard" - account_replication_type = "GRS" -} - -# NOTE: the Name used for Redis needs to be globally unique -resource "azurerm_redis_cache" "test" { - name = "tf-redis-pbkup" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - capacity = 3 - family = "P" - sku_name = "Premium" - enable_non_ssl_port = false - - redis_configuration { - rdb_backup_enabled = true - rdb_backup_frequency = 60 - rdb_backup_max_snapshot_count = 1 - rdb_storage_connection_string = "DefaultEndpointsProtocol=https;BlobEndpoint=${azurerm_storage_account.test.primary_blob_endpoint};AccountName=${azurerm_storage_account.test.name};AccountKey=${azurerm_storage_account.test.primary_access_key}" - } + redis_configuration {} } ``` @@ -127,19 +50,21 @@ The following arguments are supported: * `capacity` - (Required) The size of the Redis cache to deploy. Valid values for a SKU `family` of C (Basic/Standard) are `0, 1, 2, 3, 4, 5, 6`, and for P (Premium) `family` are `1, 2, 3, 4`. -* `family` - (Required) The SKU family to use. Valid values are `C` and `P`, where C = Basic/Standard, P = Premium. +* `family` - (Required) The SKU family/pricing group to use. Valid values are `C` (for Basic/Standard SKU family) and `P` (for `Premium`) + +* `sku_name` - (Required) The SKU of Redis to use. Possible values are `Basic`, `Standard` and `Premium`. -The pricing group for the Redis Family - either "C" or "P" at present. +--- -* `sku_name` - (Required) The SKU of Redis to use - can be either Basic, Standard or Premium. +* `enable_non_ssl_port` - (Optional) Enable the non-SSL port (6379) - disabled by default. -* `enable_non_ssl_port` - (Optional) Enable the non-SSL port (6789) - disabled by default. +* `minimum_tls_version` - (Optional) The minimum TLS version. Defaults to `1.0`. * `patch_schedule` - (Optional) A list of `patch_schedule` blocks as defined below - only available for Premium SKU's. * `private_static_ip_address` - (Optional) The Static IP Address to assign to the Redis Cache when hosted inside the Virtual Network. Changing this forces a new resource to be created. -* `redis_configuration` - (Required) A `redis_configuration` as defined below - with some limitations by SKU - defaults/details are shown below. +* `redis_configuration` - (Optional) A `redis_configuration` as defined below - with some limitations by SKU - defaults/details are shown below. * `shard_count` - (Optional) *Only available when using the Premium SKU* The number of Shards to create on the Redis Cluster. @@ -149,10 +74,15 @@ The pricing group for the Redis Family - either "C" or "P" at present. * `zones` - (Optional) A list of a single item of the Availability Zone which the Redis Cache should be allocated in. - -> **Please Note**: Availability Zones are [in Preview and only supported in several regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview) - as such you must be opted into the Preview to use this functionality. You can [opt into the Availability Zones Preview in the Azure Portal](http://aka.ms/azenroll). +-> **Please Note**: Availability Zones are [in Preview and only supported in several regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview) - as such you must be opted into the Preview to use this functionality. You can [opt into the Availability Zones Preview in the Azure Portal](http://aka.ms/azenroll). + --- -* `redis_configuration` supports the following: +A `redis_configuration` block supports the following: + +* `enable_authentication` - (Optional) If set to `false`, the Redis instance will be accessible without authentication. Defaults to `true`. + +-> **NOTE:** `enable_authentication` can only be set to `false` if a `subnet_id` is specified; and only works if there aren't existing instances within the subnet with `enable_authentication` set to `true`. * `maxmemory_reserved` - (Optional) Value in megabytes reserved for non-cache usage e.g. failover. Defaults are shown below. * `maxmemory_delta` - (Optional) The max-memory delta for this Redis instance. Defaults are shown below. @@ -185,18 +115,23 @@ redis_configuration { ``` ## Default Redis Configuration Values + | Redis Value | Basic | Standard | Premium | | ------------------------------- | ------------ | ------------ | ------------ | +| enable_authentication | true | true | true | | maxmemory_reserved | 2 | 50 | 200 | | maxfragmentationmemory_reserved | 2 | 50 | 200 | | maxmemory_delta | 2 | 50 | 200 | | maxmemory_policy | volatile-lru | volatile-lru | volatile-lru | -_*Important*: The `maxmemory_reserved`, `maxmemory_delta` and `maxfragmentationmemory-reserved` settings are only available for Standard and Premium caches. More details are available in the Relevant Links section below._ +~> **NOTE:** The `maxmemory_reserved`, `maxmemory_delta` and `maxfragmentationmemory-reserved` settings are only available for Standard and Premium caches. More details are available in the Relevant Links section below._ -* `patch_schedule` supports the following: +--- + +A `patch_schedule` block supports the following: * `day_of_week` (Required) the Weekday name - possible values include `Monday`, `Tuesday`, `Wednesday` etc. + * `start_hour_utc` - (Optional) the Start Hour for maintenance in UTC - possible values range from `0 - 23`. ~> **Note:** The Patch Window lasts for `5` hours from the `start_hour_utc`. diff --git a/website/docs/r/relay_namespace.html.markdown b/website/docs/r/relay_namespace.html.markdown index 1cef0b3e228a..9397211af75e 100644 --- a/website/docs/r/relay_namespace.html.markdown +++ b/website/docs/r/relay_namespace.html.markdown @@ -24,9 +24,7 @@ resource "azurerm_relay_namespace" "test" { location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - sku { - name = "Standard" - } + sku_name = "Standard" tags = { source = "terraform" @@ -44,16 +42,17 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the Azure Relay Namespace exists. Changing this forces a new resource to be created. -* `sku` - (Required) A `sku` block as defined below. +* `sku` - (Optional **Deprecated**)) A `sku` block as described below. + +* `sku_name` - (Optional) The name of the SKU to use. At this time the only supported value is `Standard`. * `tags` - (Optional) A mapping of tags to assign to the resource. ---- +---- A `sku` block contains: -* `name` - (Required) The name of the SKU to use. At this time the only supported value is `Standard`. - +* `name` - (Optional) The name of the SKU to use. At this time the only supported value is `Standard`. ## Attributes Reference @@ -61,8 +60,7 @@ The following attributes are exported: * `id` - The Azure Relay Namespace ID. -The following attributes are exported only if there is an authorization rule named -`RootManageSharedAccessKey` which is created automatically by Azure. +The following attributes are exported only if there is an authorization rule named `RootManageSharedAccessKey` which is created automatically by Azure. * `primary_connection_string` - The primary connection string for the authorization rule `RootManageSharedAccessKey`. diff --git a/website/docs/r/resource_group.html.markdown b/website/docs/r/resource_group.html.markdown index 507319c77923..0024a7b232f0 100644 --- a/website/docs/r/resource_group.html.markdown +++ b/website/docs/r/resource_group.html.markdown @@ -37,11 +37,10 @@ The following arguments are supported: ## Attributes Reference -The following attributes are exported: +In addition to the arguments above, the following attributes are exported: * `id` - The resource group ID. - ## Import Resource Groups can be imported using the `resource id`, e.g. diff --git a/website/docs/r/role_assignment.html.markdown b/website/docs/r/role_assignment.html.markdown index 1ec6748426ea..294a06f58935 100644 --- a/website/docs/r/role_assignment.html.markdown +++ b/website/docs/r/role_assignment.html.markdown @@ -85,20 +85,53 @@ resource "azurerm_role_assignment" "test" { } ``` +## Example Usage (Custom Role & Management Group) + +```hcl +data "azurerm_subscription" "primary" {} + +data "azurerm_client_config" "test" {} + +data "azurerm_management_group" "test" {} + +resource "azurerm_role_definition" "test" { + role_definition_id = "00000000-0000-0000-0000-000000000000" + name = "my-custom-role-definition" + scope = "${data.azurerm_subscription.primary.id}" + + permissions { + actions = ["Microsoft.Resources/subscriptions/resourceGroups/read"] + not_actions = [] + } + + assignable_scopes = [ + "${data.azurerm_subscription.primary.id}", + ] +} + +resource "azurerm_role_assignment" "test" { + name = "00000000-0000-0000-0000-000000000000" + scope = "${data.azurerm_management_group.primary.id}" + role_definition_id = "${azurerm_role_definition.test.id}" + principal_id = "${data.azurerm_client_config.test.client_id}" +} +``` + ## Argument Reference The following arguments are supported: * `name` - (Optional) A unique UUID/GUID for this Role Assignment - one will be generated if not specified. Changing this forces a new resource to be created. -* `scope` - (Required) The scope at which the Role Assignment applies too, such as `/subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333`, `/subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333/resourceGroups/myGroup`, or `/subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333/resourceGroups/myGroup/providers/Microsoft.Compute/virtualMachines/myVM`. Changing this forces a new resource to be created. +* `scope` - (Required) The scope at which the Role Assignment applies to, such as `/subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333`, `/subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333/resourceGroups/myGroup`, or `/subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333/resourceGroups/myGroup/providers/Microsoft.Compute/virtualMachines/myVM`, or `/providers/Microsoft.Management/managementGroups/myMG`. Changing this forces a new resource to be created. * `role_definition_id` - (Optional) The Scoped-ID of the Role Definition. Changing this forces a new resource to be created. Conflicts with `role_definition_name`. * `role_definition_name` - (Optional) The name of a built-in Role. Changing this forces a new resource to be created. Conflicts with `role_definition_id`. -* `principal_id` - (Required) The ID of the Principal (User or Application) to assign the Role Definition to. Changing this forces a new resource to be created. +* `principal_id` - (Required) The ID of the Principal (User, Group, Service Principal, or Application) to assign the Role Definition to. Changing this forces a new resource to be created. +~> **NOTE:** The Principal ID is also known as the Object ID (ie not the "Application ID" for applications). ## Attributes Reference diff --git a/website/docs/r/route.html.markdown b/website/docs/r/route.html.markdown index 66375f7a671b..ef77826df892 100644 --- a/website/docs/r/route.html.markdown +++ b/website/docs/r/route.html.markdown @@ -10,6 +10,10 @@ description: |- Manages a Route within a Route Table. +~> **NOTE on Route Tables and Routes:** Terraform currently +provides both a standalone [Route resource](route.html), and allows for Routes to be defined in-line within the [Route Table resource](route_table.html). +At this time you cannot use a Route Table with in-line Routes in conjunction with any Route resources. Doing so will cause a conflict of Route configurations and will overwrite Routes. + ## Example Usage ```hcl diff --git a/website/docs/r/route_table.html.markdown b/website/docs/r/route_table.html.markdown index 43625f3320a8..e794ad5d672b 100644 --- a/website/docs/r/route_table.html.markdown +++ b/website/docs/r/route_table.html.markdown @@ -47,13 +47,13 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `route` - (Optional) Can be specified multiple times to define multiple routes. Each `route` block supports fields documented below. +* `route` - (Optional) [List of objects](/docs/configuration/attr-as-blocks.html) representing routes. Each object accepts the arguments documented below. * `disable_bgp_route_propagation` - (Optional) Boolean flag which controls propagation of routes learned by BGP on that route table. True means disable. * `tags` - (Optional) A mapping of tags to assign to the resource. -The `route` block supports: +Elements of `route` support: * `name` - (Required) The name of the route. @@ -63,7 +63,6 @@ The `route` block supports: * `next_hop_in_ip_address` - (Optional) Contains the IP address packets should be forwarded to. Next hop values are only allowed in routes where the next hop type is `VirtualAppliance`. - ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/scheduler_job.html.markdown b/website/docs/r/scheduler_job.html.markdown index 058acd33b5bf..4f2b62b6b661 100644 --- a/website/docs/r/scheduler_job.html.markdown +++ b/website/docs/r/scheduler_job.html.markdown @@ -86,7 +86,7 @@ resource "azurerm_scheduler_job" "web-recurring-daily" { url = "https://this.url.fails" authentication_certificate { - pfx = "${base64encode(file("your_cert.pfx"))}" + pfx = "${filebase64("your_cert.pfx")}" password = "cert_password" } } diff --git a/website/docs/r/search_service.html.markdown b/website/docs/r/search_service.html.markdown index 6c0ee5dc9785..c56f9b94497a 100644 --- a/website/docs/r/search_service.html.markdown +++ b/website/docs/r/search_service.html.markdown @@ -3,7 +3,7 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_search_service" sidebar_current: "docs-azurerm-resource-search-service" description: |- - Manage a Search Service. + Manages a Search Service. --- # azurerm_search_service @@ -22,7 +22,7 @@ resource "azurerm_search_service" "test" { name = "acceptanceTestSearchService1" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" - sku = "Standard" + sku = "standard" tags = { environment = "staging" @@ -46,7 +46,7 @@ The following arguments are supported: * `partition_count` - (Optional) Default is 1. Valid values include 1, 2, 3, 4, 6, or 12. Valid only when `sku` is `standard`. Changing this forces a new resource to be created. -* `tags` - (Optional) A mapping of tags to assign to the resource. Changing this forces a new resource to be created. +* `tags` - (Optional) A mapping of tags to assign to the resource. ## Attributes Reference diff --git a/website/docs/r/security_center_contact.markdown b/website/docs/r/security_center_contact.markdown index 5de33d8da632..26b129967147 100644 --- a/website/docs/r/security_center_contact.markdown +++ b/website/docs/r/security_center_contact.markdown @@ -29,7 +29,7 @@ resource "azurerm_security_center_contact" "example" { The following arguments are supported: * `email` - (Required) The email of the Security Center Contact. -* `phone` - (Required) The phone number of the Security Center Contact. +* `phone` - (Optional) The phone number of the Security Center Contact. * `alert_notifications` - (Required) Whether to send security alerts notifications to the security contact. * `alerts_to_admins` - (Required) Whether to send security alerts notifications to subscription admins. diff --git a/website/docs/r/service_fabric_cluster.html.markdown b/website/docs/r/service_fabric_cluster.html.markdown index a60e63d94128..048369794c2b 100644 --- a/website/docs/r/service_fabric_cluster.html.markdown +++ b/website/docs/r/service_fabric_cluster.html.markdown @@ -3,12 +3,12 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_service_fabric_cluster" sidebar_current: "docs-azurerm-resource-service-fabric-cluster" description: |- - Manage a Service Fabric Cluster. + Manages a Service Fabric Cluster. --- # azurerm_service_fabric_cluster -Manage a Service Fabric Cluster. +Manages a Service Fabric Cluster. ## Example Usage @@ -65,9 +65,11 @@ The following arguments are supported: * `add_on_features` - (Optional) A List of one or more features which should be enabled, such as `DnsService`. -* `azure_active_directory` - (Optional) An `azure_active_directory` block as defined below. Changing this forces a new resource to be created. +* `azure_active_directory` - (Optional) An `azure_active_directory` block as defined below. -* `certificate` - (Optional) A `certificate` block as defined below. +* `certificate_common_names` - (Optional) A `certificate_common_names` block as defined below. Conflicts with `certificate`. + +* `certificate` - (Optional) A `certificate` block as defined below. Conflicts with `certificate_common_names`. * `reverse_proxy_certificate` - (Optional) A `reverse_proxy_certificate` block as defined below. @@ -85,11 +87,29 @@ The following arguments are supported: A `azure_active_directory` block supports the following: -* `tenant_id` - (Required) The Azure Active Directory Tenant ID. Changing this forces a new resource to be created. +* `tenant_id` - (Required) The Azure Active Directory Tenant ID. + +* `cluster_application_id` - (Required) The Azure Active Directory Cluster Application ID. + +* `client_application_id` - (Required) The Azure Active Directory Client ID which should be used for the Client Application. + +--- + +A `certificate_common_names` block supports the following: + +* `common_names` - (Required) A `common_names` block as defined below. + +* `x509_store_name` - (Required) The X509 Store where the Certificate Exists, such as `My`. + +--- + +A `common_names` block supports the following: + +* `certificate_common_name` - (Required) The common or subject name of the certificate. -* `cluster_application_id` - (Required) The Azure Active Directory Cluster Application ID. Changing this forces a new resource to be created. +* `certificate_issuer_thumbprint` - (Optional) The Issuer Thumbprint of the Certificate. -* `client_application_id` - (Required) The Azure Active Directory Client ID which should be used for the Client Application. Changing this forces a new resource to be created. +-> **NOTE:** Certificate Issuer Thumbprint may become required in the future, `https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-create-cluster-using-cert-cn#download-and-update-a-sample-template`. --- diff --git a/website/docs/r/servicebus_namespace.html.markdown b/website/docs/r/servicebus_namespace.html.markdown index 47dfe3b90aec..bc4d9d726a55 100644 --- a/website/docs/r/servicebus_namespace.html.markdown +++ b/website/docs/r/servicebus_namespace.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_servicebus_namespace -Manage a ServiceBus Namespace. +Manages a ServiceBus Namespace. ## Example Usage diff --git a/website/docs/r/servicebus_queue.html.markdown b/website/docs/r/servicebus_queue.html.markdown index b790e1df3e9c..80561b55165a 100644 --- a/website/docs/r/servicebus_queue.html.markdown +++ b/website/docs/r/servicebus_queue.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_servicebus_queue -Manage and manage a ServiceBus Queue. +Manages a ServiceBus Queue. ## Example Usage diff --git a/website/docs/r/servicebus_subscription.html.markdown b/website/docs/r/servicebus_subscription.html.markdown index 671d5ab7d019..b77bb189df1e 100644 --- a/website/docs/r/servicebus_subscription.html.markdown +++ b/website/docs/r/servicebus_subscription.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_servicebus_subscription -Manage a ServiceBus Subscription. +Manages a ServiceBus Subscription. ## Example Usage diff --git a/website/docs/r/servicebus_subscription_rule.html.markdown b/website/docs/r/servicebus_subscription_rule.html.markdown index 93d43395c681..4690a4c480cd 100644 --- a/website/docs/r/servicebus_subscription_rule.html.markdown +++ b/website/docs/r/servicebus_subscription_rule.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_servicebus_subscription_rule -Manage a ServiceBus Subscription Rule. +Manages a ServiceBus Subscription Rule. ## Example Usage (SQL Filter) @@ -160,5 +160,5 @@ The following attributes are exported: Service Bus Subscription Rule can be imported using the `resource id`, e.g. ```shell -terraform import azurerm_servicebus_subscription.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/microsoft.servicebus/namespaces/sbns1/topics/sntopic1/subscriptions/sbsub1/rules/sbrule1 +terraform import azurerm_servicebus_subscription_rule.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/microsoft.servicebus/namespaces/sbns1/topics/sntopic1/subscriptions/sbsub1/rules/sbrule1 ``` diff --git a/website/docs/r/servicebus_topic.html.markdown b/website/docs/r/servicebus_topic.html.markdown index d474ee4f3f08..c6046a11347e 100644 --- a/website/docs/r/servicebus_topic.html.markdown +++ b/website/docs/r/servicebus_topic.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_servicebus_topic -Manage a ServiceBus Topic. +Manages a ServiceBus Topic. **Note** Topics can only be created in Namespaces with an SKU of `standard` or higher. diff --git a/website/docs/r/shared_image.html.markdown b/website/docs/r/shared_image.html.markdown index 98e02eaa3f3d..f652981bb11a 100644 --- a/website/docs/r/shared_image.html.markdown +++ b/website/docs/r/shared_image.html.markdown @@ -60,7 +60,7 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the Shared Image Gallery exists. Changing this forces a new resource to be created. -* `identity` - (Required) An `identity` block as defined below. +* `identifier` - (Required) An `identifier` block as defined below. * `os_type` - (Required) The type of Operating System present in this Shared Image. Possible values are `Linux` and `Windows`. @@ -78,7 +78,7 @@ The following arguments are supported: --- -A `identity` block supports the following: +A `identifier` block supports the following: * `offer` - (Required) The Offer Name for this Shared Image. diff --git a/website/docs/r/shared_image_version.html.markdown b/website/docs/r/shared_image_version.html.markdown index b1607bee8eb6..5bdb23f01a1f 100644 --- a/website/docs/r/shared_image_version.html.markdown +++ b/website/docs/r/shared_image_version.html.markdown @@ -85,5 +85,5 @@ The following attributes are exported: Shared Image Versions can be imported using the `resource id`, e.g. ```shell -terraform import azurerm_shared_image_version.version1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Compute/galleries/gallery1/images/image1/versions/1.2.3 +terraform import azurerm_shared_image_version.version /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Compute/galleries/gallery1/images/image1/versions/1.2.3 ``` diff --git a/website/docs/r/sql_database.html.markdown b/website/docs/r/sql_database.html.markdown index 032d99c0f0d5..116c1c566677 100644 --- a/website/docs/r/sql_database.html.markdown +++ b/website/docs/r/sql_database.html.markdown @@ -50,7 +50,7 @@ The following arguments are supported: * `server_name` - (Required) The name of the SQL Server on which to create the database. -* `create_mode` - (Optional) Specifies the type of database to create. Defaults to `Default`. See below for the accepted values/ +* `create_mode` - (Optional) Specifies how to create the database. Must be either `Default` to create a new database or `PointInTimeRestore` to restore from a snapshot. Defaults to `Default`. * `import` - (Optional) A Database Import block as documented below. `create_mode` must be set to `Default`. @@ -58,7 +58,7 @@ The following arguments are supported: * `restore_point_in_time` - (Optional) The point in time for the restore. Only applies if `create_mode` is `PointInTimeRestore` e.g. 2013-11-08T22:00:40Z -* `edition` - (Optional) The edition of the database to be created. Applies only if `create_mode` is `Default`. Valid values are: `Basic`, `Standard`, `Premium`, or `DataWarehouse`. Please see [Azure SQL Database Service Tiers](https://azure.microsoft.com/en-gb/documentation/articles/sql-database-service-tiers/). +* `edition` - (Optional) The edition of the database to be created. Applies only if `create_mode` is `Default`. Valid values are: `Basic`, `Standard`, `Premium`, `DataWarehouse`, `Business`, `BusinessCritical`, `Free`, `GeneralPurpose`, `Hyperscale`, `Premium`, `PremiumRS`, `Standard`, `Stretch`, `System`, `System2`, or `Web`. Please see [Azure SQL Database Service Tiers](https://azure.microsoft.com/en-gb/documentation/articles/sql-database-service-tiers/). * `collation` - (Optional) The name of the collation. Applies only if `create_mode` is `Default`. Azure default is `SQL_LATIN1_GENERAL_CP1_CI_AS`. Changing this forces a new resource to be created. @@ -75,6 +75,8 @@ The following arguments are supported: * `threat_detection_policy` - (Optional) Threat detection policy configuration. The `threat_detection_policy` block supports fields documented below. +* `read_scale` - (Optional) Read-only connections will be redirected to a high-available replica. Please see [Use read-only replicas to load-balance read-only query workloads](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-read-scale-out). + * `tags` - (Optional) A mapping of tags to assign to the resource. `import` supports the following: diff --git a/website/docs/r/sql_failover_group.html.markdown b/website/docs/r/sql_failover_group.html.markdown new file mode 100644 index 000000000000..5e89672ee33a --- /dev/null +++ b/website/docs/r/sql_failover_group.html.markdown @@ -0,0 +1,115 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_sql_failover_group" +sidebar_current: "docs-azurerm-resource-database-sql-fail_over_group" +description: |- + Manages a SQL Failover Group. +--- + +# azurerm_sql_failover_group + +Create a failover group of databases on a collection of Azure SQL servers. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example" + location = "uksouth" +} + +resource "azurerm_sql_server" "primary" { + name = "sql-primary" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + version = "12.0" + administrator_login = "sqladmin" + administrator_login_password = "pa$$$$w0rd" + +} + +resource "azurerm_sql_server" "secondary" { + name = "sql-secondary" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "northeurope" + version = "12.0" + administrator_login = "sqladmin" + administrator_login_password = "pa$$$$w0rd" + +} + +resource azurerm_sql_database db1 { + name = "db1" + resource_group_name = "${azurerm_sql_server.primary.resource_group_name}" + location = "${azurerm_sql_server.primary.location}" + server_name = "${azurerm_sql_server.primary.name}" +} + +resource "azurerm_sql_failover_group" "example" { + name = "example-failover-group" + resource_group_name = "${azurerm_sql_server.primary.resource_group_name}" + server_name = "${azurerm_sql_server.primary.name}" + databases = ["${azurerm_sql_database.db1.id}"] + partner_servers { + id = "${azurerm_sql_server.secondary.id}" + } + + read_write_endpoint_failover_policy = { + mode = "Automatic" + grace_minutes = 60 + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the failover group. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group containing the SQL server + +* `server_name` - (Required) The name of the primary SQL server. Changing this forces a new resource to be created. + +* `databases` - A list of database ids to add to the failover group + +-> **NOTE:** The failover group will create a secondary database for each database listed in `databases`. If the secondary databases need to be managed through Terraform, they should be defined as resources and a dependency added to the failover group to ensure the secondary databases are created first. + +* `partner_servers` - (Required) A list of secondary servers as documented below + +* `read_write_endpoint_failover_policy` - (Required) A read/write policy as documented below + +* `readonly_endpoint_failover_policy` - (Optional) a read-only policy as documented below + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +`partner_servers` supports the following: + +* `id` - (Required) the SQL server ID + +`read_write_endpoint_failover_policy` supports the following: + +* `mode` - (Required) the failover mode. Possible values are `Manual`, `Automatic` + +* `grace_minutes` - Applies only if `mode` is `Automatic`. The grace period in minutes before failover with data loss is attempted + +`readonly_endpoint_failover_policy` supports the following: + +* `mode` - Failover policy for the read-only endpoint. Possible values are `Enabled`, and `Disabled` + +## Attribute Reference + +The following attributes are exported: + +* `id` - The failover group ID +* `location` - the location of a SQL server in `partner_servers` +* `role` - the current role of a SQL server in `partner_servers` +* `role` - the current role of the SQL server named in `server_name` + +## Import + +SQL Failover Groups can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_sql_database.database1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.Sql/servers/myserver/failovergroups/group1 +``` \ No newline at end of file diff --git a/website/docs/r/storage_account.html.markdown b/website/docs/r/storage_account.html.markdown index 4c2f05f15cb3..7f4dd939e668 100644 --- a/website/docs/r/storage_account.html.markdown +++ b/website/docs/r/storage_account.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_storage_account -Manage an Azure Storage Account. +Manages an Azure Storage Account. ## Example Usage @@ -63,7 +63,8 @@ resource "azurerm_storage_account" "testsa" { account_replication_type = "LRS" network_rules { - ip_rules = ["127.0.0.1"] + default_action = "Deny" + ip_rules = ["100.0.0.1"] virtual_network_subnet_ids = ["${azurerm_subnet.test.id}"] } @@ -77,25 +78,19 @@ resource "azurerm_storage_account" "testsa" { The following arguments are supported: -* `name` - (Required) Specifies the name of the storage account. Changing this forces a - new resource to be created. This must be unique across the entire Azure service, - not just within the resource group. +* `name` - (Required) Specifies the name of the storage account. Changing this forces a new resource to be created. This must be unique across the entire Azure service, not just within the resource group. -* `resource_group_name` - (Required) The name of the resource group in which to - create the storage account. Changing this forces a new resource to be created. +* `resource_group_name` - (Required) The name of the resource group in which to create the storage account. Changing this forces a new resource to be created. -* `location` - (Required) Specifies the supported Azure location where the - resource exists. Changing this forces a new resource to be created. +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `account_kind` - (Optional) Defines the Kind of account. Valid options are `Storage`, - `StorageV2` and `BlobStorage`. Changing this forces a new resource to be created. - Defaults to `Storage`. +* `account_kind` - (Optional) Defines the Kind of account. Valid options are `BlobStorage`, `BlockBlobStorage`, `FileStorage`, `Storage` and `StorageV2`. Changing this forces a new resource to be created. Defaults to `Storage`. -* `account_tier` - (Required) Defines the Tier to use for this storage account. Valid options are `Standard` and `Premium`. Changing this forces a new resource to be created +* `account_tier` - (Required) Defines the Tier to use for this storage account. Valid options are `Standard` and `Premium`. For `FileStorage` accounts only `Premium` is valid. Changing this forces a new resource to be created. * `account_replication_type` - (Required) Defines the type of replication to use for this storage account. Valid options are `LRS`, `GRS`, `RAGRS` and `ZRS`. -* `access_tier` - (Optional) Defines the access tier for `BlobStorage` and `StorageV2` accounts. Valid options are `Hot` and `Cool`, defaults to `Hot`. +* `access_tier` - (Optional) Defines the access tier for `BlobStorage`, `FileStorage` and `StorageV2` accounts. Valid options are `Hot` and `Cool`, defaults to `Hot`. * `enable_blob_encryption` - (Optional) Boolean flag which controls if Encryption Services are enabled for Blob storage, see [here](https://azure.microsoft.com/en-us/documentation/articles/storage-service-encryption/) for more information. Defaults to `true`. @@ -110,37 +105,113 @@ The following arguments are supported: * `custom_domain` - (Optional) A `custom_domain` block as documented below. +* `enable_advanced_threat_protection` (Optional) Boolean flag which controls if advanced threat protection is enabled, see [here](https://docs.microsoft.com/en-us/azure/storage/common/storage-advanced-threat-protection) for more information. Defaults to `false`. + +~> **Note:** `enable_advanced_threat_protection` is not supported in all regions. + +* `identity` - (Optional) A `identity` block as defined below. + +* `queue_properties` - (Optional) A `queue_properties` block as defined below. + +~> **NOTE:** `queue_properties` cannot be set when the `access_tier` is set to `BlobStorage` + * `network_rules` - (Optional) A `network_rules` block as documented below. * `tags` - (Optional) A mapping of tags to assign to the resource. -* `identity` - (Optional) A Managed Service Identity block as defined below. +--- + +A `cors_rule` block supports the following: + +* `allowed_headers` - (Required) A list of headers that are allowed to be a part of the cross-origin request. + +* `allowed_methods` - (Required) A list of http headers that are allowed to be executed by the origin. Valid options are +`DELETE`, `GET`, `HEAD`, `MERGE`, `POST`, `OPTIONS` or `PUT`. + +* `allowed_origins` - (Required) A list of origin domains that will be allowed by CORS. + +* `exposed_headers` - (Required) A list of response headers that are exposed to CORS clients. + +* `max_age_in_seconds` - (Required) The number of seconds the client should cache a preflight response. --- -* `custom_domain` supports the following: +A `custom_domain` block supports the following: * `name` - (Optional) The Custom Domain Name to use for the Storage Account, which will be validated by Azure. * `use_subdomain` - (Optional) Should the Custom Domain Name be validated by using indirect CNAME validation? +--- + +A `hour_metrics` block supports the following: + +* `enabled` - (Required) Indicates whether hour metrics are enabled for the Queue service. Changing this forces a new resource. + +* `version` - (Required) The version of storage analytics to configure. Changing this forces a new resource. + +* `include_apis` - (Optional) Indicates whether metrics should generate summary statistics for called API operations. + +* `retention_policy_days` - (Optional) Specifies the number of days that logs will be retained. Changing this forces a new resource. + +--- + +A `identity` block supports the following: + +* `type` - (Required) Specifies the identity type of the Storage Account. At this time the only allowed value is `SystemAssigned`. + +~> The assigned `principal_id` and `tenant_id` can be retrieved after the identity `type` has been set to `SystemAssigned` and Storage Account has been created. More details are available below. + --- -* `network_rules` supports the following: +A `logging` block supports the following: + +* `delete` - (Required) Indicates whether all delete requests should be logged. Changing this forces a new resource. + +* `read` - (Required) Indicates whether all read requests should be logged. Changing this forces a new resource. + +* `version` - (Required) The version of storage analytics to configure. Changing this forces a new resource. +* `write` - (Required) Indicates whether all write requests should be logged. Changing this forces a new resource. + +* `retention_policy_days` - (Optional) Specifies the number of days that logs will be retained. Changing this forces a new resource. + +--- + +A `minute_metrics` block supports the following: + +* `enabled` - (Required) Indicates whether minute metrics are enabled for the Queue service. Changing this forces a new resource. + +* `version` - (Required) The version of storage analytics to configure. Changing this forces a new resource. + +* `include_apis` - (Optional) Indicates whether metrics should generate summary statistics for called API operations. + +* `retention_policy_days` - (Optional) Specifies the number of days that logs will be retained. Changing this forces a new resource. + +--- + +A `network_rules` block supports the following: + +* `default_action` - (Required) Specifies the default action of allow or deny when no other rules match. Valid options are `Deny` or `Allow`. * `bypass` - (Optional) Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Valid options are any combination of `Logging`, `Metrics`, `AzureServices`, or `None`. -* `ip_rules` - (Optional) List of IP or IP ranges in CIDR Format. Only IPV4 addresses are allowed. +* `ip_rules` - (Optional) List of public IP or IP ranges in CIDR Format. Only IPV4 addresses are allowed. Private IP address ranges (as defined in [RFC 1918](https://tools.ietf.org/html/rfc1918#section-3)) are not allowed. * `virtual_network_subnet_ids` - (Optional) A list of resource ids for subnets. +~> **Note:** If specifying `network_rules`, one of either `ip_rules` or `virtual_network_subnet_ids` must be specified and `default_action` must be set to `Deny`. + ~> **Note:** [More information on Validation is available here](https://docs.microsoft.com/en-gb/azure/storage/blobs/storage-custom-domain-name) --- -`identity` supports the following: +A `queue_properties` block supports the following: -* `type` - (Required) Specifies the identity type of the Storage Account. At this time the only allowed value is `SystemAssigned`. +* `cors_rule` - (Optional) A `cors_rule` block as defined below. -~> The assigned `principal_id` and `tenant_id` can be retrieved after the identity `type` has been set to `SystemAssigned` and Storage Account has been created. More details are available below. +* `logging` - (Optional) A `logging` block as defined below. + +* `minute_metrics` - (Optional) A `minute_metrics` block as defined below. + +* `hour_metrics` - (Optional) A `hour_metrics` block as defined below. ## Attributes Reference @@ -180,6 +251,26 @@ The following attributes are exported in addition to the arguments listed above: * `primary_file_host` - The hostname with port if applicable for file storage in the primary location. +* `secondary_file_endpoint` - The endpoint URL for file storage in the secondary location. + +* `secondary_file_host` - The hostname with port if applicable for file storage in the secondary location. + +* `primary_dfs_endpoint` - The endpoint URL for DFS storage in the primary location. + +* `primary_dfs_host` - The hostname with port if applicable for DFS storage in the primary location. + +* `secondary_dfs_endpoint` - The endpoint URL for DFS storage in the secondary location. + +* `secondary_dfs_host` - The hostname with port if applicable for DFS storage in the secondary location. + +* `primary_web_endpoint` - The endpoint URL for web storage in the primary location. + +* `primary_web_host` - The hostname with port if applicable for web storage in the primary location. + +* `secondary_web_endpoint` - The endpoint URL for web storage in the secondary location. + +* `secondary_web_host` - The hostname with port if applicable for web storage in the secondary location. + * `primary_access_key` - The primary access key for the storage account. * `secondary_access_key` - The secondary access key for the storage account. diff --git a/website/docs/r/storage_blob.html.markdown b/website/docs/r/storage_blob.html.markdown index 2a37a1ab0d45..187d77d7fadd 100644 --- a/website/docs/r/storage_blob.html.markdown +++ b/website/docs/r/storage_blob.html.markdown @@ -3,12 +3,12 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_storage_blob" sidebar_current: "docs-azurerm-resource-storage-blob" description: |- - Manages a Azure Storage Blob. + Manages a Blob within a Storage Container. --- # azurerm_storage_blob -Manage an Azure Storage Blob. +Manages a Blob within a Storage Container. ## Example Usage @@ -21,7 +21,7 @@ resource "azurerm_resource_group" "test" { resource "azurerm_storage_account" "test" { name = "acctestaccs" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "${azurerm_resource_group.test.location}" account_tier = "Standard" account_replication_type = "LRS" } @@ -51,9 +51,6 @@ The following arguments are supported: * `name` - (Required) The name of the storage blob. Must be unique within the storage container the blob is located. -* `resource_group_name` - (Required) The name of the resource group in which to - create the storage container. Changing this forces a new resource to be created. - * `storage_account_name` - (Required) Specifies the storage account in which to create the storage container. Changing this forces a new resource to be created. @@ -73,7 +70,11 @@ The following arguments are supported: * `parallelism` - (Optional) The number of workers per CPU core to run for concurrent uploads. Defaults to `8`. -* `attempts` - (Optional) The number of attempts to make per page or block when uploading. Defaults to `1`. +* `metadata` - (Optional) A map of custom blob metadata. + +* `attempts` - (Optional / **Deprecated**) The number of attempts to make per page or block when uploading. Defaults to `1`. + +* `resource_group_name` - (Optional / **Deprecated**) The name of the resource group in which to create the storage container. ## Attributes Reference diff --git a/website/docs/r/storage_container.html.markdown b/website/docs/r/storage_container.html.markdown index ef4eb8a95faf..65b4d2d8d7a6 100644 --- a/website/docs/r/storage_container.html.markdown +++ b/website/docs/r/storage_container.html.markdown @@ -3,25 +3,25 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_storage_container" sidebar_current: "docs-azurerm-resource-storage-container" description: |- - Manages a Azure Storage Container. + Manages a Container within an Azure Storage Account. --- # azurerm_storage_container -Manage an Azure Storage Container. +Manages a Container within an Azure Storage Account. ## Example Usage ```hcl resource "azurerm_resource_group" "test" { - name = "acctestRG" - location = "westus" + name = "example-resources" + location = "West Europe" } resource "azurerm_storage_account" "test" { - name = "accteststorageaccount" + name = "examplestoraccount" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "${azurerm_resource_group.test.location}" account_tier = "Standard" account_replication_type = "LRS" @@ -42,22 +42,27 @@ resource "azurerm_storage_container" "test" { The following arguments are supported: -* `name` - (Required) The name of the storage container. Must be unique within the storage service the container is located. +* `name` - (Required) The name of the Container which should be created within the Storage Account. -* `resource_group_name` - (Required) The name of the resource group in which to - create the storage container. Changing this forces a new resource to be created. +* `storage_account_name` - (Required) The name of the Storage Account where the Container should be created. -* `storage_account_name` - (Required) Specifies the storage account in which to create the storage container. - Changing this forces a new resource to be created. +* `container_access_type` - (Optional) The Access Level configured for this Container. Possible values are `blob`, `container` or `private`. Defaults to `private`. -* `container_access_type` - (Optional) The 'interface' for access the container provides. Can be either `blob`, `container` or `private`. Defaults to `private`. +* `metadata` - (Optional) A mapping of MetaData for this Container. + +* `resource_group_name` - (Optional / **Deprecated**) The name of the resource group in which to create the storage container. This field is no longer used and will be removed in 2.0. ## Attributes Reference The following attributes are exported in addition to the arguments listed above: * `id` - The ID of the Storage Container. -* `properties` - Key-value definition of additional properties associated to the storage container + +* `has_immutability_policy` - Is there an Immutability Policy configured on this Storage Container? + +* `has_legal_hold` - Is there a Legal Hold configured on this Storage Container? + +* `properties` - (**Deprecated**) Key-value definition of additional properties associated to the Storage Container ## Import diff --git a/website/docs/r/storage_queue.html.markdown b/website/docs/r/storage_queue.html.markdown index 022b8a255eff..e7da7ffebe98 100644 --- a/website/docs/r/storage_queue.html.markdown +++ b/website/docs/r/storage_queue.html.markdown @@ -3,19 +3,19 @@ layout: "azurerm" page_title: "Azure Resource Manager: azurerm_storage_queue" sidebar_current: "docs-azurerm-resource-storage-queue" description: |- - Manages a Azure Storage Queue. + Manages a Queue within an Azure Storage Account. --- # azurerm_storage_queue -Manage an Azure Storage Queue. +Manages a Queue within an Azure Storage Account. ## Example Usage ```hcl resource "azurerm_resource_group" "test" { name = "example-resources" - location = "westus" + location = "West Europe" } resource "azurerm_storage_account" "test" { @@ -37,13 +37,13 @@ resource "azurerm_storage_queue" "test" { The following arguments are supported: -* `name` - (Required) The name of the storage queue. Must be unique within the storage account the queue is located. +* `name` - (Required) The name of the Queue which should be created within the Storage Account. Must be unique within the storage account the queue is located. -* `resource_group_name` - (Required) The name of the resource group in which to - create the storage queue. Changing this forces a new resource to be created. +* `storage_account_name` - (Required) Specifies the Storage Account in which the Storage Queue should exist. Changing this forces a new resource to be created. -* `storage_account_name` - (Required) Specifies the storage account in which to create the storage queue. - Changing this forces a new resource to be created. +* `resource_group_name` - (Optional / **Deprecated**) The name of the resource group in which to create the storage queue. + +* `metadata` - (Optional) A mapping of MetaData which should be assigned to this Storage Queue. ## Attributes Reference diff --git a/website/docs/r/storage_share.html.markdown b/website/docs/r/storage_share.html.markdown index 86e56e1c70c1..c105491ab63a 100644 --- a/website/docs/r/storage_share.html.markdown +++ b/website/docs/r/storage_share.html.markdown @@ -1,38 +1,35 @@ --- layout: "azurerm" page_title: "Azure Resource Manager: azurerm_storage_share" -sidebar_current: "docs-azurerm-resource-storage-share" +sidebar_current: "docs-azurerm-resource-storage-share-x" description: |- - Manages an Azure Storage Share. + Manages a File Share within Azure Storage. --- # azurerm_storage_share -Manage an Azure Storage File Share. +Manages a File Share within Azure Storage. ## Example Usage ```hcl resource "azurerm_resource_group" "test" { name = "azuretest" - location = "westus" + location = "West Europe" } resource "azurerm_storage_account" "test" { name = "azureteststorage" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "${azurerm_resource_group.test.location}" account_tier = "Standard" account_replication_type = "LRS" } resource "azurerm_storage_share" "testshare" { - name = "sharename" - - resource_group_name = "${azurerm_resource_group.test.name}" + name = "sharename" storage_account_name = "${azurerm_storage_account.test.name}" - - quota = 50 + quota = 50 } ``` @@ -42,28 +39,47 @@ The following arguments are supported: * `name` - (Required) The name of the share. Must be unique within the storage account where the share is located. -* `resource_group_name` - (Required) The name of the resource group in which to - create the share. Changing this forces a new resource to be created. - * `storage_account_name` - (Required) Specifies the storage account in which to create the share. Changing this forces a new resource to be created. -* `quota` - (Optional) The maximum size of the share, in gigabytes. Must be greater than 0, and less than or equal to 5 TB (5120 GB). Default is 5120. +* `acl` - (Optional) One or more `acl` blocks as defined below. + +* `quota` - (Optional) The maximum size of the share, in gigabytes. Must be greater than 0, and less than or equal to 5 TB (5120 GB) for Standard storage accounts or 100 TB (102400 GB) for Premium storage accounts. Default is 5120. + +* `metadata` - (Optional) A mapping of MetaData for this File Share. + +* `resource_group_name` - (Optional / **Deprecated**) The name of the resource group in which to + create the share. Changing this forces a new resource to be created. + +--- + +A `acl` block supports the following: + +* `id` - (Required) The ID which should be used for this Shared Identifier. + +* `access_policy` - (Required) An `access_policy` block as defined below. + +--- +A `access_policy` block supports the following: + +* `expiry` - (Required) The ISO8061 UTC time at which this Access Policy should be valid until. + +* `permissions` - (Required) The permissions which should associated with this Shared Identifier. + +* `start` - (Required) The ISO8061 UTC time at which this Access Policy should be valid from. ## Attributes Reference The following attributes are exported in addition to the arguments listed above: -* `id` - The storage share Resource ID. -* `url` - The URL of the share +* `id` - The ID of the File Share. +* `url` - The URL of the File Share ## Import Storage Shares can be imported using the `resource id`, e.g. ```shell -terraform import azurerm_storage_share.testShare storageShareName/resourceGroupName/storageAccoutName +terraform import azurerm_storage_share.testShare https://account1.file.core.windows.net/share1 ``` - --> **NOTE:** This identifier is unique to Terraform diff --git a/website/docs/r/storage_share_directory.html.markdown b/website/docs/r/storage_share_directory.html.markdown new file mode 100644 index 000000000000..37b68fb54fe8 --- /dev/null +++ b/website/docs/r/storage_share_directory.html.markdown @@ -0,0 +1,66 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_storage_share_directory" +sidebar_current: "docs-azurerm-resource-storage-share-directory" +description: |- + Manages a Directory within an Azure Storage File Share. +--- + +# azurerm_storage_share_directory + +Manages a Directory within an Azure Storage File Share. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "azuretest" + location = "West Europe" +} + +resource "azurerm_storage_account" "test" { + name = "azureteststorage" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_share" "test" { + name = "sharename" + storage_account_name = "${azurerm_storage_account.test.name}" + quota = 50 +} + +resource "azurerm_storage_share_directory" "test" { + name = "example" + share_name = "${azurerm_storage_share.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name (or path) of the Directory that should be created within this File Share. Changing this forces a new resource to be created. + +* `share_name` - (Required) The name of the File Share where this Directory should be created. Changing this forces a new resource to be created. + +* `storage_account_name` - (Required) The name of the Storage Account within which the File Share is located. Changing this forces a new resource to be created. + +* `metadata` - (Optional) A mapping of metadata to assign to this Directory. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Directory within the File Share. + +## Import + +Directories within an Azure Storage File Share can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_storage_share_directory.test https://tomdevsa20.file.core.windows.net/share1/directory1 +``` diff --git a/website/docs/r/storage_table.html.markdown b/website/docs/r/storage_table.html.markdown index 506650f0cfc1..5df4b9ad55e9 100644 --- a/website/docs/r/storage_table.html.markdown +++ b/website/docs/r/storage_table.html.markdown @@ -1,27 +1,27 @@ --- layout: "azurerm" page_title: "Azure Resource Manager: azurerm_storage_table" -sidebar_current: "docs-azurerm-resource-storage-table" +sidebar_current: "docs-azurerm-resource-storage-table-x" description: |- - Manages a Azure Storage Table. + Manages a Table within an Azure Storage Account. --- # azurerm_storage_table -Manage an Azure Storage Table. +Manages a Table within an Azure Storage Account. ## Example Usage ```hcl resource "azurerm_resource_group" "test" { name = "azuretest" - location = "westus" + location = "West Europe" } resource "azurerm_storage_account" "test" { name = "azureteststorage1" resource_group_name = "${azurerm_resource_group.test.name}" - location = "westus" + location = "${azurerm_resource_group.test.location}" account_tier = "Standard" account_replication_type = "LRS" } @@ -39,21 +39,41 @@ The following arguments are supported: * `name` - (Required) The name of the storage table. Must be unique within the storage account the table is located. -* `resource_group_name` - (Required) The name of the resource group in which to - create the storage table. Changing this forces a new resource to be created. - * `storage_account_name` - (Required) Specifies the storage account in which to create the storage table. Changing this forces a new resource to be created. +* `resource_group_name` - (Optional / **Deprecated**) The name of the resource group in which to create the storage table. + +* `acl` - (Optional) One or more `acl` blocks as defined below. + +--- + +A `acl` block supports the following: + +* `id` - (Required) The ID which should be used for this Shared Identifier. + +* `access_policy` - (Required) An `access_policy` block as defined below. + +--- + +A `access_policy` block supports the following: + +* `expiry` - (Required) The ISO8061 UTC time at which this Access Policy should be valid until. + +* `permissions` - (Required) The permissions which should associated with this Shared Identifier. + +* `start` - (Required) The ISO8061 UTC time at which this Access Policy should be valid from. + + ## Attributes Reference The following attributes are exported in addition to the arguments listed above: -* `id` - The ID of the Storage Table. +* `id` - The ID of the Table within the Storage Account. ## Import -Storage Table's can be imported using the `resource id`, e.g. +Table's within a Storage Account can be imported using the `resource id`, e.g. ```shell terraform import azurerm_storage_table.table1 https://example.table.core.windows.net/table1 diff --git a/website/docs/r/storage_table_entity.html.markdown b/website/docs/r/storage_table_entity.html.markdown new file mode 100644 index 000000000000..88ee5c39c38b --- /dev/null +++ b/website/docs/r/storage_table_entity.html.markdown @@ -0,0 +1,79 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_storage_table_entity" +sidebar_current: "docs-azurerm-resource-storage-table-entity" +description: |- + Manages an Entity within a Table in an Azure Storage Account. +--- + +# azurerm_storage_table_entity + +Manages an Entity within a Table in an Azure Storage Account. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "azureexample" + location = "westus" +} + +resource "azurerm_storage_account" "example" { + name = "azureexamplestorage1" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_table" "example" { + name = "myexampletable" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" +} + +resource "azurerm_storage_table_entity" "example" { + storage_account_name = "${azurerm_storage_account.example.name}" + table_name = "${azurerm_storage_table.example.name}" + + partition_key = "examplepartition" + row_key = "exmamplerow" + + entity = { + example = "sample" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `storage_account_name` - (Required) Specifies the storage account in which to create the storage table entity. + Changing this forces a new resource to be created. + +* `table_name` - (Required) The name of the storage table in which to create the storage table entity. +Changing this forces a new resource to be created. + +* `partition_key` - (Required) The key for the partition where the entity will be inserted/merged. Changing this forces a new resource. + +* `row_key` - (Required) The key for the row where the entity will be inserted/merged. Changing this forces a new resource. + +* `entity` - (Required) A map of key/value pairs that describe the entity to be inserted/merged in to the storage table. + + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Entity within the Table in the Storage Account. + +## Import + +Entities within a Table in an Azure Storage Account can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_storage_table_entity.entity1 https://example.table.core.windows.net/table1(PartitionKey='samplepartition',RowKey='samplerow') +``` + + diff --git a/website/docs/r/stream_analytics_function_javascript_udf.html.markdown b/website/docs/r/stream_analytics_function_javascript_udf.html.markdown new file mode 100644 index 000000000000..c5419a582a83 --- /dev/null +++ b/website/docs/r/stream_analytics_function_javascript_udf.html.markdown @@ -0,0 +1,86 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_function_javascript_udf" +sidebar_current: "docs-azurerm-resource-stream-analytics-function-javascript-udf" +description: |- + Manages a JavaScript UDF Function within Stream Analytics Streaming Job. +--- + +# azurerm_stream_analytics_function_javascript_udf + +Manages a JavaScript UDF Function within Stream Analytics Streaming Job. + +## Example Usage + +```hcl +data "azurerm_resource_group" "example" { + name = "example-resources" +} + +data "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_stream_analytics_function_javascript_udf" "test" { + name = "example-javascript-function" + stream_analytics_job_name = "${data.azurerm_stream_analytics_job.example.name}" + resource_group_name = "${data.azurerm_stream_analytics_job.example.resource_group_name}" + + script = <<SCRIPT +function getRandomNumber(in) { + return in; +} +SCRIPT + + input { + type = "bigint" + } + + output { + type = "bigint" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the JavaScript UDF Function. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job exists. Changing this forces a new resource to be created. + +* `stream_analytics_job_name` - (Required) The name of the Stream Analytics Job where this Function should be created. Changing this forces a new resource to be created. + +* `input` - (Required) One or more `input` blocks as defined below. + +* `output` - (Required) An `output` blocks as defined below. + +* `script` - (Required) The JavaScript of this UDF Function. + +--- + +A `input` block supports the following: + +* `type` - The Data Type for the Input Argument of this JavaScript Function. Possible values include `array`, `any`, `bigint`, `datetime`, `float`, `nvarchar(max)` and `record`. + +--- + +A `output` block supports the following: + +* `type` - The Data Type output from this JavaScript Function. Possible values include `array`, `any`, `bigint`, `datetime`, `float`, `nvarchar(max)` and `record`. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics JavaScript UDF Function. + +## Import + +Stream Analytics JavaScript UDF Functions can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_output_blob.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/outputs/output1 +``` diff --git a/website/docs/r/stream_analytics_job.html.markdown b/website/docs/r/stream_analytics_job.html.markdown new file mode 100644 index 000000000000..38d5021f4f72 --- /dev/null +++ b/website/docs/r/stream_analytics_job.html.markdown @@ -0,0 +1,89 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_job" +sidebar_current: "docs-azurerm-resource-stream-analytics-job" +description: |- + Manages a Stream Analytics Job. +--- + +# azurerm_stream_analytics_job + +Manages a Stream Analytics Job. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + compatibility_level = "1.1" + data_locale = "en-GB" + events_late_arrival_max_delay_in_seconds = 60 + events_out_of_order_max_delay_in_seconds = 50 + events_out_of_order_policy = "Adjust" + output_error_policy = "Drop" + streaming_units = 3 + + tags = { + environment = "Example" + } + + transformation_query = <<QUERY + SELECT * + INTO [YourOutputAlias] + FROM [YourInputAlias] +QUERY +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Stream Analytics Job. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job should exist. Changing this forces a new resource to be created. + +* `location` - (Required) The Azure Region in which the Resource Group exists. Changing this forces a new resource to be created. + +* `compatibility_level` - (Required) Specifies the compatibility level for this job - which controls certain runtime behaviors of the streaming job. Possible values are `1.0` and 1.1`. + +-> **NOTE:** Support for Compatibility Level 1.2 is dependent on a new version of the Stream Analytics API, which [being tracked in this issue](https://github.com/Azure/azure-rest-api-specs/issues/5604). + +* `data_locale` - (Required) Specifies the Data Locale of the Job, which [should be a supported .NET Culture](https://msdn.microsoft.com/en-us/library/system.globalization.culturetypes(v=vs.110).aspx). + +* `events_late_arrival_max_delay_in_seconds` - (Required) Specifies the maximum tolerable delay in seconds where events arriving late could be included. Supported range is `-1` (indefinite) to `1814399` (20d 23h 59m 59s). + +* `events_out_of_order_max_delay_in_seconds` - (Required) Specifies the maximum tolerable delay in seconds where out-of-order events can be adjusted to be back in order. Supported range is `0` to `599` (9m 59s). + +* `events_out_of_order_policy` - (Required) Specifies the policy which should be applied to events which arrive out of order in the input event stream. Possible values are `Adjust` and `Drop`. + +* `output_error_policy` - (Required) Specifies the policy which should be applied to events which arrive at the output and cannot be written to the external storage due to being malformed (such as missing column values, column values of wrong type or size). Possible values are `Drop` and `Stop`. + +* `streaming_units` - (Required) Specifies the number of streaming units that the streaming job uses. Supported values are `1`, `3`, `6` and multiples of `6` up to `120`. + +* `transformation_query` - (Required) Specifies the query that will be run in the streaming job, [written in Stream Analytics Query Language (SAQL)](https://msdn.microsoft.com/library/azure/dn834998). + +* `tags` - A mapping of tags assigned to the resource. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Job. + +* `job_id` - The Job ID assigned by the Stream Analytics Job. + +## Import + +Stream Analytics Job's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_job.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1 +``` diff --git a/website/docs/r/stream_analytics_output_blob.html.markdown b/website/docs/r/stream_analytics_output_blob.html.markdown new file mode 100644 index 000000000000..27b2fe0b8813 --- /dev/null +++ b/website/docs/r/stream_analytics_output_blob.html.markdown @@ -0,0 +1,113 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_output_blob" +sidebar_current: "docs-azurerm-resource-stream-analytics-output-blob" +description: |- + Manages a Stream Analytics Output to Blob Storage. +--- + +# azurerm_stream_analytics_output_blob + +Manages a Stream Analytics Output to Blob Storage. + +## Example Usage + +```hcl +data "azurerm_resource_group" "example" { + name = "example-resources" +} + +data "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_storage_account" "example" { + name = "examplesa" + resource_group_name = "${data.azurerm_resource_group.example.name}" + location = "${data.azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "example" + resource_group_name = "${data.azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_stream_analytics_output_blob" "example" { + name = "output-to-blob-storage" + stream_analytics_job_name = "${data.azurerm_stream_analytics_job.example.name}" + resource_group_name = "${data.azurerm_stream_analytics_job.example.resource_group_name}" + storage_account_name = "${azurerm_storage_account.example.name}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + storage_container_name = "${azurerm_storage_container.example.name}" + path_pattern = "some-pattern" + date_format = "yyyy-MM-dd" + time_format = "HH" + + serialization { + type = "Csv" + encoding = "UTF8" + field_delimiter = "," + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Stream Output. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job exists. Changing this forces a new resource to be created. + +* `stream_analytics_job_name` - (Required) The name of the Stream Analytics Job. Changing this forces a new resource to be created. + +* `date_format` - (Required) The date format. Wherever `{date}` appears in `path_pattern`, the value of this property is used as the date format instead. + +* `path_pattern` - (Required) The blob path pattern. Not a regular expression. It represents a pattern against which blob names will be matched to determine whether or not they should be included as input or output to the job. + +* `storage_account_name` - (Required) The name of the Storage Account. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to this Storage Account. + +* `storage_container_name` - (Required) The name of the Container within the Storage Account. + +* `time_format` - (Required) The time format. Wherever `{time}` appears in `path_pattern`, the value of this property is used as the time format instead. + +* `serialization` - (Required) A `serialization` block as defined below. + +--- + +A `serialization` block supports the following: + +* `type` - (Required) The serialization format used for outgoing data streams. Possible values are `Avro`, `Csv` and `Json`. + +* `encoding` - (Optional) The encoding of the incoming data in the case of input and the encoding of outgoing data in the case of output. It currently can only be set to `UTF8`. + +-> **NOTE:** This is required when `type` is set to `Csv` or `Json`. + +* `field_delimiter` - (Optional) The delimiter that will be used to separate comma-separated value (CSV) records. Possible values are ` ` (space), `,` (comma), ` ` (tab), `|` (pipe) and `;`. + +-> **NOTE:** This is required when `type` is set to `Csv`. + +* `format` - (Optional) Specifies the format of the JSON the output will be written in. Possible values are `Array` and `LineSeparated`. + +-> **NOTE:** This is Required and can only be specified when `type` is set to `Json`. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Output Blob Storage. + +## Import + +Stream Analytics Outputs to Blob Storage can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_output_blob.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/outputs/output1 +``` diff --git a/website/docs/r/stream_analytics_output_eventhub.html.markdown b/website/docs/r/stream_analytics_output_eventhub.html.markdown new file mode 100644 index 000000000000..e716f7084585 --- /dev/null +++ b/website/docs/r/stream_analytics_output_eventhub.html.markdown @@ -0,0 +1,107 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_output_eventhub" +sidebar_current: "docs-azurerm-resource-stream-analytics-output-eventhub" +description: |- + Manages a Stream Analytics Output to an EventHub. +--- + +# azurerm_stream_analytics_output_eventhub + +Manages a Stream Analytics Output to an EventHub. + +## Example Usage + +```hcl +data "azurerm_resource_group" "example" { + name = "example-resources" +} + +data "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_eventhub_namespace" "test" { + name = "example-ehnamespace" + location = "${data.azurerm_resource_group.example.location}" + resource_group_name = "${data.azurerm_resource_group.example.name}" + sku = "Standard" + capacity = 1 + kafka_enabled = false +} + +resource "azurerm_eventhub" "test" { + name = "example-eventhub" + namespace_name = "${azurerm_eventhub_namespace.example.name}" + resource_group_name = "${data.azurerm_resource_group.example.name}" + partition_count = 2 + message_retention = 1 +} + +resource "azurerm_stream_analytics_output_eventhub" "example" { + name = "output-to-eventhub" + stream_analytics_job_name = "${data.azurerm_stream_analytics_job.example.name}" + resource_group_name = "${data.azurerm_stream_analytics_job.example.resource_group_name}" + eventhub_name = "${azurerm_eventhub.example.name}" + servicebus_namespace = "${azurerm_eventhub_namespace.example.name}" + shared_access_policy_key = "${azurerm_eventhub_namespace.example.default_primary_key}" + shared_access_policy_name = "RootManageSharedAccessKey" + + serialization { + type = "Avro" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Stream Output. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job exists. Changing this forces a new resource to be created. + +* `stream_analytics_job_name` - (Required) The name of the Stream Analytics Job. Changing this forces a new resource to be created. + +* `eventhub_name` - (Required) The name of the Event Hub. + +* `servicebus_namespace` - (Required) The namespace that is associated with the desired Event Hub, Service Bus Queue, Service Bus Topic, etc. + +* `shared_access_policy_key` - (Required) The shared access policy key for the specified shared access policy. + +* `shared_access_policy_name` - (Required) The shared access policy name for the Event Hub, Service Bus Queue, Service Bus Topic, etc. + +* `serialization` - (Required) A `serialization` block as defined below. + +--- + +A `serialization` block supports the following: + +* `type` - (Required) The serialization format used for outgoing data streams. Possible values are `Avro`, `Csv` and `Json`. + +* `encoding` - (Optional) The encoding of the incoming data in the case of input and the encoding of outgoing data in the case of output. It currently can only be set to `UTF8`. + +-> **NOTE:** This is required when `type` is set to `Csv` or `Json`. + +* `field_delimiter` - (Optional) The delimiter that will be used to separate comma-separated value (CSV) records. Possible values are ` ` (space), `,` (comma), ` ` (tab), `|` (pipe) and `;`. + +-> **NOTE:** This is required when `type` is set to `Csv`. + +* `format` - (Optional) Specifies the format of the JSON the output will be written in. Possible values are `Array` and `LineSeparated`. + +-> **NOTE:** This is Required and can only be specified when `type` is set to `Json`. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Output EventHub. + +## Import + +Stream Analytics Outputs to an EventHub can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_output_eventhub.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/outputs/output1 +``` diff --git a/website/docs/r/stream_analytics_output_mssql.html.markdown b/website/docs/r/stream_analytics_output_mssql.html.markdown new file mode 100644 index 000000000000..4a83de4346fa --- /dev/null +++ b/website/docs/r/stream_analytics_output_mssql.html.markdown @@ -0,0 +1,88 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_output_mssql" +sidebar_current: "docs-azurerm-resource-stream-analytics-output-mssql" +description: |- + Manages a Stream Analytics Output to Microsoft SQL Server Database. +--- + +# azurerm_stream_analytics_output_mssql + +Manages a Stream Analytics Output to Microsoft SQL Server Database. + +## Example Usage + +```hcl +data "azurerm_resource_group" "example" { + name = "example-resources" +} + +data "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_sql_server" "example" { + name = "example-server" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + version = "12.0" + administrator_login = "dbadmin" + administrator_login_password = "example-password" +} + +resource "azurerm_sql_database" "example" { + name = "exampledb" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + server_name = "${azurerm_sql_server.example.name}" + requested_service_objective_name = "S0" + collation = "SQL_LATIN1_GENERAL_CP1_CI_AS" + max_size_bytes = "268435456000" + create_mode = "Default" +} + +resource "azurerm_stream_analytics_output_mssql" "example" { + name = "example-output-sql" + stream_analytics_job_name = "${azurerm_stream_analytics_job.example.name}" + resource_group_name = "${azurerm_stream_analytics_job.example.resource_group_name}" + + server = "${azurerm_sql_server.example.fully_qualified_domain_name}" + user = "${azurerm_sql_server.example.administrator_login}" + password = "${azurerm_sql_server.example.administrator_login_password}" + database = "${azurerm_sql_database.example.name}" + table = "ExampleTable" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Stream Output. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job exists. Changing this forces a new resource to be created. + +* `stream_analytics_job_name` - (Required) The name of the Stream Analytics Job. Changing this forces a new resource to be created. + +* `server` - (Required) The SQL server url. Changing this forces a new resource to be created. + +* `user` - (Required) Username used to login to the Microsoft SQL Server. Changing this forces a new resource to be created. + +* `password` - (Required) Password used together with username, to login to the Microsoft SQL Server. Changing this forces a new resource to be created. + +* `table` - (Required) Table in the database that the output points to. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Output Microsoft SQL Server Database. + +## Import + +Stream Analytics Outputs to Microsoft SQL Server Database can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_output_mssql.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/outputs/output1 +``` diff --git a/website/docs/r/stream_analytics_output_servicebus_queue.html.markdown b/website/docs/r/stream_analytics_output_servicebus_queue.html.markdown new file mode 100644 index 000000000000..fbd728493f85 --- /dev/null +++ b/website/docs/r/stream_analytics_output_servicebus_queue.html.markdown @@ -0,0 +1,104 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_output_servicebus_queue" +sidebar_current: "docs-azurerm-resource-stream-analytics-output-servicebus-queue" +description: |- + Manages a Stream Analytics Output to a ServiceBus Queue. +--- + +# azurerm_stream_analytics_output_servicebus_queue + +Manages a Stream Analytics Output to a ServiceBus Queue. + +## Example Usage + +```hcl +data "azurerm_resource_group" "example" { + name = "example-resources" +} + +data "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_servicebus_namespace" "example" { + name = "example-namespace" + location = "${data.azurerm_resource_group.example.location}" + resource_group_name = "${data.azurerm_resource_group.example.name}" + sku = "Standard" +} + +resource "azurerm_servicebus_queue" "example" { + name = "example-queue" + resource_group_name = "${data.azurerm_resource_group.example.name}" + namespace_name = "${azurerm_servicebus_namespace.example.name}" + enable_partitioning = true +} + +resource "azurerm_stream_analytics_output_servicebus_queue" "test" { + name = "blob-storage-output" + stream_analytics_job_name = "${data.azurerm_stream_analytics_job.example.name}" + resource_group_name = "${data.azurerm_stream_analytics_job.example.resource_group_name}" + queue_name = "${azurerm_servicebus_queue.example.name}" + servicebus_namespace = "${azurerm_servicebus_namespace.example.name}" + shared_access_policy_key = "${azurerm_servicebus_namespace.example.default_primary_key}" + shared_access_policy_name = "RootManageSharedAccessKey" + + serialization { + format = "Avro" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Stream Output. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job exists. Changing this forces a new resource to be created. + +* `stream_analytics_job_name` - (Required) The name of the Stream Analytics Job. Changing this forces a new resource to be created. + +* `queue_name` - (Required) The name of the Service Bus Queue. + +* `servicebus_namespace` - (Required) The namespace that is associated with the desired Event Hub, Service Bus Queue, Service Bus Topic, etc. + +* `shared_access_policy_key` - (Required) The shared access policy key for the specified shared access policy. + +* `shared_access_policy_name` - (Required) The shared access policy name for the Event Hub, Service Bus Queue, Service Bus Topic, etc. + +* `serialization` - (Required) A `serialization` block as defined below. + +--- + +A `serialization` block supports the following: + +* `type` - (Required) The serialization format used for outgoing data streams. Possible values are `Avro`, `Csv` and `Json`. + +* `encoding` - (Optional) The encoding of the incoming data in the case of input and the encoding of outgoing data in the case of output. It currently can only be set to `UTF8`. + +-> **NOTE:** This is required when `type` is set to `Csv` or `Json`. + +* `field_delimiter` - (Optional) The delimiter that will be used to separate comma-separated value (CSV) records. Possible values are ` ` (space), `,` (comma), ` ` (tab), `|` (pipe) and `;`. + +-> **NOTE:** This is required when `type` is set to `Csv`. + +* `format` - (Optional) Specifies the format of the JSON the output will be written in. Possible values are `Array` and `LineSeparated`. + +-> **NOTE:** This is Required and can only be specified when `type` is set to `Json`. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Output ServiceBus Queue. + +## Import + +Stream Analytics Output ServiceBus Queue's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_output_servicebus_queue.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/outputs/output1 +``` diff --git a/website/docs/r/stream_analytics_stream_input_blob.html.markdown b/website/docs/r/stream_analytics_stream_input_blob.html.markdown new file mode 100644 index 000000000000..46b7d61133c0 --- /dev/null +++ b/website/docs/r/stream_analytics_stream_input_blob.html.markdown @@ -0,0 +1,108 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_stream_input_blob" +sidebar_current: "docs-azurerm-resource-stream-analytics-stream-input-blob" +description: |- + Manages a Stream Analytics Stream Input Blob. +--- + +# azurerm_stream_analytics_stream_input_blob + +Manages a Stream Analytics Stream Input Blob. + +## Example Usage + +```hcl +data "azurerm_resource_group" "example" { + name = "example-resources" +} + +data "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_storage_account" "example" { + name = "examplestoracc" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = "example" + resource_group_name = "${azurerm_resource_group.example.name}" + storage_account_name = "${azurerm_storage_account.example.name}" + container_access_type = "private" +} + +resource "azurerm_stream_analytics_stream_input_eventhub" "test" { + name = "eventhub-stream-input" + stream_analytics_job_name = "${data.azurerm_stream_analytics_job.example.name}" + resource_group_name = "${data.azurerm_stream_analytics_job.example.resource_group_name}" + storage_account_name = "${azurerm_storage_account.example.name}" + storage_account_key = "${azurerm_storage_account.example.primary_access_key}" + storage_container_name = "${azurerm_storage_container.example.name}" + path_pattern = "some-random-pattern" + date_format = "yyyy/MM/dd" + time_format = "HH" + + serialization { + type = "Json" + encoding = "UTF8" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Stream Input Blob. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job exists. Changing this forces a new resource to be created. + +* `stream_analytics_job_name` - (Required) The name of the Stream Analytics Job. Changing this forces a new resource to be created. + +* `date_format` - (Required) The date format. Wherever `{date}` appears in `path_pattern`, the value of this property is used as the date format instead. + +* `path_pattern` - (Required) The blob path pattern. Not a regular expression. It represents a pattern against which blob names will be matched to determine whether or not they should be included as input or output to the job. + +* `storage_account_name` - (Required) The name of the Storage Account. + +* `storage_account_key` - (Required) The Access Key which should be used to connect to this Storage Account. + +* `storage_container_name` - (Required) The name of the Container within the Storage Account. + +* `time_format` - (Required) The time format. Wherever `{time}` appears in `path_pattern`, the value of this property is used as the time format instead. + +* `serialization` - (Required) A `serialization` block as defined below. + +--- + +A `serialization` block supports the following: + +* `type` - (Required) The serialization format used for incoming data streams. Possible values are `Avro`, `Csv` and `Json`. + +* `encoding` - (Optional) The encoding of the incoming data in the case of input and the encoding of outgoing data in the case of output. It currently can only be set to `UTF8`. + +-> **NOTE:** This is required when `type` is set to `Csv` or `Json`. + +* `field_delimiter` - (Optional) The delimiter that will be used to separate comma-separated value (CSV) records. Possible values are ` ` (space), `,` (comma), ` ` (tab), `|` (pipe) and `;`. + +-> **NOTE:** This is required when `type` is set to `Csv`. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Stream Input Blob. + +## Import + +Stream Analytics Stream Input Blob's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_stream_input_blob.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/inputs/input1 +``` diff --git a/website/docs/r/stream_analytics_stream_input_eventhub.html.markdown b/website/docs/r/stream_analytics_stream_input_eventhub.html.markdown new file mode 100644 index 000000000000..49084e1a6c03 --- /dev/null +++ b/website/docs/r/stream_analytics_stream_input_eventhub.html.markdown @@ -0,0 +1,114 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_stream_input_eventhub" +sidebar_current: "docs-azurerm-resource-stream-analytics-stream-input-eventhub" +description: |- + Manages a Stream Analytics Stream Input EventHub. +--- + +# azurerm_stream_analytics_stream_input_eventhub + +Manages a Stream Analytics Stream Input EventHub. + +## Example Usage + +```hcl +data "azurerm_resource_group" "example" { + name = "example-resources" +} + +data "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_eventhub_namespace" "example" { + name = "example-namespace" + location = "${data.azurerm_resource_group.example.location}" + resource_group_name = "${data.azurerm_resource_group.example.name}" + sku = "Standard" + capacity = 1 + kafka_enabled = false +} + +resource "azurerm_eventhub" "example" { + name = "example-eventhub" + namespace_name = "${azurerm_eventhub_namespace.example.name}" + resource_group_name = "${data.azurerm_resource_group.example.name}" + partition_count = 2 + message_retention = 1 +} + +resource "azurerm_eventhub_consumer_group" "test" { + name = "example-consumergroup" + namespace_name = "${azurerm_eventhub_namespace.test.name}" + eventhub_name = "${azurerm_eventhub.test.name}" + resource_group_name = "${data.azurerm_resource_group.test.name}" +} + +resource "azurerm_stream_analytics_stream_input_eventhub" "test" { + name = "eventhub-stream-input" + stream_analytics_job_name = "${data.azurerm_stream_analytics_job.example.name}" + resource_group_name = "${data.azurerm_stream_analytics_job.example.resource_group_name}" + eventhub_consumer_group_name = "${azurerm_eventhub_consumer_group.example.name}" + eventhub_name = "${azurerm_eventhub.example.name}" + servicebus_namespace = "${azurerm_eventhub_namespace.example.name}" + shared_access_policy_key = "${azurerm_eventhub_namespace.example.default_primary_key}" + shared_access_policy_name = "RootManageSharedAccessKey" + + serialization { + type = "Json" + encoding = "UTF8" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Stream Input EventHub. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job exists. Changing this forces a new resource to be created. + +* `stream_analytics_job_name` - (Required) The name of the Stream Analytics Job. Changing this forces a new resource to be created. + +* `eventhub_consumer_group_name` - (Required) The name of an Event Hub Consumer Group that should be used to read events from the Event Hub. Specifying distinct consumer group names for multiple inputs allows each of those inputs to receive the same events from the Event Hub. + +* `eventhub_name` - (Required) The name of the Event Hub. + +* `servicebus_namespace` - (Required) The namespace that is associated with the desired Event Hub, Service Bus Queue, Service Bus Topic, etc. + +* `shared_access_policy_key` - (Required) The shared access policy key for the specified shared access policy. + +* `shared_access_policy_name` - (Required) The shared access policy name for the Event Hub, Service Bus Queue, Service Bus Topic, etc. + +* `serialization` - (Required) A `serialization` block as defined below. + +--- + +A `serialization` block supports the following: + +* `type` - (Required) The serialization format used for incoming data streams. Possible values are `Avro`, `Csv` and `Json`. + +* `encoding` - (Optional) The encoding of the incoming data in the case of input and the encoding of outgoing data in the case of output. It currently can only be set to `UTF8`. + +-> **NOTE:** This is required when `type` is set to `Csv` or `Json`. + +* `field_delimiter` - (Optional) The delimiter that will be used to separate comma-separated value (CSV) records. Possible values are ` ` (space), `,` (comma), ` ` (tab), `|` (pipe) and `;`. + +-> **NOTE:** This is required when `type` is set to `Csv`. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Stream Input EventHub. + +## Import + +Stream Analytics Stream Input EventHub's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_stream_input_eventhub.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/inputs/input1 +``` diff --git a/website/docs/r/stream_analytics_stream_input_iothub.html.markdown b/website/docs/r/stream_analytics_stream_input_iothub.html.markdown new file mode 100644 index 000000000000..538ad464bc1f --- /dev/null +++ b/website/docs/r/stream_analytics_stream_input_iothub.html.markdown @@ -0,0 +1,102 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_stream_analytics_stream_input_iothub" +sidebar_current: "docs-azurerm-resource-stream-analytics-stream-input-iothub" +description: |- + Manages a Stream Analytics Stream Input IoTHub. +--- + +# azurerm_stream_analytics_stream_input_iothub + +Manages a Stream Analytics Stream Input IoTHub. + +## Example Usage + +```hcl +data "azurerm_resource_group" "example" { + name = "example-resources" +} + +data "azurerm_stream_analytics_job" "example" { + name = "example-job" + resource_group_name = "${azurerm_resource_group.example.name}" +} + +resource "azurerm_iothub" "test" { + name = "example-iothub" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} + +resource "azurerm_stream_analytics_stream_input_iothub" "test" { + name = "example-iothub-input" + stream_analytics_job_name = "${data.azurerm_stream_analytics_job.example.name}" + resource_group_name = "${data.azurerm_stream_analytics_job.example.resource_group_name}" + endpoint = "messages/events" + eventhub_consumer_group_name = "$Default" + iothub_namespace = "${azurerm_iothub.example.name}" + shared_access_policy_key = "${azurerm_iothub.example.shared_access_policy.0.primary_key}" + shared_access_policy_name = "iothubowner" + + serialization { + type = "Json" + encoding = "UTF8" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Stream Input IoTHub. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the Resource Group where the Stream Analytics Job exists. Changing this forces a new resource to be created. + +* `stream_analytics_job_name` - (Required) The name of the Stream Analytics Job. Changing this forces a new resource to be created. + +* `eventhub_consumer_group_name` - (Required) The name of an Event Hub Consumer Group that should be used to read events from the Event Hub. Specifying distinct consumer group names for multiple inputs allows each of those inputs to receive the same events from the Event Hub. + +* `endpoint` - (Required) The IoT Hub endpoint to connect to (ie. messages/events, messages/operationsMonitoringEvents, etc.). + +* `iothub_namespace` - (Required) The name or the URI of the IoT Hub. + +* `serialization` - (Required) A `serialization` block as defined below. + +* `shared_access_policy_key` - (Required) The shared access policy key for the specified shared access policy. + +* `shared_access_policy_name` - (Required) The shared access policy name for the Event Hub, Service Bus Queue, Service Bus Topic, etc. + +--- + +A `serialization` block supports the following: + +* `type` - (Required) The serialization format used for incoming data streams. Possible values are `Avro`, `Csv` and `Json`. + +* `encoding` - (Optional) The encoding of the incoming data in the case of input and the encoding of outgoing data in the case of output. It currently can only be set to `UTF8`. + +-> **NOTE:** This is required when `type` is set to `Csv` or `Json`. + +* `field_delimiter` - (Optional) The delimiter that will be used to separate comma-separated value (CSV) records. Possible values are ` ` (space), `,` (comma), ` ` (tab), `|` (pipe) and `;`. + +-> **NOTE:** This is required when `type` is set to `Csv`. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Stream Input IoTHub. + +## Import + +Stream Analytics Stream Input IoTHub's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_stream_input_iothub.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/inputs/input1 +``` diff --git a/website/docs/r/subnet.html.markdown b/website/docs/r/subnet.html.markdown index 227fb5ffe9f7..693f3afdc957 100644 --- a/website/docs/r/subnet.html.markdown +++ b/website/docs/r/subnet.html.markdown @@ -35,11 +35,13 @@ resource "azurerm_subnet" "test" { resource_group_name = "${azurerm_resource_group.test.name}" virtual_network_name = "${azurerm_virtual_network.test.name}" address_prefix = "10.0.1.0/24" + delegation { name = "acctestdelegation" + service_delegation { name = "Microsoft.ContainerInstance/containerGroups" - actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"] } } } @@ -59,20 +61,22 @@ The following arguments are supported: * `network_security_group_id` - (Optional / **Deprecated**) The ID of the Network Security Group to associate with the subnet. --> **NOTE:** At this time Subnet `<->` Network Security Group associations need to be configured both using this field (which is now Deprecated) and/or using the `azurerm_subnet_network_security_group_association` resource. This field field is deprecated and will be removed in favour of that resource in the next major version (2.0) of the AzureRM Provider. +-> **NOTE:** At this time Subnet `<->` Network Security Group associations need to be configured both using this field (which is now Deprecated) and/or using the `azurerm_subnet_network_security_group_association` resource. This field is deprecated and will be removed in favour of that resource in the next major version (2.0) of the AzureRM Provider. * `route_table_id` - (Optional / **Deprecated**) The ID of the Route Table to associate with the subnet. -> **NOTE:** At this time Subnet `<->` Route Table associations need to be configured both using this field (which is now Deprecated) and/or using the `azurerm_subnet_route_table_association` resource. This field is deprecated and will be removed in favour of that resource in the next major version (2.0) of the AzureRM Provider. -* `service_endpoints` - (Optional) The list of Service endpoints to associate with the subnet. Possible values include: `Microsoft.AzureActiveDirectory`, `Microsoft.AzureCosmosDB`, `Microsoft.EventHub`, `Microsoft.KeyVault`, `Microsoft.ServiceBus`, `Microsoft.Sql` and `Microsoft.Storage`. +* `service_endpoints` - (Optional) The list of Service endpoints to associate with the subnet. Possible values include: `Microsoft.AzureActiveDirectory`, `Microsoft.AzureCosmosDB`, `Microsoft.ContainerRegistry`, `Microsoft.EventHub`, `Microsoft.KeyVault`, `Microsoft.ServiceBus`, `Microsoft.Sql`, `Microsoft.Storage` and `Microsoft.Web`. * `delegation` - (Optional) One or more `delegation` blocks as defined below. --- A `delegation` block supports the following: + * `name` (Required) A name for this delegation. + * `service_delegation` (Required) A `service_delegation` block as defined below. --- @@ -80,8 +84,10 @@ A `delegation` block supports the following: A `service_delegation` block supports the following: -> **NOTE:** Delegating to services may not be available in all regions. Check that the service you are delegating to is available in your region using the [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/network/vnet/subnet?view=azure-cli-latest#az-network-vnet-subnet-list-available-delegations) -* `name` - (Required) The name of service to delegate to. Possible values include: `Microsoft.Batch/batchAccounts`, `Microsoft.ContainerInstance/containerGroups`, `Microsoft.HardwareSecurityModules/dedicatedHSMs`, `Microsoft.Logic/integrationServiceEnvironments`, `Microsoft.Netapp/volumes`, `Microsoft.ServiceFabricMesh/networks`, `Microsoft.Sql/managedInstances`, `Microsoft.Sql/servers` or `Microsoft.Web/serverFarms`. -* `actions` - (Optional) A list of Actions which should be delegated. Possible values include: `Microsoft.Network/virtualNetworks/subnets/action`. + +* `name` - (Required) The name of service to delegate to. Possible values include `Microsoft.BareMetal/AzureVMware`, `Microsoft.BareMetal/CrayServers`, `Microsoft.Batch/batchAccounts`, `Microsoft.ContainerInstance/containerGroups`, `Microsoft.Databricks/workspaces`, `Microsoft.HardwareSecurityModules/dedicatedHSMs`, `Microsoft.Logic/integrationServiceEnvironments`, `Microsoft.Netapp/volumes`, `Microsoft.ServiceFabricMesh/networks`, `Microsoft.Sql/managedInstances`, `Microsoft.Sql/servers`, `Microsoft.Web/hostingEnvironments` and `Microsoft.Web/serverFarms`. + +* `actions` - (Required) A list of Actions which should be delegated. Possible values include `Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action`, `Microsoft.Network/virtualNetworks/subnets/action` and `Microsoft.Network/virtualNetworks/subnets/join/action`. ## Attributes Reference diff --git a/website/docs/r/template_deployment.html.markdown b/website/docs/r/template_deployment.html.markdown index 21edb1bb6bf0..ec3632c9f6a9 100644 --- a/website/docs/r/template_deployment.html.markdown +++ b/website/docs/r/template_deployment.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_template_deployment -Manage a template deployment of resources +Manages a template deployment of resources ~> **Note on ARM Template Deployments:** Due to the way the underlying Azure API is designed, Terraform can only manage the deployment of the ARM Template - and not any resources which are created by it. This means that when deleting the `azurerm_template_deployment` resource, Terraform will only remove the reference to the deployment, whilst leaving any resources created by that ARM Template Deployment. diff --git a/website/docs/r/traffic_manager_endpoint.html.markdown b/website/docs/r/traffic_manager_endpoint.html.markdown index 131744b775d0..b6b237b255ae 100644 --- a/website/docs/r/traffic_manager_endpoint.html.markdown +++ b/website/docs/r/traffic_manager_endpoint.html.markdown @@ -38,9 +38,12 @@ resource "azurerm_traffic_manager_profile" "test" { } monitor_config { - protocol = "http" - port = 80 - path = "/" + protocol = "http" + port = 80 + path = "/" + interval_in_seconds = 30 + timeout_in_seconds = 9 + tolerated_number_of_failures = 3 } tags = { @@ -110,6 +113,27 @@ The following arguments are supported: * `geo_mappings` - (Optional) A list of Geographic Regions used to distribute traffic, such as `WORLD`, `UK` or `DE`. The same location can't be specified in two endpoints. [See the Geographic Hierarchies documentation for more information](https://docs.microsoft.com/en-us/rest/api/trafficmanager/geographichierarchies/getdefault). +* `custom_header` - (Optional) One or more `custom_header` blocks as defined below + +* `subnet` - (Optional) One or more `subnet` blocks as defined below + +--- +A `custom_header` block supports the following: + +* `name` - (Required) The name of the custom header. + +* `value` - (Required) The value of custom header. Applicable for Http and Https protocol. + +A `subnet` block supports the following: + +* `first` - (Required) The First IP.... + +* `last` - (Optional) The Last IP... + +* `scope` - (Optional) The Scope... + +-> **NOTE:** One and only one of either `last` (in case of IP range) or `scope` (in case of CIDR) must be specified. + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/traffic_manager_profile.html.markdown b/website/docs/r/traffic_manager_profile.html.markdown index e8785a589e2b..4b1f03553c14 100644 --- a/website/docs/r/traffic_manager_profile.html.markdown +++ b/website/docs/r/traffic_manager_profile.html.markdown @@ -39,9 +39,12 @@ resource "azurerm_traffic_manager_profile" "test" { } monitor_config { - protocol = "http" - port = 80 - path = "/" + protocol = "http" + port = 80 + path = "/" + interval_in_seconds = 30 + timeout_in_seconds = 9 + tolerated_number_of_failures = 3 } tags = { @@ -63,12 +66,13 @@ The following arguments are supported: * `profile_status` - (Optional) The status of the profile, can be set to either `Enabled` or `Disabled`. Defaults to `Enabled`. -* `traffic_routing_method` - (Required) Specifies the algorithm used to route - traffic, possible values are: +* `traffic_routing_method` - (Required) Specifies the algorithm used to route traffic, possible values are: - `Geographic` - Traffic is routed based on Geographic regions specified in the Endpoint. + - `MultiValue`- All healthy Endpoints are returned. MultiValue routing method works only if all the endpoints of type ‘External’ and are specified as IPv4 or IPv6 addresses. - `Performance` - Traffic is routed via the User's closest Endpoint - - `Weighted` - Traffic is spread across Endpoints proportional to their `weight` value. - `Priority` - Traffic is routed to the Endpoint with the lowest `priority` value. + - `Subnet` - Traffic is routed based on a mapping of sets of end-user IP address ranges to a specific Endpoint within a Traffic Manager profile. + - `Weighted` - Traffic is spread across Endpoints proportional to their `weight` value. * `dns_config` - (Required) This block specifies the DNS configuration of the Profile, it supports the fields documented below. @@ -96,6 +100,12 @@ The `monitor_config` block supports: * `path` - (Optional) The path used by the monitoring checks. Required when `protocol` is set to `HTTP` or `HTTPS` - cannot be set when `protocol` is set to `TCP`. +* `interval_in_seconds` - (Optional) The interval used to check the endpoint health from a Traffic Manager probing agent. You can specify two values here: `30` (normal probing) and `10` (fast probing). The default value is `30`. + +* `timeout_in_seconds` - (Optional) The amount of time the Traffic Manager probing agent should wait before considering that check a failure when a health check probe is sent to the endpoint. If `interval_in_seconds` is set to `30`, then `timeout_in_seconds` can be between `5` and `10`. The default value is `10`. If `interval_in_seconds` is set to `10`, then valid values are between `5` and `9` and `timeout_in_seconds` is required. + +* `tolerated_number_of_failures` - (Optional) The number of failures a Traffic Manager probing agent tolerates before marking that endpoint as unhealthy. Valid values are between `0` and `9`. The default value is `3` + ## Attributes Reference The following attributes are exported: diff --git a/website/docs/r/user_assigned_identity.markdown b/website/docs/r/user_assigned_identity.markdown index 5e7a47207a75..9812ce1d32af 100644 --- a/website/docs/r/user_assigned_identity.markdown +++ b/website/docs/r/user_assigned_identity.markdown @@ -53,7 +53,7 @@ The following attributes are exported: ## Import -User Assigned Identitites can be imported using the `resource id`, e.g. +User Assigned Identities can be imported using the `resource id`, e.g. ```shell terraform import azurerm_user_assigned_identity.testIdentity /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/acceptanceTestResourceGroup1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testIdentity diff --git a/website/docs/r/virtual_machine.html.markdown b/website/docs/r/virtual_machine.html.markdown index b2b93b5718eb..61ef25512a2b 100644 --- a/website/docs/r/virtual_machine.html.markdown +++ b/website/docs/r/virtual_machine.html.markdown @@ -116,6 +116,8 @@ The following arguments are supported: * `boot_diagnostics` - (Optional) A `boot_diagnostics` block. +* `additional_capabilities` - (Optional) A `additional_capabilities` block. + * `delete_os_disk_on_termination` - (Optional) Should the OS Disk (either the Managed Disk / VHD Blob) be deleted when the Virtual Machine is destroyed? Defaults to `false`. * `delete_data_disks_on_termination` - (Optional) Should the Data Disks (either the Managed Disks / VHD Blobs) be deleted when the Virtual Machine is destroyed? Defaults to `false`. @@ -172,6 +174,14 @@ A `boot_diagnostics` block supports the following: --- +A `additional_capabilities` block supports the following: + +* `ultra_ssd_enabled` - (Required) Should Ultra SSD disk be enabled for this Virtual Machine? + +-> **Note**: Azure Ultra Disk Storage is currently in preview and are not available to subscriptions that have not [requested](https://aka.ms/UltraSSDPreviewSignUp) onboarding to `Azure Ultra Disk Storage` preview. `Azure Ultra Disk Storage` is only available in `East US 2`, `North Europe`, and `Southeast Asia` regions. For more information see the `Azure Ultra Disk Storage` [product documentation](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/disks-enable-ultra-ssd), [product blog](https://azure.microsoft.com/en-us/blog/announcing-the-general-availability-of-azure-ultra-disk-storage/) and [FAQ](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/faq-for-disks#ultra-disks). + +--- + A `identity` block supports the following: * `type` - (Required) The Managed Service Identity Type of this Virtual Machine. Possible values are `SystemAssigned` (where Azure will generate a Service Principal for you), `UserAssigned` (where you can specify the Service Principal ID's) to be used by this Virtual Machine using the `identity_ids` field, and `SystemAssigned, UserAssigned` which assigns both a system managed identity as well as the specified user assigned identities. @@ -291,7 +301,7 @@ A `storage_data_disk` block supports the following: * `create_option` - (Required) Specifies how the data disk should be created. Possible values are `Attach`, `FromImage` and `Empty`. -* `disk_size_gb` - (Required) Specifies the size of the data disk in gigabytes. +* `disk_size_gb` - (Optional) Specifies the size of the data disk in gigabytes. * `lun` - (Required) Specifies the logical unit number of the data disk. This needs to be unique within all the Data Disks on the Virtual Machine. @@ -299,7 +309,9 @@ A `storage_data_disk` block supports the following: The following properties apply when using Managed Disks: -* `managed_disk_type` - (Optional) Specifies the type of managed disk to create. Possible values are either `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS`. +* `managed_disk_type` - (Optional) Specifies the type of managed disk to create. Possible values are either `Standard_LRS`, `StandardSSD_LRS`, `Premium_LRS` or `UltraSSD_LRS`. + +-> **Note**: `managed_disk_type` of type `UltraSSD_LRS` is currently in preview and are not available to subscriptions that have not [requested](https://aka.ms/UltraSSDPreviewSignUp) onboarding to `Azure Ultra Disk Storage` preview. `Azure Ultra Disk Storage` is only available in `East US 2`, `North Europe`, and `Southeast Asia` regions. For more information see the `Azure Ultra Disk Storage` [product documentation](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/disks-enable-ultra-ssd), [product blog](https://azure.microsoft.com/en-us/blog/announcing-the-general-availability-of-azure-ultra-disk-storage/) and [FAQ](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/faq-for-disks#ultra-disks). You must also set `additional_capabilities.ultra_ssd_enabled` to `true`. * `managed_disk_id` - (Optional) Specifies the ID of an Existing Managed Disk which should be attached to this Virtual Machine. When this field is set `create_option` must be set to `Attach`. diff --git a/website/docs/r/virtual_machine_scale_set.html.markdown b/website/docs/r/virtual_machine_scale_set.html.markdown index 0b07a5207eb8..5c6001cb2978 100644 --- a/website/docs/r/virtual_machine_scale_set.html.markdown +++ b/website/docs/r/virtual_machine_scale_set.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_virtual_machine_scale_set -Manage a virtual machine scale set. +Manages a virtual machine scale set. ~> **Note:** All arguments including the administrator login and password will be stored in the raw state as plain-text. [Read more about sensitive data in state](/docs/state/sensitive-data.html). @@ -65,7 +65,6 @@ resource "azurerm_lb_backend_address_pool" "bpepool" { } resource "azurerm_lb_nat_pool" "lbnatpool" { - count = 3 resource_group_name = "${azurerm_resource_group.test.name}" name = "ssh" loadbalancer_id = "${azurerm_lb.test.id}" @@ -80,6 +79,7 @@ resource "azurerm_lb_probe" "test" { resource_group_name = "${azurerm_resource_group.test.name}" loadbalancer_id = "${azurerm_lb.test.id}" name = "http-probe" + protocol = "Http" request_path = "/health" port = 8080 } @@ -444,7 +444,7 @@ output "principal_id" { `public_ip_address_configuration` supports the following: * `name` - (Required) The name of the public ip address configuration -* `idle_timeout` - (Required) The idle timeout in minutes. This value must be between 4 and 32. +* `idle_timeout` - (Required) The idle timeout in minutes. This value must be between 4 and 30. * `domain_name_label` - (Required) The domain name label for the dns settings. `storage_profile_os_disk` supports the following: @@ -489,6 +489,7 @@ machine scale set, as in the [example below](#example-of-storage_profile_image_r * `type` - (Required) The type of extension, available types for a publisher can be found using the Azure CLI. * `type_handler_version` - (Required) Specifies the version of the extension to use, available versions can be found using the Azure CLI. * `auto_upgrade_minor_version` - (Optional) Specifies whether or not to use the latest minor version available. +* `provision_after_extensions` - (Optional) Specifies a dependency array of extensions required to be executed before, the array stores the name of each extension. * `settings` - (Required) The settings passed to the extension, these are specified as a JSON object in a string. * `protected_settings` - (Optional) The protected_settings passed to the extension, like settings, these are specified as a JSON object in a string. diff --git a/website/docs/r/virtual_network.html.markdown b/website/docs/r/virtual_network.html.markdown index c73e4c518a3e..7c08d34fe5ce 100644 --- a/website/docs/r/virtual_network.html.markdown +++ b/website/docs/r/virtual_network.html.markdown @@ -41,7 +41,7 @@ resource "azurerm_virtual_network" "test" { resource_group_name = "${azurerm_resource_group.test.name}" address_space = ["10.0.0.0/16"] dns_servers = ["10.0.0.4", "10.0.0.5"] - + ddos_protection_plan { id = "${azurerm_ddos_protection_plan.test.id}" enable = true diff --git a/website/docs/r/virtual_network_gateway.html.markdown b/website/docs/r/virtual_network_gateway.html.markdown index 92c6358f6090..19f4fe55d732 100644 --- a/website/docs/r/virtual_network_gateway.html.markdown +++ b/website/docs/r/virtual_network_gateway.html.markdown @@ -135,7 +135,7 @@ The following arguments are supported: * `sku` - (Required) Configuration of the size and capacity of the virtual network gateway. Valid options are `Basic`, `Standard`, `HighPerformance`, `UltraPerformance`, - `ErGw1AZ`, `ErGw2AZ`, `ErGw3AZ`, `VpnGw1`, `VpnGw2` and `VpnGw3` + `ErGw1AZ`, `ErGw2AZ`, `ErGw3AZ`, `VpnGw1`, `VpnGw2`, `VpnGw3`, `VpnGw1AZ`, `VpnGw2AZ`, and `VpnGw3AZ` and depend on the `type` and `vpn_type` arguments. A `PolicyBased` gateway only supports the `Basic` sku. Further, the `UltraPerformance` sku is only supported by an `ExpressRoute` gateway. diff --git a/website/docs/r/virtual_network_gateway_connection.html.markdown b/website/docs/r/virtual_network_gateway_connection.html.markdown index 6291f947868b..bb4079b01af1 100644 --- a/website/docs/r/virtual_network_gateway_connection.html.markdown +++ b/website/docs/r/virtual_network_gateway_connection.html.markdown @@ -247,6 +247,8 @@ The following arguments are supported: * `enable_bgp` - (Optional) If `true`, BGP (Border Gateway Protocol) is enabled for this connection. Defaults to `false`. +* `express_route_gateway_bypass` - (Optional) If `true`, data packets will bypass ExpressRoute Gateway for data forwarding This is only valid for ExpressRoute connections. + * `use_policy_based_traffic_selectors` - (Optional) If `true`, policy-based traffic selectors are enabled for this connection. Enabling policy-based traffic selectors requires an `ipsec_policy` block. Defaults to `false`. diff --git a/website/docs/r/virtual_wan.html.markdown b/website/docs/r/virtual_wan.html.markdown new file mode 100644 index 000000000000..a8440db27597 --- /dev/null +++ b/website/docs/r/virtual_wan.html.markdown @@ -0,0 +1,63 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_virtual_wan" +sidebar_current: "docs-azurerm-resource-network-virtual-wan" +description: |- + Manages a Virtual WAN. + +--- + +# azurerm_virtual_wan + +Manages a Virtual WAN. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_virtual_wan" "test" { + name = "example-vwan" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Virtual WAN. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to create the Virtual WAN. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `disable_vpn_encryption` - (Optional) Boolean flag to specify whether VPN encryption is disabled. Defaults to `false`. + +* `security_provider_name` - (Optional) The name of the Security Provider. + +* `allow_branch_to_branch_traffic` - (Optional) Boolean flag to specify whether branch to branch traffic is allowed. Defaults to `true`. + +* `allow_vnet_to_vnet_traffic` - (Optional) Boolean flag to specify whether VNet to VNet traffic is allowed. Defaults to `false`. + +* `office365_local_breakout_category` - (Optional) Specifies the Office365 local breakout category. Possible values include: `Optimize`, `OptimizeAndAllow`, `All`, `None`. Defaults to `None`. + +* `tags` - (Optional) A mapping of tags to assign to the Virtual WAN. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Virtual WAN. + +## Import + +Virtual WAN can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_virtual_wan.test /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Network/virtualWans/testvwan +``` diff --git a/website/docs/r/web_application_firewall_policy.html.markdown b/website/docs/r/web_application_firewall_policy.html.markdown new file mode 100644 index 000000000000..e8aacfcf975f --- /dev/null +++ b/website/docs/r/web_application_firewall_policy.html.markdown @@ -0,0 +1,145 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_web_application_firewall_policy" +sidebar_current: "docs-azurerm-resource-web-application-firewall-policy" +description: |- + Manages a Azure Web Application Firewall Policy instance. +--- + +# azurerm_web_application_firewall_policy + +Manages a Azure Web Application Firewall Policy instance. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-rg" + location = "West US 2" +} + +resource "azurerm_web_application_firewall_policy" "example" { + name = "example-wafpolicy" + resource_group_name = "${azurerm_resource_group.example.name}" + location = "${azurerm_resource_group.example.location}" + + custom_rules { + name = "Rule1" + priority = 1 + rule_type = "MatchRule" + + match_conditions { + match_variables { + variable_name = "RemoteAddr" + } + + operator = "IPMatch" + negation_condition = false + match_values = ["192.168.1.0/24", "10.0.0.0/24"] + } + + action = "Block" + } + + custom_rules { + name = "Rule2" + priority = 2 + rule_type = "MatchRule" + + match_conditions { + match_variables { + variable_name = "RemoteAddr" + } + + operator = "IPMatch" + negation_condition = false + match_values = ["192.168.1.0/24"] + } + + match_conditions { + match_variables { + variable_name = "RequestHeaders" + selector = "UserAgent" + } + + operator = "Contains" + negation_condition = false + match_values = ["Windows"] + } + + action = "Block" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the policy. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group. Changing this forces a new resource to be created. + +* `location` - (Optional) Resource location. Changing this forces a new resource to be created. + +* `custom_rules` - (Optional) One or more `custom_rule` blocks as defined below. + +* `policy_settings` - (Optional) A `policy_setting` block as defined below. + +* `tags` - (Optional) A mapping of tags to assign to the Web Application Firewall Policy. + +--- + +The `custom_rule` block supports the following: + +* `name` - (Optional) Gets name of the resource that is unique within a policy. This name can be used to access the resource. + +* `priority` - (Required) Describes priority of the rule. Rules with a lower value will be evaluated before rules with a higher value + +* `rule_type` - (Required) Describes the type of rule + +* `match_conditions` - (Required) One or more `match_condition` block defined below. + +* `action` - (Required) Type of Actions + +--- + +The `match_condition` block supports the following: + +* `match_variables` - (Required) One or more `match_variable` block defined below. + +* `operator` - (Required) Describes operator to be matched + +* `negation_condition` - (Optional) Describes if this is negate condition or not + +* `match_values` - (Required) Match value + +--- + +The `match_variable` block supports the following: + +* `variable_name` - (Required) The name of the Match Variable + +* `selector` - (Optional) Describes field of the matchVariable collection + +--- + +The `policy_setting` block supports the following: + +* `enabled` - (Optional) Describes if the policy is in enabled state or disabled state Defaults to `Enabled`. + +* `mode` - (Optional) Describes if it is in detection mode or prevention mode at the policy level Defaults to `Prevention`. + +## Attributes Reference + +The following attributes are exported: + +* `id` - Resource ID. + +## Import + +Web Application Firewall Policy can be imported using the `resource id`, e.g. + +```shell +$ terraform import azurerm_web_application_firewall_policy.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/example-wafpolicy +```